Files
wecom_it_smart_desk/docs/01-产品文档/04-坐席工作台/原型-REQ-坐席-000-坐席工作台-v1.4.archive.html
T
Simon facc04aa65 chore: docs 结构整改 + compose 双目录对齐(合并重建提交)
本提交为 .git 对象库损坏后的重建提交,内容等价于原先三个本地提交
(5e2fd4c2 / 57a53c98 / 5d7e1873)的累积结果,未做任何额外改动。

一、docs 结构整改(整改 #14)
根因:重构时新结构为 untracked 文件,执行 git stash(未带 -u)未纳入,
随后 git reset 拉回 HEAD 旧 tracked 树,导致旧树复活、新旧两棵目录
树并存于 docs/,共 791 文件、双分类体系冲突。

修复动作:
- b2 同名异主题文件改名迁移保全 9 个
- C 类 39 个孤立文件按主题正确归类
- A/B1 类 222 个重复文件删除(新结构已有内容副本)
- 9 个旧独有空目录删除
- 270 处内部引用按 verified 映射改写
- 整改记录 #14 登记于 04-运维文档/部署运维

结果:docs 791 → 569 文件,顶层仅规范 8 类 + 治理文件,单树恢复。
残留:约 20 处指向从未存在文件的陈旧死链,归入独立文档卫生任务。

二、compose 双目录对齐(消除踩坑 A)
- docker-compose.yml:nginx 前端挂载全部由根目录 frontend-*/dist
  改为 src/frontend-*/dist(h5 / agent / admin / terminal)
- docker-compose.dev.yml:dev 服务 build context 与卷同步改 src/
- 效果:本地 docker compose up 不再把根目录 stale dist 挂回,
  与线上一致,分叉隐患消除(已 docker compose config 校验通过)

防复发铁律:
- 重构须提交;仓库修复须 git stash -u 或先 commit
- 新结构须 git add 并提交,避免再次 untracked 复活
- H5 改动只动 src/frontend-h5/,禁改根目录遗留 frontend-*/
2026-08-07 22:31:32 +08:00

962 lines
50 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.0">
<title>IT智能服务台 · 坐席工作台 v1.4(B方案分栏 + 排查步骤全屏流程图)</title>
<style>
:root {
--bg-primary: #f5f7fa;
--bg-secondary: #ffffff;
--bg-tertiary: #f0f2f5;
--bg-hover: #e8ecf1;
--bg-active: #dce3ec;
--border: #e2e8f0;
--border-light: #cbd5e1;
--text-primary: #1e293b;
--text-secondary: #64748b;
--text-muted: #94a3b8;
--accent: #3b82f6;
--accent-soft: #dbeafe;
--success: #22c55e;
--success-soft: #dcfce7;
--warning: #f59e0b;
--warning-soft: #fef3c7;
--danger: #ef4444;
--danger-soft: #fee2e2;
--info: #60a5fa;
--purple: #8b5cf6;
--purple-soft: #ede9fe;
--orange: #f97316;
--orange-soft: #fff7ed;
--shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
--shadow: 0 2px 8px rgba(0,0,0,0.08);
--radius: 6px;
--radius-lg: 10px;
--transition: 0.25s cubic-bezier(0.4,0,0.2,1);
--qr-c0: #3b82f6; /* 电脑 - 蓝 */
--qr-c1: #22c55e; /* 软件 - 绿 */
--qr-c2: #f97316; /* 外设 - 橙 */
--qr-c3: #8b5cf6; /* 网络 - 紫 */
--qr-c4: #ef4444; /* 安全 - 红 */
--qr-c5: #0ea5e9; /* 资产 - 青 */
--qr-c6: #6b7280; /* 其他 - 灰 */
}
[data-theme="dark"] {
--bg-primary: #0f1923;
--bg-secondary: #151f2b;
--bg-tertiary: #1a2736;
--bg-hover: #1e3044;
--bg-active: #243b52;
--border: #1e3044;
--border-light: #2a3f56;
--text-primary: #e8edf2;
--text-secondary: #8ba1b7;
--text-muted: #5c7185;
--accent: #4da6ff;
--accent-soft: #2b5f8a;
--success: #34d399;
--success-soft: #1a3a2a;
--warning: #fbbf24;
--warning-soft: #3a2f10;
--danger: #f87171;
--danger-soft: #3a1a1a;
--info: #60a5fa;
--purple: #a78bfa;
--purple-soft: #2d2060;
--orange: #fb923c;
--orange-soft: #3d1f08;
--shadow-sm: 0 1px 2px rgba(0,0,0,0.2);
--shadow: 0 2px 8px rgba(0,0,0,0.3);
--qr-c0: #60a5fa;
--qr-c1: #4ade80;
--qr-c2: #fb923c;
--qr-c3: #a78bfa;
--qr-c4: #f87171;
--qr-c5: #22d3ee;
--qr-c6: #9ca3af;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'PingFang SC', 'Microsoft YaHei', 'Noto Sans SC', sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
height: 100vh;
overflow: hidden;
font-size: 13px;
line-height: 1.5;
transition: background 0.3s, color 0.3s;
}
/* ========== TOP BAR ========== */
.theme-toggle-bar {
position: fixed; top: 0; left: 0; right: 0;
height: 44px;
background: var(--bg-secondary);
border-bottom: 1px solid var(--border);
display: flex; align-items: center;
justify-content: space-between;
padding: 0 16px;
z-index: 100;
box-shadow: var(--shadow-sm);
}
.bar-left { display: flex; align-items: center; gap: 10px; }
.logo-sm {
width: 26px; height: 26px;
background: linear-gradient(135deg, var(--accent), var(--purple));
border-radius: 6px; display: flex; align-items: center; justify-content: center;
font-weight: 700; font-size: 10px; color: #fff;
}
.sys-name {
font-size: 13px; font-weight: 700;
background: linear-gradient(135deg, var(--accent), var(--purple));
-webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}
.v-tag {
font-size: 10px; font-weight: 600; color: #fff;
background: var(--purple); padding: 1px 7px; border-radius: 8px;
}
.bar-right { display: flex; align-items: center; gap: 14px; }
.theme-switch { display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; font-size: 12px; }
.session-state-switch {
display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none;
font-size: 12px; padding: 4px 10px; border-radius: 16px;
border: 1px solid var(--border); background: var(--bg-tertiary);
transition: var(--transition);
}
.ss-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--success); }
.session-state-switch .ss-hint { color: var(--text-muted); font-size: 11px; }
body.session-ended .session-state-switch { background: var(--purple-soft); border-color: var(--purple); }
body.session-ended .session-state-switch .ss-dot { background: var(--purple); }
body.session-ended .session-state-switch .ss-label { color: var(--purple); }
/* ========== WORKSPACEB 方案:左固定 / 中 flex1.5 / 右 flex1 ≈ 60:40 ========== */
.workspace {
position: fixed; top: 44px; left: 0; right: 0; bottom: 0;
display: flex;
height: calc(100vh - 44px);
overflow: hidden;
}
/* 列宽标注徽标(原型示意,便于评审直观看到 60:40) */
.col-badge {
font-size: 10px; color: var(--text-muted);
background: var(--bg-tertiary); border: 1px dashed var(--border-light);
padding: 1px 7px; border-radius: 8px; white-space: nowrap; margin-left: auto;
}
/* ----- 左栏:会话列表(固定 260px ----- */
.sidebar-left {
width: 260px; flex-shrink: 0;
background: var(--bg-secondary);
border-right: 1px solid var(--border);
display: flex; flex-direction: column;
overflow: hidden;
}
.sl-header {
padding: 10px 14px; font-size: 13px; font-weight: 600;
display: flex; align-items: center; gap: 8px;
border-bottom: 1px solid var(--border); flex-shrink: 0;
}
.sl-list { flex: 1; overflow-y: auto; padding: 6px; }
.conv-item {
padding: 9px 10px; border-radius: var(--radius); cursor: pointer;
margin-bottom: 4px; display: flex; gap: 9px; align-items: center;
transition: var(--transition);
}
.conv-item:hover { background: var(--bg-hover); }
.conv-item.active { background: var(--accent-soft); }
.conv-avatar {
width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
display: flex; align-items: center; justify-content: center;
color: #fff; font-weight: 600; font-size: 13px;
}
.conv-main { flex: 1; min-width: 0; }
.conv-top { display: flex; justify-content: space-between; align-items: baseline; }
.conv-name { font-size: 12px; font-weight: 600; }
.conv-time { font-size: 10px; color: var(--text-muted); }
.conv-preview { font-size: 11px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.conv-unread { background: var(--danger); color: #fff; font-size: 10px; border-radius: 10px; padding: 0 6px; min-width: 16px; text-align: center; }
/* ----- 中栏:对话区(flex:1.5 ≈ 60% ----- */
.workspace-main {
flex: 1.5; min-width: 0;
background: var(--bg-primary);
display: flex; flex-direction: column;
overflow: hidden;
border-right: 1px solid var(--border);
}
.user-info-bar {
padding: 10px 16px; background: var(--bg-secondary);
border-bottom: 1px solid var(--border);
display: flex; align-items: center; gap: 10px; flex-shrink: 0;
}
.uib-avatar { width: 36px; height: 36px; border-radius: 50%; background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 600; }
.uib-name { font-size: 13px; font-weight: 600; }
.uib-meta { font-size: 11px; color: var(--text-muted); }
.uib-status { margin-left: auto; font-size: 11px; color: var(--success); display: flex; align-items: center; gap: 5px; }
.uib-status .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--success); }
.chat-messages { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.msg { display: flex; gap: 8px; max-width: 78%; }
.msg.user { align-self: flex-end; flex-direction: row-reverse; }
.msg-avatar { width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 600; font-size: 11px; }
.msg.user .msg-avatar { background: var(--accent); }
.msg.agent .msg-avatar { background: var(--purple); }
.bubble { padding: 9px 12px; border-radius: 10px; font-size: 12.5px; line-height: 1.55; }
.msg.user .bubble { background: var(--accent); color: #fff; border-top-right-radius: 2px; }
.msg.agent .bubble { background: var(--bg-secondary); border: 1px solid var(--border); border-top-left-radius: 2px; }
.msg-time { font-size: 10px; color: var(--text-muted); margin-top: 3px; }
/* 快速回复:中栏消息框工具栏上方 */
.quick-reply-section {
flex-shrink: 0; height: 220px; border-top: 1px solid var(--border);
background: var(--bg-secondary); display: flex; flex-direction: column; overflow: hidden;
}
.qr-head { padding: 6px 12px; font-size: 12px; font-weight: 600; display: flex; align-items: center; gap: 6px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.qr-search { padding: 6px 12px; flex-shrink: 0; }
.qr-search-input { width: 100%; background: var(--bg-tertiary); border: 1px solid var(--border); border-radius: var(--radius); padding: 6px 10px; color: var(--text-primary); font-size: 12px; outline: none; }
.qr-grid { flex: 1; overflow-y: auto; padding: 6px 10px; display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; align-content: start; }
.qr-cat {
padding: 8px 6px; border-radius: var(--radius); cursor: pointer; text-align: center;
border: 1px solid var(--border); background: var(--bg-tertiary); transition: var(--transition); font-size: 11px;
}
.qr-cat:hover { transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.qr-cat .qr-cat-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 4px; }
.qr-cat .qr-cat-key { font-size: 9px; color: var(--text-muted); margin-left: 3px; }
.reply-box { flex-shrink: 0; border-top: 1px solid var(--border); background: var(--bg-secondary); padding: 8px 12px 10px; }
.reply-toolbar { display: flex; gap: 6px; margin-bottom: 6px; flex-wrap: wrap; }
.tb-btn { font-size: 11px; padding: 4px 9px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-tertiary); cursor: pointer; transition: var(--transition); }
.tb-btn:hover { border-color: var(--accent); color: var(--accent); }
.reply-input { width: 100%; min-height: 38px; background: var(--bg-tertiary); border: 1px solid var(--border); border-radius: var(--radius); padding: 8px 10px; color: var(--text-primary); font-size: 12.5px; font-family: inherit; outline: none; resize: none; }
.reply-input:focus { border-color: var(--accent); }
.reply-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 6px; }
.btn-send { background: var(--accent); color: #fff; border: none; padding: 6px 18px; border-radius: var(--radius); font-size: 12px; cursor: pointer; font-weight: 600; }
.btn-send:hover { filter: brightness(1.05); }
/* ----- 右栏:辅助面板(flex:1 ≈ 40%min 320 / max 560 ----- */
.sidebar-right {
flex: 1; min-width: 320px; max-width: 560px;
background: var(--bg-secondary);
display: flex; flex-direction: column;
overflow-y: auto;
transition: var(--transition);
}
.sidebar-right::-webkit-scrollbar { width: 5px; }
.sidebar-right::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
/* 排查步骤面板(右栏顶部,默认展开,可折叠;新增「全屏查看」) */
.ts-panel { flex-shrink: 0; border-bottom: 1px solid var(--border); background: var(--bg-secondary); }
.ts-panel-head {
display: flex; align-items: center; gap: 8px;
padding: 9px 12px; cursor: pointer; transition: var(--transition);
position: sticky; top: 0; background: var(--bg-secondary); z-index: 2;
}
.ts-panel-head:hover { background: var(--bg-hover); }
.ts-panel-title { font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.ts-panel-collapse { font-size: 12px; color: var(--text-muted); transition: transform 0.2s; margin-left: 4px; }
.ts-panel.collapsed .ts-panel-collapse { transform: rotate(-90deg); }
.ts-fullscreen-btn {
margin-left: auto; font-size: 11px; color: var(--accent); cursor: pointer;
padding: 3px 8px; border: 1px solid var(--border); border-radius: 4px;
background: var(--bg-tertiary); transition: var(--transition); flex-shrink: 0;
display: flex; align-items: center; gap: 4px;
}
.ts-fullscreen-btn:hover { background: var(--accent-soft); border-color: var(--accent); }
.ts-panel-body { overflow: hidden; transition: max-height 0.3s ease; max-height: 1600px; }
.ts-panel.collapsed .ts-panel-body { max-height: 0; }
.ts-path-inline { display: flex; align-items: center; gap: 0; padding: 8px 12px; flex-wrap: wrap; }
.path-step { padding: 2px 7px; background: var(--bg-tertiary); border: 1px solid var(--border-light); border-radius: 3px; font-size: 11px; color: var(--text-secondary); white-space: nowrap; }
.path-step.done { background: var(--success-soft); border-color: var(--success); color: var(--success); }
.path-step.current { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: 600; }
.path-arrow-inline { color: var(--text-muted); font-size: 10px; padding: 0 3px; }
.ts-flowchart-toggle { display: block; padding: 6px 12px; font-size: 12px; color: var(--accent); cursor: pointer; user-select: none; }
.ts-flowchart-toggle:hover { background: var(--accent-soft); }
/* 决策树(侧栏内:默认展开,可收起) */
.ts-flowchart { padding: 4px 14px 12px; overflow-y: auto; max-height: 520px; transition: max-height 0.35s ease, padding 0.35s ease; }
.ts-flowchart.collapsed-flow { max-height: 0; padding-top: 0; padding-bottom: 0; overflow: hidden; }
.flow-step { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 6px; position: relative; }
.flow-step:last-child { margin-bottom: 0; }
.flow-step-connector { position: absolute; left: 10px; top: 26px; bottom: -14px; width: 2px; background: var(--border); }
.flow-step:last-child .flow-step-connector { display: none; }
.flow-node { width: 22px; height: 22px; border-radius: 50%; background: var(--accent-soft); color: var(--accent); display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 600; flex-shrink: 0; z-index: 1; border: 1px solid var(--accent); }
.flow-node.done { background: var(--success-soft); color: var(--success); border-color: var(--success); }
.flow-node.current { background: var(--accent); color: #fff; }
.flow-node.judge { width: auto; height: auto; border-radius: var(--radius); padding: 3px 8px; font-size: 10px; font-weight: 500; background: var(--warning-soft); color: var(--warning); border-color: var(--warning); }
.flow-content { flex: 1; }
.flow-title { font-size: 12px; font-weight: 500; color: var(--text-primary); margin-bottom: 2px; }
.flow-desc { font-size: 11px; color: var(--text-secondary); line-height: 1.4; }
.flow-branch { margin-left: 20px; margin-top: 4px; padding-left: 10px; border-left: 2px dashed var(--border-light); }
.flow-branch-item { font-size: 11px; color: var(--text-muted); padding: 2px 0; cursor: pointer; transition: var(--transition); }
.flow-branch-item:hover { color: var(--accent); }
.flow-branch-item.active { color: var(--success); font-weight: 500; }
/* AI 推荐 */
.ai-recommend-section { flex-shrink: 0; padding: 10px 12px; border-bottom: 1px solid var(--border); }
.ars-title { font-size: 12px; font-weight: 600; color: var(--accent); margin-bottom: 8px; display: flex; align-items: center; gap: 6px; }
.ars-title::before { content: ''; width: 3px; height: 12px; background: var(--accent); border-radius: 2px; display: inline-block; }
.ars-card { background: var(--bg-tertiary); border: 1px solid var(--border); border-radius: var(--radius); padding: 8px 10px; margin-bottom: 5px; cursor: pointer; transition: var(--transition); }
.ars-card:hover { border-color: var(--accent); background: var(--bg-hover); }
.ars-card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 3px; }
.ars-confidence { font-size: 10px; padding: 1px 6px; border-radius: 8px; background: var(--accent-soft); color: var(--accent); }
.ars-card-text { font-size: 11px; color: var(--text-secondary); line-height: 1.5; }
.ars-shortcut-hint { font-size: 10px; color: var(--text-muted); margin-top: 3px; display: flex; align-items: center; gap: 4px; }
.key-badge { display: inline-flex; align-items: center; justify-content: center; font-size: 10px; padding: 1px 5px; background: var(--bg-hover); border: 1px solid var(--border); border-radius: 3px; color: var(--text-muted); min-width: 18px; font-family: monospace; }
/* 待办事项 Kanban */
.kanban { flex-shrink: 0; padding: 10px 12px; border-bottom: 1px solid var(--border); }
.kanban-title { font-size: 12px; font-weight: 600; margin-bottom: 8px; display: flex; align-items: center; gap: 6px; }
.kanban-title .count { background: var(--accent-soft); color: var(--accent); font-size: 10px; padding: 0 7px; border-radius: 8px; }
.kanban-item { display: flex; align-items: center; gap: 8px; padding: 7px 8px; border-radius: var(--radius); cursor: pointer; transition: var(--transition); border: 1px solid transparent; margin-bottom: 3px; }
.kanban-item:hover { background: var(--bg-hover); border-color: var(--border); }
.ki-priority { width: 6px; height: 26px; border-radius: 3px; flex-shrink: 0; }
.ki-priority.urgent { background: var(--danger); }
.ki-priority.high { background: var(--warning); }
.ki-priority.normal { background: var(--accent); }
.ki-priority.done { background: var(--success); }
.ki-text { flex: 1; font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ki-type { font-size: 9px; padding: 1px 5px; border-radius: 4px; flex-shrink: 0; }
.ki-type.ticket { background: var(--accent-soft); color: var(--accent); }
.ki-type.approval { background: var(--purple-soft); color: var(--purple); }
.ki-type.device { background: var(--orange-soft); color: var(--orange); }
.ki-time { font-size: 10px; color: var(--text-muted); flex-shrink: 0; }
.ki-avatar { width: 22px; height: 22px; border-radius: 50%; color: #fff; font-size: 10px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.ki-avatar.ka-red { background: var(--danger); }
.ki-avatar.ka-orange { background: var(--orange); }
.ki-avatar.ka-blue { background: var(--accent); }
.ki-avatar.ka-green { background: var(--success); }
.ki-avatar.ka-purple { background: var(--purple); }
.kanban-item.resolved { opacity: 0.6; }
.kanban-stats { display: flex; gap: 12px; font-size: 10px; color: var(--text-muted); margin-top: 6px; }
.kanban-stats .dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; margin-right: 3px; }
.dot-online { background: var(--success); }
.dot-busy { background: var(--warning); }
.dot-offline { background: var(--text-muted); }
/* 复盘类模块(仅会话结束后显示) */
.post-session-hint { margin: 10px 12px; padding: 8px 10px; background: var(--bg-tertiary); border: 1px dashed var(--border-light); border-radius: var(--radius); font-size: 11px; color: var(--text-secondary); }
.post-session-card { display: none; margin: 10px 12px; padding: 10px 12px; background: var(--bg-tertiary); border: 1px solid var(--border); border-radius: var(--radius-lg); }
body.session-ended .post-session-card { display: block; }
body.session-ended .post-session-hint { display: none; }
.psc-title { font-size: 13px; font-weight: 600; margin-bottom: 8px; }
.psc-field { margin-bottom: 8px; }
.psc-field-label { font-size: 10px; color: var(--text-muted); margin-bottom: 3px; }
.psc-field-value { font-size: 11.5px; color: var(--text-primary); line-height: 1.5; }
.psc-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 4px; }
.psc-tag { font-size: 10px; padding: 2px 8px; border-radius: 10px; background: var(--bg-hover); color: var(--text-secondary); border: 1px solid var(--border); }
.psc-tag.auto { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }
.psc-stars { font-size: 14px; color: var(--warning); }
.psc-stars .star-off { color: var(--border-light); }
.psc-row { display: flex; justify-content: space-between; font-size: 11px; padding: 2px 0; }
.psc-row .psc-k { color: var(--text-muted); }
.psc-textarea { width: 100%; min-height: 44px; background: var(--bg-secondary); border: 1px solid var(--border); border-radius: var(--radius); padding: 6px 8px; font-size: 11px; font-family: inherit; color: var(--text-primary); outline: none; resize: vertical; }
.psc-check { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-secondary); margin-top: 6px; }
/* ========== 全屏流程图浮层 ========== */
.flowchart-fullscreen {
position: fixed; inset: 0; z-index: 1000;
background: var(--bg-primary);
display: none; flex-direction: column;
}
.flowchart-fullscreen.open { display: flex; }
.ff-topbar {
height: 48px; flex-shrink: 0; display: flex; align-items: center; gap: 12px;
padding: 0 18px; background: var(--bg-secondary); border-bottom: 1px solid var(--border);
box-shadow: var(--shadow-sm);
}
.ff-title { font-size: 14px; font-weight: 600; display: flex; align-items: center; gap: 8px; }
.ff-subtitle { font-size: 11px; color: var(--text-muted); }
.ff-close {
margin-left: auto; cursor: pointer; font-size: 13px; color: var(--text-secondary);
padding: 6px 14px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--bg-tertiary);
transition: var(--transition);
}
.ff-close:hover { border-color: var(--danger); color: var(--danger); }
.ff-stage { flex: 1; overflow: auto; padding: 28px 40px; }
.ff-tree { max-width: 920px; margin: 0 auto; }
.ff-tree .flow-step { margin-bottom: 14px; }
.ff-tree .flow-node { width: 28px; height: 28px; font-size: 12px; }
.ff-tree .flow-step-connector { left: 13px; top: 32px; bottom: -18px; width: 2px; }
.ff-tree .flow-title { font-size: 14px; }
.ff-tree .flow-desc { font-size: 12.5px; }
.ff-tree .flow-branch-item { font-size: 12.5px; }
.ff-hint { text-align: center; font-size: 11px; color: var(--text-muted); padding: 8px; flex-shrink: 0; }
/* ========== 原型说明对话框 ========== */
.modal-mask { position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: 900; display: none; align-items: center; justify-content: center; }
.modal-mask.open { display: flex; }
.modal-box { width: 560px; max-width: 92vw; max-height: 80vh; overflow-y: auto; background: var(--bg-secondary); border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: 20px 22px; }
.modal-box h3 { font-size: 15px; margin-bottom: 12px; display: flex; align-items: center; gap: 8px; }
.modal-box h4 { font-size: 13px; margin: 14px 0 6px; color: var(--accent); }
.modal-box ul { padding-left: 18px; }
.modal-box li { font-size: 12px; color: var(--text-secondary); margin-bottom: 5px; line-height: 1.55; }
.modal-box .kbd { font-family: monospace; background: var(--bg-tertiary); border: 1px solid var(--border); border-radius: 3px; padding: 1px 6px; font-size: 11px; color: var(--text-primary); }
.modal-box .close-x { float: right; cursor: pointer; color: var(--text-muted); font-size: 18px; line-height: 1; }
.modal-box .close-x:hover { color: var(--danger); }
.proto-btn {
position: fixed; right: 16px; bottom: 16px; z-index: 800;
background: var(--purple); color: #fff; border: none; border-radius: 20px;
padding: 9px 16px; font-size: 12px; font-weight: 600; cursor: pointer; box-shadow: var(--shadow);
transition: var(--transition);
}
.proto-btn:hover { filter: brightness(1.08); transform: translateY(-1px); }
</style>
</head>
<body>
<!-- ============ TOP BAR ============ -->
<div class="theme-toggle-bar">
<div class="bar-left">
<div class="logo-sm">IT</div>
<span class="sys-name">IT智能服务台 · 坐席工作台</span>
<span class="v-tag">v1.4</span>
</div>
<div class="bar-right">
<div class="theme-switch" onclick="toggleTheme()">
<span id="themeIcon">🌙</span><span id="themeLabel">深色</span>
</div>
<div class="session-state-switch" id="sessionStateSwitch" onclick="toggleSessionState()">
<span class="ss-dot"></span>
<span class="ss-label" id="sessionStateLabel">会话进行中</span>
<span class="ss-hint">(点击模拟「会话已结束」)</span>
</div>
</div>
</div>
<!-- ============ WORKSPACEB 方案:左 260px / 中 flex1.5 / 右 flex1 ============ -->
<div class="workspace">
<!-- ===== 左栏:会话列表(固定 260px ===== -->
<aside class="sidebar-left">
<div class="sl-header">💬 会话列表 <span class="col-badge">260px 固定</span></div>
<div class="sl-list">
<div class="conv-item active">
<div class="conv-avatar" style="background:var(--accent)"></div>
<div class="conv-main">
<div class="conv-top"><span class="conv-name">王莉 · CEO办公室</span><span class="conv-time">5m</span></div>
<div class="conv-preview">投屏设备无法连接,提示驱动异常…</div>
</div>
<span class="conv-unread">2</span>
</div>
<div class="conv-item">
<div class="conv-avatar" style="background:var(--orange)"></div>
<div class="conv-main">
<div class="conv-top"><span class="conv-name">财务部 · 税控系统</span><span class="conv-time">12m</span></div>
<div class="conv-preview">税控系统登录后白屏,报错 500…</div>
</div>
</div>
<div class="conv-item">
<div class="conv-avatar" style="background:var(--purple)"></div>
<div class="conv-main">
<div class="conv-top"><span class="conv-name">李研发 · VPN 故障</span><span class="conv-time">28m</span></div>
<div class="conv-preview">AnyConnect 连不上,提示协商失败…</div>
</div>
</div>
<div class="conv-item">
<div class="conv-avatar" style="background:var(--success)"></div>
<div class="conv-main">
<div class="conv-top"><span class="conv-name">行政部 · 会议室A</span><span class="conv-time">45m</span></div>
<div class="conv-preview">投影仪离线,需现场排查…</div>
</div>
</div>
<div class="conv-item">
<div class="conv-avatar" style="background:var(--accent-soft);color:var(--accent)"></div>
<div class="conv-main">
<div class="conv-top"><span class="conv-name">客服部 · 耳机无声</span><span class="conv-time">1h</span></div>
<div class="conv-preview">重装驱动后恢复正常,待回访…</div>
</div>
</div>
</div>
</aside>
<!-- ===== 中栏:对话区(flex:1.5 ≈ 60% ===== -->
<main class="workspace-main">
<div class="user-info-bar">
<div class="uib-avatar"></div>
<div>
<div class="uib-name">王莉 · CEO办公室</div>
<div class="uib-meta">工号 E10245 · 杭州滨江 · 桌面云</div>
</div>
<div class="uib-status"><span class="dot"></span> 在线 · 已认证</div>
</div>
<div class="chat-messages">
<div class="msg user">
<div class="msg-avatar"></div>
<div>
<div class="bubble">投屏设备连不上,提示驱动异常,会议马上要开始了,急!</div>
<div class="msg-time">09:12</div>
</div>
</div>
<div class="msg agent">
<div class="msg-avatar"></div>
<div>
<div class="bubble">收到,先帮您确认投屏设备型号与连接方式,右栏「排查步骤」已定位到对应决策树,请稍候。</div>
<div class="msg-time">09:12</div>
</div>
</div>
<div class="msg user">
<div class="msg-avatar"></div>
<div>
<div class="bubble">是无线投屏器,插在会议室的 HDMI 上。</div>
<div class="msg-time">09:13</div>
</div>
</div>
<div class="msg agent">
<div class="msg-avatar"></div>
<div>
<div class="bubble">明白,已派单至会议室现场运维,同时给您一个临时方案:用笔记本直连 HDMI 过渡。详见右栏 AI 推荐。</div>
<div class="msg-time">09:14</div>
</div>
</div>
</div>
<!-- 快速回复:中栏消息框工具栏上方 -->
<div class="quick-reply-section">
<div class="qr-head">⚡ 快速回复(三层渐进式 · 位于消息框工具栏上方) <span class="col-badge">中栏 ≈ 60%</span></div>
<div class="qr-search"><input class="qr-search-input" placeholder="搜索快速回复 / Alt+目录数字"></div>
<div class="qr-grid">
<div class="qr-cat"><span class="qr-cat-dot" style="background:var(--qr-c0)"></span>电脑<span class="qr-cat-key">1</span></div>
<div class="qr-cat"><span class="qr-cat-dot" style="background:var(--qr-c1)"></span>软件<span class="qr-cat-key">2</span></div>
<div class="qr-cat"><span class="qr-cat-dot" style="background:var(--qr-c2)"></span>外设<span class="qr-cat-key">3</span></div>
<div class="qr-cat"><span class="qr-cat-dot" style="background:var(--qr-c3)"></span>网络<span class="qr-cat-key">4</span></div>
<div class="qr-cat"><span class="qr-cat-dot" style="background:var(--qr-c4)"></span>安全<span class="qr-cat-key">5</span></div>
<div class="qr-cat"><span class="qr-cat-dot" style="background:var(--qr-c5)"></span>资产<span class="qr-cat-key">6</span></div>
<div class="qr-cat"><span class="qr-cat-dot" style="background:var(--qr-c6)"></span>其他<span class="qr-cat-key">7</span></div>
<div class="qr-cat" style="border-style:dashed;color:var(--text-muted)"> 全部</div>
</div>
</div>
<div class="reply-box">
<div class="reply-toolbar">
<button class="tb-btn">📎 附件</button>
<button class="tb-btn">😊 表情</button>
<button class="tb-btn">🖼️ 截图</button>
<button class="tb-btn">🤖 AI润色</button>
<button class="tb-btn">⚡ 快速回复</button>
</div>
<textarea class="reply-input" placeholder="输入回复内容…(Enter 发送 / Shift+Enter 换行)"></textarea>
<div class="reply-actions">
<button class="btn-send">发送</button>
</div>
</div>
</main>
<!-- ===== 右栏:辅助面板(flex:1 ≈ 40%min 320 / max 560 ===== -->
<aside class="sidebar-right">
<!-- 排查步骤(右栏顶部,默认展开;新增「全屏查看」) -->
<div class="ts-panel" id="tsPanel">
<div class="ts-panel-head" onclick="toggleTsPanel()" title="点击折叠/展开排查步骤">
<span class="ts-panel-title">🔧 排查步骤</span>
<span class="ts-panel-collapse"></span>
<span class="col-badge">右栏 ≈ 40%</span>
<span class="ts-fullscreen-btn" onclick="event.stopPropagation(); openFlowFullscreen()" title="全屏查看完整决策树">⛶ 全屏查看</span>
</div>
<div class="ts-panel-body">
<div class="ts-path-inline">
<span class="path-step done">① 确认型号</span>
<span class="path-arrow-inline"></span>
<span class="path-step done">② 检查连接</span>
<span class="path-arrow-inline"></span>
<span class="path-step current">③ 驱动排查</span>
<span class="path-arrow-inline"></span>
<span class="path-step">④ 现场派单</span>
<span class="path-arrow-inline"></span>
<span class="path-step">⑤ 回访确认</span>
</div>
<span class="ts-flowchart-toggle" id="tsFlowBtn" onclick="toggleTsFlow()">▼ 收起完整排查决策树</span>
<div class="ts-flowchart" id="tsFlowchart">
<div style="font-size:11px;color:var(--text-muted);margin-bottom:8px;">🔀 无线投屏器故障 — 完整排查决策树</div>
<div class="flow-step">
<div class="flow-node done">1</div>
<div class="flow-step-connector"></div>
<div class="flow-content">
<div class="flow-title">确认投屏设备型号</div>
<div class="flow-desc">询问用户是无线投屏器 / 会议主机自带投屏 / 第三方软件(如乐播)</div>
<div class="flow-branch">
<div class="flow-branch-item active">→ 无线投屏器:进入 HDMI 直连与驱动分支</div>
<div class="flow-branch-item">→ 会议主机自带:进入系统投屏服务分支</div>
<div class="flow-branch-item">→ 第三方软件:进入网络与权限分支</div>
</div>
</div>
</div>
<div class="flow-step">
<div class="flow-node judge">❓ 判断</div>
<div class="flow-step-connector"></div>
<div class="flow-content">
<div class="flow-title">HDMI 直连是否正常?</div>
<div class="flow-desc">请用户将笔记本直连会议室 HDMI 验证,排除无线链路问题</div>
<div class="flow-branch">
<div class="flow-branch-item active">正常 → 锁定为无线投屏器驱动/固件问题,进入步骤②</div>
<div class="flow-branch-item">仍异常 → 进入显示接口/线缆硬件分支</div>
</div>
</div>
</div>
<div class="flow-step">
<div class="flow-node done">2</div>
<div class="flow-step-connector"></div>
<div class="flow-content">
<div class="flow-title">重装 / 更新投屏驱动</div>
<div class="flow-desc">指导用户通过软件管家重装无线投屏驱动,重启投屏器与笔记本</div>
</div>
</div>
<div class="flow-step">
<div class="flow-node judge">❓ 判断</div>
<div class="flow-step-connector"></div>
<div class="flow-content">
<div class="flow-title">重装驱动后能否投屏?</div>
<div class="flow-branch">
<div class="flow-branch-item active">能 → 标记为「已解决」,进入步骤⑤回访</div>
<div class="flow-branch-item">不能 → 进入步骤③现场派单</div>
</div>
</div>
</div>
<div class="flow-step">
<div class="flow-node current">3</div>
<div class="flow-step-connector"></div>
<div class="flow-content">
<div class="flow-title">现场派单排查</div>
<div class="flow-desc">创建现场工单,指派会议室运维检查投屏器固件、WiFi 信道与供电</div>
</div>
</div>
<div class="flow-step">
<div class="flow-node">4</div>
<div class="flow-step-connector"></div>
<div class="flow-content">
<div class="flow-title">固件升级 / 替换设备</div>
<div class="flow-desc">若固件过旧则升级;硬件损坏则走备件替换流程</div>
</div>
</div>
<div class="flow-step">
<div class="flow-node">5</div>
<div class="flow-content">
<div class="flow-title">24H 后回访确认</div>
<div class="flow-desc">创建提醒任务,24小时后通过企业微信确认投屏使用正常</div>
</div>
</div>
</div>
</div>
</div>
<!-- AI 推荐 -->
<div class="ai-recommend-section">
<div class="ars-title">🤖 AI 智能推荐</div>
<div class="ars-card" onclick="alert('回填至输入框(原型示意)')">
<div class="ars-card-header"><span style="font-size:10px;color:var(--text-secondary);">临时过渡方案</span><span class="ars-confidence">94%</span></div>
<div class="ars-card-text">可先用笔记本直连 HDMI 过渡,同时已为您派单现场运维,预计 10 分钟内到达。</div>
<div class="ars-shortcut-hint"><span class="key-badge">Ctrl</span>+<span class="key-badge">1</span></div>
</div>
<div class="ars-card" onclick="alert('回填至输入框(原型示意)')">
<div class="ars-card-header"><span style="font-size:10px;color:var(--text-secondary);">驱动重装指引</span><span class="ars-confidence">88%</span></div>
<div class="ars-card-text">打开软件管家搜索「无线投屏驱动」一键重装,重启投屏器后重试。</div>
<div class="ars-shortcut-hint"><span class="key-badge">Ctrl</span>+<span class="key-badge">2</span></div>
</div>
</div>
<!-- 待办事项(右栏底部) -->
<div class="kanban">
<div class="kanban-title">待办事项 <span class="count">6</span></div>
<div class="kanban-item">
<span class="ki-priority urgent"></span>
<span class="ki-text">CEO办公室 - 投屏设备故障</span>
<span class="ki-type ticket">工单</span>
<span class="ki-time">5m</span>
<div class="ki-avatar ka-red"></div>
</div>
<div class="kanban-item">
<span class="ki-priority urgent"></span>
<span class="ki-text">财务部 - 税控系统无法登录</span>
<span class="ki-type ticket">工单</span>
<span class="ki-time">12m</span>
<div class="ki-avatar ka-orange"></div>
</div>
<div class="kanban-item">
<span class="ki-priority high"></span>
<span class="ki-text">IT采购申请 - 研发部笔记本</span>
<span class="ki-type approval">审批</span>
<span class="ki-time">28m</span>
<div class="ki-avatar ka-blue"></div>
</div>
<div class="kanban-item">
<span class="ki-priority high"></span>
<span class="ki-text">会议室 A - 投影仪离线</span>
<span class="ki-type device">设备</span>
<span class="ki-time">45m</span>
<div class="ki-avatar ka-green"></div>
</div>
<div class="kanban-item">
<span class="ki-priority normal"></span>
<span class="ki-text">新员工入职 - 设备申领审批</span>
<span class="ki-type approval">审批</span>
<span class="ki-time">32m</span>
<div class="ki-avatar ka-purple">H</div>
</div>
<div class="kanban-item resolved">
<span class="ki-priority done"></span>
<span class="ki-text">客服部 - 耳机无声(驱动重装)</span>
<span class="ki-type ticket">工单</span>
<span class="ki-time">1h</span>
<div class="ki-avatar ka-blue"></div>
</div>
<div class="kanban-stats"><span><span class="dot dot-online"></span> 在线 4</span><span><span class="dot dot-busy"></span> 忙碌 2</span><span><span class="dot dot-offline"></span> 离线 1</span></div>
</div>
<!-- 会话进行中占位提示 -->
<div class="post-session-hint">
📌 <b>复盘模块待激活</b>:以下模块将在 <b>中栏会话结束后</b> 自动显示——<br>
🏷️ 智能标注 · ⭐ 质量反馈 · 📚 知识共享
</div>
<!-- 智能标注(仅会话结束后显示) -->
<div class="post-session-card">
<div class="psc-title">🏷️ 智能标注</div>
<div class="psc-field">
<div class="psc-field-label">AI 推荐分类(可修改)</div>
<div class="psc-field-value">投屏设备故障 / 无线投屏器驱动</div>
<div class="psc-tags">
<span class="psc-tag auto">无线投屏器</span>
<span class="psc-tag auto">驱动重装</span>
<span class="psc-tag auto">现场派单</span>
<span class="psc-tag">重复问题</span>
</div>
</div>
<div class="psc-field">
<div class="psc-field-label">优先级(由会话指标推导)</div>
<div class="psc-field-value">🔴 紧急 · 影响会议 · 高管</div>
</div>
<div class="psc-field">
<div class="psc-field-label">解决方案摘要(自动提取)</div>
<div class="psc-field-value">HDMI 直连验证 → 驱动重装 → 无效 → 现场派单固件升级。</div>
</div>
</div>
<!-- 质量反馈(仅会话结束后显示) -->
<div class="post-session-card">
<div class="psc-title">⭐ 质量反馈</div>
<div class="psc-field">
<div class="psc-field-label">本次服务评分</div>
<div class="psc-stars">★★★★<span class="star-off"></span> <span style="font-size:11px;color:var(--text-muted);">4.0 / 5</span></div>
</div>
<div class="psc-row"><span class="psc-k">解决时长</span><span class="psc-v">12 分钟</span></div>
<div class="psc-row"><span class="psc-k">一次解决率</span><span class="psc-v">是(无需二次进线)</span></div>
<div class="psc-row"><span class="psc-k">用户情绪走向</span><span class="psc-v">😟 焦虑 → 🙂 满意</span></div>
<div class="psc-field" style="margin-top:8px;">
<div class="psc-field-label">改进建议(可填写)</div>
<textarea class="psc-textarea" placeholder="记录本次可优化点,如:提前推送投屏器自助文档…"></textarea>
</div>
</div>
<!-- 知识共享(仅会话结束后显示) -->
<div class="post-session-card">
<div class="psc-title">📚 知识共享</div>
<div class="psc-field">
<div class="psc-field-label">沉淀为知识库条目</div>
<div class="psc-field-value">《无线投屏器驱动重装后仍异常 → 现场派单与固件升级指引》</div>
</div>
<div class="psc-field">
<div class="psc-field-label">可见范围</div>
<div class="psc-tags">
<span class="psc-tag">全员自助</span>
<span class="psc-tag">坐席知识库</span>
</div>
</div>
<label class="psc-check"><input type="checkbox"> 已加入知识库(去重校验通过)</label>
<div class="psc-field" style="margin-top:8px;">
<div class="psc-field-label">补充备注</div>
<textarea class="psc-textarea" placeholder="补充适用场景、关联工单号等…"></textarea>
</div>
</div>
</aside>
</div>
<!-- ============ 全屏流程图浮层 ============ -->
<div class="flowchart-fullscreen" id="flowFullscreen">
<div class="ff-topbar">
<div class="ff-title">🔧 排查步骤 · 完整决策树(全屏)</div>
<div class="ff-subtitle">无线投屏器故障 — 当前定位:③ 驱动排查</div>
<div class="ff-close" onclick="closeFlowFullscreen()">✕ 关闭(Esc</div>
</div>
<div class="ff-stage">
<div class="ff-tree">
<div class="flow-step">
<div class="flow-node done">1</div>
<div class="flow-step-connector"></div>
<div class="flow-content">
<div class="flow-title">确认投屏设备型号</div>
<div class="flow-desc">询问用户是无线投屏器 / 会议主机自带投屏 / 第三方软件(如乐播)</div>
<div class="flow-branch">
<div class="flow-branch-item active">→ 无线投屏器:进入 HDMI 直连与驱动分支</div>
<div class="flow-branch-item">→ 会议主机自带:进入系统投屏服务分支</div>
<div class="flow-branch-item">→ 第三方软件:进入网络与权限分支</div>
</div>
</div>
</div>
<div class="flow-step">
<div class="flow-node judge">❓ 判断</div>
<div class="flow-step-connector"></div>
<div class="flow-content">
<div class="flow-title">HDMI 直连是否正常?</div>
<div class="flow-desc">请用户将笔记本直连会议室 HDMI 验证,排除无线链路问题</div>
<div class="flow-branch">
<div class="flow-branch-item active">正常 → 锁定为无线投屏器驱动/固件问题,进入步骤②</div>
<div class="flow-branch-item">仍异常 → 进入显示接口/线缆硬件分支</div>
</div>
</div>
</div>
<div class="flow-step">
<div class="flow-node done">2</div>
<div class="flow-step-connector"></div>
<div class="flow-content">
<div class="flow-title">重装 / 更新投屏驱动</div>
<div class="flow-desc">指导用户通过软件管家重装无线投屏驱动,重启投屏器与笔记本</div>
</div>
</div>
<div class="flow-step">
<div class="flow-node judge">❓ 判断</div>
<div class="flow-step-connector"></div>
<div class="flow-content">
<div class="flow-title">重装驱动后能否投屏?</div>
<div class="flow-branch">
<div class="flow-branch-item active">能 → 标记为「已解决」,进入步骤⑤回访</div>
<div class="flow-branch-item">不能 → 进入步骤③现场派单</div>
</div>
</div>
</div>
<div class="flow-step">
<div class="flow-node current">3</div>
<div class="flow-step-connector"></div>
<div class="flow-content">
<div class="flow-title">现场派单排查</div>
<div class="flow-desc">创建现场工单,指派会议室运维检查投屏器固件、WiFi 信道与供电</div>
</div>
</div>
<div class="flow-step">
<div class="flow-node">4</div>
<div class="flow-step-connector"></div>
<div class="flow-content">
<div class="flow-title">固件升级 / 替换设备</div>
<div class="flow-desc">若固件过旧则升级;硬件损坏则走备件替换流程</div>
</div>
</div>
<div class="flow-step">
<div class="flow-node">5</div>
<div class="flow-content">
<div class="flow-title">24H 后回访确认</div>
<div class="flow-desc">创建提醒任务,24小时后通过企业微信确认投屏使用正常</div>
</div>
</div>
</div>
</div>
<div class="ff-hint">全屏模式便于研读完整决策树与分支;关闭后回到右栏「排查步骤」原状态(展开/收起态保留)</div>
</div>
<!-- ============ 原型说明按钮 ============ -->
<button class="proto-btn" onclick="openProtoNote()">📋 原型说明 v1.4</button>
<!-- ============ 原型说明对话框 ============ -->
<div class="modal-mask" id="protoModal">
<div class="modal-box">
<span class="close-x" onclick="closeProtoNote()"></span>
<h3>📋 坐席工作台原型 v1.4 变更说明</h3>
<p style="font-size:12px;color:var(--text-secondary);margin-bottom:6px;">基于 v1.3(右栏重组)演进,本次两处调整,请重点评审:</p>
<h4>① 右栏宽度方案 B(加权 60:40 分栏)</h4>
<ul>
<li><b>左栏</b>:固定 <span class="kbd">260px</span>(会话列表,不变)。</li>
<li><b>中栏(对话区)</b><span class="kbd">flex: 1.5</span>,约占总宽 60%(扣除左栏后),坐席主工作面保持主导。</li>
<li><b>右栏(辅助面板)</b><span class="kbd">flex: 1</span>,约占总宽 40%;并设 <span class="kbd">min 320px / max 560px</span> 防止极端屏 collapsing 或过宽。</li>
<li>相对 v1.3 的「右栏固定 320px」,方案 B 让右栏随视口自适应拿到更舒适空间,同时不挤占聊天区。</li>
<li>评审对比:A 严格 50/50(聊天被砍半,大屏右栏过宽) / C 仅提升默认到 560px(1920 屏仍偏窄)。</li>
</ul>
<h4>② 排查步骤「全屏查看」流程图浮层</h4>
<ul>
<li>右栏「排查步骤」头部新增 <span class="kbd">⛶ 全屏查看</span> 按钮(与折叠箭头并列)。</li>
<li>点击打开<b>全屏浮层</b>,完整决策树以更大字号铺满视口,便于研读分支与定位当前节点。</li>
<li>关闭(✕ / <span class="kbd">Esc</span>)后回到右栏「排查步骤」原状态,展开/收起态不丢失。</li>
<li>设计取舍:仅浮层承载流程图(非整栏放大、非仅靠加宽),不影响 AI推荐/待办/复盘模块的常态布局。</li>
</ul>
<h4>评审操作提示</h4>
<ul>
<li>顶栏「会话状态」开关:模拟<b>会话进行中 / 已结束</b>,验证复盘三模块(智能标注/质量反馈/知识共享)显隐。</li>
<li>右下角「📋 原型说明」可随时回看本说明。</li>
<li>右上角可切换深/浅色主题。</li>
</ul>
</div>
</div>
<script>
/* ========== 主题切换 ========== */
function toggleTheme() {
const body = document.body;
const next = body.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
body.setAttribute('data-theme', next);
document.getElementById('themeIcon').textContent = next === 'dark' ? '☀️' : '🌙';
document.getElementById('themeLabel').textContent = next === 'dark' ? '浅色' : '深色';
}
/* ========== 排查步骤面板折叠/展开 ========== */
function toggleTsPanel() {
document.getElementById('tsPanel').classList.toggle('collapsed');
}
/* ========== 决策树 展开/收起 ========== */
function toggleTsFlow() {
var fc = document.getElementById('tsFlowchart');
var btn = document.getElementById('tsFlowBtn');
var collapsed = fc.classList.toggle('collapsed-flow');
btn.textContent = collapsed ? '▶ 展开完整排查决策树' : '▼ 收起完整排查决策树';
}
/* ========== 全屏流程图浮层 ========== */
function openFlowFullscreen() {
document.getElementById('flowFullscreen').classList.add('open');
}
function closeFlowFullscreen() {
document.getElementById('flowFullscreen').classList.remove('open');
}
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
closeFlowFullscreen();
closeProtoNote();
}
});
/* ========== 会话状态开关(验证「仅会话结束后显示」) ========== */
function toggleSessionState() {
var ended = document.body.classList.toggle('session-ended');
var label = document.getElementById('sessionStateLabel');
if (label) label.textContent = ended ? '会话已结束' : '会话进行中';
if (ended) {
var firstCard = document.querySelector('.post-session-card');
if (firstCard && firstCard.scrollIntoView) {
setTimeout(function(){ firstCard.scrollIntoView({ behavior: 'smooth', block: 'start' }); }, 60);
}
}
}
/* ========== 原型说明对话框 ========== */
function openProtoNote() { document.getElementById('protoModal').classList.add('open'); }
function closeProtoNote() { document.getElementById('protoModal').classList.remove('open'); }
document.getElementById('protoModal').addEventListener('click', function(e) {
if (e.target === this) closeProtoNote();
});
</script>
</body>
</html>