# HANDOFF — 功能测试报告模块会话交接文档

> **生成时间**: 2026-08-13
> **当前分支**: `platform-auto-test`
> **最近提交**: `f3f5d771` feat(frontend): 菜单重构为自动化测试父菜单，性能/功能报告独立，修复性能任务编辑详情加载
> **状态**: ✅ 功能测试报告模块全部完成（后端服务 + API + 前端页面 + ERP 上传 + ERP 配置持久化）

---

## ⚠️ 多窗口并行开发注意（功能测试报告窗口）

本窗口是**功能测试报告模块开发**，与可能的其他窗口并行开发。**必须遵守** `Docs/多窗口并行开发指南.md`：

| 项目 | 本窗口（功能测试报告） | 其他窗口 |
|------|----------------------|----------|
| 后端端口 | 8001（或 8002） | 视情况 |
| 前端端口 | 3000（或 3001） | 视情况 |
| 开发模块 | 功能测试报告 | 其他模块 |
| Git 提交 | 提交前先 `git pull` | 提交后 push |
| 数据库 | 错开写入时间 | 错开写入时间 |

---

## 一、本次任务（已完成）

### 任务：报告中心-功能测试报告模块（含 ERP 配置管理）

**参考工具**：`E:\GithubData\ubains-module-test\develop\AuxiliaryTool\FunctionalTestReportGeneration\`

**核心能力**：
1. ✅ 上传测试用例 Excel（表头第 3 行，数据第 4 行起，17 列）+ BUG 列表 Excel（表头第 1 行，数据第 2 行起，9 列）
2. ✅ 自动数据分析（用例通过率/执行率/模块分布、BUG 等级/状态/类型分布、遗留 BUG、用例-BUG 关联）
3. ✅ 生成 4 张统计图表（BUG 等级饼图、测试结果饼图、通过率柱状图、各模块 BUG 堆叠柱状图）
4. ✅ 生成 Word 报告（10 章节）和/或 Markdown 报告
5. ✅ 报告下载 + Markdown 在线预览
6. ✅ 上传报告到 ERP 系统（测试单报告 + 项目资料 + 协作文档）

### 参考工具 bug 修复记录

| # | 问题 | 根因 | 修复 |
|---|------|------|------|
| 1 | `generate_bug_by_module_chart` 报错 | `module_distribution` 是扁平 `Dict[str, int]`，但被当作嵌套 `Dict[str, Dict]` 使用 | 新增 `module_level_distribution: Dict[str, Dict[str, int]]` 字段，在 `analyze_bugs` 中填充 |
| 2 | 未执行用例数翻倍 | `unexecuted = unverified_cases + unverified_cases`（重复加自己） | 改为 `unverified_cases + undeveloped_cases` |
| 3 | `generate_all_charts` 无输出目录参数 | 原函数无 `charts_dir` 参数，无法指定输出路径 | 签名改为 `generate_all_charts(case_analysis, bug_analysis, charts_dir)` |
| 4 | 模块级 `ensure_directories()` 副作用 | 在 `config.py` 模块加载时自动创建目录 | 移除该调用，目录创建由服务类管理 |

---

## 二、已完成事项清单

### 2.1 后端新增文件

| 文件 | 说明 |
|------|------|
| `backend/app/services/functional/__init__.py` | 包初始化，导出所有子模块 |
| `backend/app/services/functional/config.py` | 常量配置：列索引、测试结果枚举、BUG 等级/状态、图表配置、ERP 配置、报告文件名/编号生成器 |
| `backend/app/services/functional/excel_reader.py` | Excel 读取：`TestCase`/`Bug` dataclass、`read_test_cases`(行4起)、`read_bug_list`(行2起)、结果/等级/状态归一化 |
| `backend/app/services/functional/data_analyzer.py` | 数据分析：`TestCaseAnalysis`/`BugAnalysis`/`ModuleStats` dataclass、`analyze_test_cases`、`analyze_bugs`、`link_bugs_to_cases` |
| `backend/app/services/functional/data_extractor.py` | 数据提取：IP地址、关键词、版本信息、测试人员、服务器信息、部署环境、测试负责人 |
| `backend/app/services/functional/chart_generator.py` | 图表生成：4 张图（BUG 等级饼图、测试结果饼图、通过率柱状图、各模块 BUG 堆叠柱状图）、中文字体兼容（Windows/Linux/macOS） |
| `backend/app/services/functional/word_generator.py` | Word 报告生成：10 章节完整报告（python-docx），含表格、图表嵌入 |
| `backend/app/services/functional/markdown_generator.py` | Markdown 报告生成：10 章节完整报告，含表格、图表引用 |
| `backend/app/services/functional_report_service.py` | 核心服务类：上传文件保存、数据分析和报告生成编排、会话管理 |
| `backend/app/services/erp_service.py` | ERP 上传服务：人员列表查询、姓名-ID 匹配、图片上传、报告创建（Word→HTML→图片→创建报告）、项目资料上传、协作文档上传 |
| `backend/app/schemas/functional_report.py` | Pydantic 数据模型：UploadResponse、GenerateRequest/Response、DownloadResponse、UploadToErpRequest/Response、ErpConfigResponse、ErpConfigUpdateRequest、ReportInfoResponse |
| `backend/app/routers/functional_report.py` | API 路由：7 个端点（upload/generate/download/preview/info/upload-to-erp/config） |

### 2.2 后端修改文件

| 文件 | 修改内容 |
|------|---------|
| `backend/app/config.py` | 新增 5 个 ERP 配置项：`ERP_API_KEY`、`ERP_BASE_URL`、`ERP_DEVELOPTESTING_ID`、`ERP_TYPE_ID`、`ERP_IMAGE_URL_PREFIX` |
| `backend/app/main.py` | 导入并注册 `functional_report.router`，前缀 `/api/functional-report` |
| `backend/requirements.txt` | 新增 4 个依赖：`python-docx`、`mammoth`、`Pillow`、`matplotlib` |

### 2.3 前端新增文件

| 文件 | 说明 |
|------|------|
| `frontend/src/api/functionalReport.ts` | API 封装：7 个方法（upload/generate/info/downloadUrl/previewUrl/uploadToErp/getErpConfig/updateErpConfig） |
| `frontend/src/views/functional-report/FunctionalReport.vue` | 完整页面：步骤 1 上传 Excel（拖拽双文件）、步骤 2 生成报告（项目名/格式选择）、分析摘要（7 指标）、图表预览（2×2 网格）、报告下载/预览/ERP 上传 |

### 2.4 前端修改文件

| 文件 | 修改内容 |
|------|---------|
| `frontend/src/router/index.ts` | 新增 `/reports/functional` 独立路由，指向 `FunctionalReport.vue`（在 catch-all `/reports/:type?` 之前） |

### 2.5 文档

| 文件 | 说明 |
|------|------|
| `Docs/PRD/需求文档/报告中心/_PRD_功能测试报告模块.md` | 需求文档 |
| `Docs/PRD/需求文档/报告中心/_PRD_功能测试报告模块_计划执行.md` | 计划执行文档 |

---

## 三、API 参考

### 端点一览

```
POST   /api/functional-report/upload       → 上传测试用例 Excel + BUG 列表 Excel
POST   /api/functional-report/generate     → 基于已上传文件生成报告
GET    /api/functional-report/download/{session_id}  → 下载报告文件
GET    /api/functional-report/preview/{session_id}   → 预览 Markdown 报告（HTML）
GET    /api/functional-report/info/{session_id}      → 获取会话报告信息
POST   /api/functional-report/upload-to-erp          → 上传报告到 ERP
GET    /api/functional-report/config       → 获取 ERP 配置（DB 优先，回退环境变量）
PUT    /api/functional-report/config       → 更新 ERP 配置（持久化到数据库）
```

### 上传接口

```http
POST /api/functional-report/upload
Content-Type: multipart/form-data

testcase_file: <测试用例 Excel>
buglist_file: <BUG 列表 Excel>
session_id:   <可选，已有会话 ID>
```

响应：`{ session_id, testcase_path, buglist_path, message }`

### 生成接口

```http
POST /api/functional-report/generate
Content-Type: application/json

{
  "session_id": "xxx",
  "project_name": "项目名称",
  "report_format": "docx"  // docx | md | both
}
```

响应：`{ session_id, project_name, case_analysis, bug_analysis, case_bug_link_count, charts, reports }`

### ERP 上传接口

```http
POST /api/functional-report/upload-to-erp
Content-Type: application/json

{
  "session_id": "xxx",
  "report_filename": "项目名称_功能测试报告_2026年08月12日.docx",
  "developtesting_id": 397,
  "copyuser_names": ["张三", "李四"],
  "createuser_name": "王五"
}
```

响应：`{ success: true, report_id: 123, message: "..." }`

---

## 四、架构与数据流

### 目录结构

```
backend/app/services/functional/          # 核心功能模块（6 个文件，从参考工具移植）
backend/app/services/functional_report_service.py  # 服务编排层
backend/app/services/erp_service.py                # ERP 上传服务
backend/app/routers/functional_report.py           # API 路由层
backend/app/schemas/functional_report.py           # 数据模型
```

### 数据流

```
用户上传 Excel → 后端保存到 data/functional_report/{session_id}/
  → excel_reader 解析 Excel → TestCase[] / Bug[] dataclass
  → data_analyzer 分析 → TestCaseAnalysis / BugAnalysis
  → chart_generator 生成图表 → charts/ 目录（4 张 PNG）
  → word_generator / markdown_generator 生成报告 → reports/ 目录
  → 用户下载/预览
  → 用户触发 ERP 上传 → erp_service:
      Word → HTML(mammoth) → 逐张图片上传 ERP → 创建测试报告
      (可选) 上传项目资料 / 协作文档
```

### ERP 上传流程

```
erp_service.upload_report_to_erp(file_path, ...):
  1. GET /openclaw/stuff → 获取人员列表（含 ID）
  2. match_names_to_ids() → 抄送人姓名→ID 映射
  3. word_to_html_with_images():
     - mammoth 将 docx 转为 HTML
     - 提取图片 → POST /openclaw/upload/richtext → 替换为 ERP URL
  4. POST /openclaw/report → 创建测试报告

erp_service.upload_file_to_project(file_path, project_id, name):
  - POST /openclaw/upload/project → 上传项目资料

erp_service.upload_file_to_cooperation(file_path, project_id, name, group_id):
  - POST /openclaw/upload/cooperation → 上传协作文档
```

### 报告 10 章节结构

| 章节 | 编号 | 内容 |
|------|------|------|
| 测试概述 | 一 | 项目名称、测试目的、测试范围、参考文档 |
| 测试环境与资源 | 二 | 服务器信息、部署环境、测试人员、IP 地址、版本信息 |
| 测试执行情况 | 三 | 测试用例统计表、通过/失败/未执行分布 |
| 测试结果详细分析 | 四 | 各模块执行情况明细表 |
| 遗留 BUG 分析 | 五 | 遗留 BUG 统计（按等级/模块）、表格列出每个遗留 BUG |
| 关闭 BUG 分析 | 六 | 已关闭 BUG 统计表格 |
| 用例-BUG 关联分析 | 七 | 关联数量统计 |
| 测试结论与建议 | 八 | 通过率/执行率、评估结论、建议 |
| 测试统计图表 | 九 | 4 张图表插入 |
| 附录 | 十 | 测试用例清单、测试环境截图索引、参考资料 |

---

## 五、ERP 配置

ERP 配置通过环境变量管理，默认值在 `backend/app/config.py` 的 `Settings` 类中：

| 配置项 | 环境变量 | 默认值 |
|-------|---------|-------|
| ERP_API_KEY | `ERP_API_KEY` | `9adc1ce611544fae9bbbc5f6b1d6ce87` |
| ERP_BASE_URL | `ERP_BASE_URL` | `https://office.ubainsyun.com:5082/api/uerp` |
| ERP_DEVELOPTESTING_ID | `ERP_DEVELOPTESTING_ID` | `397` |
| ERP_TYPE_ID | `ERP_TYPE_ID` | `2` |
| ERP_IMAGE_URL_PREFIX | `ERP_IMAGE_URL_PREFIX` | `https://office.ubainsyun.com:5015/` |

ERP 请求参数：超时 30s，最多重试 3 次（间隔 5s），4xx 错误不重试。

### ERP 配置持久化（v2 — 2026-08-13 新增）

| 内容 | 说明 |
|------|------|
| 数据库模型 | `backend/app/models/erp_config.py` — 单行表 `erp_configs`（id=1），5 个配置字段 |
| 配置端点改造 | `GET /config` 优先读 DB，DB 空字段回退到环境变量；`PUT /config` upsert 到 DB |
| 前端配置页面 | `ErpConfig.vue` — 5 字段表单（API Key 密码框/Base URL/测试单 ID/Type ID/图片 URL 前缀），加载自动填充默认值 |
| 路由改造 | 功能测试报告改为父菜单（`/reports/functional`），含 `generate`（生成报告）和 `erp-config`（ERP 配置）两个子页面 |
| 持久化验证 | ✅ 写入 DB 后重启后端，GET 仍返回已保存值 |

---

## 六、当前数据状态

| 内容 | 状态 | 备注 |
|------|------|------|
| 后端功能模块 | ✅ 6 个文件 | 从参考工具移植，修复 2 个 bug |
| 后端服务类 | ✅ 2 个 | FunctionalReportService + ErpService |
| 后端 API 路由 | ✅ 7 个端点 | 全部注册到 main.py |
| 后端 ERP 配置模型 | ✅ 新增 | `ErpConfig`（erp_configs 表），config 端点持久化到 DB |
| 前端 API 封装 | ✅ 8 个方法 | 在 functionalReport.ts 中 |
| 前端页面 | ✅ 完成 | FunctionalReport.vue（生成报告）+ ErpConfig.vue（ERP 配置） |
| 前端路由 | ✅ 改造 | `/reports/functional` 父路由 + 2 个子路由（generate/erp-config） |
| 前端菜单 | ✅ 改造 | 功能测试报告改为父菜单，含"生成报告"/"ERP 配置"子项 |
| 前端构建 | ✅ 通过 | vue-tsc 类型检查 + Vite 构建均通过 |
| 后端导入 | ✅ 通过 | 所有模块可正常 import |

---

## 七、下次会话建议

### 待办（按优先级）

| 优先级 | 待办 | 说明 |
|--------|------|------|
| **P0** | 后端启动验证 | 启动后端服务，用示例 Excel 测试完整流程（上传→生成→下载） |
| **P0** | 前端联调验证 | 启动前端服务，访问 `/reports/functional`，确认上传/生成/下载/预览正常，ERP 配置页加载/保存正常 |
| **P1** | 系统设置页 ERP 配置 | 在 Settings.vue 中增加 ERP 配置项（API Key/URL/默认测试单 ID） |
| **P2** | 前端页面加载状态细化 | 上传/生成过程中的 loading 状态、进度提示等 |
| **P2** | 报告历史管理 | 支持查看历史报告列表、删除、重新生成 |
| **P3** | 批量生成 | 支持多项目批量生成报告 |

### 踩坑记录

| # | 现象 | 根因 | 正确做法 |
|---|------|------|---------|
| F1 | 图表生成中文乱码 | matplotlib 缺少中文字体配置 | `_setup_chinese_font()` 自动检测 Windows/Linux/macOS 字体路径 |
| F2 | ERP 图片上传失败 | 图片 URL 前缀未正确拼接 | `image_url_prefix` 确保末尾有 `/`，拼接时不重复 |
| F3 | mammoth 转换 Word 图片丢失 | 图片提取为 base64 未替换为 ERP URL | `word_to_html_with_images` 中逐张上传并替换 src |
| F4 | 路由 `/reports/functional` 被 `:type?` 捕获 | Vue Router 静态路由写在动态路由之后 | 将 `/reports/functional` 放在 `/reports/:type?` 之前 |
| F5 | 前端 `baseURL` 双重前缀 404 | axios baseURL 设为 `/api` 后路径又写 `/api/...` | baseURL 留空，路径写完整 `/api/...` |
| F6 | `updateErpConfig`/`getErpConfig` 导入报 TS 错误 | `functionalReport.ts` 导出的是对象 `functionalReportApi`，非命名导出 | 用 `functionalReportApi.getErpConfig()` 调用 |
| F7 | PUT config 后 api_key 返回空字符串 | DB 记录只更新了非空字段，空字段未回退环境变量 | GET/PUT 返回时空字段一律回退到 `settings` 默认值 |

---

## 八、启动与验证

```bash
# 后端
cd backend
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8001

# 前端
cd frontend
npm run dev

# 访问
# 前端: http://localhost:3000/reports/functional/generate（生成报告）
# 前端: http://localhost:3000/reports/functional/erp-config（ERP 配置）
# API 文档: http://localhost:8001/docs（搜 functional-report 标签）
# 健康检查: http://localhost:8001/health

# 测试用示例 Excel 文件
# 参考工具目录: E:\GithubData\ubains-module-test\develop\AuxiliaryTool\FunctionalTestReportGeneration\
# 示例文件: data/input/用例模板.xlsx, data/input/BUG列表模板.xlsx
```

---

## 九、文件完整清单

### 后端新增（15 个文件）

```
backend/app/services/functional/__init__.py
backend/app/services/functional/config.py
backend/app/services/functional/excel_reader.py
backend/app/services/functional/data_analyzer.py
backend/app/services/functional/data_extractor.py
backend/app/services/functional/chart_generator.py
backend/app/services/functional/word_generator.py
backend/app/services/functional/markdown_generator.py
backend/app/services/functional_report_service.py
backend/app/services/erp_service.py
backend/app/schemas/functional_report.py
backend/app/routers/functional_report.py
backend/app/models/erp_config.py           — ERP 配置数据库模型
```

### 后端修改（4 个文件）

```
backend/app/config.py           — 新增 ERP 配置项
backend/app/main.py             — 注册 functional_report 路由
backend/requirements.txt        — 新增 python-docx/mammoth/Pillow/matplotlib
backend/app/models/__init__.py  — 注册 ErpConfig 模型
```

### 前端新增（4 个文件）

```
frontend/src/api/functionalReport.ts
frontend/src/views/functional-report/FunctionalReport.vue
frontend/src/views/functional-report/index.vue    — 父容器组件
frontend/src/views/functional-report/ErpConfig.vue — ERP 配置页面
```

### 前端修改（2 个文件）

```
frontend/src/router/index.ts    — 改为父路由 + 子路由结构
frontend/src/App.vue            — 菜单改为 el-sub-menu 子菜单结构
```

### 文档（2 个文件）

```
Docs/PRD/需求文档/报告中心/_PRD_功能测试报告模块.md
Docs/PRD/需求文档/报告中心/_PRD_功能测试报告模块_计划执行.md
```

---

*本文档由功能测试报告开发窗口生成，供下一次会话快速恢复上下文。其他窗口的交接见 `HANDOFF.md`（主文档）、`HANDOFF_安全测试.md`、`HANDOFF_设备模拟.md` 等。*