Files
wecom_it_smart_desk/docs/01-产品文档/02-会话管理/原型-REQ-会话-001-结束会话流程-v1.4.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

1345 lines
60 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>员工结束会话 - 原型图 v1.4</title>
<style>
:root {
--primary: #07C160;
--primary-light: #e8f9ed;
--info: #1989fa;
--info-light: #ecf5ff;
--text: #333;
--text-light: #666;
--text-tertiary: #999;
--border: #e5e5e5;
--bg: #f7f7f7;
--white: #fff;
--warning: #ff976a;
--danger: #ee0a24;
--danger-soft: rgba(239, 68, 68, 0.1);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', sans-serif;
background: var(--bg);
padding: 20px;
min-height: 100vh;
color: var(--text);
line-height: 1.6;
}
.container { max-width: 920px; margin: 0 auto; }
h1 { text-align: center; margin-bottom: 8px; font-size: 24px; }
.subtitle { text-align: center; color: var(--text-light); margin-bottom: 30px; font-size: 13px; }
.section {
background: var(--white);
border-radius: 12px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
}
.section-title {
font-size: 16px;
font-weight: 600;
margin-bottom: 16px;
color: var(--text);
display: flex;
align-items: center;
gap: 8px;
}
.section-title::before {
content: '';
width: 4px;
height: 16px;
background: var(--primary);
border-radius: 2px;
}
.section-desc {
font-size: 13px;
color: var(--text-light);
margin-bottom: 16px;
}
/* === 头部 mockup === */
.header-mock {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 14px;
background: var(--white);
border: 1px solid var(--border);
border-radius: 10px;
margin-bottom: 10px;
}
.header-mock__left {
display: flex;
align-items: center;
gap: 12px;
}
.header-mock__brand {
display: flex;
align-items: center;
gap: 8px;
font-weight: 600;
font-size: 13px;
}
.header-mock__logo {
background: var(--primary);
color: var(--white);
padding: 3px 7px;
border-radius: 4px;
font-size: 11px;
font-weight: 700;
}
.header-mock__status {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 3px 10px;
border-radius: 12px;
font-size: 11px;
font-weight: 500;
}
.header-mock__status--online {
background: var(--primary-light);
color: var(--primary);
}
.header-mock__status--offline {
background: #f5f5f5;
color: var(--text-tertiary);
}
.header-mock__status-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: currentColor;
}
.header-mock__actions {
display: flex;
align-items: center;
gap: 10px;
}
.header-mock__avatar {
width: 28px;
height: 28px;
border-radius: 50%;
background: var(--bg);
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: var(--text-light);
}
.header-mock__exit {
width: 32px;
height: 32px;
border-radius: 8px;
border: 1px solid var(--danger);
color: var(--danger);
background: var(--danger-soft);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 14px;
}
.header-mock__exit--hidden {
visibility: hidden;
}
.header-mock__theme {
color: var(--text-light);
font-size: 12px;
}
/* === 对话区 mockup === */
.chat-mock {
border: 1px solid var(--border);
border-radius: 12px;
overflow: hidden;
background: var(--bg);
max-width: 460px;
margin: 0 auto;
}
.chat-mock__header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px;
background: var(--white);
border-bottom: 1px solid var(--border);
font-size: 12px;
}
.chat-mock__messages {
padding: 14px;
display: flex;
flex-direction: column;
gap: 10px;
min-height: 160px;
}
.msg {
max-width: 75%;
padding: 7px 11px;
border-radius: 10px;
font-size: 13px;
line-height: 1.5;
}
.msg--employee {
align-self: flex-end;
background: var(--primary);
color: var(--white);
border-bottom-right-radius: 4px;
}
.msg--ai {
align-self: flex-start;
background: var(--white);
color: var(--text);
border-bottom-left-radius: 4px;
}
.msg--system {
align-self: center;
background: rgba(0,0,0,0.05);
color: var(--text-light);
font-size: 12px;
text-align: center;
max-width: 90%;
}
/* 排队进度胶囊 */
.queue-capsule {
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
margin: 10px 14px;
padding: 8px 12px;
border-radius: 18px;
font-size: 12px;
font-weight: 500;
background: rgba(245, 158, 11, 0.1);
color: var(--warning);
border: 1px solid var(--warning);
text-align: center;
}
.queue-capsule--connected {
background: var(--primary-light);
color: var(--primary);
border-color: var(--primary);
}
/* 输入栏 */
.input-bar-mock {
padding: 8px 10px;
background: var(--white);
border-top: 1px solid var(--border);
}
.input-bar-mock__top {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
margin-bottom: 6px;
}
.input-bar-mock__field {
flex: 1;
padding: 5px 9px;
border: 1px solid var(--border);
border-radius: 7px;
font-size: 12px;
color: var(--text-light);
}
.input-bar-mock__send {
padding: 5px 12px;
background: var(--primary);
color: var(--white);
border: none;
border-radius: 6px;
font-size: 12px;
cursor: pointer;
}
.call-btn {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 4px 12px;
border-radius: 14px;
font-size: 12px;
font-weight: 600;
border: 1.5px solid;
cursor: pointer;
white-space: nowrap;
}
.call-btn--disabled {
border-color: var(--border);
background: var(--bg);
color: var(--text-tertiary);
opacity: 0.6;
cursor: not-allowed;
}
.call-btn--active {
border-color: var(--primary);
background: var(--primary-light);
color: var(--primary);
}
.call-btn--urgent {
border-color: var(--danger);
background: var(--danger-soft);
color: var(--danger);
animation: pulse 1.5s ease-in-out infinite;
}
.call-btn--waiting {
border-color: var(--warning);
background: rgba(245, 158, 11, 0.1);
color: var(--warning);
}
.call-btn--end {
border-color: var(--danger);
background: var(--danger);
color: var(--white);
font-weight: 700;
}
.call-btn--reopen {
border-color: var(--info);
background: var(--info-light);
color: var(--info);
}
@keyframes pulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }
50% { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
}
.input-bar-mock__guide {
text-align: center;
font-size: 11px;
color: var(--text-placeholder, var(--text-tertiary));
margin-top: 6px;
padding: 2px 0;
}
.input-bar-mock__guide--warn {
color: var(--warning);
}
/* 6 态网格 */
.states-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
margin-top: 12px;
}
.state-card {
border: 1.5px dashed var(--border);
border-radius: 10px;
padding: 14px 10px;
text-align: center;
background: var(--white);
}
.state-card__label {
font-size: 11px;
color: var(--text-tertiary);
margin-bottom: 10px;
font-family: monospace;
}
.state-card__guide {
margin-top: 8px;
font-size: 11px;
color: var(--text-light);
line-height: 1.4;
}
.state-card__scene {
margin-top: 6px;
font-size: 10px;
color: var(--text-tertiary);
}
/* 场景对比 */
.compare-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-top: 16px;
}
.compare-pane {
border: 1px solid var(--border);
border-radius: 10px;
padding: 14px;
background: var(--bg);
}
.compare-pane__title {
font-size: 13px;
font-weight: 600;
margin-bottom: 10px;
color: var(--text);
}
.compare-pane--ai { border-top: 3px solid var(--primary); }
.compare-pane--human { border-top: 3px solid var(--danger); }
/* 流程图 */
.flow {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 6px;
flex-wrap: wrap;
padding: 16px 0;
}
.flow-step {
background: var(--primary);
color: var(--white);
padding: 8px 14px;
border-radius: 16px;
font-size: 13px;
font-weight: 500;
}
.flow-step--system { background: var(--text-tertiary); }
.flow-step--warn { background: var(--warning); }
.flow-step--danger { background: var(--danger); }
.flow-step--info { background: var(--info); }
.flow-arrow { font-size: 18px; color: var(--text-light); }
/* 注释 */
.note {
background: #fff7e6;
border: 1px solid #ffd591;
border-radius: 8px;
padding: 12px;
font-size: 13px;
color: #d46b08;
margin-top: 12px;
}
.note--info {
background: var(--info-light);
border-color: var(--info);
color: var(--text);
}
.note--danger {
background: #fff0f0;
border-color: #ffccc7;
color: var(--danger);
}
.note--success {
background: var(--primary-light);
border-color: var(--primary);
color: var(--text);
}
/* 表格式对比 */
.cmp-table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
margin-top: 12px;
}
.cmp-table th, .cmp-table td {
text-align: left;
padding: 8px 10px;
border: 1px solid var(--border);
}
.cmp-table th {
background: var(--bg);
font-weight: 600;
}
.cmp-table td { color: var(--text-light); }
.cmp-table tr td:first-child {
font-weight: 600;
color: var(--text);
}
.yes { color: var(--primary); font-weight: 600; }
.no { color: var(--danger); font-weight: 600; }
/* 流程图分支 */
.flow-branch {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-top: 12px;
}
.flow-branch__col {
padding: 14px;
border-radius: 10px;
background: var(--bg);
}
.flow-branch__col--ai { border-left: 3px solid var(--primary); }
.flow-branch__col--human { border-left: 3px solid var(--danger); }
.flow-branch__title {
font-size: 13px;
font-weight: 600;
margin-bottom: 10px;
}
.flow-branch__steps {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 4px;
}
.flow-branch__step {
background: var(--white);
border: 1px solid var(--border);
padding: 4px 10px;
border-radius: 12px;
font-size: 11px;
color: var(--text);
}
.flow-branch__arrow { color: var(--text-tertiary); font-size: 12px; }
</style>
</head>
<body>
<div class="container">
<h1>🎯 员工结束会话功能 · 原型图 v1.4</h1>
<div class="subtitle">
v1.4 调整(2026-08-03)— 方案 A 整合区:操作按钮/进度胶囊/引导语三元素(状态条已删除,v1.3.5 决策)
</div>
<!-- ========== 章节 1:设计哲学 ========== -->
<div class="section">
<div class="section-title">设计哲学:4 维度分离(v1.2 新增"退出兜底"独立维度)</div>
<div class="section-desc">
v1.1 三维度基础上,新增"退出兜底"作为独立维度——<b>顶部按钮语义收窄到 AI 场景</b>,与操作按钮 end 态<b>场景互斥</b>
</div>
<table class="cmp-table">
<thead>
<tr>
<th>维度</th>
<th>性质</th>
<th>UI 形式</th>
<th>位置</th>
<th>v1.2 变化</th>
</tr>
</thead>
<tbody>
<tr>
<td>A. 服务可用性</td>
<td>系统状态</td>
<td>标题栏徽章 🟢/⚫</td>
<td>顶部</td>
<td>沿用</td>
</tr>
<tr>
<td>B. 会话进程</td>
<td>用户动作</td>
<td>操作按钮 6 态 + 引导语</td>
<td>输入栏</td>
<td><b>5 态 → 6 态 + 引导语</b></td>
</tr>
<tr>
<td>C. 排队进度</td>
<td>实时反馈</td>
<td>底部消息胶囊</td>
<td>输入框上方</td>
<td>沿用</td>
</tr>
<tr style="background:var(--primary-light);">
<td>D. 退出兜底 🆕</td>
<td>AI 场景专属</td>
<td>标题栏红色退出按钮</td>
<td>顶部右侧</td>
<td><b>仅 AI 场景显示</b></td>
</tr>
</tbody>
</table>
<div class="note note--success">
💡 维度 D 与维度 B 的 end 态<b>场景互斥</b>,任何时候只有一个可用,从根本上避免"双入口混乱"
</div>
</div>
<!-- ========== 章节 2:操作按钮 6 态 + 引导语 ⭐核心变更⭐ ========== -->
<div class="section" style="border:2px solid var(--primary);">
<div class="section-title">⭐ 操作按钮 · 6 态 + 4 种引导语(v1.2 核心变更)</div>
<div class="section-desc">
v1.1 的 5 态调整:<span class="no">❌ 移除 hidden</span> / <span class="yes">✅ 恢复 end</span> / <span class="yes">✅ 新增 reopen</span><br>
新增 4 种场景引导语,按钮永远可见(仅状态变化),用户不会再"找不到入口"。
</div>
<div class="states-grid">
<!-- disabled: 无会话 -->
<div class="state-card">
<div class="state-card__label">disabled · 无会话</div>
<button class="call-btn call-btn--disabled">🔒 人工坐席</button>
<div class="state-card__guide">💡 先描述一下你遇到的问题,AI 助手会先帮你看看</div>
<div class="state-card__scene">用户刚打开应用</div>
</div>
<!-- disabled: AI <3 轮 -->
<div class="state-card">
<div class="state-card__label">disabled · AI &lt;3 轮</div>
<button class="call-btn call-btn--disabled">🔒 人工坐席</button>
<div class="state-card__guide">请继续描述您的问题或需求</div>
<div class="state-card__scene">AI 对话早期</div>
</div>
<!-- disabled: 坐席离线 -->
<div class="state-card">
<div class="state-card__label">disabled · 坐席离线</div>
<button class="call-btn call-btn--disabled">🔒 人工坐席</button>
<div class="state-card__guide input-bar-mock__guide--warn">⚠️ 坐席当前离线,建议先用 AI 解答</div>
<div class="state-card__scene">!store.agentOnline</div>
</div>
<!-- active -->
<div class="state-card">
<div class="state-card__label">active · AI ≥3 轮</div>
<button class="call-btn call-btn--active">🎧 人工坐席</button>
<div class="state-card__scene">可呼叫</div>
</div>
<!-- urgent -->
<div class="state-card">
<div class="state-card__label">urgent · 紧急关键词</div>
<button class="call-btn call-btn--urgent">🚨 人工坐席</button>
<div class="state-card__scene">高优一键呼叫</div>
</div>
<!-- waiting -->
<div class="state-card">
<div class="state-card__label">waiting · 排队中</div>
<button class="call-btn call-btn--waiting">⏳ 排队等待</button>
<div class="state-card__scene">点击取消排队</div>
</div>
<!-- end (v1.2 恢复) -->
<div class="state-card" style="background:#fff5f5;">
<div class="state-card__label">end 🆕 · 坐席服务中</div>
<button class="call-btn call-btn--end">📴 结束咨询</button>
<div class="state-card__scene">v1.2 恢复 · 主动挂断人工</div>
</div>
<!-- reopen (v1.2 新增) -->
<div class="state-card" style="background:var(--info-light);">
<div class="state-card__label">reopen 🆕 · 24h 内重开</div>
<button class="call-btn call-btn--reopen">🔄 重新打开</button>
<div class="state-card__scene">v1.2 新增 · 蓝色填充</div>
</div>
<!-- disabled: 会话过期 -->
<div class="state-card">
<div class="state-card__label">disabled · 会话过期</div>
<button class="call-btn call-btn--disabled">🔒 人工坐席</button>
<div class="state-card__guide">⏰ 上一会话已过期,开始新对话吧</div>
<div class="state-card__scene">&gt;24h 不可重开</div>
</div>
</div>
<div class="note">
⚠️ 优先级:<b>end &gt; reopen &gt; waiting &gt; active/urgent &gt; disabled</b>。hidden 已完全移除。
</div>
</div>
<!-- ========== 章节 3:顶部按钮可见性规则 ⭐⭐关键变更⭐⭐ ========== -->
<div class="section" style="border:2px solid var(--danger);">
<div class="section-title">⭐⭐ 顶部退出按钮 · 仅 AI 场景显示(v1.2 G7 关键变更)</div>
<div class="section-desc">
产品澄清:顶部按钮的语义被收窄为<b>"AI 会话兜底退出"</b>——告诉系统"我走了,别发倒计时"。<br>
人工咨询启动后(waiting / serving),顶部按钮<b>自动隐藏</b>,由操作按钮 end 态接管"结束人工"动作。
</div>
<table class="cmp-table">
<thead>
<tr>
<th>会话场景</th>
<th>顶部"退出会话"</th>
<th>操作按钮</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>无会话</td>
<td class="no">❌ 隐藏</td>
<td>🔒 disabled(引导"先说问题"</td>
<td>用户还没开始</td>
</tr>
<tr style="background:var(--primary-light);">
<td>AI 对话中(任何状态)</td>
<td class="yes">✅ 显示</td>
<td>🎧 active / 🔒 disabled</td>
<td>顶部 = AI 兜底退出</td>
</tr>
<tr style="background:#fff5f5;">
<td><b>人工咨询启动后(waiting</b></td>
<td class="no">❌ 隐藏</td>
<td>⏳ waiting(取消排队)</td>
<td>操作按钮接管</td>
</tr>
<tr style="background:#fff5f5;">
<td><b>坐席服务中(serving</b></td>
<td class="no">❌ 隐藏</td>
<td>📴 end(结束咨询)</td>
<td>操作按钮 end 态接管</td>
</tr>
<tr>
<td>会话已关闭(24h 内)</td>
<td class="no">❌ 隐藏</td>
<td>🔄 reopen(重新打开)</td>
<td>操作按钮 reopen 接管</td>
</tr>
<tr>
<td>会话已关闭(&gt;24h</td>
<td class="no">❌ 隐藏</td>
<td>🔒 disabled(引导"开新会话"</td>
<td>过期失效</td>
</tr>
</tbody>
</table>
</div>
<!-- ========== 章节 4:场景对比 mockup ========== -->
<div class="section">
<div class="section-title">场景对比 mockup:AI 对话 vs 坐席服务中</div>
<div class="compare-grid">
<!-- AI 对话场景 -->
<div class="compare-pane compare-pane--ai">
<div class="compare-pane__title">AI 对话中(顶部按钮可见)</div>
<div class="header-mock" style="margin-bottom:8px;">
<div class="header-mock__left">
<div class="header-mock__brand">
<span class="header-mock__logo">IT</span>
<span>智能IT服务</span>
</div>
<span class="header-mock__status header-mock__status--online">
<span class="header-mock__status-dot"></span>在线
</span>
</div>
<div class="header-mock__actions">
<span class="header-mock__theme">☀️🌙</span>
<div class="header-mock__avatar">S</div>
<div class="header-mock__exit" title="结束会话(不再发送提醒)"></div>
</div>
</div>
<div class="chat-mock">
<div class="chat-mock__messages">
<div class="msg msg--employee">VPN 连不上</div>
<div class="msg msg--ai">请尝试重启...</div>
<div class="msg msg--employee">重启了还是不行</div>
</div>
<div class="input-bar-mock">
<div class="input-bar-mock__top">
<span style="font-size:14px;">😊</span><span style="font-size:14px;">📎</span>
<div class="input-bar-mock__field">请输入消息...</div>
<button class="call-btn call-btn--active">🎧 人工坐席</button>
<button class="input-bar-mock__send">发送</button>
</div>
</div>
</div>
<div style="text-align:center;font-size:11px;color:var(--text-tertiary);margin-top:6px;">
▲ 顶部红色按钮可用 · 用户可主动告诉系统"我走了"
</div>
</div>
<!-- 人工服务场景 -->
<div class="compare-pane compare-pane--human">
<div class="compare-pane__title">坐席服务中(顶部按钮隐藏)</div>
<div class="header-mock" style="margin-bottom:8px;">
<div class="header-mock__left">
<div class="header-mock__brand">
<span class="header-mock__logo">IT</span>
<span>智能IT服务</span>
</div>
<span class="header-mock__status header-mock__status--online">
<span class="header-mock__status-dot"></span>在线
</span>
</div>
<div class="header-mock__actions">
<span class="header-mock__theme">☀️🌙</span>
<div class="header-mock__avatar">S</div>
<!-- 顶部按钮隐藏 -->
<div class="header-mock__exit header-mock__exit--hidden" title=""></div>
</div>
</div>
<div class="chat-mock">
<div class="chat-mock__messages">
<div class="msg msg--employee">VPN 连不上</div>
<div class="msg msg--ai">请尝试重启...</div>
<div class="msg msg--system">客服小王已接入服务</div>
<div class="msg msg--ai" style="background:#e8f9ed;">您好,我是小王,我来帮您处理 VPN 问题</div>
</div>
<div class="input-bar-mock">
<div class="input-bar-mock__top">
<span style="font-size:14px;">😊</span><span style="font-size:14px;">📎</span>
<div class="input-bar-mock__field">请输入消息...</div>
<button class="call-btn call-btn--end">📴 结束咨询</button>
<button class="input-bar-mock__send">发送</button>
</div>
</div>
</div>
<div style="text-align:center;font-size:11px;color:var(--text-tertiary);margin-top:6px;">
▲ 顶部按钮已隐藏 · 操作按钮 end 态接管"结束人工"
</div>
</div>
</div>
<div class="note note--success">
💡 两个按钮<b>场景互斥</b>,从根源避免"两个都能结束,点哪个"的混乱
</div>
</div>
<!-- ========== 章节 5:重新打开按钮 mockup ========== -->
<div class="section">
<div class="section-title">🔄 「重新打开」按钮 mockup(v1.2 新增)</div>
<div class="section-desc">
会话已关闭 + 24h 内,按钮变 🔄 重新打开(蓝色)。不显示 24h 倒计时数字,避免紧迫感。
</div>
<div class="chat-mock" style="max-width:400px;">
<div class="chat-mock__header">
<span>💬 对话(已结束)</span>
</div>
<div class="chat-mock__messages">
<div class="msg msg--employee">好的,谢谢小王</div>
<div class="msg msg--ai">不客气,随时找我</div>
<div class="msg msg--system">✅ 会话已关闭。24 小时内可重新打开。</div>
</div>
<div class="input-bar-mock">
<div class="input-bar-mock__top">
<span style="font-size:14px;">😊</span><span style="font-size:14px;">📎</span>
<div class="input-bar-mock__field" style="opacity:0.5;">会话已关闭</div>
<button class="call-btn call-btn--reopen">🔄 重新打开</button>
</div>
</div>
</div>
<div class="note note--info">
💡 颜色选择:蓝色(<code>--info: #1989fa</code>),与"激活"绿色和"危险"红色明确区分,传达"中性恢复"语义
</div>
</div>
<!-- ========== 章节 6:完整流程(双入口分流) ========== -->
<div class="section">
<div class="section-title">⑥ 完整流程 · 双入口场景分流(v1.2 修订)</div>
<div class="section-desc">
AI 会话走<b>顶部退出</b>路径,人工会话走<b>操作按钮 end</b>路径,两个入口<b>场景互斥</b>
</div>
<div class="flow-branch">
<!-- AI 分支 -->
<div class="flow-branch__col flow-branch__col--ai">
<div class="flow-branch__title">🅰️ AI 会话路径(顶部退出入口)</div>
<div class="flow-branch__steps">
<span class="flow-branch__step">🎧 AI 咨询</span>
<span class="flow-branch__arrow"></span>
<span class="flow-branch__step">⏏ 点击顶部退出</span>
<span class="flow-branch__arrow"></span>
<span class="flow-branch__step">确认弹窗</span>
<span class="flow-branch__arrow"></span>
<span class="flow-branch__step">😊 满意度评价</span>
<span class="flow-branch__arrow"></span>
<span class="flow-branch__step">🚪 关闭窗口</span>
</div>
</div>
<!-- 人工分支 -->
<div class="flow-branch__col flow-branch__col--human">
<div class="flow-branch__title">🅱️ 人工会话路径(操作按钮 end 入口)</div>
<div class="flow-branch__steps">
<span class="flow-branch__step">🎧 呼叫人工</span>
<span class="flow-branch__arrow"></span>
<span class="flow-branch__step">⏳ 排队</span>
<span class="flow-branch__arrow"></span>
<span class="flow-branch__step">📴 服务中 end</span>
<span class="flow-branch__arrow"></span>
<span class="flow-branch__step">📴 点击结束</span>
<span class="flow-branch__arrow"></span>
<span class="flow-branch__step">😊 满意度评价</span>
<span class="flow-branch__arrow"></span>
<span class="flow-branch__step">🚪 关闭窗口</span>
</div>
</div>
</div>
</div>
<!-- ========== 章节 7:右栏对比(v1.1 沿用) ========== -->
<div class="section">
<div class="section-title">⑦ 右栏简化(v1.1 沿用 · G6)</div>
<div class="compare-grid">
<div class="compare-pane compare-pane--v1">
<div class="compare-pane__title">v1.0 右栏(4 大区块)</div>
<div class="mini-panel">
<div class="mini-panel__title">▼ 设备信息</div>
CPU / 内存 / 硬盘
</div>
<div class="mini-panel">
<div class="mini-panel__title">▼ 自助诊断</div>
一键诊断 + 异常徽章
</div>
<div class="mini-panel">
<div class="mini-panel__title">⚡ 智能推荐</div>
操作步骤 / 联系人 / 下载
</div>
<div class="mini-panel mini-panel--removed" style="background:#fff0f0;color:var(--danger);text-decoration:line-through;padding:10px;border-radius:8px;margin-bottom:6px;font-size:12px;">
<div class="mini-panel__title" style="font-weight:600;color:inherit;margin-bottom:4px;">⏳ 排队等待</div>
位置 / 预计时长 / 答题挑战
</div>
</div>
<div class="compare-pane compare-pane--v11">
<div class="compare-pane__title">v1.2 右栏(2 大区块)✅</div>
<div class="mini-panel" style="background:var(--white);border-radius:8px;padding:10px;margin-bottom:6px;font-size:12px;">
<div class="mini-panel__title" style="font-weight:600;color:var(--text);margin-bottom:4px;">▼ 设备信息</div>
CPU / 内存 / 硬盘
</div>
<div class="mini-panel" style="background:var(--white);border-radius:8px;padding:10px;margin-bottom:6px;font-size:12px;">
<div class="mini-panel__title" style="font-weight:600;color:var(--text);margin-bottom:4px;">▼ 自助诊断</div>
一键诊断 + 异常徽章
</div>
<div class="mini-panel" style="background:var(--white);border-radius:8px;padding:10px;margin-bottom:6px;font-size:12px;">
<div class="mini-panel__title" style="font-weight:600;color:var(--text);margin-bottom:4px;">⚡ 智能推荐</div>
操作步骤 / 联系人 / 下载
</div>
</div>
</div>
</div>
<!-- ========== 章节 8:变更摘要 ========== -->
<div class="section">
<div class="section-title">⑧ v1.1 → v1.2 关键变更(已有) · v1.2 → v1.3 增量变更(待评审 ⏳)</div>
<table class="cmp-table">
<thead>
<tr>
<th>变更项</th>
<th>v1.2</th>
<th>v1.3(待评审 ⏳)</th>
</tr>
</thead>
<tbody>
<tr>
<td>操作按钮状态数</td>
<td>6 态(移除 hidden / 恢复 end / 新增 reopen</td>
<td>沿用 6 态(不动)</td>
</tr>
<tr>
<td>引导语</td>
<td>4 种场景分阶段引导语</td>
<td><b>迁移至整合区按钮下方</b></td>
</tr>
<tr>
<td>顶部按钮可见性</td>
<td>仅 AI 场景显示</td>
<td>沿用(仅 AI 场景显示)</td>
</tr>
<tr>
<td>「重新打开」按钮</td>
<td>新增(蓝色)</td>
<td>沿用(位置从 InputBar 移至整合区)</td>
</tr>
<tr>
<td>{n}/3 进度提示</td>
<td>移除(避免催促感)</td>
<td>沿用(移除)</td>
</tr>
<tr>
<td>顶部按钮文案</td>
<td>加 tooltip + 确认弹窗</td>
<td>沿用</td>
</tr>
<tr>
<td>状态机互斥保证</td>
<td>showHeaderExitBtn 计算逻辑</td>
<td>沿用(整合区状态条 v1.4 已删除)</td>
</tr>
<tr>
<td>结束会话入口</td>
<td>顶部(AI)+ 操作按钮 end(人工)双入口</td>
<td>沿用(按钮位置从 InputBar 移至整合区)</td>
</tr>
<tr>
<td>维度划分</td>
<td>4 维度(新增"退出兜底"独立维度)</td>
<td><b>4 维度(整合区降为三元素,状态条 v1.4 已删除)</b></td>
</tr>
<!-- ========== v1.2 → v1.3 增量变更项(待评审) ========== -->
<tr style="background:var(--primary-light);">
<td>整合区结构 🆕</td>
<td>4 维度分散(标题栏徽章 / 输入栏按钮 / 消息胶囊)</td>
<td><b>4 维度整合区(按钮 + 进度胶囊 + 引导语)</b></td>
</tr>
<tr style="background:var(--primary-light);">
<td>标题栏坐席徽章 🆕</td>
<td>显示 🟢/⚫</td>
<td><b>移至整合区顶部(标题栏瘦身)</b></td>
</tr>
<tr style="background:var(--primary-light);">
<td>InputBar 操作按钮 🆕</td>
<td>在工具栏内(与发送按钮并列)</td>
<td><b>移至整合区(InputBar 工具栏更简洁)</b></td>
</tr>
<tr style="background:var(--primary-light);">
<td>引导语位置 🆕</td>
<td>InputBar 按钮下方</td>
<td><b>整合区按钮下方(v1.3 待评审)</b></td>
</tr>
</tbody>
</table>
<div class="note">
📌 对应 PRD:<code>PRD-REQ-会话-001-员工结束会话-v1.4.md</code><br>
📌 对应技术方案:<code>技术方案-REQ-会话-001-员工结束会话-v1.4.md</code>
</div>
<div class="note note--info">✅ v1.3 方案 A 5 项细节已拍板(2026-07-31),见章节 9.6;⚠️ v1.42026-08-03)反转删除状态条</div>
</div>
<!-- ========== 章节 9:方案 A 整合区设计(v1.3 待评审) ========== -->
<div class="section" style="border:2px solid var(--primary);">
<div class="section-title">⑨ 方案 A 整合区设计(v1.3 已拍板 ✅ · v1.4 删除状态条)</div>
<div class="section-desc">
把 v1.2 的 <b>4 维度分离</b>(服务可用性 / 会话进程 / 排队进度 / 退出兜底)重新组织为 <b>"整合区 + 顶部退出"</b> 两段式。<br>
整合区统一收容三元素:<b>操作按钮(核心 CTA</b> + <b>进度消息胶囊(按需)</b> + <b>引导语</b>,标题栏瘦身(移除坐席徽章),InputBar 工具栏更简洁。<br>
<b>✅ 5 项细节已拍板(2026-07-31),详见 9.6 节;⚠️ v1.42026-08-03)反转删除状态条,整合区降为三元素</b>
</div>
<!-- 9.2 整合区结构示意 -->
<div class="section-desc" style="margin-top:18px;"><b>9.2 整合区结构示意(3 元素纵向堆叠,v1.4 移除状态条)</b></div>
<table class="cmp-table">
<thead>
<tr>
<th>元素</th>
<th>位置</th>
<th>性质</th>
<th>视觉表现(沿用 v1.2 类)</th>
</tr>
</thead>
<tbody>
<tr>
<td>状态条(v1.4 已删除)</td>
<td></td>
<td>v1.3 永久可见 → v1.4 删除</td>
<td>不再渲染坐席在线/离线(v1.3.5 决策)</td>
</tr>
<tr>
<td>操作按钮</td>
<td>整合区中部</td>
<td>核心 CTA</td>
<td>6 态样式(<code>.call-btn--disabled/active/urgent/waiting/end/reopen</code></td>
</tr>
<tr>
<td>进度消息胶囊</td>
<td>整合区下部</td>
<td>按需显示</td>
<td><code>.queue-capsule</code> 4 态(含 <code>--connected</code> 变体)</td>
</tr>
<tr>
<td>引导语</td>
<td>按钮下方</td>
<td>4 种场景</td>
<td><code>.input-bar-mock__guide</code>(含 <code>--warn</code> 变体)</td>
</tr>
<tr style="background:var(--bg);">
<td>(整合区边界容器)</td>
<td>InputBar 上方</td>
<td>浅色背景容器</td>
<td>用 inline 样式表达,不新增 CSS 类</td>
</tr>
<tr style="background:var(--primary-light);">
<td>背景色 ✅</td>
<td>整合区整体</td>
<td>浅色容器</td>
<td><b><code>#fafafa</code>(浅灰,沿用 chat-mock</b></td>
</tr>
</tbody>
</table>
<!-- 9.3 9 场景 mockup -->
<div class="section-desc" style="margin-top:20px;"><b>9.3 9 场景 mockup(用 v1.2 现有 <code>.header-mock</code> / <code>.chat-mock</code> / <code>.call-btn--*</code> / <code>.queue-capsule</code> 表达,3 列网格共 3 行)</b></div>
<div class="states-grid">
<!-- 场景 1:无会话 -->
<div class="state-card">
<div class="state-card__label">场景 1 · 无会话</div>
<div class="header-mock" style="margin-bottom:6px; padding:6px 10px;">
<div class="header-mock__left">
<div class="header-mock__brand">
<span class="header-mock__logo">IT</span><span>智能IT</span>
</div>
</div>
<div class="header-mock__actions">
<div class="header-mock__exit header-mock__exit--hidden" title=""></div>
</div>
</div>
<button class="call-btn call-btn--disabled">🔒 人工坐席</button>
<div class="input-bar-mock__guide">💡 先描述一下你遇到的问题</div>
<div class="state-card__scene">用户刚打开应用</div>
</div>
<!-- 场景 2AI &lt; 3 轮 -->
<div class="state-card">
<div class="state-card__label">场景 2 · AI &lt; 3 轮</div>
<div class="header-mock" style="margin-bottom:6px; padding:6px 10px;">
<div class="header-mock__left">
<div class="header-mock__brand">
<span class="header-mock__logo">IT</span><span>智能IT</span>
</div>
</div>
<div class="header-mock__actions">
<div class="header-mock__exit" title="结束会话(AI 兜底)"></div>
</div>
</div>
<button class="call-btn call-btn--disabled">🔒 人工坐席</button>
<div class="input-bar-mock__guide">请继续描述您的问题或需求</div>
<div class="state-card__scene">AI 对话早期</div>
</div>
<!-- 场景 3AI ≥ 3 轮 -->
<div class="state-card">
<div class="state-card__label">场景 3 · AI ≥ 3 轮</div>
<div class="header-mock" style="margin-bottom:6px; padding:6px 10px;">
<div class="header-mock__left">
<div class="header-mock__brand">
<span class="header-mock__logo">IT</span><span>智能IT</span>
</div>
</div>
<div class="header-mock__actions">
<div class="header-mock__exit" title="结束会话(AI 兜底)"></div>
</div>
</div>
<button class="call-btn call-btn--active">🎧 人工坐席</button>
<div class="state-card__scene">可呼叫</div>
</div>
<!-- 场景 4:紧急关键词 -->
<div class="state-card">
<div class="state-card__label">场景 4 · 紧急关键词</div>
<div class="header-mock" style="margin-bottom:6px; padding:6px 10px;">
<div class="header-mock__left">
<div class="header-mock__brand">
<span class="header-mock__logo">IT</span><span>智能IT</span>
</div>
</div>
<div class="header-mock__actions">
<div class="header-mock__exit" title="结束会话(AI 兜底)"></div>
</div>
</div>
<button class="call-btn call-btn--urgent">🚨 人工坐席</button>
<div class="state-card__scene">高优一键呼叫</div>
</div>
<!-- 场景 5:坐席离线 -->
<div class="state-card">
<div class="state-card__label" style="color:var(--danger);">场景 5 · 坐席离线</div>
<div class="header-mock" style="margin-bottom:6px; padding:6px 10px;">
<div class="header-mock__left">
<div class="header-mock__brand">
<span class="header-mock__logo">IT</span><span>智能IT</span>
</div>
</div>
<div class="header-mock__actions">
<div class="header-mock__exit header-mock__exit--hidden" title=""></div>
</div>
</div>
<button class="call-btn call-btn--disabled">🔒 人工坐席</button>
<div class="input-bar-mock__guide input-bar-mock__guide--warn">⚠️ 坐席当前离线,建议先用 AI 解答</div>
<div class="state-card__scene">!store.agentOnline</div>
</div>
<!-- 场景 6:排队中 -->
<div class="state-card">
<div class="state-card__label">场景 6 · 排队中</div>
<div class="header-mock" style="margin-bottom:6px; padding:6px 10px;">
<div class="header-mock__left">
<div class="header-mock__brand">
<span class="header-mock__logo">IT</span><span>智能IT</span>
</div>
</div>
<div class="header-mock__actions">
<div class="header-mock__exit header-mock__exit--hidden" title=""></div>
</div>
</div>
<button class="call-btn call-btn--waiting">⏳ 排队取消</button>
<div class="queue-capsule">🟠 排队中 · 前面 2 人 · 预计 1 分钟</div>
<div class="state-card__scene">点击取消排队</div>
</div>
<!-- 场景 7:已接入 -->
<div class="state-card">
<div class="state-card__label" style="color:var(--danger);">场景 7 · 已接入</div>
<div class="header-mock" style="margin-bottom:6px; padding:6px 10px;">
<div class="header-mock__left">
<div class="header-mock__brand">
<span class="header-mock__logo">IT</span><span>智能IT</span>
</div>
</div>
<div class="header-mock__actions">
<div class="header-mock__exit header-mock__exit--hidden" title=""></div>
</div>
</div>
<button class="call-btn call-btn--end">📴 结束咨询</button>
<div class="queue-capsule queue-capsule--connected">🟢 已接入 · 客服小王(3 秒淡出)</div>
<div class="state-card__scene">v1.2 恢复 · 主动挂断人工</div>
</div>
<!-- 场景 8:重新打开(24h 内) -->
<div class="state-card" style="background:var(--info-light);">
<div class="state-card__label">场景 8 · 重新打开(24h 内)</div>
<div class="header-mock" style="margin-bottom:6px; padding:6px 10px;">
<div class="header-mock__left">
<div class="header-mock__brand">
<span class="header-mock__logo">IT</span><span>智能IT</span>
</div>
</div>
<div class="header-mock__actions">
<div class="header-mock__exit header-mock__exit--hidden" title=""></div>
</div>
</div>
<button class="call-btn call-btn--reopen">🔄 重新打开</button>
<div class="state-card__scene">v1.2 新增 · 蓝色填充</div>
</div>
<!-- 场景 9:会话过期(&gt;24h -->
<div class="state-card">
<div class="state-card__label">场景 9 · 会话过期(&gt;24h</div>
<div class="header-mock" style="margin-bottom:6px; padding:6px 10px;">
<div class="header-mock__left">
<div class="header-mock__brand">
<span class="header-mock__logo">IT</span><span>智能IT</span>
</div>
</div>
<div class="header-mock__actions">
<div class="header-mock__exit header-mock__exit--hidden" title=""></div>
</div>
</div>
<button class="call-btn call-btn--disabled">🔒 人工坐席</button>
<div class="input-bar-mock__guide">⏰ 上一会话已过期,开始新对话吧</div>
<div class="state-card__scene">&gt;24h 不可重开</div>
</div>
</div>
<div class="note note--success">
💡 每个 mockup 的整合区由"操作按钮 + 引导语/进度胶囊"纵向堆叠(v1.4 移除状态条),标题栏瘦身(无坐席徽章),退出按钮仅 AI 场景(场景 2-4)可见
</div>
<!-- 9.4 关键交互细节 -->
<div class="section-desc" style="margin-top:20px;"><b>9.4 关键交互细节(R1-R5 · 沿用 v1.2 已 PASS 内容)</b></div>
<div class="note note--info">
<b>R1 · 状态条三态文案(v1.3 已拍板 ✅ → v1.4 已删除 ❌)</b><br>
<s>🟢 在线 · 9:00-18:00 / 🟡 繁忙 · 预计 N 分钟 / ⚫ 客服暂休 · 9:00-18:00</s><br>
<small>v1.4 依 v1.3.5 决策删除状态条,不再向员工暴露坐席在线/离线;`store.shiftHours` 计划同步取消</small>
</div>
<div class="note note--info">
<b>R2 · 操作按钮 6 态保持</b><br>
disabled / active / urgent / waiting / end / reopen 文案不变<br>
<small>waiting 态文案"排队取消"v1.2y 已拍板),end 态"结束咨询"reopen 态"重新打开"</small>
</div>
<div class="note note--info">
<b>R3 · 进度消息按需显示</b><br>
无排队时隐藏;queued 显示"🟠 排队中 · 前面 N 人"(整合区按钮下方);serving 显示"🟢 已接入 · 客服小王"(3 秒淡出);resolved 显示灰色"会话已关闭"<br>
<small>位置从消息流底部 → 整合区(与按钮同一容器)</small>
</div>
<div class="note note--info">
<b>R4 · 引导语迁移</b><br>
原 InputBar 4 种引导语(无会话 / AI&lt;3 轮 / 坐席离线 / 会话过期)迁移到 <b>整合区按钮下方</b>,作为灰色小字<br>
<small>InputBar 工具栏更简洁(移除引导语容器)</small>
</div>
<div class="note note--info">
<b>R5 · 不动 v1.2y 已 PASS 内容</b><br>
6 态按钮文案 / 坐席离线拦截(shakeAgent agentOnline=false/ 取消入口合并(只通过按钮)/ 3 秒淡出(serving capsule)全部保持<br>
<small>本次只做"位置迁移 + 容器整合",不动交互逻辑</small>
</div>
<!-- 9.5 与 v1.2 对比表 -->
<div class="section-desc" style="margin-top:20px;"><b>9.5 与 v1.2 对比</b></div>
<table class="cmp-table">
<thead>
<tr>
<th>位置</th>
<th>v1.2 现状</th>
<th>v1.3 方案 A</th>
<th>变化</th>
</tr>
</thead>
<tbody>
<tr>
<td>标题栏</td>
<td>logo + 标题 + 坐席状态🟢⚫ + 主题 + 头像 + 退出</td>
<td>logo + 标题 + 主题 + 头像 + 退出</td>
<td><span class="yes">-1 元素(坐席状态)</span></td>
</tr>
<tr>
<td>整合区(永久)</td>
<td></td>
<td>v1.4 已移除(原状态条 3 态文案)</td>
<td><span style="color:#c0392b;font-weight:600;">-1 永久元素(v1.4 移除)</span></td>
</tr>
<tr>
<td>整合区(按钮)</td>
<td>InputBar 工具栏内</td>
<td>整合区中部</td>
<td><span class="yes">位置迁移</span></td>
</tr>
<tr>
<td>整合区(按需胶囊)</td>
<td>消息流底部独立</td>
<td>整合区下部(与按钮同容器)</td>
<td><span class="yes">位置迁移</span></td>
</tr>
<tr>
<td>InputBar 工具栏</td>
<td>😊📎[输入框][🎧人工坐席][发送]</td>
<td>😊📎[输入框][发送]</td>
<td><span class="yes">-1 元素(按钮)</span></td>
</tr>
</tbody>
</table>
<!-- 9.6 6 项已拍板结论(含 v1.4 反转) -->
<div class="section-desc" style="margin-top:20px;"><b>9.6 6 项已拍板结论(2026-07-31 五项 + 2026-08-03 v1.4 反转一项)</b></div>
<table class="cmp-table">
<thead>
<tr>
<th>#</th>
<th>维度</th>
<th>拍板结果</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>状态条策略</td>
<td><span style="color:#c0392b;font-weight:600;">❌ v1.3 永久显示 → v1.4 删除</span></td>
</tr>
<tr>
<td>2</td>
<td>状态条文案</td>
<td><span style="color:#c0392b;font-weight:600;">❌ 随状态条一并删除</span></td>
</tr>
<tr style="background:#fff4f4;">
<td>6</td>
<td>状态条反转(v1.4</td>
<td><span style="color:#c0392b;font-weight:600;">✅ 2026-08-03 反转:删除整合区状态条(v1.3.5 决策),整合区降为三元素</span></td>
</tr>
<tr>
<td>3</td>
<td>整合区背景色</td>
<td><span class="yes">✅ 浅灰 #fafafa</span></td>
</tr>
<tr>
<td>4</td>
<td>引导语位置</td>
<td><span class="yes">✅ 整合区按钮下方(方案 A 默认)</span></td>
</tr>
<tr>
<td>5</td>
<td>移动端折叠</td>
<td><span class="yes">✅ 不折叠,默认展开</span></td>
</tr>
</tbody>
</table>
<div style="font-size:11px; color:var(--text-tertiary); margin-top:8px;">
📌 拍板日期:2026-07-31 下午。后续 PRD/技术方案/任务说明书将同步更新。
</div>
<div class="note note--success">
✅ 本章节为 <b>v1.3 方案 A 已拍板方案(2026-07-31</b>v1.2 已 PASS 的 6 态按钮 / 引导语 / 坐席离线拦截 / 取消入口合并 / 淡出交互 全部保留不动,v1.4(2026-08-03)反转删除状态条
</div>
</div>
</div>
</body>
</html>