Files
ccdi/docs/design/2026-03-30-project-detail-risk-people-export-design.md

341 lines
9.2 KiB
Markdown
Raw 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.
# 项目详情风险总览人员列表导出设计文档
**模块**: 项目详情 - 结果总览 - 风险总览人员列表导出
**日期**: 2026-03-30
**作者**: Codex
**状态**: 已确认
## 一、背景
当前项目详情页 `结果总览 -> 风险总览` 中的人员列表已经支持分页展示与“查看项目”操作,但列表上方的“导出”按钮仍未接入真实导出能力。
结合现有页面语义与本次确认结果,本轮需求要求:
1.`开发风险总览` 的人员列表中补齐真实导出能力。
2. 导出范围为当前项目下的全部风险人员,而不是当前分页 5 条。
3. 导出字段口径必须与页面表格保持一致。
4. 导出文件中不包含“操作”列。
## 二、目标
本次设计目标如下:
1. 为风险总览人员列表新增独立导出接口。
2. 前端点击“导出”按钮后可直接下载 Excel 文件。
3. 导出字段与页面展示字段保持一致:
- 姓名
- 身份证号
- 所属部门
- 疑似违规数
- 风险等级
- 命中模型数
- 核心异常点
4. 分页展示与导出逻辑解耦,翻页不影响导出范围。
## 三、范围
### 3.1 本次范围
- 新增风险总览人员列表导出接口
- 新增风险总览人员导出 Excel 对象
- 为前端“导出”按钮绑定真实下载动作
- 补充本次设计文档,以及后续前后端实施计划入口
### 3.2 不在本次范围
- 不新增筛选条件、排序条件、搜索条件
- 不修改风险总览人员列表当前分页查询逻辑
- 不修改风险模型区、风险明细区功能
- 不修改人员详情、项目分析弹窗链路
- 不新增导出确认弹窗、二次筛选或降级方案
## 四、现状分析
### 4.1 前端现状
当前核心组件为:
- `ruoyi-ui/src/views/ccdiProject/components/detail/RiskPeopleSection.vue`
当前组件已经具备:
1. 表格字段展示
2. “查看项目”操作
3. 固定每页 5 条的分页能力
4. 顶部“导出”按钮文案
但当前“导出”按钮尚未绑定点击事件,也未接入下载接口。
### 4.2 后端现状
当前结果总览控制器为:
- `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiProjectOverviewController.java`
已具备以下相关能力:
1. `GET /ccdi/project/overview/risk-people`:分页查询风险人员总览
2. `POST /ccdi/project/overview/suspicious-transactions/export`:导出涉疑交易明细
3. `POST /ccdi/project/overview/risk-details/export`:统一导出风险明细
说明当前结果总览域内已经存在标准后端导出模式:
- 控制器暴露导出接口
- 服务层返回导出行对象列表
- 使用 `ExcelUtil` 输出 Excel 文件
风险人员列表本身已经有稳定的查询与字段组装逻辑:
1. 服务层通过 `getRiskPeopleOverview(CcdiProjectRiskPeopleQueryDTO queryDTO)` 查询分页数据
2. 使用 `buildRiskPeopleItem(projectId, aggregate)` 统一组装单行字段
因此,本次导出最合理的方式是复用现有字段组装逻辑,而不是重新设计一套独立口径。
## 五、方案对比
### 5.1 方案 A新增后端导出接口复用现有人员字段组装逻辑
做法:
- 新增 `POST /ccdi/project/overview/risk-people/export`
- 前端导出按钮直接调用下载接口
- 后端按当前项目查询全部风险人员
- 复用现有人员列表组装逻辑,再映射到 Excel 对象
优点:
- 最符合当前仓库导出模式
- 前端改动最小
- 页面字段与导出口径最容易保持一致
- 不会把分页展示逻辑和导出逻辑耦合在一起
缺点:
- 需要补一个导出 Excel 对象与对应测试
### 5.2 方案 B前端请求超大分页自行导出 Excel
做法:
- 点击导出时调用 `risk-people` 接口并传超大 `pageSize`
- 前端拿到全量数据后自行生成文件
问题:
- 不符合当前仓库常用导出模式
- 页面查询接口与导出职责混杂
- 前端文件生成链路与现有维护方式不一致
### 5.3 方案 C新增导出接口但单独写一套导出 SQL 和字段组装
做法:
- 后端新写独立导出查询
- 页面查询与导出查询分别维护
问题:
- 页面与导出会形成两套口径
- 后续字段扩展时最容易出现偏移
- 不符合最短路径要求
### 5.4 结论
采用 **方案 A新增后端导出接口复用现有人员字段组装逻辑**
## 六、总体设计
### 6.1 交互链路
点击“导出”后的数据流如下:
1. 用户在 `RiskPeopleSection.vue` 点击“导出”按钮。
2. 前端通过 `this.download(...)` 调用新的后端导出接口。
3. 前端仅传 `projectId`,不传当前页码、页大小等分页参数。
4. 控制器接收请求后调用 `overviewService.exportRiskPeopleOverview(projectId)`
5. 服务层校验项目存在后,查询当前项目下全部风险人员。
6. 服务层复用现有风险人员字段组装逻辑,生成 Excel 行对象列表。
7. 控制器使用 `ExcelUtil` 输出 `xlsx` 文件。
### 6.2 导出范围
导出范围固定为:
- 当前项目下的全部风险人员
说明:
- 不受当前分页影响
- 不只导出当前页 5 条
- 不增加额外筛选条件
### 6.3 导出字段
导出列固定如下:
1. 姓名
2. 身份证号
3. 所属部门
4. 疑似违规数
5. 风险等级
6. 命中模型数
7. 核心异常点
约束:
- 不导出“操作”列
- 不导出页面专用辅助字段,例如 `riskLevelType`
- 核心异常点展示口径需与页面一致
## 七、后端设计
### 7.1 控制器
`CcdiProjectOverviewController` 中新增导出接口:
- `POST /ccdi/project/overview/risk-people/export`
接口入参:
- `projectId`
权限控制沿用当前结果总览域的查询权限,不单独新增本轮设计范围外的权限体系。
### 7.2 服务层
`ICcdiProjectOverviewService` 与实现类中新增方法:
- `List<CcdiProjectRiskPeopleOverviewExcel> exportRiskPeopleOverview(Long projectId)`
服务层职责:
1. 校验项目存在
2. 查询当前项目全部风险人员
3. 复用现有人员列表字段组装逻辑
4. 将页面字段映射为导出对象
5. 返回 Excel 数据列表
### 7.3 查询策略
导出查询不复用当前分页接口返回值,也不走前端多页聚合。
建议实现方式:
1. 后端直接基于现有风险人员数据来源查询当前项目全部记录
2. 排序口径与分页列表保持一致:
- `risk_level_sort asc`
- `model_count desc`
- `rule_count desc`
- `staff_id_card asc`
这样可以保证页面与导出的记录顺序一致。
### 7.4 导出对象
新增导出对象:
- `CcdiProjectRiskPeopleOverviewExcel`
字段包含:
- `name`
- `idNo`
- `department`
- `riskCount`
- `riskLevel`
- `modelCount`
- `riskPoint`
其中:
- `riskPoint` 需要输出与页面“核心异常点”一致的文本口径
- 如果页面当前优先使用 `riskPointTagList` 组装展示,则导出时也应使用同样的归并顺序
## 八、前端设计
### 8.1 API 封装
`ruoyi-ui/src/api/ccdi/projectOverview.js` 中新增导出调用入口,供组件通过 `this.download(...)` 使用。
接口路径:
- `ccdi/project/overview/risk-people/export`
### 8.2 组件交互
`RiskPeopleSection.vue` 中:
1. 为当前“导出”按钮绑定点击事件
2. 点击后调用下载方法
3. 仅传 `projectId`
4. 文件名统一使用时间戳后缀
建议文件名:
- `风险人员总览_<timestamp>.xlsx`
### 8.3 交互约束
- 不新增确认弹窗
- 不新增 loading 外挂交互
- 不修改现有分页逻辑
- 不影响“查看项目”按钮行为
## 九、异常处理
本次导出错误处理遵循结果总览当前后端风格:
1. `projectId` 为空或项目不存在时,导出直接失败。
2. 查询异常或 Excel 生成异常时,导出整体失败。
3. 不生成空白文件作为兜底结果。
4. 不引入静默降级或兼容性补丁分支。
字段空值处理约束:
- 若部分字段为空,按现有页面语义导出为空字符串或统一文本结果
- 不因单行字段为空而跳过整行
## 十、测试口径
### 10.1 后端验证
需要验证:
1. 新增导出接口路径正确,且能委托到服务层
2. 导出服务会校验项目存在
3. 导出结果为当前项目全部风险人员,而不是当前页
4. 导出字段顺序与名称正确
5. 导出数据口径与页面表格一致
### 10.2 前端验证
需要验证:
1. “导出”按钮已绑定下载动作
2. 下载请求只传 `projectId`
3. 翻页功能仍正常
4. “查看项目”功能仍正常
## 十一、实施计划输出要求
根据仓库约定,进入实施阶段时默认同步输出两份实施计划:
1. 后端实施计划:`docs/plans/backend/`
2. 前端实施计划:`docs/plans/frontend/`
同时补充:
- 实施记录:`docs/reports/implementation/`
- 测试记录:`docs/tests/records/`
## 十二、结论
本次功能采用“后端新增导出接口 + 复用现有风险人员字段组装逻辑 + 前端按钮直连下载”的实现方式。
该方案满足以下要求:
1. 导出范围为当前项目全部风险人员
2. 导出字段与页面口径一致
3. 不引入额外筛选、补丁或兼容性分支
4. 改动路径短,符合当前仓库的导出实现风格