10 KiB
项目详情风险总览员工列表分页设计文档
模块: 项目详情 - 结果总览 - 风险总览员工列表 日期: 2026-03-29
一、背景
当前项目详情页 结果总览 -> 风险总览 中的员工列表直接消费 GET /ccdi/project/overview/risk-people 返回的全量 overviewList。页面没有分页能力,项目内风险员工较多时会导致:
- 单屏信息过长,浏览成本高。
- 前端一次性渲染全量列表,交互体验不稳定。
- 接口返回风格与当前结果总览域内其他分页接口不一致。
本轮需求要求为该员工列表增加分页,并固定为每页 5 条。同时,需求明确要求改造现有接口,不采用前端本地切片或新增补丁接口的方式。
二、目标
本次设计目标如下:
- 将
GET /ccdi/project/overview/risk-people改造成真实分页接口。 - 风险总览员工列表固定每页展示 5 条。
- 前端翻页时仅刷新员工列表,不影响结果总览内其他区块。
- 分页接口返回结构对齐项目现有分页风格,统一为
rows + total + pageNum + pageSize。
三、范围
3.1 本次范围
- 改造
risk-people接口入参与返回结构 - 为后端风险人员查询增加数据库分页
- 调整项目详情结果总览首屏数据装配
- 在
RiskPeopleSection.vue增加分页条与翻页请求 - 补充本次设计文档、设计记录,以及后续前后端实施计划入口
3.2 不在本次范围
- 不修改风险仪表盘接口
- 不修改风险模型卡片与模型命中人员查询
- 不修改风险明细区块
- 不新增筛选条件、搜索条件或排序条件
- 不修改风险等级、命中模型数、核心异常点的业务口径
- 不删除现有
GET /ccdi/project/overview/top-risk-people
四、现状分析
4.1 前端现状
当前 PreliminaryCheck.vue 在页面加载时并发请求:
GET /ccdi/project/overview/dashboardGET /ccdi/project/overview/risk-peopleGET /ccdi/project/overview/risk-models/cardsGET /ccdi/project/overview/suspicious-transactionsGET /ccdi/project/overview/employee-credit-negative
其中 risk-people 的返回结果被直接注入 currentData.riskPeople.overviewList,RiskPeopleSection.vue 直接用该数组渲染表格,没有分页状态,也没有独立二次加载链路。
4.2 后端现状
当前 CcdiProjectOverviewController.getRiskPeople(Long projectId) 只接收项目 ID。
CcdiProjectOverviewServiceImpl.getRiskPeopleOverview(Long projectId) 的实现为:
- 校验项目存在
- 调用
overviewMapper.selectRiskPeopleOverviewByProjectId(projectId)查询全量员工结果 - 在 Java 层逐行映射为
overviewList - 返回
CcdiProjectRiskPeopleOverviewVO { overviewList }
当前 SQL 直接从 ccdi_project_overview_employee_result 查询并排序:
risk_level_sort ascmodel_count descrule_count descstaff_id_card asc
现状能够提供正确列表语义,但不具备分页能力。
五、方案对比
5.1 方案 A:改造现有 risk-people 为标准分页接口
做法:
- 保持接口路径不变
- 入参扩展为
projectId + pageNum + pageSize - 返回结构改为
rows + total + pageNum + pageSize - 后端通过数据库分页查询返回当前页数据
- 前端首屏与翻页统一走该接口
优点:
- 满足“改接口”的明确要求
- 与
risk-models/people、employee-credit-negative的分页风格一致 - 逻辑单一,没有重复接口
- 数据量增大时性能与语义都正确
缺点:
- 需要同步调整前后端契约与测试
5.2 方案 B:新增 risk-people/page,保留原接口不动
做法:
- 原
risk-people继续返回全量列表 - 新增单独分页接口供前端切换
问题:
- 留下两个语义重复的接口
- 不符合“改接口”的要求
- 增加后续维护成本
5.3 方案 C:后端仍全量查,Java 或前端再切页
做法:
- 接口表面返回分页结构
- 实际仍走全量查询后截断
问题:
- 不是真分页
- 数据量增大时性能与语义都不成立
- 属于补丁式方案,不符合最短路径要求
5.4 结论
采用方案 A。
六、接口设计
6.1 接口路径
GET /ccdi/project/overview/risk-people
6.2 入参
projectId: 项目 ID,必填pageNum: 页码,非必填,默认1pageSize: 每页条数,非必填,默认5
说明:
- 前端固定传
pageSize = 5 - 后端默认值同样收敛为
5,避免前端漏传时行为偏移
6.3 返回结构
返回结构统一为:
{
"rows": [
{
"name": "李四",
"idNo": "330000000000000001",
"department": "信息二部",
"riskCount": 5,
"riskLevel": "中风险",
"riskLevelType": "warning",
"modelCount": 4,
"riskPoint": "大额单笔收入、疑似兼职",
"actionLabel": "查看项目"
}
],
"total": 18,
"pageNum": 1,
"pageSize": 5
}
说明:
- 原
overviewList字段移除,统一改为rows - 单行字段保持现有页面绑定语义不变
- 本次不引入额外统计字段
七、后端设计
7.1 控制器
CcdiProjectOverviewController.getRiskPeople 改为接收独立 DTO,例如:
CcdiProjectRiskPeopleQueryDTO
DTO 仅包含:
projectIdpageNumpageSize
不额外引入筛选项,保持最短路径。
7.2 服务层
ICcdiProjectOverviewService.getRiskPeopleOverview 改为接收查询 DTO,并返回分页 VO。
服务层职责:
- 校验项目存在
- 规范化分页参数,默认
pageNum=1、pageSize=5 - 构造 MyBatis Plus
Page - 调用 mapper 分页查询
- 将记录映射为现有员工列表行结构
- 返回
rows + total + pageNum + pageSize
7.3 VO 调整
CcdiProjectRiskPeopleOverviewVO 改为标准分页 VO,字段包括:
List<CcdiProjectRiskPeopleOverviewItemVO> rowsLong totalLong pageNumLong pageSize
说明:
CcdiProjectRiskPeopleOverviewItemVO本身字段不做语义调整- 既有的风险等级映射与异常点标签来源保持不变
7.4 Mapper 与 SQL
Mapper 从“全量列表查询”改为“分页查询”,直接在数据库层完成分页。
排序规则保持现状不变:
risk_level_sort ascmodel_count descrule_count descstaff_id_card asc
数据来源继续使用 ccdi_project_overview_employee_result,不新增统计口径,不回退到历史复杂聚合链路。
7.5 默认值与边界
projectId为空时沿用现有参数校验/项目不存在校验逻辑pageNum <= 0时按1处理pageSize <= 0或为空时按5处理- 本次不开放前端修改每页条数,接口虽接收
pageSize,但页面固定使用 5
八、前端设计
8.1 API 封装
ruoyi-ui/src/api/ccdi/projectOverview.js 中:
getOverviewRiskPeople从接收单个projectId改为接收params- 透传:
projectIdpageNumpageSize
8.2 首屏加载
PreliminaryCheck.vue 首次加载结果总览时,请求:
getOverviewRiskPeople({ projectId, pageNum: 1, pageSize: 5 })
返回结果注入 currentData.riskPeople 时,直接保存分页结构:
rowstotalpageNumpageSize
页面是否进入 loaded 状态的判断,从原来的 overviewList.length 改为 rows.length。
8.3 风险总览员工列表组件
RiskPeopleSection.vue 调整为:
- 表格数据源从
sectionData.overviewList改为sectionData.rows - 在表格下方增加分页组件
- 分页组件固定:
:page-sizes="[5]"layout="total, prev, pager, next, jumper"
- 页码变化时触发独立请求,仅刷新员工列表分页数据
分页条展示规则:
total > 0时展示total = 0时隐藏
8.4 页面刷新策略
翻页时只刷新风险总览员工列表,不重新拉取:
- 风险仪表盘
- 风险模型卡片
- 风险明细涉疑交易
- 风险明细员工负面征信
这样可以避免其他区块闪动,也避免把简单翻页放大成整页重载。
8.5 交互保持不变
以下内容本次保持不变:
- 表格列顺序
- 风险等级标签渲染
- 核心异常点标签拆分与色板逻辑
- 操作列文案与点击事件
- 空态文案
九、测试设计
9.1 后端测试
新增或调整以下验证:
-
Controller 测试
- 断言
/risk-people接口改为接收 DTO - 断言返回
rows + total + pageNum + pageSize
- 断言
-
Service 测试
- 断言服务层使用分页参数构造
Page - 断言现有字段映射未变化
- 断言默认分页参数回落为
1 / 5
- 断言服务层使用分页参数构造
-
Mapper/SQL 测试
- 断言风险人员查询改为分页查询方法
- 断言排序字段未变化
- 断言数据来源仍为
ccdi_project_overview_employee_result
9.2 前端测试
新增或调整以下验证:
-
API 封装测试
- 断言
getOverviewRiskPeople(params)透传projectId/pageNum/pageSize
- 断言
-
页面接入测试
- 断言
PreliminaryCheck.vue首次加载传pageNum: 1 - 断言固定传
pageSize: 5 - 断言风险人员数据改为读取
rows
- 断言
-
风险总览组件测试
- 断言
RiskPeopleSection.vue存在分页组件 - 断言分页绑定
rows/total/pageNum/pageSize - 断言分页大小固定为 5
- 断言
十、实施文档要求
本次设计确认后,按仓库规范继续产出两份实施计划:
- 后端实施计划:
docs/plans/backend/ - 前端实施计划:
docs/plans/frontend/
实施完成后,补充对应实施记录,记录本次真实改动内容。
十一、结论
本次需求本质是将结果总览中的风险员工列表从“全量列表展示”升级为“标准分页列表展示”。
最终方案为:
- 保持
GET /ccdi/project/overview/risk-people路径不变 - 改为标准分页接口,返回
rows + total + pageNum + pageSize - 后端在数据库层做真分页,默认每页 5 条
- 前端首屏和翻页统一走该接口
- 翻页仅刷新员工列表,不重载结果总览其他区块
该方案满足需求边界明确、链路完整、实现路径最短,且不引入额外补丁接口或兼容分支。