1. 文档定位

本文说明 DGJ2.0 内部帮助业务的四套能力:用户问答、标准题库、结构化知识库、七鱼机器人知识读取,并补充 Elasticsearch 索引和 Excel 导入。它服务于服务站自助查询、OPS 审核、客服复用和机器人回答。

这里的“知识库”是 DGJ2 产品功能,不等于 jb2ai.ltd 统一知识地图。前者是业务运行数据,后者是项目研发文档入口。

2. 业务边界

2.1 包含

  • 老帮助中心兼容入口。
  • 新版问题、回答、审核、采纳和删除。
  • 已采纳回答转标准题库。
  • 题库新增、编辑、启停、FAQ、搜索和 Excel 导入。
  • ES 索引创建、增删改同步和搜索回表。
  • 知识分类树、列表、详情、收藏。
  • 七鱼机器人知识分类和列表读取。
  • 状态、权限、表关系、异常、重建索引和回归。

2.2 不包含

  • DGJ2 RobotV2 会话、Intent 和 AI 控制台,见第 39 篇。
  • Udesk 人工客服接管。
  • jb2ai.ltd 文档发布和统一知识地图治理。
  • 七鱼后台的生产知识编辑、审核和训练机制。

3. 四套内容模型

内容域主表/来源生产者使用者是否进入 DGJ2 ES
用户问答t_help_question、t_help_answer服务站、OPS 回答者全部/我的问答是,问题索引
标准题库t_help_question_libOPS 手工、导入、回答转题库搜索、FAQ是,独立题库索引
结构化知识库t_knowledge*后台同步/初始化分类、列表、详情、收藏当前 Service 未见复用 Help ES
七鱼机器人知识七鱼外部接口七鱼后台DGJ2 读取分类和列表由七鱼负责检索
flowchart LR
    U[服务站提问] --> Q[用户问题]
    A[回答者] --> R[候选回答]
    Q --> R
    R --> C{审核/采纳}
    C -->|采纳| B[最佳答案]
    B --> T[转标准题库]
    T --> E2[题库ES]
    Q --> E1[问题ES]
    K[结构化知识库] --> KC[分类/收藏]
    Y[七鱼知识] --> YR[机器人读取]

4. 入口地图

模块Controller主要方法
老帮助中心help/Dgj.phpcommonProblem、productKnowledge、ask、search、questionDetail、myQuestion、myAnswer
新问题newhelp/Question.phpallList、myList、info、modules、create、update、delete
新回答newhelp/Answer.phpallList、myList、info、create、update、delete、remark、check
题库newhelp/QuestionLib.phpsearch、faq、info、create、update、delete、status、transform、import
结构化知识库knowledge/Knowledge.phpgetCategoryTree、getKnowledgeList、getCollectKnowledgeList、getKnowledgeInfo、collectKnowledge
旧 QAqa/Qa.php历史问答入口

5. Service 地图

Service职责
HelpBaseService模型初始化、可写字段、状态映射、输出格式
HelpQuestionService问题列表、创建、编辑、删除、详情
HelpAnswerService新版回答列表、审核/采纳等
AnswerService老回答提交兼容
HelpLibService题库 CRUD、FAQ、启停、转题库
HelpCacheEsSer问题/题库 ES 增删改查
ExcelService题库上传、模板、错误文件和下载
KnowledgeSer分类树、内容、收藏和初始化
QiYuRobotKnowledgeSer七鱼分类/知识列表适配

6. 核心表

表关键键作用重要字段
t_help_questionid、sid、uid用户问题question、module、keyword、status、question_lib_id
t_help_answerid、question_id问题回答answer、is_accept、remark、媒体标记
t_help_question_libid、answer_id标准题库问题、答案、模块、关键词、状态、浏览数
t_knowledgeid、分类 ID知识内容标题、正文、发布/排序字段待 DDL 确认
t_knowledge_categoryid、父 ID分类树名称、层级、排序
t_knowledge_collect用户、知识 ID收藏关系sid/uid、知识 ID
t_scm_robot_conversation_knowledge会话、知识机器人会话引用不属于帮助题库主链
erDiagram
    HELP_QUESTION ||--o{ HELP_ANSWER : has
    HELP_ANSWER ||--o| HELP_QUESTION_LIB : transforms
    HELP_QUESTION ||--o| HELP_QUESTION_LIB : links
    KNOWLEDGE_CATEGORY ||--o{ KNOWLEDGE_CATEGORY : children
    KNOWLEDGE_CATEGORY ||--o{ KNOWLEDGE : contains
    KNOWLEDGE ||--o{ KNOWLEDGE_COLLECT : collected

7. 可写字段白名单

HelpBaseService 限制写入:

对象允许字段
问题question、attachments、module、not_system_module、keyword
回答answer、is_has_img、is_has_video
题库模块、非系统模块、问题、附件、关键词、答案、图片/视频标记

Controller 传入的 sid、uid、状态、浏览量、采纳标识等不得由前端任意覆盖,必须由登录上下文或 Service 生成。

8. 问题状态

底层 QuestionEnums:

数值底层状态API 显示值
0未解答Q_DJD 待解答
2已回答待审核Q_DSH 待审核
1已审核Q_YSH 已审核
3已解答Q_YJD 已解答
stateDiagram-v2
    [*] --> 待解答: 创建问题
    待解答 --> 待审核: 提交回答
    待审核 --> 已审核: 后台审核
    待审核 --> 已解答: 采纳并完成
    已审核 --> 已解答: 确认最佳回答

真实迁移以 HelpAnswerService::check 为准;显示值不是数据库值,排查时不要拿 Q_DJD 直接查整数状态列。

9. 回答状态

回答状态由“问题状态 + 回答 is_accept”动态计算:

条件API 状态
问题为待审核A_DSH 待审核
问题已审核/已解答且 is_accept = 1A_YCN 已采纳
问题已审核/已解答且 is_accept = 0A_WCN 未采纳

因此回答表没有必要保存完整显示状态。修复回答状态前应先检查问题主状态和采纳标记。

10. 提问流程

sequenceDiagram
    participant U as 服务站用户
    participant C as Question Controller
    participant S as HelpQuestionService
    participant DB as MySQL
    participant ES as 问题ES
    U->>C: create(question,module,keyword,attachments)
    C->>S: 注入sid/uid
    S->>S: 字段白名单和业务校验
    S->>DB: 新增status=0
    S->>DB: 读取完整新行
    S->>ES: operationIndex + batchHandle
    S-->>U: questionId

10.1 创建副作用

  • 新增问题主表。
  • 状态固定为未解答。
  • 同步创建 ES 文档。
  • ES 同步是否与 MySQL 同事务,当前实现不是数据库事务一体化;索引失败可能形成“库有、搜不到”。

10.2 编辑与删除限制

  • 普通用户只能处理有权限的问题。
  • 问题只有未解答状态允许编辑/删除。
  • 编辑后更新 ES 字段。
  • 删除数据库行后删除 ES 文档。

11. 问题列表与搜索

HelpQuestionService::list:

  1. 统计我的问题和我的回答。
  2. 有关键词/模块时先调用 ES 得到问题 ID。
  3. 将 ID、状态、站点等条件回表分页。
  4. 格式化状态、附件、回答数和媒体标记。
flowchart LR
    Q[关键词/模块] --> E[ES searchQuestionIds]
    E --> I[命中ID列表]
    I --> M[MySQL状态和权限过滤]
    M --> F[格式化列表]
    F --> U[页面]

ES 只负责召回,MySQL 是业务状态真值。索引中的旧状态不应绕过回表权限和删除过滤。

12. 回答流程

flowchart TD
    A[选择问题] --> B[提交回答]
    B --> C{问题允许回答?}
    C -- 否 --> X[拒绝]
    C -- 是 --> D[新增回答]
    D --> E[问题进入待审核]
    E --> F[OPS审核]
    F --> G{采纳?}
    G -- 是 --> H[is_accept=1并完成问题]
    G -- 否 --> I[未采纳/继续回答]
    H --> J[可转题库]

回答详情区分 my_answer、best_answer 和全部回答。前端不应把“我的回答”误当最佳答案。

13. 回答审核与采纳

审核必须保证:

  • 问题存在且未删除。
  • 回答属于该问题。
  • 同一问题最多一个采纳回答。
  • 审核人具备 OPS 权限。
  • 重复审核不会重复增加统计或覆盖最佳回答。
  • 问题和回答状态变更要在同一数据库事务内完成。

14. 回答转题库

HelpLibService::transform(answerId) 的硬性条件:

  1. 回答存在。
  2. answer_id 尚未在题库出现。
  3. 根据问题状态和 is_accept 计算结果必须是 A_YCN。
  4. 复制问题的模块、问题、附件、关键词。
  5. 复制回答正文、媒体标记和备注。
  6. 事务中创建题库并回写问题 question_lib_id。
sequenceDiagram
    participant O as OPS
    participant L as HelpLibService
    participant DB as MySQL
    participant ES as 题库ES
    O->>L: transform(answerId)
    L->>DB: 查回答、问题、重复answer_id
    L->>L: 必须为已采纳
    L->>DB: BEGIN
    L->>DB: 新增题库
    L->>ES: 新增题库索引
    L->>DB: 回写question_lib_id
    L->>DB: COMMIT

ES 调用发生在题库 create 内,数据库事务无法回滚外部 ES。若事务后半段失败,可能出现孤立 ES 文档。

15. 题库生命周期

动作权限MySQLES
创建OPS新增operationIndex
批量创建OPS/导入多行新增operationBatchCreate
更新OPS白名单字段更新operationUpdateFields
删除OPS软删/模型删除operationDelete
启停OPS批量更新 status逐条更新状态
查看详情有访问权view_num + 1不更新浏览量

FAQ 只查询 status = 1,按 view_num desc 取前 10 条。

16. 题库 ES 索引

HelpCacheEsSer 默认问题索引可被 ES_INDEX_DGJ_HELP 配置覆盖;题库索引固定逻辑名 dgj_help_question_lib。

索引搜索字段用途
问题索引question用户问题搜索
题库索引question、keyword标准答案搜索

searchQuestionIds(keyword, modules) 返回 ID,再回 MySQL。索引文档 ID 必须与表 ID 一致。

17. 索引一致性窗口

操作可能差异用户表现
MySQL 新增成功、ES 失败库有索引无列表可见,搜索不到
MySQL 更新成功、ES 失败ES 旧内容搜旧词能命中,详情是新内容
MySQL 删除成功、ES 失败ES 孤立 ID搜索召回后回表为空
ES 成功、数据库事务回滚ES 孤立文档搜索命中无详情
批量启停部分 ES 失败状态不一致停用题仍被召回后回表过滤

18. 索引重建策略

flowchart TD
    A[确定问题或题库索引] --> B[导出MySQL有效全量]
    B --> C[创建新索引/校验mapping]
    C --> D[分批bulk写入]
    D --> E[核对总数和抽样关键词]
    E --> F[切别名或替换索引]
    F --> G[观察无结果率和错误]
    G --> H[保留旧索引回滚窗口]

当前 createIndex 是否会删除旧索引需先读 Provider 实现;生产禁止在未备份和未确认别名机制时直接执行。

19. 题库 Excel 导入

QuestionLib::import 使用 ExcelService 和题库批量创建。完整链:

  1. 下载固定模板。
  2. 上传文件并校验扩展名/大小。
  3. 读取首个 Sheet 和表头。
  4. 逐行转换模块、问题、关键词、答案、媒体标记。
  5. 校验必填、枚举和重复。
  6. 合法行批量创建。
  7. 错误行生成错误文件。
  8. 成功数据批量写 ES。

20. ExcelService 文件域

ExcelService 支持:

  • upload
  • createExcel
  • createError
  • createTemplate
  • download
  • downloadTemplate
  • 按 sid 和时间生成文件名
  • 可选保存到 OSS

导入安全:禁止公式注入、路径穿越和超大压缩文件;导出以 = + - @ 开头的用户文本应按纯文本处理。

21. 导入原子性

批量创建代码逐行写 MySQL,再统一构造 ES bulk。需要确认失败策略:

  • 全量失败:任一错误整批不落库。
  • 合法行成功:错误行输出错误文件。
  • MySQL 部分成功后 ES bulk 失败:需按导入批次补索引。

文档和页面必须明确采用哪一种,不能只返回“导入成功”而不带成功/失败数量。

22. 结构化知识库

KnowledgeSer:

方法作用
getCategoryTree返回多级分类树
getKnowledgeList按分类/关键词分页
getCollectKnowledgeList当前用户收藏列表
getKnowledgeInfo详情并处理展示字段
createKnowledgeCategory初始化/同步分类
createKnowledge初始化/同步内容
collectKnowledge收藏或取消收藏
flowchart LR
    C[知识分类树] --> L[分类内容列表]
    L --> D[知识详情]
    D --> F{收藏/取消}
    F --> R[knowledge_collect关系]
    R --> M[我的收藏]

23. 收藏幂等

收藏关系应以“用户 + 知识 ID”唯一:

  • 重复收藏不新增重复行。
  • 取消不存在关系应视为幂等成功或明确无变化。
  • 不同服务站/用户收藏隔离。
  • 知识下线后收藏列表不应泄露不可见正文。
  • 数据库唯一索引待环境确认。

24. 七鱼机器人知识

QiYuRobotKnowledgeSer 提供 getCategoryTree 和 getKnowledgeList,构造时接收参数并调用七鱼外部能力。DGJ2 主要是读取/适配层。

sequenceDiagram
    participant U as DGJ2页面/机器人
    participant S as QiYuRobotKnowledgeSer
    participant Q as 七鱼
    U->>S: 分类或分页请求
    S->>S: 映射分页/过滤参数
    S->>Q: 外部请求
    Q-->>S: code/data或异常
    S-->>U: DGJ2统一结构

七鱼不可用不应破坏本地问题和题库;需有超时、错误提示和降级边界。

25. 权限模型

动作服务站用户OPS
查看可见问题/题库是是
创建自己的问题是可代操作时需审计
编辑/删除问题仅本人且待解答可按权限处理
回答依产品角色是
审核/采纳否是
创建/编辑/启停题库否是
导入题库否是
收藏知识是依登录上下文

HelpBaseService::isOps() 决定多处写权限和列表条件。不能只靠前端隐藏按钮。

26. 附件与媒体

  • 问题附件字段与回答图片/视频标记分开。
  • is_has_img、is_has_video 是展示提示,不等于文件真实存在。
  • 问题列表会从已采纳回答聚合媒体标记。
  • 文件 URL 必须有访问控制、有效期和内容类型限制。
  • 删除问题/回答后附件的生命周期和物理清理待文件中心确认。

27. 常见故障:搜不到

flowchart TD
    A[关键词搜不到] --> B{MySQL有有效记录?}
    B -- 否 --> C[查状态/删除/权限/模块]
    B -- 是 --> D{正确索引有文档?}
    D -- 否 --> E[补索引/重建]
    D -- 是 --> F{搜索字段和分词命中?}
    F -- 否 --> G[查mapping、关键词、模块过滤]
    F -- 是 --> H{回表是否被过滤?}
    H -- 是 --> I[查sid/OPS/状态条件]
    H -- 否 --> J[查分页和前端展示]

28. 常见故障:回答不能采纳/转题库

检查项预期
问题状态已回答待审核或允许审核状态
回答关系answer.question_id = question.id
权限当前账号为 OPS/审核角色
采纳唯一性同问题无另一采纳回答
转题库条件动态回答状态为 A_YCN
重复转化question_lib.answer_id 不存在
事务结果题库行与 question_lib_id 同时存在
ES题库索引文档存在

29. 常见故障:知识库不同步

先区分数据源:

  1. 本地 t_knowledge 不显示:查分类、内容、发布状态和 Service 过滤。
  2. 收藏列表不显示:查用户关系和内容可见性。
  3. 七鱼列表不显示:查外部接口、账号、分类 ID、分页和超时。
  4. Help 题库搜不到:查 dgj_help_question_lib,与 t_knowledge 无关。

30. 只读 SQL

SELECT id, sid, uid, question, module, keyword, status,
       question_lib_id, ask_num, is_delete, create_time, modify_time
FROM t_help_question
WHERE id = 10001;
SELECT id, question_id, sid, uid, is_accept, is_has_img,
       is_has_video, is_delete, create_time, modify_time
FROM t_help_answer
WHERE question_id = 10001
ORDER BY id;
SELECT id, answer_id, module, question, keyword, status,
       view_num, is_delete, create_time, modify_time
FROM t_help_question_lib
WHERE id = 20001 OR answer_id = 30001;
SELECT question_id, SUM(is_accept = 1) AS accepted_count
FROM t_help_answer
WHERE is_delete = 0
GROUP BY question_id
HAVING accepted_count > 1;
SELECT c.id, c.parent_id, c.name, COUNT(k.id) AS knowledge_count
FROM t_knowledge_category c
LEFT JOIN t_knowledge k ON k.category_id = c.id
GROUP BY c.id, c.parent_id, c.name;

收藏表字段需以线上 DDL 为准:

SELECT * FROM t_knowledge_collect
WHERE knowledge_id = 10001
ORDER BY id DESC;

31. ES 只读排查模板

GET dgj_help_question_lib/_search
{
  "query": {
    "bool": {
      "must": [{"multi_match": {"query": "采购入库", "fields": ["question", "keyword"]}}]
    }
  },
  "_source": ["id", "question", "keyword", "module", "status"]
}

索引名应先从运行环境配置确认;禁止在生产直接执行删除索引。

32. 代码定位

rg -n "QUESTION_STATUS|ANSWER_STATUS|ABLE_WRITE_FIELDS" application/Services/Help/HelpBaseService.php
rg -n "function (create|update|delete|info|list)" application/Services/Help/HelpQuestionService.php
rg -n "function (check|remark|transform|status|batchCreate)" application/Services/Help
rg -n "operationIndex|operationDelete|operationUpdateFields|createIndex|searchQuestionIds" application/Services/Help/HelpCacheEsSer.php
rg -n "createError|downloadTemplate|upload" application/Services/Help/ExcelService.php application/controllers/newhelp/QuestionLib.php
rg -n "getCategoryTree|getKnowledgeList|collectKnowledge" application/Services/Knowledge application/controllers/knowledge

33. 补偿 SOP

33.1 MySQL 有、ES 无

  1. 按表 ID 确认记录有效且可见。
  2. 生成与 operationIndex 相同的文档。
  3. 使用原 ID 写入正确索引。
  4. 按关键词检索并回表验证。

33.2 ES 有、MySQL 无

  1. 确认数据库是否软删、分环境或事务回滚。
  2. 不恢复无来源业务数据。
  3. 删除孤立 ES 文档。
  4. 观察是否有持续同步任务再次写入。

33.3 转题库部分成功

  1. 查 answer_id 对应题库行。
  2. 查问题 question_lib_id。
  3. 查题库 ES 文档。
  4. 以 MySQL 事务最终状态为准补回写或删孤立 ES。
  5. 不重新生成第二条题库。

34. 禁止动作

  • 为了让搜索命中只改 ES、不改 MySQL 真值。
  • 将未采纳回答直接转题库。
  • 直接改问题显示状态字符串。
  • 删除整个 ES 索引后再考虑备份。
  • 把七鱼知识故障当成本地题库故障处理。
  • 导入文件含用户公式时原样输出到 Excel。
  • 在知识正文和附件中暴露客户隐私或内部密钥。

35. 监控建议

指标维度作用
问题创建量/待解答时长模块、站点客服负载
待审核回答量审核队列防止积压
问题与 ES 数量差索引一致性
题库与 ES 数量差状态一致性
搜索无结果率关键词、模块内容覆盖/分词
搜索回表空 ID 数索引孤立文档
导入成功/失败行批次数据质量
重复采纳回答问题数据约束
收藏重复关系用户、知识唯一性
七鱼错误率/延迟API外部 SLA

36. 回归清单:问答

  • [ ] 普通用户创建问题,登录上下文不能伪造。
  • [ ] 系统模块和非系统模块。
  • [ ] 关键词、空格、长文本和特殊字符。
  • [ ] 图片/视频/普通附件。
  • [ ] 待解答可编辑删除,其他状态不可。
  • [ ] 我的列表和全量列表权限。
  • [ ] 单个/多个回答。
  • [ ] 审核通过、拒绝、采纳和未采纳。
  • [ ] 同问题只能一个最佳答案。
  • [ ] 重复审核和并发采纳。
  • [ ] 状态显示值与整数映射。

37. 回归清单:题库与搜索

  • [ ] 手工创建、更新、删除题库。
  • [ ] 启用/停用批量操作。
  • [ ] FAQ 只取启用且按浏览量排序。
  • [ ] 已采纳回答转题库。
  • [ ] 未采纳和重复回答拒绝转化。
  • [ ] 转化事务失败后的 ES 清理。
  • [ ] 问题索引和题库索引隔离。
  • [ ] 中文、英文、数字、短词和组合关键词。
  • [ ] 模块过滤和空关键词。
  • [ ] MySQL/ES 新增、更新、删除失败窗口。
  • [ ] 全量重建和增量补索引。

38. 回归清单:导入与知识库

  • [ ] 正确模板、错误表头、空文件和多 Sheet。
  • [ ] 重复问题、缺少答案、非法模块。
  • [ ] 超长文本、公式注入、科学计数法。
  • [ ] 部分成功策略和错误文件。
  • [ ] MySQL 成功、ES bulk 失败恢复。
  • [ ] 分类树多级、空分类和排序。
  • [ ] 列表、详情和不可见内容。
  • [ ] 收藏、重复收藏、取消和用户隔离。
  • [ ] 七鱼成功、超时、非零错误和空数据。
  • [ ] 七鱼故障不影响本地题库。

39. 改动风险

级别改动最低回归
P0问题/回答状态和采纳事务全状态、并发、转题库
P1HelpCacheEsSer 索引/mapping/bulk两索引 CRUD、重建、回表
P1题库导入文件安全、原子性、错误文件
P1权限和 isOps用户/OPS 全入口
P1知识收藏唯一性多用户、重复、下线
P2FAQ 排序、列表格式页面和兼容字段

40. 已确认与待确认

40.1 已确认

  • 问题、回答、题库可写字段白名单。
  • 四个问题显示状态和三个回答显示状态。
  • 问题创建/编辑/删除同步 ES。
  • 题库使用独立索引 dgj_help_question_lib。
  • 题库搜索字段含 question、keyword。
  • 已采纳回答才能转题库,且按 answer_id 防重复。
  • 转题库事务回写 question_lib_id。
  • FAQ 查询启用题并按浏览量排序。
  • 知识库有分类、内容和收藏三表。
  • 七鱼 Service 只提供分类和列表读取。

40.2 待确认

  • 生产 ES mapping、分词器、别名和副本配置。
  • batchHandle 的失败重试、超时和部分失败结果。
  • 问答表生产唯一索引和软删字段约束。
  • 审核/采纳的完整权限矩阵。
  • Excel 最大行数、文件保留和 OSS 生命周期。
  • 知识库发布状态和初始化数据来源。
  • 收藏表唯一索引。
  • 七鱼鉴权、限流、缓存和降级 SLA。

41. 证据来源

  • application/controllers/help/Dgj.php
  • application/controllers/newhelp/Question.php
  • application/controllers/newhelp/Answer.php
  • application/controllers/newhelp/QuestionLib.php
  • application/controllers/knowledge/Knowledge.php
  • application/controllers/qa/Qa.php
  • application/Services/Help/HelpBaseService.php
  • application/Services/Help/HelpQuestionService.php
  • application/Services/Help/HelpAnswerService.php
  • application/Services/Help/HelpLibService.php
  • application/Services/Help/HelpCacheEsSer.php
  • application/Services/Help/ExcelService.php
  • application/Services/Knowledge/KnowledgeSer.php
  • application/Services/Knowledge/QiYuRobotKnowledgeSer.php
  • application/KzData/Enums/QuestionEnums.php
  • application/config/tables.php

42. 一页式交接结论

  1. 用户问题、标准题库、结构化知识库和七鱼知识是四套数据源。
  2. 问题/题库 ES 只做召回,MySQL 是状态、权限和删除真值。
  3. 问题显示状态是整数枚举的 API 映射;回答状态由问题状态和采纳标记动态得出。
  4. 只有已采纳回答可转题库,题库用 answer_id 防重复。
  5. 转题库事务不能回滚已成功的 ES 调用,必须处理孤立索引。
  6. 题库启停要同时更新 MySQL 和 ES,但回表仍要过滤。
  7. 导入需明确全失败还是合法行成功,并输出成功/失败数量。
  8. 本地知识库收藏应以用户和知识 ID 唯一。
  9. 七鱼故障与 DGJ2 题库故障分开排查。
  10. 修复搜索时以表 ID 为幂等键补索引,不直接修改业务状态。

请求-日志-数据变更追踪卡

多入口请求链路

场景调用方与入口请求载荷/上下文Controller/ConsumerService/Provider汇合点最终业务事实
用户提问/回答help/newhelp 页面用户、问题、分类、内容help/Dgj.php、newhelp/Question.php/Answer.phpHelpQuestion/Answer Servicequestion/answer ID问答保存并进入审核状态
题库/知识维护管理页题目、答案、分类、上下架QuestionLib/Knowledge ControllerHelp/Knowledge Servicecontent ID题库和知识文章版本落库
审核发布OPS/任务对象 ID、审核动作、意见管理 Controller/TaskHelp Service对象 ID状态从待审核到发布/拒绝
搜索help/knowledge/qa 搜索入口关键词、分类、分页knowledge/Knowledge.php、qa/Qa.phpSearch/ES Service表 ID/ES doc ID返回已发布内容

日志证据矩阵

| 链路段 | 日志来源 | 可检索锚点 | 成功信号 | 失败信号 | 与下一段关联方式 | | --- | --- | --- | --- | --- | --- | --- | | 内容提交 | Controller/Service | request_id、用户、question/content ID | 主记录 commit | 敏感词/分类/权限失败 | 表 ID 查状态与正文 | | 审核 | Help Service | 对象 ID、oldStatus、action、操作人 | Q_DJD -> Q_YSH 等合法迁移 | 并发审核、非法回退 | 对象 ID 触发索引刷新 | | 索引同步 | ES Service/Task | ES_INDEX_DGJ_HELP、doc ID、更新时间 | 文档写入/删除成功 | mapping/连接失败、旧版本覆盖 | doc ID = 表 ID 回查 DB | | 搜索查询 | Search Service | request ID、关键词、index、doc ID | 仅返回发布态且内容新 | DB 有、ES 无/旧/未过滤 | doc ID 对比 DB 状态/更新时间 |

环节数据变更台账

步骤代码位置事务读取事实写入表/缓存/MQ字段或数量变化回查证据
创建内容HelpQuestion/Answer/Knowledge Service内容事务用户、分类、重复内容问题/答案/知识表insert;status=待审核;版本/正文初始化表 ID、创建人、时间
审核发布Help Service审核事务当前状态和审核动作主表/审核记录待审 -> 已审/已拒;发布态可检索状态、操作人、审核时间
建索引Search/ES ServiceDB 外部边界已发布 DB 记录和更新时间ES_INDEX_DGJ_HELPdoc insert/update;下架则 delete/不可搜doc ID、DB/ES update time
搜索Search Controller只读ES 文档、筛选条件无DB 不变;返回排序分页结果request ID、doc ID 列表
修复索引补偿 task分批幂等DB 发布态与 ES 集合差ES以表 ID upsert/delete,不改业务 status修复前后集合差、重跑 0 变化

子模块追踪:help-question 用户提问

环节入口/触发请求/业务键代码链路读取事实写入与字段变化日志证据异常与补偿
创建问题用户提交标题/正文/分类request ID、user/sid、question IDapplication/controllers/newhelp/Question.php -> application/Services/Help/HelpQuestionService.php用户、分类、重复/敏感内容和权限内容本地事务 insert,status none -> pending、版本初始化request ID + question/user ID校验/重复失败零写入;正文日志脱敏/摘要化
编辑回查用户修改未发布问题question ID、versionapplication/Services/Help/HelpQuestionService.php所有权、当前态、乐观版本和已有回答本地事务 content/version old -> new;已发布按规则重新待审request ID + question + before/after version并发版本冲突零覆盖;索引更新仅在发布后

子模块追踪:help-answer 回答与采纳

环节入口/触发请求/业务键代码链路读取事实写入与字段变化日志证据异常与补偿
回答用户/运营提交答案question/answer ID、userapplication/controllers/newhelp/Answer.php -> application/Services/Help/HelpAnswerService.php问题可答态、重复内容和用户权限回答本地事务 insert,status none -> pending/publishedrequest ID + question/answer/user问题关闭或无权零写入;失败不改变问题状态
采纳提问者/运营采纳答案question/answer ID、actionapplication/Services/Help/HelpAnswerService.php回答属于问题、当前采纳项和状态同一本地事务旧采纳 true -> false、目标 false -> truerequest ID + question/answer + affected rows并发仅一个采纳;索引/统计 commit 后异步刷新

子模块追踪:help-library 题库维护

环节入口/触发请求/业务键代码链路读取事实写入与字段变化日志证据异常与补偿
题库配置运营新增/编辑/分类/停用题目lib/question ID、category、operatorapplication/controllers/newhelp/QuestionLib.php -> application/Services/Help/HelpLibService.php原题、分类、重复和引用使用配置本地事务 content/status/order old -> newrequest ID + lib/question + operator停用不物理删除历史引用;批量失败按事务回滚
导入导出题库 Excel 维护file/task ID、rowNo、business keyapplication/Services/Help/ExcelService.php表头、字段、重复集合和现有题库校验不写;通过后每批本地事务 upserttask + row/error/affected counts只重跑失败键;模板版本明确且错误带行号

子模块追踪:help-knowledge 知识文章维护

环节入口/触发请求/业务键代码链路读取事实写入与字段变化日志证据异常与补偿
保存文章运营新建/编辑知识内容article ID、category、versionapplication/controllers/knowledge/Knowledge.php -> application/Services/Knowledge/KnowledgeSer.php分类、重复标题、正文和当前发布态内容本地事务 insert/update,version old -> new、status draft/pendingrequest ID + article/category/version并发版本冲突不覆盖;敏感正文不完整写日志
机器人同步发布内容同步七鱼/机器人知识article ID、external IDapplication/Services/Knowledge/QiYuRobotKnowledgeSer.php本地发布快照、外部映射和同步态外部调用事务外;本地 sync pending -> success/failedrequest ID + local/external ID + code失败只补外部同步,不重复发布本地文章

子模块追踪:help-audit 内容审核与发布

环节入口/触发请求/业务键代码链路读取事实写入与字段变化日志证据异常与补偿
审核发布审核问题/回答/知识文章content type/ID、action、operatorapplication/Services/Help/HelpBaseService.php当前待审态、内容版本、审核权限审核本地事务 pending -> published/rejected,写审核记录request ID + content type/ID + action旧版本审核不得覆盖新稿;终态重复请求 0 变化
下架运营撤回已发布内容content ID、reasonapplication/Services/Knowledge/KnowledgeSer.php发布态、引用和外部/ES 同步本地事务 published -> offline;索引删除 commit 后request ID + content ID + index taskDB 已下架只补索引/外部删除,不恢复业务状态

子模块追踪:help-search 知识库搜索

环节入口/触发请求/业务键代码链路读取事实写入与字段变化日志证据异常与补偿
搜索请求用户按关键字/分类查询request ID、query、filters/pageapplication/controllers/qa/Qa.php -> application/Services/Help/HelpCacheEsSer.phpES 已发布文档、权限、分类和排序查询只读 不写;仅返回可发布态request ID + query + doc IDs/hit countDB 有 ES 无定位同步;空 query 和超页码不写业务数据
结果核对搜索到下架/搜不到发布内容content ID、ES doc/versionapplication/Services/Help/HelpCacheEsSer.phpDB 状态/更新时间与 ES 文档查询只读;比较 status/version/update timecontent/doc ID + both timestampsDB 为业务真值;只修目标索引文档

子模块追踪:help-index-repair ES 索引同步与修复

环节入口/触发请求/业务键代码链路读取事实写入与字段变化日志证据异常与补偿
增量同步内容发布/下架后content type/ID、version、task/message IDapplication/Services/Help/HelpCacheEsSer.phpDB 发布态、ES 旧 doc 和更新时间DB 事务外 upsert/delete old doc -> DB snapshottask + content/doc ID + index result旧事件不覆盖新版本;失败保留业务键重试
差异修复批量对比 DB 与 ES_INDEX_DGJ_HELPbatch、ID rangeapplication/Services/Help/HelpCacheEsSer.phpDB published 集合与 ES ID/version 集合分批事务外 upsert/delete;业务 status 不变batch + scanned/upsert/delete/error counts先 dry-run/小批,重跑差异 0;索引环境待确认