doc-forge-remark/docs/需求与设计/01-需求规格说明书.md

183 lines
5.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
```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 编号属于该段落的内部子结构,不拆分为新段落。导出时作为该段落的正文内容,应用该段落的样式。
## 三、导出策略
采用 **基于原模板替换内容** 策略:
1. 解析时记录每个段落在原始 docx 中的段落索引 + xpath
2. 导出时复制原始模板文件
3. 遍历每个段落,找到对应位置替换内容:
- 纯文本:替换 `<w:t>` 节点文本
- 表格:删除原有表格占位,插入新表格的 XML 节点
4. 样式完全不修改(字体、字号、颜色、行距、段间距、页边距、页眉页脚、页码全部保留)
## 四、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
```