Files
wecom_it_smart_desk/docs/02-产品需求/业务路由推荐-PRD.md
T
Simon bea288e414 feat: 2026-07-11 全量更新 - 代办集成+会议室预定+知识迭代修复+UI统一+Bug修复
== 已部署上线 (9项) ==
- 代办事项真实数据源集成 (企微审批API 8bug修复链)
- H5/坐席端 Logo样式统一+绿色背景
- 视频引导页修复 (localStorage key v2)
- 坐席端 v9 Vue版本修复 (ElMessage._context)
- 截图按钮 v10 修复 (getDisplayMedia user gesture)
- 扫码样式恢复+H5扫码登录跳转修复
- H5截图快捷键提示

== 代码完成待部署 (3项) ==
- 知识迭代3Bug修复 (#8 POST端点/#7 MERGE幂等/#6 过期检查)
- 会议室预定-小鱼易联终端 (40文件, 40/40测试通过)
- IT资产升级审批推送 (asset_service.py)

== 需求文档 (2项) ==
- 坐席端AI辅助消息框-PRD (4项新功能确认)
- 坐席端布局优化建议 v2.0 (7天计划)

== 新增文档 ==
- 日报-2026-07-11.md
- 知识迭代Bug修复报告-20260711.md
- 会议室预定-部署指南.md
- CHANGELOG.md 更新

== 测试 ==
- test_todo_integration.py: 40/40
- test_meetingroom.py: 40/40
- test_bugfix_ki_suggestions.py: 21/21
2026-07-11 23:13:10 +08:00

354 lines
17 KiB
Markdown
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.
# 业务路由推荐功能 PRD
> **版本**: v1.0
> **日期**: 2026-07-15
> **作者**: Alice(产品经理)
> **状态**: 待评审
---
## 1. 项目信息
| 字段 | 值 |
|------|-----|
| **项目名称** | business_routing |
| **技术栈** | H5端: Vue3 + Vant4 + TypeScript / 坐席端: Vue3 + Element Plus / 后端: FastAPI + SQLAlchemy + PostgreSQL + Redis / AI: Dify 原生 API |
| **语言** | 中文 |
| **UI风格** | 企微浅色扁平风格,accent = #07C160 |
### 原始需求复述
IT智能服务台当前通过 Dify Prompt 识别用户消息中的审批意图并返回审批类型卡片。但当员工提出的问题**不属于 IT 服务台服务范围**时(如打印机问题属行政、工牌补办属 HR、报销问题属财务等),系统当前无法给出有效引导。
本需求要求系统在识别出「非 IT 业务」后,在聊天中主动发送对应业务联系人的**员工名片卡片**,员工点击名片上的「联系TA」按钮即可跳转到与该联系人的企微单聊(`wx.invoke('openEnterpriseChat', {userids: 'xxx'})`),实现精准的业务路由分发。
### 架构决策(已确认)
采用 **方案A:统一到同一个 Dify Prompt**
- 将现有「审批意图识别」Dify Prompt 扩展为统一的意图识别引擎
- 一次 API 调用同时判断:IT服务台范围内(审批/咨询) / 非IT业务路由
- 现有审批功能需回归测试确保不受影响
---
## 2. 产品定义
### 2.1 产品目标
**实现非IT业务的精准路由分发**:当员工提出的问题超出 IT 服务台服务范围时,系统自动识别业务类别并推荐对应业务联系人,员工一键即可跳转企微单聊,消除「问了半天才发现找错人」的体验断层。
### 2.2 用户故事
| # | 角色 | 用户故事 |
|---|------|---------|
| US-1 | 员工 | **As a** 报修员工, **I want** 当我问了非IT问题(如打印机故障、工牌补办)时,服务台直接给我推荐对应业务联系人的名片, **so that** 我不需要到处打听该找谁,一键就能联系到对的人 |
| US-2 | 员工 | **As a** 员工, **I want** 点击名片上的「联系TA」按钮直接跳转到与该联系人的企微单聊, **so that** 我无需手动搜索联系人、复制工号,降低沟通发起成本 |
| US-3 | 坐席 | **As a** IT坐席, **I want** 系统自动拦截非IT问题并路由给对应业务联系人, **so that** 我不被非IT工单打扰,能专注于真正的IT支持工作 |
| US-4 | 坐席 | **As a** 坐席, **I want** 在会话中看到AI已发送的路由名片记录及推荐原因, **so that** 如果员工后续追问,我能知道之前已推荐了谁,避免重复推荐 |
| US-5 | 管理员 | **As a** 系统管理员, **I want** 在后台维护业务联系人数据(姓名、部门、负责业务、企微userid), **so that** 人员变动时我能及时更新路由数据,保证推荐准确 |
---
## 3. 需求池(P0/P1/P2
### P0 — 必须完成(核心体验)
#### BE-01 统一意图识别 Prompt 扩展
| 项目 | 说明 |
|------|------|
| **需求** | 将现有 Dify 审批意图识别 Prompt 扩展为统一意图识别引擎,一次调用同时输出审批意图判断 + 非IT业务路由判断 |
| **扩展字段** | 在现有 JSON 输出基础上新增 `intent_type``business_category``routing_confidence` 字段(详见第5节) |
| **兼容性** | `is_approval_request` / `confidence` / `approval_type` 三个原字段语义和取值范围保持不变,确保审批功能零回归 |
| **调用方式** | 继续使用现有 Dify API`http://yw-dify.dc.servyou-it.com/v1/chat-messages`API Key: `app-7jkRkAzvX4QM9v9SM3P8mMEO` |
#### BE-02 业务联系人数据模型
| 项目 | 说明 |
|------|------|
| **需求** | 新建 `business_contacts` 表存储业务联系人信息(详见第6节) |
| **初始数据** | 预置行政、HR、财务、法务等非IT部门的联系人数据 |
| **查询接口** | 后端根据 Dify 返回的 `business_category` 查询匹配联系人,支持按业务类别 + 服务区域筛选 |
#### BE-03 名片卡片消息发送
| 项目 | 说明 |
|------|------|
| **需求** | 当 Dify 判定为非IT业务路由时,后端自动发送一条 `msg_type = 'contact_card'` 的消息 |
| **消息结构** | `extra_data` 中携带联系人完整信息(姓名、部门、岗位、负责业务、分机号、服务区域、企微userid) |
| **前置消息** | 名片发送前,先发送一条文本消息说明路由原因(如"打印机问题属于行政设备范畴,不在IT服务台服务范围内,为您推荐行政服务联系人") |
| **双通道** | 通过企微消息(必达) + WebSocket(即时) 双通道下发 |
#### FE-H5-01 员工名片卡片组件
| 项目 | 说明 |
|------|------|
| **需求** | 新建 `ContactCard.vue` 组件,在 `MessageBubble.vue` 中增加 `msg_type === 'contact_card'` 渲染分支 |
| **字段** | 头像、姓名+性别、部门·岗位、负责业务(绿色高亮)、分机号、服务区域/办公地点、「员工名片」标识 |
| **交互** | 点击「联系TA」按钮 → 调用 `wx.invoke('openEnterpriseChat', {userids: contact_userid})` 打开企微单聊 |
| **容错** | userid 为空或企微SDK未就绪时,Toast 提示「暂时无法发起聊天,请联系管理员」 |
| **原型参考** | `docs/04-原型设计/prototypes-原型图/employee-contact-card-demo.html` |
#### FE-H5-02 消息类型映射层扩展
| 项目 | 说明 |
|------|------|
| **需求** | 在 `conversation.ts``MsgContentType` 类型中新增 `'contact_card'` |
| **映射** | `mapMessage()` 无需改动核心逻辑(`msg_type``extra_data` 已透传),仅需扩展类型定义 |
### P1 — 应该完成(增强体验)
#### BE-04 坐席端名片可见性
| 项目 | 说明 |
|------|------|
| **需求** | 坐席端也能看到 AI 发送的路由名片消息,展示联系人信息 + 推荐原因 |
| **渲染** | 坐席端 `MessageBubble` 增加 `contact_card` 渲染分支,复用名片组件(Element Plus 风格适配) |
| **目的** | 坐席可了解路由历史,避免重复推荐,必要时可手动跟进 |
#### BE-05 路由命中统计
| 项目 | 说明 |
|------|------|
| **需求** | 记录每次路由推荐事件:会话ID、员工消息内容、识别的业务类别、推荐联系人、是否点击联系 |
| **存储** | 新建 `routing_events` 表或写入现有日志表 |
| **目的** | 为后续优化 Prompt 准确率、分析高频非IT业务提供数据支撑 |
### P2 — 可以完成(后续迭代)
#### BE-06 管理后台联系人管理
| 项目 | 说明 |
|------|------|
| **需求** | 坐席端管理页面提供业务联系人的 CRUD 界面 |
| **功能** | 新增/编辑/停用联系人,按业务类别分组管理 |
| **优先级说明** | 初期可通过数据库直接维护,管理后台为后续迭代 |
#### FE-H5-03 多联系人推荐
| 项目 | 说明 |
|------|------|
| **需求** | 当一个业务类别有多个联系人时,支持按服务区域匹配最合适的联系人,或在名片中展示多个备选 |
| **优先级说明** | 初期单联系人推荐即可满足核心需求 |
---
## 4. UI 设计描述
### 4.1 名片卡片布局
```
┌─────────────────────────────────┐
│ ┌──────┐ │
│ │ 头像 │ 王芳 ♀ 员工名片 │
│ │ 44px │ 行政部 · 设备管理岗 │
│ └──────┘ │
│─────────────────────────────────│
│ 负责业务 打印机/复印机/扫描仪 │ ← 绿色高亮 #07C160
│ 分机号 8002 │
│ 服务区域 滨江园区 3-5楼 │
│─────────────────────────────────│
│ ┌─────────────────────────────┐ │
│ │ 💬 联系TA │ │ ← 绿色按钮 #07C160
│ └─────────────────────────────┘ │
└─────────────────────────────────┘
```
### 4.2 卡片字段定义
| 字段 | 数据来源 | 说明 |
|------|---------|------|
| 头像 | `avatar_url` 或姓名首字渐变色块 | 44×44px 圆角6px |
| 姓名 | `name` | 16px 加粗 |
| 性别 | `gender` | 小图标,男蓝女粉 |
| 部门·岗位 | `department` + `position` | 13px 灰色 #888 |
| 负责业务 | `responsibility` | **绿色高亮** #07C160,加粗 |
| 分机号 | `extension` | 13px |
| 服务区域 | `service_area` | 13px,标签文案可为「服务区域」或「办公地点」 |
| 名片标识 | 固定文本「员工名片」 | 11px 灰色徽标,右上角 |
| 企微userid | `wecom_userid` | 隐藏字段,用于 `openEnterpriseChat` 调用 |
### 4.3 交互流程
```
员工发送非IT消息
Dify 统一意图识别 → intent_type: "non_it_routing"
后端发送文本消息(路由说明)
后端发送 contact_card 消息(联系人名片)
后端发送 system 消息("以上为AI自动推荐,点击名片可直接发起企微聊天")
员工点击「联系TA」
wx.invoke('openEnterpriseChat', {userids: 'WangFang'})
跳转企微单聊
```
### 4.4 与现有审批卡片的统一性
名片卡片与现有 `approval_card` / `byod_card` 采用相同的渲染架构:
- 后端统一通过 `msg_type` 区分卡片类型
- 卡片数据通过 `extra_data` 透传
- 前端 `MessageBubble.vue` 增加 `v-else-if="msg.msg_type === 'contact_card'"` 分支
---
## 5. 意图识别扩展方案
### 5.1 扩展策略:向后兼容的 JSON Schema 演进
现有 Dify Prompt 输出:
```json
{
"is_approval_request": true,
"confidence": 0.95,
"approval_type": "设备申请"
}
```
扩展后输出(**原3个字段语义不变,新增3个字段**):
```json
{
"is_approval_request": true,
"confidence": 0.95,
"approval_type": "设备申请",
"intent_type": "approval",
"business_category": null,
"routing_confidence": 0.0
}
```
### 5.2 新增字段说明
| 字段 | 类型 | 取值 | 说明 |
|------|------|------|------|
| `intent_type` | string | `"approval"` / `"it_consult"` / `"non_it_routing"` / `"chitchat"` | 意图大类:审批 / IT咨询 / 非IT业务路由 / 闲聊 |
| `business_category` | string\|null | `"行政"` / `"人力资源"` / `"财务"` / `"法务"` / `"行政-设备"` 等 | 非IT业务类别,仅 `intent_type === "non_it_routing"` 时有值 |
| `routing_confidence` | float | 0.0~1.0 | 非IT路由置信度,≥0.7 触发名片推荐 |
### 5.3 判断优先级(Prompt 内部逻辑链)
```
1. 先判断是否为 IT 审批意图(现有逻辑不变)
→ 是: intent_type = "approval", is_approval_request = true
2. 非审批 → 判断是否为 IT 范围内的咨询/报修
→ 是: intent_type = "it_consult", is_approval_request = false
3. 非 IT 范围 → 判断具体业务类别
→ 是: intent_type = "non_it_routing", business_category = "行政"/"人力资源"/...
4. 闲聊/无关
→ intent_type = "chitchat"
```
### 5.4 Prompt 扩展要点
在现有 Prompt 基础上增加以下内容(不修改原有审批判断规则):
```markdown
### 非IT业务路由识别(新增)
当用户消息不属于上述12种IT审批类型,且不属于IT服务台服务范围时,判断其属于哪个非IT业务类别:
| 业务类别 | 典型场景 | 关键词线索 |
|---------|---------|-----------|
| 行政 | 打印机/复印机/扫描仪故障、办公用品、名片印刷、保洁 | 打印机、复印机、保洁、名片 |
| 人力资源 | 工牌补办、考勤异常、入职/离职手续、社保公积金 | 工牌、考勤、入职、离职、社保 |
| 财务 | 报销、发票、借款、工资 | 报销、发票、借款、工资条 |
| 法务 | 合同、法律咨询、知识产权 | 合同、法务、知识产权 |
| 行政-物业 | 空调、电梯、门禁、停车 | 空调、电梯、门禁、停车 |
判断规则:
- 明确非IT业务 → intent_type: "non_it_routing", routing_confidence ≥ 0.8
- 可能非IT但不确定 → routing_confidence: 0.5~0.7(后端可决定是否推荐)
- 明确是IT范围 → routing_confidence ≤ 0.2, business_category = null
```
### 5.5 回归测试要点
| 测试场景 | 预期结果 |
|---------|---------|
| "我要申请一台笔记本电脑" | `intent_type: "approval"`, `is_approval_request: true`, `approval_type: "设备申请"` |
| "我的VPN连不上了" | `intent_type: "it_consult"`, `is_approval_request: false` |
| "电脑连不上打印机了" | `intent_type: "non_it_routing"`, `business_category: "行政"`, `routing_confidence ≥ 0.8` |
| "工牌丢了补办找谁" | `intent_type: "non_it_routing"`, `business_category: "人力资源"` |
| "你好" | `intent_type: "chitchat"`, `routing_confidence ≤ 0.1` |
---
## 6. 业务联系人数据模型
### 6.1 表结构设计:`business_contacts`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | Integer PK | 自增主键 |
| `name` | String(50) | 联系人姓名 |
| `gender` | String(10) | 性别(male/female |
| `department` | String(100) | 部门名称(如「行政部」) |
| `position` | String(100) | 岗位(如「设备管理岗」) |
| `responsibility` | String(500) | 负责业务描述(如「打印机/复印机/扫描仪」) |
| `extension` | String(20) | 分机号 |
| `service_area` | String(200) | 服务区域/办公地点 |
| `wecom_userid` | String(100) | 企微用户ID(用于 `openEnterpriseChat` |
| `avatar_url` | String(500) | 头像URL(为空时用姓名首字渲染) |
| `business_category` | String(50) | 业务类别(对应 Dify 返回的 `business_category` |
| `is_active` | Boolean | 是否启用(默认 true |
| `created_at` | DateTime | 创建时间 |
| `updated_at` | DateTime | 更新时间 |
### 6.2 业务类别与联系人映射关系
```
business_category (Dify输出) → business_contacts 表查询
─────────────────────────────────────────────────────
"行政" → WHERE business_category = '行政' AND is_active = true
"人力资源" → WHERE business_category = '人力资源' AND is_active = true
"财务" → WHERE business_category = '财务' AND is_active = true
"法务" → WHERE business_category = '法务' AND is_active = true
```
一个 `business_category` 可对应多个联系人(P2 支持多推荐),初期取第一个有效联系人。
### 6.3 API 接口(内部)
| 接口 | 方法 | 说明 |
|------|------|------|
| `/api/h5/routing/contact` | GET | 根据 `business_category` 查询联系人,返回名片数据 |
---
## 7. 待确认问题
| # | 问题 | 影响范围 | 建议 |
|---|------|---------|------|
| Q1 | 非IT业务类别除了行政/HR/财务/法务/物业,是否还有其他需要覆盖的部门? | Prompt 设计 + 数据初始化 | 建议与各部门确认完整清单 |
| Q2 | 一个业务类别有多个联系人时,初期是取第一个还是按服务区域匹配? | 后端查询逻辑 | 建议 P0 取第一个有效联系人,P2 支持区域匹配 |
| Q3 | `routing_confidence` 在 0.5~0.7 之间(不确定是否非IT)时,是否仍然推荐名片? | 路由触发策略 | 建议不推荐,走正常 AI 回复流程,避免误路由 |
| Q4 | 员工点击「联系TA」跳转企微单聊后,当前 IT 服务台会话是否自动结束? | 会话生命周期 | 建议不自动结束,员工可能还需要回来继续咨询 |
| Q5 | 联系人名片是否需要支持「长按保存到通讯录」? | 前端交互 | 建议 P2 迭代,初期仅需「联系TA」跳转 |
| Q6 | 坐席端是否需要手动发送名片的能力(如坐席判断需要路由时主动发名片)? | 坐席端功能 | 建议 P1 增加,坐席应能手动触发路由推荐 |
| Q7 | Dify Prompt 修改后,是否需要 A/B 测试对比新旧 Prompt 的审批识别准确率? | 上线策略 | 建议灰度上线,监控审批识别准确率无下降后全量 |
| Q8 | 企微 `openEnterpriseChat``userids` 参数是企微账号ID还是工号?需要确认与 `business_contacts.wecom_userid` 的对应关系 | 数据模型字段 | 需确认企微通讯录同步的 userid 字段格式 |
---
## 8. 技术风险与对策
| 风险 | 影响 | 对策 |
|------|------|------|
| Prompt 扩展后审批识别准确率下降 | 现有功能回归 | 扩展时保留原审批判断规则原文不动,仅新增非IT判断段落;上线前用审批测试用例集回归 |
| Dify 单次调用延迟增加 | 用户等待感 | Prompt 扩展内容有限,预计延迟增加 <200ms;如明显可考虑流式输出 |
| 企微 userid 数据不准确导致跳转失败 | 核心功能不可用 | 上线前核对联系人 userid 数据;前端做好容错 Toast |
| 误路由:IT问题被识别为非IT | 用户体验受损 | `routing_confidence < 0.7` 不触发路由;可增加「仍需IT帮助」兜底文案 |
---
> **附**:交互原型文件 `docs/04-原型设计/prototypes-原型图/employee-contact-card-demo.html`
> **附**:现有 Dify Prompt `docs/02-产品需求/dify_approval_system_prompt_v2.md`