64 lines
4.4 KiB
Markdown
64 lines
4.4 KiB
Markdown
# ticket — 平台工单管理模块
|
||
|
||
客户提出问题 → 登记工单 → agent 先处理(检索'0'机构知识库+历史工单,能答直接回复客户)
|
||
→ 答不了转人工运维(owner.maintainer,params 可配)→ 人工回复客户 → 关闭;
|
||
人工处理不了可转派 owner 组织类型下任意角色或具体用户。
|
||
|
||
## 关键设计(详见 pipeline-app/docs 或设计文档 ticket-module-design.md)
|
||
|
||
- **状态机**:8 态 13 迁移,全部乐观锁(UPDATE...WHERE status=前置态 + SELECT 验证,
|
||
照 pipeline_service agent_loop 的 claim 范式),并发冲突返回明确错误码。
|
||
- **平台待办集成**(用户定夺 2026-09-10):工单不建独立通知表,通过
|
||
`register_todo_provider` 钩子接入平台待办通道(pipeline-service 聚合,
|
||
todo_badge 角标 + my_todos 弹窗异步通知到人)。待办由工单状态派生:
|
||
客户回复待确认 / 运维角色池待认领 / 受理人待处理——状态流转待办自动消失,
|
||
天然满足「同一事项只发一次」。
|
||
- **角色不硬编码**:默认受理角色存 params(ticket_default_role,兜底 owner.maintainer);
|
||
转派候选实时查 role 表 owner 组织类型全部角色 + '0' 机构用户(role/orgtypes 运行时可动态增删)。
|
||
- **agent**:异步 poller(照 bid_flow 范式,PIPELINE_MODE=web 不启动),
|
||
RAG 检索走 rag HTTP API(dapi Bearer key,平台账号='0'机构 → 只见 org_id='0' 的 KB),
|
||
LLM 走 pipeline_service.llm_bridge.llm_call(内部 token+门禁链+记账,org_id='0')。
|
||
「能否回答」由 LLM 裁决(语义判断铁律,禁关键词匹配),严格 JSON 输出;
|
||
硬门禁:reply 空/短于20字符一律转人工。基础设施故障(LLM/RAG异常)≠答不了:
|
||
fail_rounds+1 回退重试,≥3 轮转人工(reason=agent服务不可用)。
|
||
|
||
## 数据表(3张,tk_ 前缀)
|
||
|
||
| 表 | 说明 |
|
||
|---|------|
|
||
| tk_tickets | 工单主表(状态机+当前受理角色/人+agent处理锁;customer_user_id 必填=提单人,待办精确到人) |
|
||
| tk_messages | 往来消息(visibility: customer客户可见/internal内部备注;attachments JSON 列存附件清单) |
|
||
| tk_transfers | 转派流水(append-only,每次受理方变更必留痕) |
|
||
|
||
## 附件(2026-09-11 上线,全链路)
|
||
|
||
- **上传**:客户建单表单(Form uitype=file multiple)、追问/回复弹窗(UiFile multiple)→
|
||
FormData multipart → ahserver getPostData 自动落 FileStorage(filesroot,按用户目录分片),
|
||
params_kw['attachments'] 得 webpath(单 str / 多 list)。前端拦截:单条 ≤9 个、总量 ≤9.5MB。
|
||
- **服务端规整**:core.normalize_attachments 生成 [{id,name,webpath,size}](不信任客户端):
|
||
路径必须 '/' 开头无 '..'、realpath 不越出 filesroot、真实存在;并调 tfr.file_useful 把文件
|
||
从临时清理队列摘除(否则 multipart 上传 1 小时后被当临时文件删)。错误码 TK_E014。
|
||
- **展示**:ticket_detail_popup.dspy(页面详情与平台待办共用)消息流内联附件行 +
|
||
末尾「全部附件」汇总区;上传方彩色徽标区分(客户蓝/智能助手紫/人工客服橙)+昵称。
|
||
附件不做 markdown 链接——MdWidget 会劫持同源 <a> 为加载 markdown,用独立按钮行。
|
||
- **打开/下载**:ticket_attachment.dspy(msg_id+att_id 反查,I5 服务端校验:客户只能取
|
||
visibility=customer 消息附件;staff/admin 全量)→ FileResponse;?download=1 加 attachment 头。
|
||
文本类显式 Content-Type charset=utf-8(aiohttp FileResponse 猜类型不附 charset → 中文乱码)。
|
||
错误码 TK_E015(附件不存在/丢失)。load_path 已注册 logined。
|
||
|
||
## 参数(params 表,运行时可改)
|
||
|
||
| 参数 | 默认 | 说明 |
|
||
|------|------|------|
|
||
| ticket_default_role | owner.maintainer | agent 转人工的默认受理角色 |
|
||
| ticket_followup_max | 2 | agent 回复后客户追问上限,超限自动转人工 |
|
||
| ticket_agent_fail_max | 3 | agent 基础设施连续失败轮数上限,超限转人工 |
|
||
| ticket_agent_username | admin | agent 检索知识库用的平台账号('0'机构) |
|
||
|
||
## 安装
|
||
|
||
宿主 build.sh 四处清单 + `load_ticket()`(见宿主集成)。模块注册:
|
||
- env.create_ticket / ticket_detail / ticket_followup / ... (dspy 消费)
|
||
- register_todo_provider(list_ticket_todos)(平台待办聚合)
|
||
- start_poller()(agent 后台处理)
|