# 飞书通知与问答接入功能设计 ## 文档信息 | 项目 | 内容 | | --- | --- | | 需求分析文档 | docs/1.需求分析/4.飞书通知与问答接入.md | | 依赖功能设计 | docs/2.功能设计/1.自动汇总.md;docs/2.功能设计/2.NMPA注册资料法规核查与整改闭环.md;docs/2.功能设计/3.产品关键信息提取与申报文件自动填表.md | | 功能名称 | 飞书通知与问答接入 | | 所属模块 | 审核智能体 review_agent | | 设计日期 | 2026-06-07 | | 设计版本 | V1.0 | --- ## 一、设计目标 本功能用于将系统内工作流结果通过飞书官方智能体/应用机器人同步到指定个人账号,并为后续飞书内问答能力预留数据模型和服务边界。首期实现重点是:自动汇总、NMPA 注册资料法规核查与整改闭环、产品关键信息提取与申报文件自动填表三个流程结束后,使用 App ID/App Secret 获取 `tenant_access_token`,调用飞书消息 API 向指定个人账号发送富文本私聊提醒。 首期不实现飞书事件订阅回调和私聊问答,但需要在设计上预留用户映射、查询服务、权限过滤和问答日志能力,保证后续可以平滑扩展到“用户在飞书私聊机器人中查询批次状态、风险摘要、缺失摘要和导出摘要”。 --- ## 二、设计范围 ### 2.1 本期范围 | 序号 | 范围项 | 说明 | | --- | --- | --- | | 1 | 指定个人通知 | 通过飞书官方智能体/应用机器人消息 API 向一个指定个人账号发送通知 | | 2 | 发起人展示 | 消息正文展示批次发起人或上传人,不做群内 @ | | 3 | 三流程接入 | 自动汇总、法规核查、自动填表均发送完成通知 | | 4 | 富文本消息 | 使用飞书富文本格式展示标题、批次、状态、摘要、链接和发起人 | | 5 | token 管理 | 使用 App ID/App Secret 获取并缓存 tenant_access_token | | 6 | 通知判重 | 同一批次、同一工作流、同一状态只发送一次 | | 7 | 通知记录 | 保存摘要、通道、目标、状态、失败原因、发送时间等信息 | | 8 | 批次详情展示 | 在对应批次详情页展示通知状态和失败原因 | | 9 | 用户映射管理 | 通过 Django Admin 手工维护系统用户与飞书用户标识,服务后续按发起人私聊和问答身份识别 | | 10 | 问答预留 | 预留飞书用户映射、查询服务、权限规则和问答日志模型 | ### 2.2 非本期范围 | 序号 | 范围项 | 说明 | | --- | --- | --- | | 1 | 飞书私聊问答回调 | 不实现事件订阅接口和问答回复处理 | | 2 | 群聊 @ 机器人问答 | 不接收群消息,不处理群内权限问题 | | 3 | 飞书事件订阅回调 | 首期不接收私聊或群聊消息事件 | | 4 | 复杂消息卡片 | 不做交互式卡片按钮和回调 | | 5 | 自动后台重试 | 飞书发送失败只记录,不自动重试 | | 6 | 飞书通讯录同步 | 不自动拉取用户,首期手工维护映射 | --- ## 三、与既有功能的关系 | 既有能力 | 处理方式 | 说明 | | --- | --- | --- | | 自动汇总工作流 | 接入通知 | 文件汇总完成后生成摘要通知 | | 法规核查工作流 | 替换/扩展 mock 通知 | 风险分级和报告生成后发送摘要通知 | | 自动填表工作流 | 扩展现有 notifier | Word/追溯清单生成后发送摘要通知 | | 通知记录模型 | 统一扩展 | 现有法规和填表通知记录已存在,本设计建议抽象统一通知服务 | | 工作流事件 | 复用 | 通知发送结果可作为节点事件或批次附属信息展示 | | Django Admin | 扩展 | 新增飞书用户映射管理入口 | --- ## 四、总体架构 ### 4.1 逻辑架构 ```mermaid flowchart TD A["业务工作流完成"] --> B["NotificationDispatcher"] B --> C["WorkflowNotificationBuilder"] C --> D["ConfiguredPersonalRecipientResolver"] D --> E["RichTextMessageBuilder"] E --> F{"通知是否已发送"} F -->|"已发送"| G["写入/返回重复跳过结果"] F -->|"未发送"| H{"飞书通知是否启用"} H -->|"否"| I["写入 mock/未启用记录"] H -->|"是"| J["FeishuTokenProvider"] J --> K["获取/复用 tenant_access_token"] K --> L["FeishuMessageApiClient"] L --> X["POST /im/v1/messages"] X --> M["保存通知记录"] M --> N["批次详情页展示"] O["后续飞书私聊消息"] -.预留.-> P["FeishuQuestionService"] P -.预留.-> Q["BatchSummaryQueryService"] Q -.预留.-> R["权限过滤"] P -.预留.-> S["FeishuQuestionLog"] ``` ### 4.2 模块划分 | 模块 | 责任 | | --- | --- | | `notification_dispatcher` | 工作流完成后统一调度通知发送 | | `workflow_notification_builder` | 将不同工作流批次转换为统一通知上下文 | | `feishu_recipient_resolver` | 首期读取配置中的个人 open_id/user_id;后续支持按系统用户映射解析 | | `feishu_message_builder` | 构造飞书富文本消息体 | | `feishu_token_provider` | 使用 App ID/App Secret 获取并缓存 tenant_access_token | | `feishu_message_api_client` | 调用飞书发送消息 API、处理超时和响应解析 | | `notification_record_service` | 判重、保存成功/失败/未启用记录 | | `batch_notification_presenter` | 为批次详情页输出通知状态 | | `feishu_question_service` | 后续问答预留,解析问题并查询摘要 | | `batch_summary_query_service` | 后续问答预留,按权限查询批次摘要 | --- ## 五、通知业务流程 ### 5.1 主流程 ```text 业务工作流进入 success、partial_success 或 failed -> 工作流调用统一通知服务 -> 通知服务生成 workflow_type、batch_id、status 组成的判重键 -> 检查是否已有同一判重键的成功通知 -> 若已有成功通知,跳过发送并返回 skipped -> 读取批次、用户、摘要、结果链接 -> 读取配置中的个人 open_id/user_id 作为接收人 -> 构造富文本消息,正文展示批次发起人或上传人 -> 判断 FEISHU_NOTIFY_ENABLED -> 未启用时写入 mock/disabled 记录 -> 已启用时获取或复用 tenant_access_token -> 调用飞书消息 API 向指定个人 open_id/user_id 发送消息 -> 发送成功写入 sent/success 记录 -> 发送失败写入 failed 记录,记录错误信息 -> 业务工作流不因通知失败而失败 ``` ### 5.2 三类工作流通知摘要 | 工作流 | workflow_type | 摘要字段 | 下一步 | | --- | --- | --- | --- | | 自动汇总 | `file_summary` | 文件总数、成功解析数、失败/跳过数、导出文件数 | 查看汇总结果或下载 Excel | | 法规核查 | `regulatory_review` | 风险总数、阻断项数、高风险数、中风险数、报告导出状态 | 查看风险报告和整改建议 | | 自动填表 | `application_form_fill` | 选中模板数、导出文件数、冲突字段数、失败原因概述 | 下载 Word/追溯清单并人工确认 | ### 5.3 通知状态 | 状态 | 含义 | 是否阻断主流程 | | --- | --- | --- | | pending | 已创建记录但未发送 | 否 | | sent/success | 已成功发送到飞书 | 否 | | failed | 发送失败或配置异常 | 否 | | skipped_duplicate | 已存在同一批次、同一流程、同一状态通知 | 否 | | disabled/mock | 真实通知未启用,记录为模拟或未启用 | 否 | --- ## 六、飞书富文本设计 ### 6.1 消息结构 飞书富文本消息建议使用 `post` 类型。首期内容只放摘要,不展开完整风险项和缺失项。 ```json { "msg_type": "post", "content": { "post": { "zh_cn": { "title": "自动填表流程已完成", "content": [ [ {"tag": "text", "text": "状态:成功\n"}, {"tag": "text", "text": "批次:AFF-20260607-001\n"}, {"tag": "text", "text": "发起人:owner\n"} ], [ {"tag": "text", "text": "摘要:生成 2 个文件,冲突字段 1 个。\n"}, {"tag": "a", "text": "查看系统结果", "href": "http://127.0.0.1:8000/..."} ] ] } } } } ``` ### 6.2 接收人标识优先级 首期接收人来自环境变量配置。若同时配置多个飞书标识,按以下优先级选取: ```text FEISHU_DEFAULT_USER_OPEN_ID -> FEISHU_DEFAULT_USER_ID ``` 若无可用接收人标识,系统不发送真实飞书消息,并记录配置缺失失败。 用户映射表仍保留,用于后续从“固定个人账号”升级为“按发起人私聊”。 ### 6.3 系统链接 首期使用本地地址,例如: ```text http://127.0.0.1:8000/ ``` 批次详情链接由各工作流已有页面路由或详情接口拼接。部署环境后续再升级为可信域名配置。 --- ## 七、配置设计 | 配置项 | 来源 | 是否敏感 | 说明 | | --- | --- | --- | --- | | FEISHU_NOTIFY_ENABLED | 环境变量 | 否 | 是否启用真实飞书通知 | | FEISHU_NOTIFY_CHANNEL | 环境变量 | 否 | 首期为 `feishu_api` | | FEISHU_APP_ID | 环境变量 | 是 | 飞书智能体/企业自建应用 App ID | | FEISHU_APP_SECRET | 环境变量 | 是 | 飞书智能体/企业自建应用 App Secret | | FEISHU_DEFAULT_USER_OPEN_ID | 环境变量 | 否 | 首期指定接收人的飞书 open_id | | FEISHU_DEFAULT_USER_ID | 环境变量 | 否 | 首期指定接收人的飞书 user_id | | FEISHU_DEFAULT_TARGET_NAME | 环境变量 | 否 | 固定群展示名称 | | FEISHU_TENANT_TOKEN_CACHE_SECONDS | 环境变量 | 否 | tenant_access_token 本地缓存秒数 | | FEISHU_REQUEST_TIMEOUT_SECONDS | 环境变量 | 否 | 默认 5 秒 | | 系统用户与飞书用户映射 | Django Admin | 部分敏感 | open_id、user_id、mobile | --- ## 八、页面设计 ### 8.1 Django Admin 新增飞书用户映射管理: | 字段 | 列表展示 | 可搜索 | 可过滤 | | --- | --- | --- | --- | | system_user | 是 | username | 是 | | feishu_display_name | 是 | 是 | 否 | | feishu_open_id | 否 | 是 | 否 | | feishu_user_id | 否 | 是 | 否 | | feishu_mobile | 否 | 是 | 否 | | is_active | 是 | 否 | 是 | ### 8.2 批次详情页 三个流程对应的批次详情或结果区域展示通知状态: | 展示项 | 说明 | | --- | --- | | 通知通道 | mock、feishu_api | | 通知目标 | 指定个人账号名称或配置名称 | | 接收人 | 指定个人账号;后续可展示发起人/上传人的飞书展示名 | | 发送状态 | 成功、失败、未启用、重复跳过 | | 发送时间 | 成功发送时间 | | 失败原因 | 配置错误、超时、飞书返回错误等摘要 | --- ## 九、飞书问答预留设计 ### 9.1 首期预留能力 | 能力 | 设计说明 | | --- | --- | | 用户映射复用 | 后续私聊事件中的飞书用户 ID 可通过映射表关联系统用户 | | 批次查询服务 | 预留按批次号、工作流类型、最近批次查询摘要的服务 | | 权限过滤 | 普通用户只查自己发起或上传的批次;管理员可查全部 | | 问答日志 | 预留日志表或服务接口,记录问题、意图、查询对象和回答摘要 | ### 9.2 后续问答能力边界 | 问题类型 | 首期问答 MVP 是否支持 | | --- | --- | | 查最近批次状态 | 是 | | 查指定批次状态 | 是 | | 查风险摘要 | 是 | | 查缺失摘要 | 是 | | 查导出摘要 | 是 | | 解释具体整改建议 | 否 | | 重新发起工作流 | 否 | --- ## 十、验收标准 | 序号 | 验收项 | 标准 | | --- | --- | --- | | 1 | 三流程通知 | 自动汇总、法规核查、自动填表完成后均调用统一通知服务 | | 2 | 个人账号发送 | 配置 App ID、App Secret 和指定个人 open_id/user_id 后,个人飞书账号能收到富文本通知 | | 3 | 发起人展示 | 消息正文能展示流程发起人或上传人 | | 4 | 接收人缺失 | 指定接收人缺失时不发送真实消息,并记录配置错误 | | 5 | token 管理 | 系统能获取并缓存 tenant_access_token,token 失效后可重新获取 | | 6 | 判重 | 同一批次、同一流程、同一状态不会重复发送成功通知 | | 7 | 失败不阻断 | 飞书接口失败时主工作流仍完成 | | 8 | 记录落库 | 成功、失败、未启用、重复跳过均可追溯 | | 9 | 页面展示 | 批次详情页展示通知状态和失败原因 | | 10 | 问答预留 | 用户映射、查询服务边界和日志设计可支持后续私聊问答 |