5.7 KiB
5.7 KiB
AI 文档模板生成系统 · 需求规格说明书
一、功能需求
1.1 模板管理
| 功能 | 描述 | 优先级 |
|---|---|---|
| 模板列表 | 卡片式展示所有模板,含名称、段落数、状态、最后编辑时间 | P0 |
| 新建模板 | 上传 .docx 文件,自动解析段落结构 | P0 |
| 模板编辑器(三栏) | 左栏段落列表、中栏文档预览、右栏段落配置 | P0 |
| 段落标注 | 配置每个段落的编辑方式、模型、提示词、参考文件 | P0 |
| 保存模板 | 将段落配置持久化到数据库 | P0 |
1.2 模型管理
| 功能 | 描述 | 优先级 |
|---|---|---|
| 模型列表 | 卡片式展示所有 AI 模型,含启用/禁用开关 | P0 |
| 添加/编辑模型 | 弹窗表单:名称、厂商、API 格式、地址、Key(加密存储) | P0 |
| 默认模型分配 | 设置文本/表格/图表各自的默认生成模型 | P0 |
1.3 执行生成
| 功能 | 描述 | 优先级 |
|---|---|---|
| 选择模板 | 下拉选择已保存的模板 | P0 |
| 上传参考文件 | 按段落需上传的文件类型提示并上传 | P0 |
| 开始生成 | 启动多段落并行 AI 生成 | P0 |
| 实时进度 | SSE 推送每个段落的生成状态 | P0 |
| 取消生成 | 中断正在进行的生成任务 | P1 |
1.4 生成记录
| 功能 | 描述 | 优先级 |
|---|---|---|
| 统计卡片 | 总次数、成功、失败、中断 | P0 |
| 历史列表 | 卡片式展示已生成文档 | P0 |
| 筛选 | 按模板、按状态筛选 | P1 |
| 预览 | 跳转到预览编辑页 | P0 |
| 下载 | 下载已生成的 Word 文档 | P0 |
1.5 预览编辑
| 功能 | 描述 | 优先级 |
|---|---|---|
| 富文本编辑 | 在线编辑文档内容 | P0 |
| AI 内容标注 | AI 生成的段落标紫色边框+模型来源 | P0 |
| 重新生成单段落 | 对某一段落单独重新请求 AI | P0 |
| 导出 Word | 保留原始模板样式 | P0 |
| 导出 PDF | 通过 LibreOffice 转换 | P1 |
二、段落解析规则
2.1 段落边界定义
段落以 Word 内置标题样式为边界:
Heading 1 → 一级段落(如 "一、经营指标")
Heading 2 → 二级段落(如 "1.1 营收分析")
Heading 3 → 三级段落
无标题样式 → 合并到上一个标题下的正文内容
表格 → 独立段落,归属于前一个标题
2.2 标题下的正文内容
标题与下一个标题之间的所有正文、表格、图片:
- 作为该段落的
content字段 - 供 AI 生成时作为上下文参考
- 导出时保留原样式
2.3 AI 返回格式约定
AI 输出必须是结构化 JSON:
{
"content": [
{"type": "text", "text": "正文内容..."},
{"type": "table", "headers": ["列1","列2"], "rows": [["a","b"],["c","d"]]},
{"type": "text", "text": "更多正文..."}
]
}
后端解析逻辑:
- type=text → 替换文档中对应段落的文本
- type=table → 在对应位置插入 Word 表格,表格样式参照该段落附近已有表格
2.4 正文内编号处理
AI 生成的 1、2、3 编号属于该段落的内部子结构,不拆分为新段落。导出时作为该段落的正文内容,应用该段落的样式。
三、导出策略
采用 基于原模板替换内容 策略:
- 解析时记录每个段落在原始 docx 中的段落索引 + xpath
- 导出时复制原始模板文件
- 遍历每个段落,找到对应位置替换内容:
- 纯文本:替换
<w:t>节点文本 - 表格:删除原有表格占位,插入新表格的 XML 节点
- 纯文本:替换
- 样式完全不修改(字体、字号、颜色、行距、段间距、页边距、页眉页脚、页码全部保留)
四、AI 并行生成设计
用户点击"开始生成"
│
▼
解析模板段落依赖关系(当前无依赖,全部并行)
│
▼
创建 asyncio.Task 池,Semaphore 控制并发数(默认 5)
│
├── 段落1 → AI 请求 → SSE 推送完成
├── 段落2 → AI 请求 → SSE 推送完成
├── 段落3 → AI 请求 → SSE 推送完成
├── 段落4 → AI 请求 → SSE 推送完成
└── 段落5 → AI 请求 → SSE 推送完成
│
▼
所有 Task 完成后,统一更新文档状态为 completed
│
▼
SSE 推送 "全部完成",前端跳转到预览编辑
五、数据结构
5.1 模板 (template)
id: int (PK)
name: str
description: str
file_path: str # 原始模板文件路径
paragraph_count: int
status: str # draft / ready
created_at: datetime
updated_at: datetime
5.2 段落 (paragraph)
id: int (PK)
template_id: int (FK)
sort_index: int
title: str # 段落标题
content: str # 正文内容(供 AI 参考)
style_json: json # 完整样式定义
is_table: bool
table_json: json # 表格结构
edit_mode: str # manual / ai
model_id: int (FK, nullable)
need_prompt: bool
prompt_text: str
need_file: bool
file_note: str
output_format: str # text / table / mixed / chart
created_at: datetime
updated_at: datetime
5.3 AI 模型 (ai_model)
id: int (PK)
name: str
provider: str
api_format: str # anthropic / openai
api_endpoint: str
api_key_encrypted: str
status: str # enabled / disabled
created_at: datetime
updated_at: datetime
5.4 生成文档 (document)
id: int (PK)
template_id: int (FK)
name: str
para_count_done: int
para_count_total: int
status: str # pending / generating / completed / failed / cancelled
file_path: str # 生成的文档路径
error: str
created_at: datetime
updated_at: datetime