From 865d8f823ba78d38ce724209ef2bb05489bd6309 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Sun, 29 Mar 2026 11:41:49 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E9=A3=8E=E9=99=A9=E6=80=BB?= =?UTF-8?q?=E8=A7=88=E5=91=98=E5=B7=A5=E5=88=97=E8=A1=A8=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...-overview-risk-people-pagination-design.md | 364 ++++++++++++++++++ ...ew-risk-people-pagination-design-record.md | 37 ++ 2 files changed, 401 insertions(+) create mode 100644 docs/design/2026-03-29-project-detail-risk-overview-risk-people-pagination-design.md create mode 100644 docs/reports/implementation/2026-03-29-project-detail-risk-overview-risk-people-pagination-design-record.md diff --git a/docs/design/2026-03-29-project-detail-risk-overview-risk-people-pagination-design.md b/docs/design/2026-03-29-project-detail-risk-overview-risk-people-pagination-design.md new file mode 100644 index 00000000..ca3147e1 --- /dev/null +++ b/docs/design/2026-03-29-project-detail-risk-overview-risk-people-pagination-design.md @@ -0,0 +1,364 @@ +# 项目详情风险总览员工列表分页设计文档 + +**模块**: 项目详情 - 结果总览 - 风险总览员工列表 +**日期**: 2026-03-29 + +## 一、背景 + +当前项目详情页 `结果总览 -> 风险总览` 中的员工列表直接消费 `GET /ccdi/project/overview/risk-people` 返回的全量 `overviewList`。页面没有分页能力,项目内风险员工较多时会导致: + +1. 单屏信息过长,浏览成本高。 +2. 前端一次性渲染全量列表,交互体验不稳定。 +3. 接口返回风格与当前结果总览域内其他分页接口不一致。 + +本轮需求要求为该员工列表增加分页,并固定为每页 5 条。同时,需求明确要求改造现有接口,不采用前端本地切片或新增补丁接口的方式。 + +## 二、目标 + +本次设计目标如下: + +1. 将 `GET /ccdi/project/overview/risk-people` 改造成真实分页接口。 +2. 风险总览员工列表固定每页展示 5 条。 +3. 前端翻页时仅刷新员工列表,不影响结果总览内其他区块。 +4. 分页接口返回结构对齐项目现有分页风格,统一为 `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/dashboard` +- `GET /ccdi/project/overview/risk-people` +- `GET /ccdi/project/overview/risk-models/cards` +- `GET /ccdi/project/overview/suspicious-transactions` +- `GET /ccdi/project/overview/employee-credit-negative` + +其中 `risk-people` 的返回结果被直接注入 `currentData.riskPeople.overviewList`,`RiskPeopleSection.vue` 直接用该数组渲染表格,没有分页状态,也没有独立二次加载链路。 + +### 4.2 后端现状 + +当前 `CcdiProjectOverviewController.getRiskPeople(Long projectId)` 只接收项目 ID。 + +`CcdiProjectOverviewServiceImpl.getRiskPeopleOverview(Long projectId)` 的实现为: + +1. 校验项目存在 +2. 调用 `overviewMapper.selectRiskPeopleOverviewByProjectId(projectId)` 查询全量员工结果 +3. 在 Java 层逐行映射为 `overviewList` +4. 返回 `CcdiProjectRiskPeopleOverviewVO { overviewList }` + +当前 SQL 直接从 `ccdi_project_overview_employee_result` 查询并排序: + +- `risk_level_sort asc` +- `model_count desc` +- `rule_count desc` +- `staff_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`: 页码,非必填,默认 `1` +- `pageSize`: 每页条数,非必填,默认 `5` + +说明: + +- 前端固定传 `pageSize = 5` +- 后端默认值同样收敛为 `5`,避免前端漏传时行为偏移 + +### 6.3 返回结构 + +返回结构统一为: + +```json +{ + "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 仅包含: + +- `projectId` +- `pageNum` +- `pageSize` + +不额外引入筛选项,保持最短路径。 + +### 7.2 服务层 + +`ICcdiProjectOverviewService.getRiskPeopleOverview` 改为接收查询 DTO,并返回分页 VO。 + +服务层职责: + +1. 校验项目存在 +2. 规范化分页参数,默认 `pageNum=1`、`pageSize=5` +3. 构造 MyBatis Plus `Page` +4. 调用 mapper 分页查询 +5. 将记录映射为现有员工列表行结构 +6. 返回 `rows + total + pageNum + pageSize` + +### 7.3 VO 调整 + +`CcdiProjectRiskPeopleOverviewVO` 改为标准分页 VO,字段包括: + +- `List rows` +- `Long total` +- `Long pageNum` +- `Long pageSize` + +说明: + +- `CcdiProjectRiskPeopleOverviewItemVO` 本身字段不做语义调整 +- 既有的风险等级映射与异常点标签来源保持不变 + +### 7.4 Mapper 与 SQL + +Mapper 从“全量列表查询”改为“分页查询”,直接在数据库层完成分页。 + +排序规则保持现状不变: + +- `risk_level_sort asc` +- `model_count desc` +- `rule_count desc` +- `staff_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` +- 透传: + - `projectId` + - `pageNum` + - `pageSize` + +### 8.2 首屏加载 + +`PreliminaryCheck.vue` 首次加载结果总览时,请求: + +- `getOverviewRiskPeople({ projectId, pageNum: 1, pageSize: 5 })` + +返回结果注入 `currentData.riskPeople` 时,直接保存分页结构: + +- `rows` +- `total` +- `pageNum` +- `pageSize` + +页面是否进入 `loaded` 状态的判断,从原来的 `overviewList.length` 改为 `rows.length`。 + +### 8.3 风险总览员工列表组件 + +`RiskPeopleSection.vue` 调整为: + +1. 表格数据源从 `sectionData.overviewList` 改为 `sectionData.rows` +2. 在表格下方增加分页组件 +3. 分页组件固定: + - `:page-sizes="[5]"` + - `layout="total, prev, pager, next, jumper"` +4. 页码变化时触发独立请求,仅刷新员工列表分页数据 + +分页条展示规则: + +- `total > 0` 时展示 +- `total = 0` 时隐藏 + +### 8.4 页面刷新策略 + +翻页时只刷新风险总览员工列表,不重新拉取: + +- 风险仪表盘 +- 风险模型卡片 +- 风险明细涉疑交易 +- 风险明细员工负面征信 + +这样可以避免其他区块闪动,也避免把简单翻页放大成整页重载。 + +### 8.5 交互保持不变 + +以下内容本次保持不变: + +- 表格列顺序 +- 风险等级标签渲染 +- 核心异常点标签拆分与色板逻辑 +- 操作列文案与点击事件 +- 空态文案 + +## 九、测试设计 + +### 9.1 后端测试 + +新增或调整以下验证: + +1. Controller 测试 + - 断言 `/risk-people` 接口改为接收 DTO + - 断言返回 `rows + total + pageNum + pageSize` + +2. Service 测试 + - 断言服务层使用分页参数构造 `Page` + - 断言现有字段映射未变化 + - 断言默认分页参数回落为 `1 / 5` + +3. Mapper/SQL 测试 + - 断言风险人员查询改为分页查询方法 + - 断言排序字段未变化 + - 断言数据来源仍为 `ccdi_project_overview_employee_result` + +### 9.2 前端测试 + +新增或调整以下验证: + +1. API 封装测试 + - 断言 `getOverviewRiskPeople(params)` 透传 `projectId/pageNum/pageSize` + +2. 页面接入测试 + - 断言 `PreliminaryCheck.vue` 首次加载传 `pageNum: 1` + - 断言固定传 `pageSize: 5` + - 断言风险人员数据改为读取 `rows` + +3. 风险总览组件测试 + - 断言 `RiskPeopleSection.vue` 存在分页组件 + - 断言分页绑定 `rows/total/pageNum/pageSize` + - 断言分页大小固定为 5 + +## 十、实施文档要求 + +本次设计确认后,按仓库规范继续产出两份实施计划: + +- 后端实施计划:`docs/plans/backend/` +- 前端实施计划:`docs/plans/frontend/` + +实施完成后,补充对应实施记录,记录本次真实改动内容。 + +## 十一、结论 + +本次需求本质是将结果总览中的风险员工列表从“全量列表展示”升级为“标准分页列表展示”。 + +最终方案为: + +1. 保持 `GET /ccdi/project/overview/risk-people` 路径不变 +2. 改为标准分页接口,返回 `rows + total + pageNum + pageSize` +3. 后端在数据库层做真分页,默认每页 5 条 +4. 前端首屏和翻页统一走该接口 +5. 翻页仅刷新员工列表,不重载结果总览其他区块 + +该方案满足需求边界明确、链路完整、实现路径最短,且不引入额外补丁接口或兼容分支。 diff --git a/docs/reports/implementation/2026-03-29-project-detail-risk-overview-risk-people-pagination-design-record.md b/docs/reports/implementation/2026-03-29-project-detail-risk-overview-risk-people-pagination-design-record.md new file mode 100644 index 00000000..dcef5342 --- /dev/null +++ b/docs/reports/implementation/2026-03-29-project-detail-risk-overview-risk-people-pagination-design-record.md @@ -0,0 +1,37 @@ +# 项目详情风险总览员工列表分页设计记录 + +**日期**: 2026-03-29 + +## 本次产出 + +- 新增正式设计文档 `docs/design/2026-03-29-project-detail-risk-overview-risk-people-pagination-design.md` +- 将“风险总览员工列表固定 5 条分页展示”收口为“改造现有 `risk-people` 接口为标准分页接口”方案 + +## 设计结论 + +### 后端 + +- 保持 `GET /ccdi/project/overview/risk-people` 路径不变 +- 入参扩展为 `projectId + pageNum + pageSize` +- 返回结构统一为 `rows + total + pageNum + pageSize` +- 基于 `ccdi_project_overview_employee_result` 做数据库分页,不走全量查询后截断 +- 排序规则继续沿用现有口径,不新增筛选条件 + +### 前端 + +- `PreliminaryCheck.vue` 首屏固定请求第一页,每页 5 条 +- `RiskPeopleSection.vue` 改为消费 `rows` 分页数据并新增分页条 +- 翻页时仅刷新风险总览员工列表,不重载风险仪表盘、风险模型和风险明细 + +## 边界约束 + +- 不新增 `risk-people/page` 之类的补丁接口 +- 不在前端做本地数组切片分页 +- 不修改风险等级、命中模型数、核心异常点的业务口径 +- 不删除现有 `top-risk-people` 接口 +- 本次仅完成设计沉淀,尚未进入代码实施 + +## 说明 + +- 设计文档已按仓库规范保存到 `docs/design/` +- 由于仓库协作约定禁止开启 subagent,本次不走技能中的 subagent 评审环节,改为人工复核文档后进入后续实施计划阶段