Files
wecom_it_smart_desk/docs/01-产品文档/04-坐席工作台/PRD-REQ-坐席-011-统一工作队列重构-v0.1.md
T
Simon 9292f41763 feat(agent/backend): 坐席端审批线降级跳转 + 回调最终一致回写
实现 Phase 0 审批线 T01+T02(依据 PRD-REQ-坐席-011 + U-1 技术验证结论)。

前端(T01):
- TaskDetailView.handleAction 移除 mock toast,审批类仅 console.info
- ApprovalDetail 通过/拒绝/转交 + 打开按钮接线为企微审批深链真实跳转(<a target="_blank">)
- useWebSocket 新增 todo_status_changed 实时刷新分支

后端(T02):
- approval.py 新增 writeback_approval_todo_status 主入口 + /approval/callback 接线
- approval_webhook.py 新增 _writeback_agent_todo 复用回调→WS 推送通道
- 以 approval:{sp_no} 为关联键,缓存就地改写 + 7天快照 + WS 推送,最终一致

测试:src/backend/tests/test_approval_todo_writeback.py(51 例全绿)
文档:PRD-REQ-坐席-011 v0.1、技术验证-U-1 v1.0
2026-08-09 00:46:31 +08:00

16 KiB
Raw Blame History

PRD — 坐席端统一工作队列重构

REQ编号: REQ-坐席-011 版本: v0.1(方案草案 / 沟通确认阶段) 状态: 🟡 待评审 — 含未决项,不得据此排期开发 优先级: P1(其中 Phase 0 为 P0 日期: 2026-08-08 作者: 宋献 关联: REQ-坐席-004(任务详情视图切换)、REQ-坐席-009(会话状态Tab筛选)、任务说明书 #132


1. 背景

1.1 提案

取消坐席工作台「待办事项」独立面板,将审批单与工单纳入左栏,与咨询会话统一按优先级和分类排列。

1.2 提案原始论据与核查结论

# 原始论据 核查结论 依据
咨询/审批/工单本质都是待处理的单个事件 成立 与 Zendesk / ServiceNow Agent Workspace 的单一工作队列范式一致
均关联对应员工(左栏) 当前不成立 TodoItemDatasrc/frontend-agent/src/api/todo.ts:17)顶层无 employee 字段
均需辅助处理功能(右栏) ⚠️ 当前未实现,且不应简单共用 AiAssistantPanel.vue:100 仅依赖 conversationId,不感知 workspaceView

对 ② 的补充:前端待办头像为伪造实现 —— todoAvatarText()TodoPanel.vue:224-233)从 title" - " 切分后取部门名最后一个字,颜色取 title 的 hash。后端 applicant 仅有 userid,埋在 description JSON 内未暴露到顶层(src/backend/app/services/todo_source_service.py:485)。

对 ③ 的补充:会话辅助信息(知识推荐 / 话术 / 排查步骤)服务于「对话」;审批辅助信息(申请人历史 / 同类通过率 / 合规校验)服务于「决策」。二者不同源、不同构。统一三栏布局 ≠ 统一右栏内容,右栏必须按工作项类型分派渲染。

1.3 立项主理由(重新论证)

原提案表述为「布局更合理、处理更高效」,论证力度不足。本 PRD 采用以下主理由:

待办面板置于右栏属于信息架构语义错位。 右栏的定义是「当前会话的上下文辅助面板」,而待办是不隶属于任何会话的全局工作队列。将全局队列置入上下文面板,破坏了右栏的语义一致性,并导致坐席的工作入口分裂为两处。

1.4 与 #132 的关系(须在评审中说明)

内容
#132 做了什么 2026-08-0208-03,待办面板由左栏底部迁至右栏底部
#132 的决策依据 任务说明书仅记载「与 v1.1 原型保持一致」,验收项含「左栏会话列表不被压缩」。无信息架构层面论证
本次是否为返工 。#132 是面板位移;本次是数据模型与列表融合,属架构升级
需规避 若仅将面板移回左栏(见 §5 方案 B),将原地重演 #132 的左栏空间竞争问题,构成第三次搬迁

2. 已确认决策

以下三项经沟通确认,作为本方案的设计约束。

# 决策项 结论 推导出的约束
D-1 左栏列表主键模型 以「事」为主键 每个咨询/审批/工单各占一条;员工信息作为条目属性展示,不作聚合维度
D-2 实施顺序 先闭环、后合并 Phase 0(操作闭环)为 Phase 2(布局合并)的硬前置,顺序不可调换
D-3 待办归属范围 本人指派 + 组内未分配 引入「认领」动作与并发控制 —— 当前系统完全没有此能力,属新增需求

2.1 D-3 的成本提示

D-3 不是筛选条件的调整,而是新增一条状态机路径。当前 todo-items 接口按 assigned_agent_id 过滤,不存在无主池概念。落地需新增:

  • 后端:未分配待办的查询口径(组边界定义见 §6 未决项 U-3)
  • 后端:claim(认领)动作 + 幂等与乐观锁(防并发抢单)
  • 前端:认领按钮、认领中态、认领失败(已被他人认领)的提示
  • 数据:认领操作的审计留痕

3. 阻塞项(P0

3.1 任务详情操作按钮全部为 Mock

// src/frontend-agent/src/components/chat/TaskDetailView.vue:117
function handleAction(action: string): void {
  ElMessage.success(`操作成功:${action}`)   // 仅 toast,不调用任何接口
}

REQ-坐席-004 §2.4 定义的全部操作 —— 工单(接单 / 开始处理 / 结单 / 转派)、审批(通过 / 拒绝 / 转交)—— 均不生效

风险定级:P0,阻塞布局合并。

理由:当前待办面板位于右栏底部 260px 区域,坐席误操作的暴露面有限。一旦将待办提升至左栏主队列首屏,等同于把不可用功能放置于最高可见度位置。坐席点击「审批通过」后收到绿色成功提示,而企业微信侧该单仍处于挂起状态 —— 属于会造成真实业务后果的错误反馈。


4. 其余工程前置条件

编号 前置项 现状 不处理的后果
B-1 待办缺员工身份字段 顶层无 employee_id/name/departmentapplicant 仅 userid 且未暴露 混排后同列表内会话条目为真人头像+姓名+部门,待办条目为伪头像+部门残字,身份密度断裂,无法按人扫视
B-2 待办无实时推送 会话走 WSuseWebSocket.ts 12 类事件);待办为 60s 轮询(TodoPanel.vue:143),后端无任何 todo WS 事件 紧急审批最长滞后 60s 才浮升;同列表内会话实时跳动而待办静止,坐席对排序失去信任
B-3 优先级不可比 会话为 urgency_score 1–5 叠加 6 档加权(置顶 10000 / 代办 5000 / 招手 2000 / 需介入 1500 / 情绪 1000 / VIP 800);待办仅 urgent/high/normal 三档,且同档内无二级排序todo_aggregator_service.py:134 无时间兜底) 混排结果不可解释,坐席无法预期条目位置
B-4 SLA 语义冲突 会话等待成本为「用户实时干等」(秒级);审批为「当日处理完毕」(小时级) 纯优先级排序会使 urgent 审批将 serving 状态会话挤出首屏。漏回一条实时会话的代价显著高于晚 30 分钟处理一单审批,纯优先级模型会系统性放大该错误

B-4 的设计要求:统一排序权重不得仅取优先级,必须引入「实时性/等待可感知度」维度。建议排序键为 f(优先级, SLA剩余时间, 对端是否在线等待),其中「对端在线等待」应具备最高权重档位。具体系数见 §6 未决项 U-2。


5. 方案选型

方案 做法 优势 劣势 采纳
A 完全融合 单列表跨类型混排 真正的单一队列 四项前置全欠;实时会话被挤压;排序不可解释 不作为首个形态
B 移回左栏保持分区 左栏上会话、下待办,可折叠 改动最小(≈0.5d),立即消除右栏语义错位 仍为两个列表;重演 #132 左栏空间竞争,构成第三次搬迁 不单独实施
C 统一容器 + Tab 分层 左栏 Tab 增加类型层「会话 / 待办 / 全部」,「全部」下混排 兼顾专注模式与全局视图;可灰度、可回退 Tab 层级加深一层 首个落地形态
D WorkItem 统一模型 后端抽象 WorkItem,会话/工单/审批为其子类型,共享优先级、SLA、关联人、状态机 架构最干净;未来接入设备告警、巡检任务零边际成本 后端工作量高一个数量级 目标态

采纳路径:以 D 为目标态,C 为首个落地形态,Phase 0 为硬前置。


6. 实施路线

工时为粗估,用于排序参考,不作为承诺。

Phase 0 — 操作闭环(P0,阻塞后续全部阶段)

U-1 已验证结论(2026-08-08:企微审批不可服务端闭环(官方文档证实无代审批接口,PC Web 无 JS-SDK 能力),审批动作必须降级为「跳转企微原系统 + 回调状态回写」;ITSM 工单因操作类 OpenAPI 尚未落地,暂不可判定服务端闭环,需先降级跳转,待 T05 外部依赖到位后升级。详见 docs/02-技术文档/技术架构/技术验证-U-1-审批与工单操作闭环可行性-v1.0.md

任务 说明 降级层级
审批操作 → 降级跳转 + 回写 通过 / 拒绝 / 转交 → 点击「在企微审批中打开」跳转原系统,由 approval_webhook.py 接收 sys_approval_change 回调 → 补全 approval.py:902 状态回写 → WS 推送 Level 0 立即可做;Level 1 需补回调回写
工单操作 → 降级跳转(暂) 接单 / 开始处理 / 结单 / 转派 → 点击「在 ITSM 中打开」跳转原系统;ITSM 写接口到位前不承诺服务端闭环(受 T05 外部阻塞)。⚠️ 注意:该跳转依赖工单可见,而当前 ITSM 读列表亦未实现(见 U-1.2),故本行在读链路打通前无实际可操作对象 Level 0(暂,受 U-1.2 前置)
失败态处理 移除无条件 ElMessage.success,改为「跳转成功提示 + 状态回写后刷新」按三态分派;仍禁止以 toast 作为验收依据

验收标准:操作后外部系统(ITSM / 企微审批)状态真实变更,且前端反馈与外部状态最终一致(通过回调 / webhook 回写达成)。禁止以 toast 成功作为验收依据。审批 / 工单在降级跳转模式下,以「跳转成功 + 原系统状态通过回调回写并刷新」作为验收闭环,不要求前端内嵌直接操作。

Phase 1 — 数据层归一(后端)

任务 对应前置项
TodoItem 顶层暴露 employee_id / employee_name / department(由 applicant userid 反查企微通讯录) B-1
新增 sla_due_at 字段 B-4
定义 WorkItem 统一排序权重模型 B-3 / B-4
新增 todo WS 事件:todo_created / todo_updated / todo_claimed / todo_resolved B-2
未分配待办查询口径 + claim 动作(幂等 + 乐观锁) D-3

Phase 2 — 左栏统一容器(前端,方案 C)

任务
左栏 Tab 分层:类型层(会话 / 待办 / 全部)+ 状态层(沿用 REQ-009 的四态)
定义统一 ListItem 类型(含 kind 判别式),条目组件支持会话态与任务态两种渲染
移除 AiAssistantPanel.vue 中的 <TodoPanel /> 挂载
右栏按 workspaceView 分派渲染(修复现存缺陷:任务详情下右栏仍显示上一会话的排查建议)
修复 selectConversation 不重置 workspaceView 的问题
视图切换时保留输入框草稿与滚动位置(当前 v-if/v-else 互斥卸载会丢失,ReplyBox.vue:307inputText 为组件局部 ref

Phase 3 — 混排与观察

任务
「全部」Tab 下按归一化权重混排
灰度发布 + 2 周数据观察(观测指标见下)
依据数据决定是否推进 D(后端 WorkItem 模型)

观测指标:会话首响时长(是否因混排而劣化)、待办平均处理时长、坐席 Tab 切换频次、认领冲突率。


7. 未决项

编号 未决项 影响 需谁决策
U-1 审批操作能否在坐席 PC Web 端完成 已验证(2026-08-08:企微审批不可服务端闭环——官方文档证实无代审批接口,PC Web 亦无 JS-SDK 原生表单能力。结论:审批动作须降级为「跳转企微原系统 + sys_approval_change 回调状态回写」。该结论不阻塞 Phase 0 启动(降级跳转可立即落地)。验证依据见 技术验证-U-1-审批与工单操作闭环可行性-v1.0.md 已闭环(技术)
U-1.1 ITSM 写接口到位时间 工单「接单 / 开始处理 / 结单 / 转派」能否服务端闭环,取决于 ITSM 平台方提供的操作类 OpenAPI 文档、app_id/secret 写权限、测试账号(对应 T05)。当前项目内 ITSM 仅实现只读查询(itsm_service.py 全文件无写操作),无写接口实证。该项是工单服务端闭环的外部阻塞项,未到位前工单同样降级跳转 平台方 / 外部协调
U-1.2 🔴 ITSM 工单当前在坐席端完全不可见(读链路即断) 代码实证(2026-08-08 主理人复核补录)ITSMService.get_todo_list()src/backend/app/services/itsm_service.py:113-130无条件 return [],仅打印告警「ITSM 代办列表 API 尚未实现」。TodoAggregatorServicetodo_aggregator_service.py:110-127)并发聚合审批与 ITSM 两源,ITSM 分支恒为空 → 待办列表中工单数量恒为 0,现有待办全部是企微审批单。且因无列表即无 process_instance_id,已实现的 get_todo_detail / workitem/detail(只读)实际也无从调用
影响:此项比 U-1.1(写接口缺失)更前置——写接口的前提是先能读到工单。在读链路打通前,「工单纳入统一队列」在数据层无内容可纳入,Phase 2 的工单部分实为空跑
平台方 / 外部协调(与 U-1.1 合并索取)
U-2 统一排序权重的具体系数 决定混排结果是否可解释、是否会挤压实时会话 产品 + 坐席试用反馈
U-3 「组内未分配」的组边界定义 全体 IT 支持组?还是按技能/区域路由后的子集?直接影响列表长度 产品
U-4 认领并发冲突的交互 两名坐席同时认领同一单时的提示与落败方引导 产品
U-5 列表长度上限与虚拟滚动 合并 + 组内未分配后列表显著变长,260px 宽左栏的承载能力 前端
U-6 待办条目的未读/变更标识 会话有 is_todo 等标志,待办无未读概念,混排后视觉规则需统一 产品

8. 风险登记

编号 风险 等级 缓解措施
R-1 实时会话被审批挤出首屏,首响时长劣化 🔴 排序模型引入「对端在线等待」最高权重档;Phase 3 灰度观测首响指标
R-2 认领并发抢单导致重复处理 🟡 后端乐观锁 + 幂等;前端落败态明确提示
R-3 轮询向 WS 迁移期间的双通道数据不一致 🟡 迁移期保留轮询作为兜底,以 WS 事件为主、轮询做对账
R-4 第三次布局搬迁引发团队对决策稳定性的质疑 🟢 评审时明确说明本次为架构升级而非位移返工(见 §1.4)
R-5 工单闭环因 ITSM 写接口缺失受阻,导致 Phase 0 工单部分停滞 🟡 U-1 已验证:审批走降级跳转不阻塞 Phase 0;工单闭环的外部阻塞已独立为 U-1.1 / T05,审批与工单降级跳转可先行落地,不拖累整体路线

9. 明确不在本次范围

  • 会话侧数据模型改造(urgency_score 与加权标志保持不变)
  • H5 员工端任何改动
  • 设备异常类型(REQ-004 §2.3 曾定义,现已从 TodoPanel 移除,本次不恢复)
  • 坐席在线统计数据源(当前取自 src/mock/data.ts,属独立技术债)

10. 变更记录

日期 版本 变更内容 变更人
2026-08-08 v0.1 创建方案草案;固化 D-1/D-2/D-3 三项决策;完成原始论据核查与现状事实核实 宋献
2026-08-08 v0.1 据 U-1 技术验证结论(架构师高见远)修订 §6 Phase 0 与 §7 U-1:审批明确为降级跳转 + 回写(U-1 已验证);新增 U-1.1 ITSM 写接口外部阻塞项;同步下调 R-5 风险表述 宋献
2026-08-08 v0.1 主理人复核补录 U-1.2:代码实证 ITSMService.get_todo_list() 无条件返回空列表,ITSM 工单在坐席端读链路即断、当前待办全为企微审批单。该项前置于 U-1.1,一并标注于 §6 Phase 0 工单行 齐活林(交付总监)