Files
wecom_it_smart_desk/docs/01-产品文档/04-坐席工作台/原型-REQ-坐席-000-坐席工作台-v1.6.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

1089 lines
59 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.6(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; }
/* ===== 消息框(v1.6:工具栏图标统一 + 移至消息框左上角 + AI 工具紧随其后) ===== */
.reply-box { flex-shrink: 0; border-top: 1px solid var(--border); background: var(--bg-secondary); padding: 0 12px 8px 12px; display: flex; flex-direction: column; position: relative; }
/* 消息框工具栏:左上角,常规工具 | 分隔 | AI 工具 */
.chat-toolbar { display: flex; align-items: center; gap: 2px; padding: 8px 0 4px; flex-shrink: 0; flex-wrap: wrap; }
.toolbar-left, .toolbar-right { display: flex; align-items: center; gap: 1px; padding: 3px 6px; border-radius: var(--radius); }
.toolbar-left { background: var(--bg-tertiary); }
/* v1.6:移除 .toolbar-right 高亮底色,AI 按钮与常规按钮共享完全相同 .tb-btn 外观(无独立高亮) */
.tb-btn {
display: flex; align-items: center; justify-content: center;
width: 32px; height: 28px; border: none; background: transparent;
border-radius: var(--radius); cursor: pointer; font-size: 14px; color: var(--text-muted);
transition: all 0.2s; position: relative;
}
.tb-btn:hover { background: var(--accent-soft); color: var(--accent); }
.tb-btn:active { transform: scale(0.92); }
.tb-tip {
display: none; position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%);
margin-bottom: 6px; background: var(--text-primary); color: var(--bg-secondary);
font-size: 10px; padding: 3px 8px; border-radius: 4px; white-space: nowrap; pointer-events: none;
box-shadow: var(--shadow);
}
.tb-btn:hover .tb-tip { display: block; }
.tb-sep { width: 1px; height: 14px; background: var(--border); margin: 0 6px; flex-shrink: 0; }
/* 输入卡片(textarea + 语音 + 发送,统一圆角卡片) */
.chat-input-card {
display: flex; align-items: flex-end; background: var(--bg-secondary);
border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden;
transition: border-color 0.25s, box-shadow 0.25s; box-shadow: var(--shadow-sm);
}
.chat-input-card:focus-within { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.chat-input {
flex: 1; background: transparent; border: none; padding: 10px 0 10px 14px;
color: var(--text-primary); font-size: 13px; font-family: inherit; resize: none;
min-height: 60px; max-height: 300px; outline: none; line-height: 1.5;
}
.chat-input::placeholder { color: var(--text-muted); }
.btn-voice {
padding: 8px 10px; margin: 4px 2px; background: transparent; color: var(--text-muted);
border: none; border-radius: var(--radius); font-size: 16px; cursor: pointer; flex-shrink: 0;
transition: all 0.25s;
}
.btn-voice:hover { background: var(--accent-soft); color: var(--accent); }
.btn-send {
padding: 8px 18px; margin: 4px 6px 4px 0; background: linear-gradient(135deg, var(--accent), var(--purple));
color: #fff; border: none; border-radius: var(--radius); font-size: 12px; font-weight: 600;
cursor: pointer; transition: all 0.25s; flex-shrink: 0; letter-spacing: 0.5px;
}
.btn-send:hover { opacity: 0.9; }
/* ----- 右栏:辅助面板(flex:1 = 40%,无 max 上限,恒与中栏 4:6 ----- */
.sidebar-right {
flex: 1; min-width: 320px;
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 推荐(v1.5/v1.6:上下排列 / 纵向列表) */
.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-refresh { margin-left: auto; cursor: pointer; font-size: 12px; opacity: 0.7; transition: var(--transition); }
.ars-refresh:hover { opacity: 1; transform: rotate(90deg); }
/* v1.6 纵向列表容器 */
.ars-list { display: flex; flex-direction: column; gap: 6px; }
.ars-card {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 7px 9px;
cursor: pointer;
transition: var(--transition);
display: flex; flex-direction: column; gap: 3px;
}
.ars-card:hover { border-color: var(--accent); background: var(--bg-hover); }
.ars-card-header { display: flex; align-items: center; gap: 6px; }
.ars-shortcut {
display: inline-flex; align-items: center; justify-content: center;
width: 16px; height: 16px; font-size: 10px; font-family: monospace; font-weight: 600;
color: var(--accent); background: var(--accent-soft); border: 1px solid var(--accent);
border-radius: 3px; line-height: 1; flex-shrink: 0; transition: var(--transition);
}
.ars-card:hover .ars-shortcut { background: var(--accent); color: #fff; }
.ars-card-title { font-size: 12px; font-weight: 600; color: var(--text-primary); flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ars-confidence { font-size: 10px; padding: 1px 6px; border-radius: 8px; background: var(--success-soft); color: var(--success); flex-shrink: 0; }
.ars-card-text { font-size: 11px; color: var(--text-secondary); line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.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: 600px; 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.6</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>
<!-- v1.6 消息框:工具栏图标统一(Emoji 同族)+ 移至消息框左上角 + AI 工具紧随其后 -->
<div class="reply-box">
<!-- 工具栏:常规工具 | 分隔 | AI 工具,位于消息框左上角 -->
<div class="chat-toolbar">
<!-- 常规工具(左组):仅 title 悬浮提示,无 tb-tip 文字 span -->
<div class="toolbar-left">
<button class="tb-btn" title="截图">✂️</button>
<button class="tb-btn" title="拍照">📷</button>
<span class="tb-sep"></span>
<button class="tb-btn" title="表情">😊</button>
<button class="tb-btn" title="文件">📎</button>
<span class="tb-sep"></span>
<button class="tb-btn" title="邀请员工/部门">👥</button>
</div>
<!-- 分组分隔(常规工具 与 AI 工具 之间) -->
<span class="tb-sep"></span>
<!-- AI 工具(右组):纯 emoji 图标、无文字标签、无高亮底色、同款 .tb-btn -->
<div class="toolbar-right">
<button class="tb-btn" title="AI 自动补齐">💡</button>
<button class="tb-btn" title="AI 语气调整">🎚️</button>
<button class="tb-btn" title="AI 文字润色">🖌️</button>
<button class="tb-btn" title="AI 智能改写">🔄</button>
</div>
</div>
<!-- 输入卡片(圆角:textarea + 语音 + 发送) -->
<div class="chat-input-card">
<textarea class="chat-input" placeholder="输入回复内容…(Enter 发送 / Shift+Enter 换行)"></textarea>
<button class="btn-voice" title="语音输入">🎤</button>
<button class="btn-send">发送</button>
</div>
</div>
</main>
<!-- ===== 右栏:辅助面板(flex:1 = 40%,无 max 上限,恒与中栏 4:6 ===== -->
<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 推荐(v1.6:上下排列 / 纵向列表) -->
<div class="ai-recommend-section">
<div class="ars-title">🤖 AI 智能推荐 <span class="ars-refresh" title="刷新推荐">🔄</span></div>
<div class="ars-list">
<div class="ars-card" onclick="alert('回填至输入框(原型示意)')">
<div class="ars-card-header">
<span class="ars-shortcut">1</span>
<span class="ars-card-title">临时过渡方案</span>
<span class="ars-confidence">94%</span>
</div>
<div class="ars-card-text">可先用笔记本直连 HDMI 过渡,同时已为您派单现场运维,预计 10 分钟内到达。</div>
</div>
<div class="ars-card" onclick="alert('回填至输入框(原型示意)')">
<div class="ars-card-header">
<span class="ars-shortcut">2</span>
<span class="ars-card-title">驱动重装指引</span>
<span class="ars-confidence">88%</span>
</div>
<div class="ars-card-text">打开软件管家搜索「无线投屏驱动」一键重装,重启投屏器后重试。</div>
</div>
<div class="ars-card" onclick="alert('回填至输入框(原型示意)')">
<div class="ars-card-header">
<span class="ars-shortcut">3</span>
<span class="ars-card-title">现场派单模板</span>
<span class="ars-confidence">81%</span>
</div>
<div class="ars-card-text">创建现场工单,指派会议室运维检查投屏器固件、WiFi 信道与供电。</div>
</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.6</button>
<!-- ============ 原型说明对话框 ============ -->
<div class="modal-mask" id="protoModal">
<div class="modal-box">
<span class="close-x" onclick="closeProtoNote()"></span>
<h3>📋 坐席工作台原型 v1.6 变更说明</h3>
<p style="font-size:12px;color:var(--text-secondary);margin-bottom:6px;">基于 v1.5(B 方案分栏 + 全屏流程图 + 智能推荐竖排 + 工具栏重组)演进,本次核心调整:<b>工具栏图标统一(Emoji 同族统一)</b></p>
<h4>① 右栏 AI 智能推荐:上下排列(纵向列表)</h4>
<ul>
<li>原 v1.4 生产实现为<b>横向滚动卡片行</b><span class="kbd">display:flex; overflow-x:auto</span>),一屏仅见 13 条、需横向滑动。</li>
<li>v1.5 起改为<b>纵向堆叠</b><span class="kbd">flex-direction:column</span>),每条推荐占满右栏宽度,自上而下依次排列,方便逐条阅读与对比。</li>
<li>保留原卡片信息密度:数字快捷键徽标 + 方案标题 + 置信度药丸 + 两行截断正文,点击回填输入框。</li>
</ul>
<h4>② 中栏消息框工具栏:图标移至消息框左上角</h4>
<ul>
<li>工具栏(常规工具 + AI 工具)整体上移并左对齐,紧贴<b>消息输入框左上角</b>,与输入卡片形成「图标条 + 输入区」的整体结构。</li>
<li>常规工具组:<b>截图 / 拍照 / 表情 / 文件 / 邀请</b>,组内以细分隔线分段。</li>
</ul>
<h4>③ AI 工具按钮:图标统一(Emoji 同族)+ 紧跟工具图标 + 中间分隔</h4>
<ul>
<li>四个 AI 按钮 <b>💡自动补齐 / 🎚️语气 / 🖌️润色 / 🔄改写</b> 采用纯 emoji 图标、<b>无文字标签</b>,图标尺寸、圆角、悬停态与常规工具按钮<b>完全一致</b>(统一 <span class="kbd">.tb-btn</span> 样式)。</li>
<li>位置紧贴常规工具图标后方,两组之间以<b>一条分隔线</b>区分,视觉上构成「常规工具 | AI 工具」的连续工具条。</li>
<li>语义:常规工具负责「输入动作」,AI 工具负责「文本智能处理」,并列且界限清晰。</li>
</ul>
<h4>④ 工具栏图标统一设计说明(v1.6 新增)</h4>
<ul>
<li><b>统一原则(Emoji 同族统一)</b>:保持 emoji 风格、不改为 SVG;全部按钮(常规 + AI)共用同一 <span class="kbd">.tb-btn</span> 样式——同尺寸、同圆角、同悬停态、同透明度;<b>AI 组不再带高亮底色</b>,仅以原生 <span class="kbd">title</span> 作为悬浮提示(无 <span class="kbd">tb-tip</span> 文字 span),视觉权重完全一致。</li>
<li>
<b>AI 图标映射表(功能 → emoji → 语义)</b>
<br>· 自动补齐 → <b>💡</b>(灯泡 = 智能建议/补齐,对象类 emoji)
<br>· 语气调整 → <b>🎚️</b>(电平滑块 = 语气层级,对象类 emoji,语义最佳)
<br>· 文字润色 → <b>🖌️</b>(画笔 = 润色,对象类 emoji)
<br>· 智能改写 → <b>🔄</b>(循环箭头 = 改写,对象类 emoji,沿用 v1.5)
</li>
<li><b>与常规工具栏 emoji 家族的一致性论证</b>:常规工具栏使用 ✂️📷😊📎👥(及输入卡片 🎤)等「具象工具/对象类」emoji;本次 AI 组将原 🎭(人脸/戏剧面具)、✨(装饰星芒)、✏️(语义偏弱的铅笔)统一替换为 💡🎚️🖌️🔄,<b>全部为「工具/对象感」emoji,已剔除所有人脸与纯装饰类</b>,家族归属与常规组对齐,工具条整体不再出现「人脸/星芒」打断工具感。</li>
<li><b>去掉高亮底色的理由</b>:原 <span class="kbd">.toolbar-right { background: var(--accent-soft) }</span> 使 AI 组呈现浅蓝胶囊高亮,看起来像被单独强调的分组,与常规按钮形成视觉权重落差。v1.6 将该底色移除,AI 按钮与常规按钮共享完全相同外观(常规组保留中性 group 背景 <span class="kbd">bg-tertiary</span> 仅作分组提示,非高亮强调),消除「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>
<!--
===========================================================
v1.6 验证清单(工具栏图标统一 · Emoji 同族统一)
===========================================================
[✓] 标签平衡:所有 HTML 标签均正确闭合,无未闭合标签(已逐项核对 div/button/span/aside/main 等)。
[✓] 4 个新 emoji 双处一致:工具栏 DOM.toolbar-right 内)与底部说明区「AI 图标映射表」均为
💡自动补齐 / 🎚️语气 / 🖌️润色 / 🔄改写。
[✓] .toolbar-right 无高亮底色:已删除 `background: var(--accent-soft)`AI 组不再单独高亮。
[✓] 无 tb-tip 文字 span:常规组与 AI 组的按钮均仅保留 title 悬浮提示,DOM 中无 <span class="tb-tip"> 文字 span。
[✓] 常规工具栏 emoji 未改动:✂️📷😊📎👥(常规组)与 🎤(输入卡片语音)保持 v1.5 原样。
[✓] 其他关键特性保留:B 方案分栏(中 flex1.5 / 右 flex1 ≈ 60:40、右栏去 max-width 上限)、
全屏流程图浮层、AI 智能推荐竖排、工具栏移至消息框左上角、4 个 AI 按钮无文字标签仅 title。
[✓] 版本号:标题、v-tag、原型说明按钮、对话框标题均升至 v1.6。
===========================================================
-->
</body>
</html>