# 报告中心-功能测试模块 · 计划执行文档

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

---

## 一、执行计划总览

### 阶段划分

| 阶段 | 内容 | 预估工时 | 产出物 |
|------|------|---------|--------|
| Phase 1 | 后端依赖安装 + 核心服务（6 个函数模块 + 业务服务 + ERP 服务） | 2 天 | `backend/app/services/functional/` 包 + 2 个服务文件 |
| Phase 2 | 后端 API 路由 + 配置 + 注册 | 1 天 | `backend/app/routers/functional_report.py` + config 修改 + main.py 修改 |
| Phase 3 | 前端页面 + API 封装 + 路由 | 1.5 天 | `FunctionalReport.vue` + `functionalReport.ts` + router 修改 |
| Phase 4 | ERP 配置管理 | 0.5 天 | 系统配置页面 ERP 配置项 |

### 参考工具路径

```
E:/GithubData/ubains-module-test/develop/AuxiliaryTool/FunctionalTestReportGeneration/src/
├── config.py               → 常量定义（Excel 列索引、枚举、ERP 配置）
├── excel_reader.py          → TestCase/Bug dataclass + 读取函数
├── data_analyzer.py         → 数据分析函数
├── data_extractor.py        → 信息提取函数
├── chart_generator.py       → matplotlib 图表生成
├── word_generator.py        → python-docx Word 报告生成
├── markdown_generator.py    → Markdown 报告生成
├── erp_uploader.py          → ERP 上传逻辑
└── cli.py                   → 主流程编排（6 步 pipeline）
```

---

## 二、Phase 1：后端核心服务

### 1.1 安装依赖

在 `backend/requirements.txt` 中新增：

```
python-docx>=1.0.0
mammoth>=1.8.0
Pillow>=10.0.0
matplotlib>=3.7.0
```

### 1.2 创建 `backend/app/services/functional/` 包

| 文件 | 说明 |
|------|------|
| `__init__.py` | 包初始化 |
| `excel_reader.py` | 复制参考工具，去除 CLI 依赖 |
| `data_analyzer.py` | 复制参考工具 |
| `data_extractor.py` | 复制参考工具 |
| `chart_generator.py` | 复制参考工具，调整 matplotlib 后端为 Agg |
| `word_generator.py` | 复制参考工具，去除模板路径依赖 |
| `markdown_generator.py` | 复制参考工具 |

### 1.3 创建 `backend/app/services/functional_report_service.py`

**核心服务类** `FunctionalReportService`，方法：

| 方法 | 说明 |
|------|------|
| `__init__(session_id, upload_dir)` | 初始化 session |
| `save_uploaded_file(file, file_type)` | 保存上传的 Excel 文件 |
| `analyze_data()` | 读取 Excel + 数据分析 |
| `generate_charts()` | 生成 4 张图表 |
| `generate_report(project_name, report_format)` | 生成 Word/Markdown 报告 |
| `get_report_info()` | 获取报告文件信息 |

### 1.4 创建 `backend/app/services/erp_service.py`

**ERP 服务类** `ErpService`，方法：

| 方法 | 说明 |
|------|------|
| `__init__(config)` | 初始化 ERP 配置 |
| `upload_report_to_erp(file_path, developtesting_id, ...)` | Word→HTML→图片上传→创建报告 |
| `upload_file_to_project(file_path, project_id, name)` | 上传项目资料 |
| `upload_file_to_cooperation(file_path, project_id, name, group_id)` | 上传协作文档 |
| `get_stuff_list()` | 获取 ERP 人员列表 |
| `match_names_to_ids(names, stuff_list)` | 姓名→ID 映射 |

---

## 三、Phase 2：后端 API 路由

### 2.1 创建 `backend/app/routers/functional_report.py`

| 接口 | 方法 | 请求体 | 响应 |
|------|------|--------|------|
| `POST /api/functional-report/upload` | `upload_files()` | `testcase_file: UploadFile, buglist_file: UploadFile` | `{session_id, files: {...}}` |
| `POST /api/functional-report/generate` | `generate_report()` | `{session_id, project_name, report_format: "docx"\|"md"\|"both"}` | `{report_id, files: {...}}` |
| `GET /api/functional-report/download/{report_id}` | `download_report()` | path param | `FileResponse` |
| `GET /api/functional-report/preview/{report_id}` | `preview_report()` | path param | Markdown 文本 |
| `POST /api/functional-report/upload-to-erp` | `upload_to_erp()` | `{session_id, report_type, developtesting_id?, copyuser_ids?}` | `{success, result}` |
| `GET /api/functional-report/config` | `get_config()` | — | `{erp_base_url, default_developtesting_id, ...}` |
| `PUT /api/functional-report/config` | `update_config()` | `{erp_api_key?, erp_base_url?, ...}` | `{success}` |

### 2.2 修改 `backend/app/config.py`

在 `Settings` 类中新增 ERP 配置：

```python
# ERP 配置
ERP_API_KEY: str = os.getenv("ERP_API_KEY", "9adc1ce611544fae9bbbc5f6b1d6ce87")
ERP_BASE_URL: str = os.getenv("ERP_BASE_URL", "https://office.ubainsyun.com:5082/api/uerp")
ERP_DEVELOPTESTING_ID: int = int(os.getenv("ERP_DEVELOPTESTING_ID", "397"))
ERP_TYPE_ID: int = int(os.getenv("ERP_TYPE_ID", "2"))
ERP_IMAGE_URL_PREFIX: str = os.getenv("ERP_IMAGE_URL_PREFIX", "https://office.ubainsyun.com:5015/")
```

### 2.3 修改 `backend/app/main.py`

注册新路由：

```python
from app.routers import functional_report

app.include_router(
    functional_report.router,
    prefix="/api/functional-report",
    tags=["功能测试报告"]
)
```

---

## 四、Phase 3：前端页面

### 3.1 创建 `frontend/src/api/functionalReport.ts`

API 封装：

```typescript
export const functionalReportApi = {
  upload(sessionId, testcaseFile, buglistFile): POST /api/functional-report/upload
  generate(params): POST /api/functional-report/generate
  downloadUrl(reportId): string
  preview(reportId): GET /api/functional-report/preview/{reportId}
  uploadToErp(params): POST /api/functional-report/upload-to-erp
  getConfig(): GET /api/functional-report/config
  updateConfig(config): PUT /api/functional-report/config
}
```

### 3.2 创建 `frontend/src/views/functional-report/FunctionalReport.vue`

页面布局：

```
┌──────────────────────────────────────────────────┐
│ [el-card] 步骤1: 上传 Excel 文件                  │
│  ┌──────────────────────────────────────────────┐│
│  │ [el-upload drag] 测试用例 Excel (.xlsx)      ││
│  │ [el-upload drag] BUG 列表 Excel (.xlsx)      ││
│  └──────────────────────────────────────────────┘│
├──────────────────────────────────────────────────┤
│ [el-card] 步骤2: 项目配置                        │
│  ┌──────────────────────────────────────────────┐│
│  │ 项目名称: [el-input]                         ││
│  │ 报告格式: [el-select] docx / md / both       ││
│  │ [el-button type=primary] 生成报告             ││
│  └──────────────────────────────────────────────┘│
├──────────────────────────────────────────────────┤
│ [el-card] 步骤3: 报告预览与下载                  │
│  ┌──────────────────────────────────────────────┐│
│  │ 报告列表: [el-table]                         ││
│  │ 操作: [下载] [预览] [上传ERP]                ││
│  └──────────────────────────────────────────────┘│
└──────────────────────────────────────────────────┘
```

### 3.3 修改 `frontend/src/router/index.ts`

新增路由：

```typescript
{
  path: '/reports/functional',
  name: 'FunctionalReport',
  component: () => import('@/views/functional-report/FunctionalReport.vue')
}
```

---

## 五、Phase 4：ERP 配置管理

### 5.1 系统配置页面

在 `Settings.vue` 中增加 ERP 配置区域：

- ERP API Key（密码输入框，带显示/隐藏切换）
- ERP 基础 URL（文本输入框）
- 默认测试单 ID（数字输入框）
- 报告类型 ID（数字输入框）
- 保存按钮

### 5.2 配置持久化

- 优先从环境变量读取
- 支持通过 API 动态更新（保存在内存中，重启后恢复为环境变量默认值）

---

## 六、验证方案

### 6.1 后端单元测试

| 测试项 | 方法 | 预期 |
|--------|------|------|
| Excel 读取 | 传入示例测试用例 Excel | 正确解析为 TestCase 列表 |
| Excel 读取 | 传入示例 BUG 列表 Excel | 正确解析为 Bug 列表 |
| 数据分析 | 传入解析后的数据 | 正确计算通过率/执行率等指标 |
| 图表生成 | 调用 chart_generator | 生成 4 张有效 PNG 图片 |
| Word 生成 | 调用 word_generator | 生成包含 10 章节的 .docx 文件 |
| Markdown 生成 | 调用 markdown_generator | 生成结构完整的 .md 文件 |
| ERP 上传 | mock ERP 接口 | 正确调用接口并返回结果 |

### 6.2 API 集成测试

| 测试项 | 步骤 | 预期 |
|--------|------|------|
| 文件上传 | curl POST /api/functional-report/upload | 返回 session_id |
| 报告生成 | curl POST /api/functional-report/generate | 返回报告文件路径 |
| 报告下载 | curl GET /api/functional-report/download/{id} | 返回文件流 |
| 报告预览 | curl GET /api/functional-report/preview/{id} | 返回 Markdown 文本 |

### 6.3 前端验证

| 测试项 | 步骤 | 预期 |
|--------|------|------|
| 页面加载 | 访问 /reports/functional | 页面正常显示 3 个步骤卡片 |
| 文件上传 | 拖拽上传测试用例 Excel | 文件显示在上传列表 |
| 报告生成 | 填写项目名称，点击生成报告 | 加载中状态，完成后显示报告列表 |
| 报告下载 | 点击下载按钮 | 浏览器下载报告文件 |
| 报告预览 | 点击预览按钮 | Markdown 报告渲染预览 |
| ERP 上传 | 点击上传 ERP | 成功提示或错误提示 |

---

## 七、文件变更清单

### 后端新增

| 文件 | 说明 |
|------|------|
| `backend/requirements.txt` | 新增依赖（修改） |
| `backend/app/services/functional/__init__.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` | ERP 上传服务 |
| `backend/app/routers/functional_report.py` | API 路由 |

### 后端修改

| 文件 | 修改内容 |
|------|---------|
| `backend/app/config.py` | 新增 ERP 配置项 |
| `backend/app/main.py` | 注册 functional_report 路由 |

### 前端新增

| 文件 | 说明 |
|------|------|
| `frontend/src/api/functionalReport.ts` | API 封装 |
| `frontend/src/views/functional-report/FunctionalReport.vue` | 页面组件 |

### 前端修改

| 文件 | 修改内容 |
|------|---------|
| `frontend/src/router/index.ts` | 新增 `/reports/functional` 路由 |

---

## 八、实施顺序

```
Phase 1: 依赖安装 → 创建 functional 包 → 移植 6 个模块 → 创建核心服务 → 创建 ERP 服务
     ↓
Phase 2: 创建 API 路由 → 修改 config → 注册到 main.py
     ↓
Phase 3: 创建 API 封装 → 创建页面 → 注册路由
     ↓
Phase 4: 系统配置页增加 ERP 配置
```