# 功能测试报告模板优化 · 需求文档（PRD）

> **文档状态**：已定稿 · **版本**：v1.0 · **最后更新**：2026-08-17
> **维护者**：czj · **所属模块**：报告中心-功能测试
> **对应计划执行**：`_PRD_功能测试报告模板优化_计划执行.md`

---

## 1. 背景与目标

### 1.1 背景

功能测试报告模块已于 2026-08-13 完成模板配置功能（多模板管理：章节开关、Word 样式、图表样式、报告默认值）。在代码审查中发现以下问题：

| 问题 | 严重性 | 说明 |
|------|--------|------|
| **章节编号硬编码** | 🔴 P0 | `word_generator.py` 中 10 个章节标题编号（一、二、三…十）为硬编码字符串；`markdown_generator.py` 的 `_title()` 中中文数字同样硬编码。**当用户关闭前置章节后，后续章节编号错误**（如关闭"报告基本信息"后，下一章仍显示"二、测试执行摘要"，实际应为"一、"） |
| **子章节编号硬编码** | 🔴 P0 | 子章节（如 `1.1 报告标识`、`2.1 测试结果统计`）的前缀数字硬编码，与主章节编号脱节，关闭章节后同样错乱 |
| **模板无描述** | 🟡 P1 | 模板列表只显示名称，多模板（5+）时难以区分用途 |
| **模板无法复制** | 🟡 P1 | 基于现有模板创建变体需手动新建再逐一配置，效率低 |

### 1.2 目标

1. **P0 章节编号动态化**：Word 与 Markdown 报告的主章节、子章节编号均随启用章节动态生成，关闭任意章节后编号连续正确
2. **P1 模板描述字段**：模板支持可选描述（≤200 字），列表与表单均可维护
3. **P1 模板复制功能**：一键复制现有模板为新模板（名称自动加"副本"后缀），配置完整继承

### 1.3 参考文件

| 文件 | 说明 |
|------|------|
| `backend/app/services/functional/word_generator.py` | Word 报告生成器（编号硬编码，需改造） |
| `backend/app/services/functional/markdown_generator.py` | Markdown 报告生成器（编号部分动态，需改造） |
| `backend/app/models/report_template.py` | 模板 ORM 模型（需新增 description 字段） |
| `backend/app/schemas/report_template.py` | 模板 Pydantic 模型（需新增 description） |
| `backend/app/routers/report_template.py` | 模板 API 路由（需新增复制端点） |
| `frontend/src/views/functional-report/TemplateConfig.vue` | 模板配置页面（需新增描述输入与复制按钮） |
| `frontend/src/api/reportTemplate.ts` | 模板 API 封装（需新增 description 与 duplicate） |

---

## 2. 功能需求

### 2.1 功能清单

| 编号 | 功能 | 说明 | 优先级 |
|------|------|------|--------|
| T1 | 主章节编号动态化 | Word/Markdown 主章节编号（一、二…十）按启用顺序动态生成 | **P0** |
| T2 | 子章节编号动态化 | 子章节前缀数字（`{ch_idx}.1`）与主章节编号联动 | **P0** |
| T3 | 模板描述字段 | 模板新增 `description` 可选字段（≤200 字），列表副标题展示 | **P1** |
| T4 | 模板复制功能 | 后端新增复制端点 + 前端"复制"按钮 | **P1** |
| T5 | 向后兼容 | 开启全部章节时，报告编号与现状完全一致；已有模板数据处理兼容 | P0 |

### 2.2 功能详细说明

#### T1. 主章节编号动态化

**现状**：
- `word_generator.py`：`_add_title_local("一、报告基本信息", level=2)` 硬编码，虽有 `ch_idx` 计数器但未使用
- `markdown_generator.py`：`_title(ch_idx, "一", "报告基本信息")` 中第一个参数 `ch_idx` 已动态，但中文数字 `"一"` 硬编码

**改造**：
- 两文件中新增 `_zh_num(n)` 工具函数：整数 → 中文数字（1→一、2→二…10→十），>10 回退为阿拉伯数字
- 主章节标题统一为 `_add_title_local(f"{_zh_num(ch_idx)}、报告基本信息")` / `_title(ch_idx, _zh_num(ch_idx), "报告基本信息")`

**结果**：关闭"报告基本信息"后，"测试执行摘要"自动变为"一、测试执行摘要"。

#### T2. 子章节编号动态化

**现状**：子章节标题硬编码为 `1.1 报告标识`、`2.1 测试结果统计`…与主章节编号脱节。

**改造**：子章节标题改为 `f"{ch_idx}.1 {子章节名}"`，其中 `ch_idx` 为当前主章节序号（注意：需在 `ch_idx += 1` 之后取值）。

**结果**：关闭章节后主章节编号变化，子章节前缀自动跟随（如原"四、测试用例执行详情"变为"三、"后，其子章节 4.1→3.1、4.2→3.2、4.3→3.3）。

#### T3. 模板描述字段

**后端**：
- `models/report_template.py`：新增 `description: Mapped[str] = mapped_column(String(200), nullable=True, default="")`，`to_dict()` / `to_list_item()` 增加 `description`
- `schemas/report_template.py`：Create / Update / ListItem / Response 增加 `description: Optional[str]`
- 路由 create/update 处理 `description`

**前端**：
- `reportTemplate.ts`：接口类型增加 `description`
- `TemplateConfig.vue`：列表中显示描述副标题（截断省略），表单基本信息区新增"模板描述"输入框（`el-input type="textarea"`，maxlength=200）

**数据库迁移**：`report_templates` 表为 SQLite/MySQL 通用，需新增一列。提供迁移 SQL / 启动时自动校验（`ALTER TABLE ... ADD COLUMN`，幂等）。

#### T4. 模板复制功能

**后端**：新增端点 `POST /templates/{template_id}/duplicate`
- 逻辑：读取原模板 config + description → 新建模板，name = `原名称_副本`（若已存在同名追加序号），is_default=False，config 深拷贝
- 返回：新模板完整信息

**前端**：
- `reportTemplate.ts`：新增 `duplicate(id)` 方法
- `TemplateConfig.vue`：模板列表操作区新增"复制"按钮（CopyDocument 图标），点击后调接口，成功后刷新列表并选中新模板

#### T5. 向后兼容

- 全部章节开启时，动态生成的编号与现状完全一致（一、二…十 / 1.1、2.1…）
- 已有模板 config 无 `description` 字段：读取时默认 `""`，不报错
- 数据库新增列采用幂等 ALTER，已存在列不重复添加

---

## 3. 非功能需求

| 项 | 说明 |
|----|------|
| 性能 | 编号动态化仅影响标题字符串生成，无额外 IO |
| 兼容 | Word/Markdown 两种格式同步改造，行为一致 |
| 回归 | 全章节开启报告与改造前输出一致（仅编号生成方式变化，内容不变） |
| 数据库 | 迁移幂等，SQLite/MySQL 均适用 |

---

## 4. 验收标准

| # | 验收点 | 预期结果 |
|---|--------|----------|
| 1 | 全章节开启生成报告 | 主章节编号一~十、子章节 1.1/2.1…10.4 与改造前一致 |
| 2 | 关闭"报告基本信息"生成报告 | 原"二、测试执行摘要"显示为"一、"，其子章节 2.1→1.1、2.2→1.2、2.3→1.3 |
| 3 | 关闭中间任意章节（如"图表分析"） | 后续章节编号自动前移，无跳号/重号 |
| 4 | Word 与 Markdown 编号行为一致 | 同一模板配置下两种格式章节编号相同 |
| 5 | 创建模板带描述 | 列表展示描述，编辑可修改，保存后持久化 |
| 6 | 复制模板 | 新模板名称带"副本"，config/description 完整继承，不改变原模板 |
| 7 | 旧模板兼容 | 无 description 的旧模板读取正常，列表 description 显示为空 |

---

## 5. 潜在风险与回退

| 风险 | 概率 | 应对 |
|------|------|------|
| 数据库 ALTER 在 MySQL 上失败 | 低 | 仅 ADD COLUMN 单列，幂等检查 | 
| 子章节前缀遗漏遗漏某些硬编码处 | 低 | 逐处 grep 核对（`^\d+\.` 模式） |
| 编号改造引入内容变化 | 低 | 全章节开启时与旧输出逐条比对 |

回退方案：`git checkout -- backend/app/services/functional/word_generator.py backend/app/services/functional/markdown_generator.py backend/app/models/report_template.py backend/app/schemas/report_template.py backend/app/routers/report_template.py`

---

## 6. 后续优化（本次不做，列入 backlog）

| 编号 | 说明 | 优先级 |
|------|------|--------|
| T6 | Word 字体下拉选择器（宋体/微软雅黑/黑体等常见字体） | P2 |
| T7 | 一键恢复系统默认配置按钮 | P2 |
| T8 | 图表颜色标签与 BUG 等级对齐（BUG-严重→1级-致命 等） | P2 |
| T9 | 模板配置导出/导入（跨环境迁移） | P2 |
| T10 | 生成报告页模板下拉显示章节摘要 | P3 |

---

*本 PRD 由 Claude Code 编写，供 prd-plan / prd-code 流程使用。*