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

411 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">
<meta name="theme-color" content="#edf2f4">
<title>AI操作台 · LianSyn-platform</title>
<link rel="stylesheet" href="styles.css?v=20260901-business-authorization-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">新密码至少 12 个字符。修改后,其他已登录会话将失效。</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" minlength="12" required></label>
<label>确认新密码<input id="confirmNewPassword" type="password" autocomplete="new-password" minlength="12" 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 执行前被阻止。</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" minlength="12" maxlength="512" 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 class="history-select-all"><input id="accountMustChangePassword" type="checkbox" checked>首次登录必须修改密码</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-hero">
<div class="operations-dashboard-hero-copy">
<p class="operations-dashboard-kicker">团队运行总览</p>
<h1>平台运行全景</h1>
<p>从整体表现进入每一项工作:看任务规模、人员贡献、业务分布,以及每次原始输入最终形成了什么结果。</p>
</div>
<div class="operations-dashboard-hero-side">
<span id="operationsDashboardFreshness">数据正在更新</span>
<button id="operationsDashboardRefresh" type="button" class="operations-dashboard-refresh">刷新数据</button>
</div>
</header>
<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="attention">待跟进</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 id="operationsDashboardActiveFilters" class="operations-dashboard-active-filters" aria-live="polite"></div>
<div id="operationsDashboardSummary" class="operations-dashboard-summary" aria-live="polite"></div>
<div class="operations-dashboard-insight-grid">
<section class="operations-dashboard-insight operations-dashboard-trend" aria-labelledby="operationsDashboardDaysTitle">
<div class="operations-dashboard-section-head">
<div>
<p>时间趋势</p>
<h2 id="operationsDashboardDaysTitle">每天完成了多少工作</h2>
</div>
<span id="operationsDashboardTodayCount">今天 0 项</span>
</div>
<div id="operationsDashboardDays" class="operations-dashboard-day-chart" aria-label="任务时间趋势"></div>
</section>
<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>
</div>
<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>
<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>
<span id="operationsDashboardTaskCount"></span>
</div>
<div class="operations-dashboard-flow-labels" aria-hidden="true">
<span>人员与时间</span>
<span>原始输入</span>
<span>最终输出</span>
</div>
<div id="operationsDashboardTasks" class="operations-dashboard-tasks"></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>
</section>
<p id="operationsDashboardMessage" class="operations-dashboard-message" role="status"></p>
</section>
<aside id="operationsDashboardDetail" class="operations-dashboard-detail" 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">每个外部用户渠道使用独立 AgentBus key;key 只写入服务端,不会回显,不再使用的渠道可以删除。</p>
</div>
</div>
<form id="channelForm" class="channel-form" novalidate>
<label>渠道名称<input id="channelDisplayName" maxlength="120" required placeholder="例如:小王"></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=20260901-business-authorization-1"></script>
</body>
</html>