自动汇总文件夹文件目录与页数流程功能设计
文档信息
| 项目 |
内容 |
| 需求分析文档 |
docs/1.需求分析/1.自动汇总.md |
| 功能名称 |
自动汇总文件夹文件目录与页数 |
| 所属模块 |
审核智能体 review_agent |
| 设计日期 |
2026-06-05 |
| 设计版本 |
V1.0 |
一、设计目标
本功能面向试剂盒 NMPA 注册申报资料审核场景,支持用户在 AI 对话页上传压缩包或多个文件,由后台异步执行文件汇总工作流,自动完成解压、文件清单扫描、页数统计、产品名识别、Markdown 报告生成和 Excel 导出。
前台 AI 对话页需要展示一个工作流卡片,实时呈现“上传中、解压中、扫描中、解析中、识别中、输出中、完成/失败”等节点状态;工作流完成后,AI 对话框展示 Markdown 简表,并提供 Markdown 报告和 Excel 明细下载链接。上传文件、批次、节点状态、文件明细和导出结果均需要与当前对话绑定,一个对话对应一套文件,不能跨对话串用。
二、总体架构
2.1 架构原则
| 原则 |
说明 |
| 对话绑定 |
上传文件、处理批次、结果文件均绑定当前 Conversation |
| 按需加载 |
将文件处理流程拆分为多个可单独执行的 Skill,按工作流节点调用 |
| 后台异步 |
用户提交后后台执行工作流,前台通过 SSE 接收状态事件 |
| 失败隔离 |
解压失败导致批次失败;单文件解析失败最多重试 3 次后记录异常并继续 |
| 可迁移 MCP |
Demo 阶段使用项目内 Skill 注册与调用,后续可迁移为 MCP Tool |
| 可追溯 |
每个节点状态、文件统计结果、导出文件均持久化入库 |
2.2 逻辑架构
2.3 技术选型
| 设计项 |
Demo 方案 |
后续演进 |
| 工作流编排 |
项目内 LangGraph 风格节点图执行器 |
接入 LangGraph |
| Skill 形态 |
Python 类或函数注册表,按节点名称动态调用 |
封装为 MCP Tool |
| 后台任务 |
Django 后台线程 + 数据库状态 |
Celery/RQ + Redis |
| 实时更新 |
沿用现有 SSE 流式能力,新增 workflow 事件 |
独立任务事件通道 |
| 文件存储 |
本地 media 目录 |
对象存储或加密文件服务 |
| Markdown 渲染 |
前端引入安全 Markdown 渲染 |
统一富文本渲染组件 |
三、工作流设计
3.1 节点图
3.2 节点定义
| 节点编码 |
节点名称 |
触发 Skill |
成功条件 |
失败处理 |
| upload |
上传中 |
上传接收 Skill |
原始文件保存成功,批次创建成功 |
批次失败 |
| extract |
解压中 |
压缩包解压 Skill |
zip/rar/7z 等压缩包解压成功 |
批次失败 |
| inventory |
扫描中 |
文件清单扫描 Skill |
生成文件清单 |
批次失败或空文件提示 |
| page_count |
解析页数中 |
文档页数统计 Skill |
支持类型完成页数统计或异常记录 |
单文件失败不阻断 |
| product_detect |
识别产品名中 |
产品信息识别 Skill |
识别到产品名或返回空 |
不阻断 |
| report |
输出中 |
汇总报告生成 Skill |
Markdown 报告与对话简表生成成功 |
批次失败 |
| export |
输出中 |
Excel 导出 Skill |
Excel 明细生成成功 |
批次失败或记录导出异常 |
| completed |
完成 |
工作流执行器 |
所有必需产物完成 |
写入完成状态 |
3.3 状态机
| 状态 |
含义 |
| pending |
已创建,等待执行 |
| running |
执行中 |
| retrying |
单文件解析失败,正在重试 |
| success |
节点执行成功 |
| failed |
节点或批次失败 |
| skipped |
当前节点不需要执行,例如非压缩包跳过解压 |
四、Skill 设计
4.1 Skill 注册与调用
Demo 阶段在项目内定义 Skill 注册表,工作流执行器根据节点编码按需加载并执行对应 Skill。
后续 MCP 化时,每个 Skill 可映射为独立 MCP Tool,输入输出保持稳定 JSON 契约。
4.2 上传接收 Skill
| 项目 |
说明 |
| 中文名称 |
上传接收 Skill |
| 职责 |
接收对话页上传的压缩包或多个文件,保存原始文件,创建上传批次 |
| 输入 |
conversation_id、user_id、uploaded_files |
| 输出 |
batch_id、upload_file_ids、upload_type、original_storage_paths |
| 数据写入 |
FileSummaryBatch、FileAttachment、FileSummaryBatchAttachment |
| 关键规则 |
文件必须绑定当前 Conversation;同一对话只使用本对话上传的文件 |
4.3 压缩包解压 Skill
| 项目 |
说明 |
| 中文名称 |
压缩包解压 Skill |
| 职责 |
识别并解压 zip、rar、7z 等常见压缩包,保留目录结构 |
| 输入 |
batch_id、source_file_path |
| 输出 |
extract_root、extracted_file_count |
| 数据写入 |
WorkflowNodeRun、批次工作目录 |
| 关键规则 |
防止路径穿越;解压目录必须限定在批次工作目录内;解压失败批次失败 |
4.4 文件清单扫描 Skill
| 项目 |
说明 |
| 中文名称 |
文件清单扫描 Skill |
| 职责 |
遍历解压目录或散装文件目录,生成文件清单 |
| 输入 |
batch_id、scan_root |
| 输出 |
inventory_items |
| 数据写入 |
FileSummaryItem |
| 关键规则 |
保留目录层级;散装文件归入同一批次根目录;隐藏文件和空文件可标记跳过 |
4.5 文档页数统计 Skill
| 项目 |
说明 |
| 中文名称 |
文档页数统计 Skill |
| 职责 |
对支持类型统计页数或数量 |
| 输入 |
batch_id、FileSummaryItem 列表 |
| 输出 |
page_count、statistics_status、error_message |
| 数据写入 |
FileSummaryItem |
| 关键规则 |
支持 pdf、doc、docx、xls、xlsx、ppt、pptx;单文件失败最多重试 3 次,仍失败则记录异常并继续 |
页数统计口径:
| 文件类型 |
统计口径 |
| pdf |
PDF 页面数量 |
| doc/docx |
优先转 PDF 后统计页面数量 |
| xls/xlsx |
Demo 阶段按工作表数量统计 |
| ppt/pptx |
按幻灯片数量统计 |
4.6 产品信息识别 Skill
| 项目 |
说明 |
| 中文名称 |
产品信息识别 Skill |
| 职责 |
尝试识别产品名称,并用于更新对话标题 |
| 输入 |
batch_id、文件名、目录名、可读取文本片段 |
| 输出 |
product_name、confidence、evidence |
| 数据写入 |
FileSummaryBatch.product_name、Conversation.title |
| 关键规则 |
优先从文件名和目录名识别;其次读取文档首页或关键文本;识别失败不阻断流程 |
会话标题规则:
| 场景 |
标题处理 |
| 识别到产品名 |
更新为“产品名-文件汇总” |
| 未识别产品名 |
保持原对话标题 |
| 用户已手动命名 |
可保留用户标题,产品名写入批次信息 |
4.7 汇总报告生成 Skill
| 项目 |
说明 |
| 中文名称 |
汇总报告生成 Skill |
| 职责 |
生成完整 Markdown 报告和对话框展示简表 |
| 输入 |
batch_id、统计摘要、文件明细、异常清单 |
| 输出 |
markdown_report_path、assistant_markdown_summary |
| 数据写入 |
ExportedSummaryFile、Message |
| 关键规则 |
Markdown 简表需要适合前端对话框渲染;完整报告包含全部文件明细 |
4.8 Excel 导出 Skill
| 项目 |
说明 |
| 中文名称 |
Excel 导出 Skill |
| 职责 |
生成 Excel 汇总文件 |
| 输入 |
batch_id、统计摘要、文件明细 |
| 输出 |
excel_path、download_url |
| 数据写入 |
ExportedSummaryFile |
| 关键规则 |
至少包含“汇总信息”“文件明细”两个 Sheet |
五、数据模型设计
5.1 FileSummaryBatch
文件汇总批次,表示一次对话内的文件汇总任务。
| 字段 |
类型 |
说明 |
| id |
BigAutoField |
主键 |
| conversation |
ForeignKey(Conversation) |
绑定对话 |
| user |
ForeignKey(User) |
上传用户 |
| batch_no |
CharField |
批次编号 |
| product_name |
CharField |
识别出的产品名,可为空 |
| upload_type |
CharField |
archive、multi_file |
| status |
CharField |
pending、running、success、failed |
| total_files |
Integer |
文件总数 |
| supported_files |
Integer |
支持统计的文件数 |
| success_files |
Integer |
统计成功数 |
| failed_files |
Integer |
统计失败数 |
| unsupported_files |
Integer |
不支持文件数 |
| total_pages |
Integer |
总页数 |
| work_dir |
CharField |
批次工作目录 |
| error_message |
TextField |
批次异常说明 |
| created_at |
DateTimeField |
创建时间 |
| started_at |
DateTimeField |
开始时间 |
| finished_at |
DateTimeField |
完成时间 |
5.2 FileAttachment
上传原始文件记录。用户上传即存储为 FileAttachment,批次启动时再通过 FileSummaryBatchAttachment 固化本次使用的附件版本。
| 字段 |
类型 |
说明 |
| id |
BigAutoField |
主键 |
| batch |
ForeignKey(FileSummaryBatch) |
所属批次 |
| original_name |
CharField |
原始文件名 |
| storage_path |
CharField |
保存路径 |
| file_size |
BigInteger |
文件大小 |
| content_type |
CharField |
MIME 类型 |
| created_at |
DateTimeField |
上传时间 |
5.3 FileSummaryItem
文件明细记录。
| 字段 |
类型 |
说明 |
| id |
BigAutoField |
主键 |
| batch |
ForeignKey(FileSummaryBatch) |
所属批次 |
| file_index |
Integer |
文件序号 |
| directory_level |
CharField |
目录层级 |
| file_name |
CharField |
文件名 |
| file_type |
CharField |
文件类型 |
| relative_path |
CharField |
相对路径 |
| storage_path |
CharField |
实际处理路径 |
| page_count |
Integer |
页数,可为空 |
| statistics_status |
CharField |
success、failed、unsupported、skipped |
| retry_count |
Integer |
页数统计重试次数 |
| error_message |
TextField |
异常说明 |
| created_at |
DateTimeField |
创建时间 |
| updated_at |
DateTimeField |
更新时间 |
5.4 WorkflowNodeRun
工作流节点运行记录。
| 字段 |
类型 |
说明 |
| id |
BigAutoField |
主键 |
| batch |
ForeignKey(FileSummaryBatch) |
所属批次 |
| node_code |
CharField |
节点编码 |
| node_name |
CharField |
节点名称 |
| status |
CharField |
pending、running、retrying、success、failed、skipped |
| progress |
Integer |
进度百分比 |
| message |
TextField |
节点提示 |
| started_at |
DateTimeField |
开始时间 |
| finished_at |
DateTimeField |
完成时间 |
5.5 ExportedSummaryFile
导出文件记录。
| 字段 |
类型 |
说明 |
| id |
BigAutoField |
主键 |
| batch |
ForeignKey(FileSummaryBatch) |
所属批次 |
| export_type |
CharField |
markdown、excel |
| file_name |
CharField |
文件名 |
| storage_path |
CharField |
保存路径 |
| download_url |
CharField |
下载链接 |
| status |
CharField |
success、failed |
| error_message |
TextField |
导出异常说明 |
| created_at |
DateTimeField |
生成时间 |
六、后端接口设计
6.1 上传并启动工作流
| 项目 |
内容 |
| URL |
POST /api/review-agent/conversations/{conversation_id}/file-summary/start/ |
| 认证 |
登录用户 |
| 请求类型 |
multipart/form-data |
| 请求参数 |
files[]、prompt |
| 响应 |
batch_id、status、workflow_nodes |
处理逻辑:
6.2 工作流 SSE 事件流
| 项目 |
内容 |
| URL |
GET /api/review-agent/file-summary/{batch_id}/events/ |
| 认证 |
登录用户 |
| 响应类型 |
text/event-stream |
事件类型:
| 事件 |
说明 |
| workflow_started |
工作流开始 |
| node_started |
节点开始 |
| node_progress |
节点进度更新 |
| node_retrying |
单文件解析重试 |
| node_completed |
节点完成 |
| node_failed |
节点失败 |
| workflow_completed |
工作流完成 |
| workflow_failed |
工作流失败 |
示例:
6.3 查询批次状态
| 项目 |
内容 |
| URL |
GET /api/review-agent/file-summary/{batch_id}/ |
| 认证 |
登录用户 |
| 响应 |
批次摘要、节点状态、文件简表、导出文件链接 |
用途:
| 场景 |
说明 |
| 页面刷新恢复 |
前端重新加载后恢复工作流卡片状态 |
| 历史记录查看 |
从会话历史进入后展示已完成汇总结果 |
6.4 下载导出文件
| 项目 |
内容 |
| URL |
GET /api/review-agent/file-summary/exports/{export_id}/download/ |
| 认证 |
登录用户 |
| 响应 |
文件流 |
权限规则:
七、前端设计
7.1 AI 对话页改造
现有 templates/home.html 和 static/js/app.js 需要增强:
| 改造点 |
说明 |
| 附件选择 |
在输入框旁增加文件上传按钮,支持压缩包和多个文件 |
| 工作流卡片 |
用户提交后在对话流中插入工作流状态卡片 |
| SSE 监听 |
监听后台节点事件,实时更新卡片节点状态 |
| Markdown 渲染 |
AI 回复支持 Markdown 表格和下载链接渲染 |
| 状态恢复 |
页面刷新后查询批次状态,恢复工作流卡片 |
7.2 工作流卡片
卡片包含节点列表:
| 节点 |
前台展示文案 |
| upload |
上传中 |
| extract |
解压中 |
| inventory |
扫描中 |
| page_count |
解析页数中 |
| product_detect |
识别产品名中 |
| report/export |
输出中 |
| completed |
已完成 |
节点状态样式:
| 状态 |
展示 |
| pending |
灰色等待 |
| running |
高亮进行中 |
| retrying |
黄色重试中 |
| success |
绿色完成 |
| failed |
红色失败 |
| skipped |
灰色跳过 |
7.3 对话框结果展示
工作流完成后,AI 对话框新增助手消息,内容为 Markdown:
八、后台服务设计
8.1 WorkflowExecutor
负责批次级工作流编排。
| 方法 |
说明 |
| start(batch_id) |
启动后台任务 |
| run(batch_id) |
串行执行节点图 |
| run_node(node_code, context) |
执行单个节点 |
| emit_event(batch_id, event_type, payload) |
写入并推送事件 |
| complete(batch_id) |
完成批次 |
| fail(batch_id, error) |
标记批次失败 |
8.2 SkillRegistry
负责 Skill 注册与按需加载。
| 方法 |
说明 |
| register(name, skill_cls) |
注册 Skill |
| get(name) |
获取 Skill |
| run(name, context) |
执行 Skill |
8.3 PageCountService
负责具体文件页数统计。
| 方法 |
说明 |
| count_pdf(path) |
统计 PDF 页面数 |
| count_word(path) |
doc/docx 转 PDF 后统计页面数 |
| count_excel(path) |
统计工作表数量 |
| count_ppt(path) |
统计幻灯片数量 |
| count_with_retry(item, max_retry=3) |
单文件重试统计 |
8.4 ExportService
负责 Markdown 和 Excel 导出。
| 方法 |
说明 |
| build_markdown_report(batch) |
生成完整 Markdown 报告 |
| build_chat_summary(batch) |
生成对话简表 |
| build_excel(batch) |
生成 Excel 明细 |
| create_download_record(batch, path, type) |
创建下载记录 |
九、异常与重试设计
9.1 批次级失败
| 场景 |
处理 |
| 上传保存失败 |
批次不创建或标记失败 |
| 压缩包无法解压 |
批次失败,工作流终止 |
| 文件清单为空 |
批次失败,提示未检测到可处理文件 |
| 报告导出失败 |
批次失败或标记导出异常 |
9.2 文件级失败
| 场景 |
处理 |
| 单文件页数解析失败 |
最多重试 3 次 |
| 重试仍失败 |
statistics_status=failed,记录异常说明,继续处理其他文件 |
| 不支持类型 |
statistics_status=unsupported,不重试 |
| 加密或损坏文件 |
statistics_status=failed,记录“文件加密或损坏” |
十、安全设计
| 设计点 |
说明 |
| 对话隔离 |
所有批次查询和下载必须校验 conversation.user |
| 防串文件 |
工作流只能读取当前 batch 通过 FileSummaryBatchAttachment 绑定的 FileAttachment |
| 解压安全 |
禁止压缩包内路径跳出批次工作目录 |
| 文件执行安全 |
不执行上传文件中的脚本、宏或外部链接 |
| 下载权限 |
下载接口必须验证当前用户拥有批次所属对话 |
| 存储隔离 |
按 user_id/conversation_id/batch_id 建立存储目录 |
十一、验收设计
| 序号 |
验收项 |
验收标准 |
| 1 |
对话绑定 |
A 对话上传的文件不会出现在 B 对话的汇总结果中 |
| 2 |
压缩包处理 |
支持 zip、rar、7z 常见压缩包解压并保留目录结构 |
| 3 |
多文件处理 |
支持一次上传多个散装文件并生成同一批次结果 |
| 4 |
工作流卡片 |
前台能实时展示上传中、解压中、扫描中、解析中、输出中、完成状态 |
| 5 |
解析重试 |
单文件解析失败最多重试 3 次,失败后记录异常并继续 |
| 6 |
Markdown 展示 |
对话框能正确渲染 Markdown 表格和下载链接 |
| 7 |
导出下载 |
Markdown 报告和 Excel 明细可通过对话框链接下载 |
| 8 |
数据存档 |
数据库保留批次、上传文件、节点状态、文件明细、导出文件记录 |
| 9 |
标题更新 |
识别到产品名后,可将会话标题更新为“产品名-文件汇总” |
十二、待确认事项
| 序号 |
问题 |
当前建议 |
状态 |
| 1 |
是否接入真实 LangGraph 依赖 |
Demo 先按 LangGraph 节点图思想自实现轻量编排器 |
待确认 |
| 2 |
rar/7z 解压依赖 |
可选 py7zr、rarfile、系统 7z 命令 |
待技术验证 |
| 3 |
doc/docx 转 PDF 依赖 |
建议使用 LibreOffice headless |
待技术验证 |
| 4 |
用户手动命名对话时是否允许覆盖 |
建议不覆盖,仅写入产品名字段 |
待确认 |
| 5 |
后台任务是否需要取消能力 |
Demo 可不做,正式版建议支持取消 |
待确认 |
十三、实施建议
- 先补充数据模型和迁移,建立批次、文件明细、节点状态和导出文件表。
- 增加上传并启动工作流接口,确保文件和当前对话强绑定。
- 实现轻量 WorkflowExecutor 和 SkillRegistry,先完成 zip、pdf、xlsx、pptx 的主链路。
- 改造前端对话框,增加附件上传、工作流卡片和 Markdown 渲染。
- 补齐 doc/docx、rar、7z 等依赖能力,再完善异常重试和下载权限测试。