Files
LWLT-AIBOT/LianSyn-platform/index.html

413 lines
23 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="theme-color" content="#edf2f4">
<title>AI操作台 · LianSyn-platform</title>
<link rel="stylesheet" href="styles.css?v=20260902-account-authorization-layout-1">
</head>
<body>
<main class="app-shell">
<header class="topbar">
<div class="brand-block">
<img class="brand-logo" src="assets/ltjt-platform-logo.png" alt="LianSyn-platform">
</div>
<nav class="top-nav" aria-label="主菜单">
<a id="workbenchNav" class="top-nav-item is-active" aria-current="page" href="/">AI操作台</a>
<a id="historyNav" class="top-nav-item" href="/history">历史任务</a>
<a id="operationsDashboardNav" class="top-nav-item" href="/operations-dashboard" hidden>平台运行看板</a>
<a id="channelsNav" class="top-nav-item" href="/channels" hidden>AgentBus 渠道</a>
<a id="parserRoutingNav" class="top-nav-item" href="/parser-routing" hidden>解析策略</a>
<a id="accountsNav" class="top-nav-item" href="/accounts" hidden>账号管理</a>
<a id="auditNav" class="top-nav-item" href="/audit" hidden>审计记录</a>
</nav>
<div class="top-actions">
<span id="authState" class="auth-state" hidden></span>
<button id="automationToggleButton" type="button" class="automation-toggle" hidden aria-pressed="false" title="开启后,所有来源的新任务解析通过后将跳过人工确认并自动进入 ERP"></button>
<button id="changePasswordButton" type="button" class="logout-button" hidden>修改密码</button>
<button id="logoutButton" type="button" class="logout-button" hidden>退出登录</button>
<button id="aiState" type="button" class="status-icon state-bad" title="点击查看 AI 状态详情" aria-expanded="false" aria-controls="statusDetailsPopover">
<span class="status-icon-glyph" aria-hidden="true"></span>
<span class="status-icon-label">AI状态</span>
<span class="status-icon-value">未连接</span>
</button>
<button id="bridgeState" type="button" class="status-icon state-bad" title="点击查看插件状态详情" aria-expanded="false" aria-controls="statusDetailsPopover">
<span class="status-icon-glyph" aria-hidden="true"></span>
<span class="status-icon-label">插件状态</span>
<span class="status-icon-value">未连接</span>
</button>
<section id="statusDetailsPopover" class="status-popover" role="dialog" aria-modal="false" aria-labelledby="statusDetailsTitle" hidden>
<header class="status-popover-head">
<div>
<p class="status-popover-eyebrow">CONNECTION DETAILS</p>
<h2 id="statusDetailsTitle">状态详情</h2>
</div>
<button id="statusDetailsClose" type="button" class="status-popover-close" aria-label="关闭状态详情">×</button>
</header>
<div id="statusDetailsBody" class="status-popover-body" aria-live="polite"></div>
<footer class="status-popover-actions">
<button id="statusDetailsRefresh" type="button" class="secondary-button">重新检测</button>
</footer>
</section>
</div>
</header>
<section id="loginPanel" class="login-panel" hidden>
<div class="login-card">
<p class="eyebrow">PRIVATE CONTROL PLANE</p>
<h1>平台登录</h1>
<p class="muted">请使用管理员分配的平台账号进入业务操作台。</p>
<form id="loginForm" novalidate>
<label>账号<input id="loginUsername" name="username" autocomplete="username" required></label>
<label>密码<input id="loginPassword" name="password" type="password" autocomplete="current-password" required></label>
<button type="submit">登录</button>
<p id="loginError" class="login-error" role="alert"></p>
</form>
</div>
</section>
<section id="passwordChangePanel" class="login-panel" hidden>
<div class="login-card">
<p class="eyebrow">ACCOUNT SECURITY</p>
<h1 id="passwordChangeTitle">修改密码</h1>
<p id="passwordChangeHint" class="muted">修改后,其他已登录会话将失效。</p>
<form id="passwordChangeForm" novalidate>
<label>当前密码<input id="currentPassword" type="password" autocomplete="current-password" required></label>
<label>新密码<input id="newPassword" type="password" autocomplete="new-password" required></label>
<label>确认新密码<input id="confirmNewPassword" type="password" autocomplete="new-password" required></label>
<div class="actions">
<button type="submit">保存新密码</button>
<button id="passwordChangeCancel" type="button" class="secondary-button">取消</button>
</div>
<p id="passwordChangeError" class="login-error" role="alert"></p>
</form>
</div>
</section>
<section id="accountsPage" class="channels-page" hidden>
<section class="panel channel-panel account-panel">
<div class="panel-head">
<div>
<p class="eyebrow">ACCOUNT DIRECTORY</p>
<h2>平台账号管理</h2>
<p class="muted">员工账号必须绑定唯一 ERP 账号;管理员只负责管理和查看,不绑定员工 ERP 执行身份。</p>
</div>
</div>
<form id="accountForm" class="channel-form" novalidate>
<label>账号<input id="accountUsername" maxlength="160" autocomplete="off" required></label>
<label>初始密码<input id="accountPassword" type="password" autocomplete="new-password" required></label>
<label>角色<select id="accountRole"><option value="user">普通用户</option><option value="team_lead">组长</option><option value="admin">管理员</option></select></label>
<label>ERP 账号<input id="accountErpAccount" maxlength="200" autocomplete="off" required placeholder="ERP 页面显示的登录账号"></label>
<button type="submit">创建账号</button>
</form>
<section id="accountAuthorizationPanel" class="account-authorization-panel" hidden aria-labelledby="accountAuthorizationTitle">
<div class="account-authorization-head">
<div>
<p class="eyebrow">TASK AUTHORIZATION</p>
<h3 id="accountAuthorizationTitle">任务类型授权</h3>
<p id="accountAuthorizationHint" class="muted"></p>
</div>
<div class="account-authorization-head-actions">
<button id="accountAuthorizationSelectAll" type="button" class="secondary-button">全选</button>
<button id="accountAuthorizationClear" type="button" class="secondary-button">清空</button>
</div>
</div>
<div id="accountAuthorizationTypes" class="account-authorization-types"></div>
<div class="account-authorization-footer">
<span id="accountAuthorizationCount" class="muted"></span>
<div class="actions">
<button id="accountAuthorizationSave" type="button">保存授权</button>
<button id="accountAuthorizationCancel" type="button" class="secondary-button">取消</button>
</div>
</div>
</section>
<div id="accountList" class="channel-list"></div>
<p id="accountMessage" class="channel-message" role="status"></p>
</section>
</section>
<section id="operationsDashboardPage" class="operations-dashboard-page" hidden>
<section class="operations-dashboard-panel">
<header class="operations-dashboard-page-head">
<div>
<p>领导工作台</p>
<h1>平台运行看板</h1>
<span>查看任务、人员与业务结果的最新汇总</span>
</div>
<a class="operations-dashboard-back-link" href="/">返回操作台</a>
</header>
<div id="operationsDashboardSummary" class="operations-dashboard-summary" aria-label="关键指标" aria-live="polite"></div>
<div class="operations-dashboard-ranking-grid">
<section class="operations-dashboard-insight operations-dashboard-business" aria-labelledby="operationsDashboardBusinessesTitle">
<div class="operations-dashboard-section-head">
<div>
<p>业务分布</p>
<h2 id="operationsDashboardBusinessesTitle">任务类型排名</h2>
</div>
<span>按操作次数排序</span>
</div>
<div id="operationsDashboardBusinesses" class="operations-dashboard-business-list"></div>
</section>
<section class="operations-dashboard-people" aria-labelledby="operationsDashboardUsersTitle">
<div class="operations-dashboard-section-head">
<div>
<p>员工操作</p>
<h2 id="operationsDashboardUsersTitle">员工操作任务排名</h2>
</div>
<span id="operationsDashboardUserCount"></span>
</div>
<div id="operationsDashboardUsers" class="operations-dashboard-users"></div>
</section>
</div>
<section class="operations-dashboard-workstream" aria-labelledby="operationsDashboardTasksTitle">
<div class="operations-dashboard-section-head operations-dashboard-workstream-head">
<div>
<p>筛选与明细</p>
<h2 id="operationsDashboardTasksTitle">任务操作明细</h2>
</div>
<div class="operations-dashboard-update-state">
<span id="operationsDashboardFreshness">数据正在更新</span>
<button id="operationsDashboardRefresh" type="button" class="operations-dashboard-refresh">刷新</button>
</div>
</div>
<form id="operationsDashboardFilters" class="operations-dashboard-filters">
<div id="operationsDashboardRangePresets" class="operations-dashboard-range-presets" aria-label="快捷时间范围">
<button type="button" data-operations-range-days="7">近 7 天</button>
<button id="operationsDashboardReset" type="button" data-operations-range-days="30" class="is-active">近 30 天</button>
<button type="button" data-operations-range-days="90">近 90 天</button>
</div>
<label>开始日期<input id="operationsDashboardFrom" type="date" required></label>
<label>结束日期<input id="operationsDashboardTo" type="date" required></label>
<label>员工名称<select id="operationsDashboardActor"><option value="">全部员工</option></select></label>
<label>任务类型<select id="operationsDashboardBusiness"><option value="">全部类型</option></select></label>
<label>任务结果<select id="operationsDashboardStatus">
<option value="all">全部结果</option>
<option value="active">进行中</option>
<option value="completed">成功</option>
<option value="failed">未成功</option>
<option value="cancelled">已取消</option>
</select></label>
<label class="operations-dashboard-search">关键词<input id="operationsDashboardSearch" maxlength="200" placeholder="员工名称、原始输入或最终输出"></label>
<button type="submit" class="operations-dashboard-submit">查询</button>
</form>
<div class="operations-dashboard-table-meta">
<span id="operationsDashboardTaskCount"></span>
<span>点击任意一行查看完整输入与输出</span>
</div>
<div class="operations-dashboard-table-wrap">
<table class="operations-dashboard-table">
<thead>
<tr>
<th scope="col">操作时间</th>
<th scope="col">员工名称</th>
<th scope="col">任务类型</th>
<th scope="col">原始输入</th>
<th scope="col">最终输出</th>
<th scope="col">任务结果</th>
</tr>
</thead>
<tbody id="operationsDashboardTasks"></tbody>
</table>
</div>
<div class="history-pagination operations-dashboard-pagination">
<span id="operationsDashboardPageInfo"></span>
<div class="history-pagination-actions">
<button id="operationsDashboardPrevious" type="button" class="secondary-button">上一页</button>
<button id="operationsDashboardNext" type="button" class="secondary-button">下一页</button>
</div>
</div>
<p id="operationsDashboardMessage" class="operations-dashboard-message" role="status"></p>
</section>
</section>
<aside id="operationsDashboardDetail" class="operations-dashboard-detail" role="dialog" hidden aria-labelledby="operationsDashboardDetailTitle">
<div class="operations-dashboard-detail-head">
<div>
<p>任务详情</p>
<h2 id="operationsDashboardDetailTitle">一次工作的完整过程</h2>
</div>
<button id="operationsDashboardDetailClose" type="button" class="secondary-button">关闭</button>
</div>
<div id="operationsDashboardDetailBody" class="operations-dashboard-detail-body"></div>
</aside>
</section>
<section id="auditPage" class="channels-page" hidden>
<section class="panel channel-panel">
<div class="panel-head">
<div>
<p class="eyebrow">AUDIT TRAIL</p>
<h2>平台审计记录</h2>
<p class="muted">记录账号变更及任务操作,不记录密码或明文业务输入。</p>
</div>
</div>
<form id="auditFilters" class="history-filters">
<label>事件类型<input id="auditEventType" maxlength="200" placeholder="例如 account.password_reset"></label>
<label>实体类型<input id="auditEntityType" maxlength="120" placeholder="例如 user 或 task"></label>
<div class="history-filter-actions"><button type="submit">筛选</button><button id="auditResetButton" type="button" class="secondary-button">重置</button></div>
</form>
<div id="auditList" class="channel-list"></div>
<p id="auditMessage" class="channel-message" role="status"></p>
</section>
</section>
<section id="channelsPage" class="channels-page" hidden>
<section id="channelPanel" class="panel channel-panel">
<div class="panel-head">
<div>
<p class="eyebrow">CHANNEL DIRECTORY</p>
<h2>AgentBus 用户渠道</h2>
<p class="muted">每个渠道必须一对一绑定有效员工账号;入站任务只会交给该账号当前唯一在线且 ERP 身份匹配的云电脑。</p>
</div>
</div>
<form id="channelForm" class="channel-form" novalidate>
<label>渠道名称<input id="channelDisplayName" maxlength="120" required placeholder="例如:小王"></label>
<label>绑定平台账号<select id="channelOwnerUserId" required><option value="">请选择员工账号</option></select></label>
<label>外部用户标识<input id="channelExternalUserRef" maxlength="200" placeholder="例如wx_user_001"></label>
<label>AgentBus key<input id="channelAgentbusKey" type="password" maxlength="4000" autocomplete="new-password" required></label>
<label>Bot 地址(可选)<input id="channelBotAddress" maxlength="200" placeholder="默认使用全局 bot 地址"></label>
<button type="submit">添加渠道</button>
</form>
<div id="channelList" class="channel-list"></div>
<p id="channelMessage" class="channel-message" role="status"></p>
</section>
</section>
<section id="parserRoutingPage" class="parser-routing-page" hidden>
<section class="panel parser-routing-panel">
<div class="panel-head parser-routing-head">
<div>
<p class="eyebrow">PARSER ROUTING CONTROL</p>
<h2>18 项业务解析策略</h2>
<p class="muted">程序与夹具即时验证后逐业务手动切换;两项名单导入固定为 Program-only不参与 AI 回退。</p>
</div>
<button id="emergencyAiButton" type="button" class="danger-button parser-emergency-button">可配置业务全部切回 AI</button>
</div>
<div id="parserAutomationNotice" class="parser-automation-notice" role="note"></div>
<div class="parser-routing-table-wrap">
<table class="parser-routing-table">
<thead>
<tr>
<th>业务</th>
<th>程序版本</th>
<th>当前模式</th>
<th>近 7 日观察</th>
<th>近 30 日观察</th>
<th>即时切换检查</th>
<th>最近修改</th>
</tr>
</thead>
<tbody id="parserRoutingRows"></tbody>
</table>
</div>
<p id="parserRoutingMessage" class="channel-message" role="status"></p>
</section>
</section>
<section id="workbench" class="workbench-grid" hidden>
<section class="panel instruction-panel">
<div class="panel-head">
<h2>输入区域</h2>
</div>
<textarea id="rawInstruction" spellcheck="false"></textarea>
<div class="task-input-request">
<div class="task-input-request-head">
<label class="task-output-label" for="rosterAttachment">名单 Excel 附件(可选)</label>
<span class="task-input-request-state">仅导入名单业务使用</span>
</div>
<input id="rosterAttachment" type="file" accept=".xls,.xlsx,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">
<p class="task-input-request-prompts">支持单个 .xls 或 .xlsx文件只在本次提交时读取不保存到浏览器。</p>
<p id="rosterAttachmentStatus" class="task-input-request-status" role="status" aria-live="polite"></p>
</div>
<div class="actions">
<button id="createTaskButton" type="button">创建任务</button>
</div>
</section>
<section class="panel task-list-panel">
<div class="panel-head">
<div class="panel-title-group">
<h2 id="taskListTitle">任务卡片</h2>
<span id="taskListHint" class="muted">最近任务</span>
</div>
<div class="task-list-head-actions">
<span id="taskCount" class="muted">0 个任务</span>
<a id="historyLink" class="secondary-button task-history-link" href="/history">查看更多</a>
</div>
</div>
<form id="historyFilters" class="history-filters" hidden>
<label>
搜索
<input id="historySearchInput" type="search" maxlength="200" placeholder="任务编号、状态消息或业务摘要">
</label>
<label>
状态
<select id="historyStatusInput">
<option value="">全部任务</option>
<option value="awaiting_attachment">等待名单附件</option>
<option value="awaiting_user_input">等待补充</option>
<option value="awaiting_confirmation">待确认</option>
<option value="confirmed">已确认</option>
<option value="running">执行中</option>
<option value="completed">已完成</option>
<option value="blocked">已阻断</option>
<option value="failed">失败</option>
<option value="reconciliation_pending">待回查</option>
</select>
</label>
<label>
范围
<select id="historyArchiveInput">
<option value="active">未归档</option>
<option value="archived">已归档</option>
</select>
</label>
<div class="history-filter-actions">
<button type="submit">筛选</button>
<button id="historyResetButton" type="button" class="secondary-button">重置</button>
</div>
</form>
<div id="historyBatchActions" class="history-batch-actions" hidden>
<label class="history-select-all">
<input id="historySelectAll" type="checkbox">
<span>选择本页</span>
</label>
<span id="historySelectionSummary" class="muted">已选 0 个</span>
<span id="historyBatchMessage" class="history-batch-message" role="status" aria-live="polite"></span>
<button id="historyDeleteSelectedButton" type="button" class="danger-button" disabled>归档所选</button>
</div>
<div id="taskCards" class="task-cards"></div>
<div id="historyPagination" class="history-pagination" hidden>
<span id="historyPageSummary" class="muted"></span>
<div class="history-pagination-actions">
<button id="historyPreviousButton" type="button" class="secondary-button">上一页</button>
<button id="historyNextButton" type="button" class="secondary-button">下一页</button>
</div>
</div>
</section>
<section class="panel detail-panel">
<div class="panel-head">
<h2>任务状态</h2>
<div class="detail-panel-actions">
<span id="taskState" class="muted">未创建</span>
<button id="confirmTaskButton" type="button" hidden disabled>确认并提交到 ERP 插件</button>
<button id="deleteTaskButton" type="button" class="danger-button" disabled>归档任务</button>
</div>
</div>
<div id="taskStages" class="task-stages" aria-label="项目处理阶段"></div>
<div id="taskDetail" class="task-detail"></div>
</section>
</section>
</main>
<script src="app.js?v=20260902-account-authorization-layout-1"></script>
</body>
</html>