Files
wecom_it_smart_desk/docs/03-测试文档/05-缺陷单/BUG-坐席-002-选项汇总标签缺失-001.md
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

12 KiB
Raw Blame History

缺陷单:坐席端缺"已选:xxx ✓"汇总标签——员工最近一次选项选择不可见

缺陷编号: BUG-坐席-002 版本: v1.0 状态: [已修复] 优先级: P3-Low 发现日期: 2026-07-28 发现人: 宋献 指派人: 宋献 修复人: Duckula (AI助手) 关闭日期: - 处理方式: 自动处理和部署 关联需求: REQ-坐席-002AI 辅助消息框) 关联文档:

  • 故障手册: docs/04-运维文档/部署运维/00-标准故障排查手册.mdCASE-20260728-06
  • 技术方案: docs/02-技术文档/技术架构/技术方案-REQ-坐席-002-AI辅助消息框-v1.0.md

1. 基本信息

字段 内容
缺陷标题 坐席端缺"已选:xxx ✓"汇总标签——员工最近一次选项选择不可见
影响范围 坐席端所有"AI 结构化消息"渲染(涉及 ai_structured 类型消息的"推荐选项"区)
涉及模块 坐席端(frontend-agent
涉及文件 src/frontend-agent/src/components/chat/MessageBubble.vueai-structured-options 渲染区)
触发条件 1. 员工在 H5 端依次点选 AI 结构化消息的"推荐选项"(如"卡纸/缺墨/其他"→"提示错误/无法连接/..."→"错误代码/文字提示/..."
2. 后端通过 WS 广播 option_selected 事件到坐席端
3. 坐席端 store conversationStore.selectedOptionLabels 累加被选 label
预期行为 最近一次被选的那条 AI 消息(即选项区里包含最近一次被选 label 的那条)的"推荐选项"区域顶部,加一个明显的"已选:错误代码 ✓"绿色徽章,让坐席一眼看到员工最终选了哪个。前几条历史 AI 消息的选项区不显示这个徽章(保持现状的"✓ 在被选条目后"设计)
实际行为(修复前) 坐席端只能看到每个 AI 消息选项区里已选条目后面带 标记,但无法一眼看出员工最终选了哪个。需要逐个气泡阅读"已选 ✓"标记才能拼出完整决策路径。

2. 复现步骤

  1. 员工在 H5 端进入"打印机"会话
  2. 员工依次点选 AI 提供的选项:
    • 第一条 AI 消息"已刷卡但打不出?...":点"卡纸"
    • 后续交互再点"其他"等
    • 第二条 AI 消息"其他问题?...":点"提示错误"
    • 第三条 AI 消息"提示错误?...":点"错误代码"
  3. 坐席端 store 收到 WS 广播 option_selected 事件,selectedOptionLabels 数组累加 ["卡纸", "其他", "提示错误", "错误代码"]
  4. 坐席端打开该会话,滚动到 3 条 AI 消息
  5. 观察:每条 AI 消息的"推荐选项"区只在自己被选条目后带 ✓ 标记
  6. 问题:坐席需要扫读 3 个气泡的 ✓ 标记才能知道员工最终选了"错误代码"(第 3 条)

影响截图

  • 页面:坐席端 → "打印机"会话
  • 元素:3 条 AI 消息下方的"推荐选项"区
  • 期望:在第 3 条 AI 消息选项区顶部显示"已选:错误代码 ✓"绿色徽章

3. 根因分析

3.1 现状(修复前)

src/frontend-agent/src/components/chat/MessageBubble.vue 第 55-65 行(v2.1 版本)只渲染了选项列表:

<div v-if="message.msg_type === 'ai_structured' && message.extra_data?.options?.length" class="ai-structured-options">
  <span class="ai-structured-options__label">推荐选项</span>
  <span
    v-for="(option, idx) in message.extra_data.options"
    :key="idx"
    class="ai-structured-options__tag"
    :class="{ 'ai-structured-options__tag--selected': conversationStore.selectedOptionLabels.includes(option.label || option.value) }"
  >
    {{ option.label || option.value }}<span v-if="conversationStore.selectedOptionLabels.includes(option.label || option.value)" class="ai-structured-options__check"> </span>
  </span>
</div>

3.2 缺失项

  • 无"汇总徽章"设计:只有"✓ 在被选条目后"的局部标记,缺少整体汇总
  • 坐席需扫读多气泡:决策路径分布在多条 AI 消息的多个 ✓ 标记中,无法一眼看清

4. 处理办法

项目 内容
处理策略 自动处理和部署(v2.2 增量)
执行时机 立即(影响坐席工作效率)
处理流程 1. 新增 latestSelectedLabel computed(取 selectedOptionLabels 数组最后一项)
2. 新增 messageHasLatestSelected computed关键:判断当前 AI 消息的 options 是否包含最近一次被选 label)
3. 模板新增"已选:xxx ✓"绿色徽章(v-if="messageHasLatestSelected"
4. CSS 新增 .ai-structured-options__summary 系列样式
5. 本地构建 → 上传 → 服务器解压 → docker restart nginx
验证方式 部署层验证:curl 200 OK + grep 确认新代码生效 + Workspace-B-lO49Vu.js 部署到容器
回滚方案 服务器保留 dist.bak.option-summary.v2.2b/ 备份目录;紧急回滚 mv dist.bak.option-summary.v2.2b dist && docker restart wecom_it_nginx

5. 修复方案

5.1 代码修复(MessageBubble.vue

5.1.1 新增计算属性 latestSelectedLabel

/**
 * 员工最近一次答案选择(v2.2 新增:坐席端"已选:xxx ✓"汇总标签)
 *
 * 做什么:从 conversationStore.selectedOptionLabels 数组中取最后一个值(最近一次被选的)
 * 为什么:让坐席在每条 AI 消息的选项区顶部一眼看到员工最终选了哪个
 * 边界:空数组时返回空字符串(不显示"已选"标签)
 */
const latestSelectedLabel = computed<string>(() => {
  const labels = conversationStore.selectedOptionLabels
  if (!labels || labels.length === 0) return ''
  return labels[labels.length - 1]
})

5.1.2 新增计算属性 messageHasLatestSelected关键

/**
 * 当前 AI 消息是否包含最近一次被选的选项(v2.2 配合"已选"标签使用)
 *
 * 做什么:判断 props.message.extra_data.options 中是否包含 latestSelectedLabel
 * 为什么:用户期望"已选:xxx ✓"只显示在"最近一次被选的那条 AI 消息"的选项区
 *        前几条历史 AI 消息的选项区不包含最近一次被选的 label,所以不显示
 * 边界:latestSelectedLabel 为空时返回 false(不显示"已选"标签)
 */
const messageHasLatestSelected = computed<boolean>(() => {
  if (!latestSelectedLabel.value) return false
  const options = props.message.extra_data?.options || []
  return options.some(
    (opt: any) => (opt?.label || opt?.value) === latestSelectedLabel.value
  )
})

5.1.3 模板新增"已选:xxx ✓"绿色徽章

<div v-if="message.msg_type === 'ai_structured' && message.extra_data?.options?.length" class="ai-structured-options">
  <!-- v2.2: 员工最近一次答案选择汇总仅在该 AI 消息的 options 包含最近一次被选的 label 时显示 -->
  <div
    v-if="messageHasLatestSelected"
    class="ai-structured-options__summary"
  >
    <span class="ai-structured-options__summary-label">已选</span>
    <span class="ai-structured-options__summary-value">{{ latestSelectedLabel }}</span>
    <span class="ai-structured-options__summary-check"></span>
  </div>
  <span class="ai-structured-options__label">推荐选项</span>
  ...
</div>

5.1.4 CSS 样式

/* v2.2 新增:员工最近一次答案选择汇总(绿色徽章,位于选项区顶部) */
.ai-structured-options__summary {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-right: 4px;
  padding: 3px 10px;
  background: #07C160;
  color: #fff;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
  /* 占据整行宽度,让"推荐选项:"换到下一行更清晰 */
  flex-basis: 100%;
  margin-bottom: 4px;
}
.ai-structured-options__summary-label { font-weight: 500; opacity: 0.9; }
.ai-structured-options__summary-value { font-weight: 700; }
.ai-structured-options__summary-check { font-weight: 700; margin-left: 2px; }

5.2 关键设计

  • 条件渲染下沉到 message 级messageHasLatestSelected 把"是否显示徽章"的判断下沉到每条消息——只有包含最近一次被选 label 的那条 AI 消息才显示"已选"徽章
  • 前几条历史 AI 消息的选项区不显示:避免无差别地所有 AI 消息都显示"已选"造成误导
  • flex-basis: 100% 让徽章独占一行:避免和"推荐选项:"label 挤在同一行造成视觉混乱

5.3 首次实现的 Bug 与修正

首次实现的 v2.2a 版(Workspace-CdGky81t.js未做"message 级判断"——v-if="latestSelectedLabel" 会让所有 AI 消息的选项区都显示"已选"徽章(前两条历史 AI 消息也会显示"已选:错误代码 ✓")。

修正后 v2.2b 版(Workspace-B-lO49Vu.js)加 messageHasLatestSelected 判断,只在最近一次被选的那条 AI 消息显示,符合用户期望的"只显示最近一次的答案选择"。


6. 验证结果

6.1 部署层验证

验证项 命令/方式 结果
本地构建 npm run build 5.21s
构建产物 dist/assets/Workspace-B-lO49Vu.jshash 变化) 157.30 kB
打包 zip dist-agent-option-summary-v2.2b.zip 1,621,981 B
上传校验 v2_ops.py upload md5 校验 通过
服务器解压 unzip /tmp/dist-agent-option-summary-v2.2b.zip 成功
Nginx 重启 docker restart wecom_it_nginx Up 3 seconds
外部访问 curl -I https://itsupport.servyou.com.cn/itagent/assets/Workspace-B-lO49Vu.js HTTP 200
新代码生效 grep -c "messageHasLatestSelected" .../Workspace-B-lO49Vu.js 1(命中)
容器内文件 docker exec wecom_it_nginx ls /usr/share/nginx/html/itagent/assets/ | grep Workspace 命中 Workspace-B-lO49Vu.js

6.2 中文标签验证

PS> $content = Get-Content "Workspace-B-lO49Vu.js" -Raw
PS> ([regex]::Matches($content, "已选")).Count
4

已选 出现 4 次(在 Vue 模板字符串中),字符编码正常,无 GBK 误读。

6.3 真实浏览器验证

待用户在坐席端人工验证(企微扫码登录后):

  1. 打开"打印机"会话
  2. 观察 3 条 AI 消息的选项区
  3. 预期看到:第 3 条 AI 消息("提示错误?...")的选项区顶部绿色徽章 "已选:错误代码 ✓"
  4. 预期看到:前两条 AI 消息的选项区显示"已选"徽章(保持现有 ✓ 在被选条目后的设计)
  5. 验证通过后,将本文档状态改为 [已验证]

6.4 浏览器测试硬性限制

坐席端是企微扫码登录agent-browser 无法脚本模拟扫码。真实浏览器测试必须由用户人工扫码完成


7. 关联信息

  • 关联需求: REQ-坐席-002AI 辅助消息框)
  • 关联技术方案: docs/02-技术文档/技术架构/技术方案-REQ-坐席-002-AI辅助消息框-v1.0.md
  • 关联故障手册: docs/04-运维文档/部署运维/00-标准故障排查手册.mdv3.1 新增 CASE-20260728-06
  • 修复代码文件: src/frontend-agent/src/components/chat/MessageBubble.vue
  • 部署包: deploy-temp/dist-agent-option-summary-v2.2b.zip(保留作为部署物证)

8. 变更记录

日期 版本 变更内容 变更人 变更原因 影响范围
2026-07-28 v1.0 创建缺陷单,记录坐席端缺"已选:xxx ✓"汇总标签 宋献 / Duckula 用户反馈坐席无法一眼看清员工最终选项 坐席端所有 AI 结构化消息渲染
2026-07-28 v1.0 修复 MessageBubble.vue:新增 latestSelectedLabel + messageHasLatestSelected 两个 computed Duckula 缺少"消息级判断"导致 v2.2a 误显示 坐席端 MessageBubble 组件
2026-07-28 v1.0 v2.2a 部署后修正为 v2.2b:补 messageHasLatestSelected 避免前几条历史 AI 消息也显示徽章 Duckula 用户要求"只显示最近一次",避免误导 坐席端 MessageBubble 组件
2026-07-28 v1.0 本地构建 + 服务器部署 + nginx 重启 + curl/grep 验证 Duckula 部署层确认修复实际生效 坐席端 dist 资产
2026-07-28 v1.0 文档规范化:故障手册 v3.0→v3.1 + 缺陷单 README 追加清单 Duckula 规范要求 BUG 修复需同步周边文档 文档体系

缺陷状态: [已修复] — 部署完成,等用户人工扫码验证。验证通过后请将状态改为 [已验证],并补充关闭日期。