init
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
# 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
|
||||
```
|
||||
Reference in New Issue
Block a user