Files
ccdi/docs/design/2026-03-25-results-overview-project-analysis-dialog-real-detail-design.md

400 lines
10 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-25
**模块**: 初核项目详情 - 结果总览
**作者**: Codex
**状态**: 已确认
## 1. 概述
现有 `结果总览` 页的“项目分析”弹窗已完成前端壳子,但弹窗内容仍依赖本地静态拼装:
- 弹窗宽度偏窄,流水类信息阅读空间不足
- `异常明细` 仍使用本地 mock 数据
- 左侧 `人员基础信息` 未读取员工信息表真实数据
- `命中模型摘要` 当前由弹窗内部拼装,和入口上下文绑定不清晰
本次设计只解决上述真实详情接入问题,目标是在保留现有弹窗结构的前提下,把“查看详情”改造成可查询真实人员详情和真实异常明细的工作台弹窗。
## 2. 设计目标
### 2.1 包含内容
- 调整 `项目分析` 弹窗宽度
- 新增结果总览详情专用后端接口
- `人员基础信息` 改为读取员工信息表真实数据
- `异常明细` 改为调用真实接口返回
- `命中模型摘要` 改为由外部列表透传进入弹窗
- `异常明细` 中:
- 流水维度异常按表格展示
- `object` 类型异常标签按摘要卡展示
### 2.2 不包含内容
- 不改造项目详情页路由和导航
- 不扩展弹窗内 `资产分析 / 征信摘要 / 关系图谱 / 资金流向` 的真实接口
- 不把弹窗拆成新页面
- 不向现有列表接口塞入详情字段
- 不增加兼容分支、降级分支或补丁式旁路方案
## 3. 当前上下文
当前相关前端文件:
- `ruoyi-ui/src/views/ccdiProject/components/detail/ProjectAnalysisDialog.vue`
- `ruoyi-ui/src/views/ccdiProject/components/detail/ProjectAnalysisSidebar.vue`
- `ruoyi-ui/src/views/ccdiProject/components/detail/ProjectAnalysisAbnormalTab.vue`
- `ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js`
当前相关后端文件:
- `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiProjectOverviewController.java`
- `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceImpl.java`
- `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiBankStatementController.java`
- `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiBankStatementServiceImpl.java`
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/CcdiBaseStaff.java`
当前问题:
1. 弹窗宽度固定为 `1280px`,流水类表格列空间不足
2. 异常明细页仍是“当前行数据 + 静态模板”拼装
3. 左侧基础信息没有使用员工主数据
4. 结果总览后端尚无详情接口,只有列表类接口
## 4. 方案比较
### 4.1 方案 A新增结果总览详情专用接口
做法:
- 在结果总览控制器下新增详情接口
- 一次返回人员基础信息和异常明细
- 前端弹窗只负责展示和状态管理
优点:
- 接口职责清晰,列表与详情边界明确
- 前端不需要并发拼多个真实接口
- 后续继续扩展其他页签时可以沿用同一详情链路
缺点:
- 需要补一条新的后端查询链路
### 4.2 方案 B前端并发查询员工信息和异常明细
做法:
- 员工信息单独查员工模块
- 异常明细单独查结果总览模块
- 前端弹窗自行合并两份结果
优点:
- 单个接口改动较小
缺点:
- 前端状态更散
- 打开弹窗时更容易出现半成功半失败
- 员工信息与详情上下文容易失去统一入口
### 4.3 方案 C把详情字段塞回现有列表接口
做法:
- 在风险人员总览和模型人员列表接口中直接追加详情字段
- 弹窗尽量少请求或不请求
优点:
- 表面改动快
缺点:
- 列表接口职责被拉坏
- 数据量被放大
- 不符合“查看详情单独获取真实信息”的语义
### 4.4 结论
采用 **方案 A**
原因:
1. 最符合“详情数据独立获取”的业务语义
2. 不破坏现有结果总览列表接口职责
3. 前后端边界最稳定,后续扩展成本最低
## 5. 总体设计
### 5.1 打开入口
以下两个入口继续共用同一个 `项目分析` 弹窗:
1. `风险人员总览`
2. `命中模型涉及人员列表`
### 5.2 打开流程
1. 用户点击列表中的 `查看详情`
2. 前端立即打开弹窗,默认进入 `异常明细`
3. 前端将入口行中的 `命中模型摘要` 直接透传给弹窗
4. 前端发起结果总览详情接口请求
5. 接口返回后刷新左侧真实人员基础信息和右侧真实异常明细
### 5.3 数据来源边界
- `人员基础信息`:后端详情接口内部查询员工信息表 `ccdi_base_staff`
- `命中模型摘要`:由外部列表透传,不由详情接口负责
- `异常明细`:由详情接口统一返回真实信息
## 6. 后端设计
### 6.1 接口设计
建议在结果总览控制器下新增接口:
- `GET /ccdi/project/overview/person-analysis/detail`
入参:
- `projectId`
- `staffIdCard`
只保留这两个字段,避免把外层上下文和真实详情查询混在一起。
### 6.2 返回结构
返回对象建议收口为:
```json
{
"basicInfo": {
"name": "张三",
"idNo": "3301********1234",
"staffCode": "A1023",
"department": "信息二部",
"phone": "138****0000",
"riskLevel": "高风险",
"projectName": "项目A"
},
"abnormalDetail": {
"groups": [
{
"groupCode": "BANK_STATEMENT",
"groupName": "流水异常明细",
"groupType": "BANK_STATEMENT",
"records": []
},
{
"groupCode": "RELATED_OBJECT",
"groupName": "异常对象摘要",
"groupType": "OBJECT",
"records": []
}
]
}
}
```
### 6.3 人员基础信息查询
人员基础信息统一从员工信息表读取:
- 主表:`ccdi_base_staff`
- 关联补充:
- 部门名称
- 当前项目名称
- 结果总览员工结果表中的风险等级
查询口径:
1. `staffIdCard` 作为员工识别主键
2. 员工表查不到时,仍允许返回异常明细,但 `basicInfo` 中对应字段为空
3. 不新增前端二次查员工接口
### 6.4 异常明细查询
异常明细统一组织为 `groups` 列表,每组包含:
- `groupCode`
- `groupName`
- `groupType`
- `records`
本轮只支持两种 `groupType`
- `BANK_STATEMENT`
- `OBJECT`
### 6.5 流水维度异常
`BANK_STATEMENT` 类型的 `records` 直接按流水明细展示口径返回,字段尽量贴近现有流水查询 VO
- `bankStatementId`
- `trxDate`
- `leAccountNo`
- `leAccountName`
- `customerAccountName`
- `customerAccountNo`
- `userMemo`
- `cashType`
- `displayAmount`
- `hitTags`
要求:
1. 展示口径与现有“流水明细查询”页面保持一致
2. 命中标签继续沿用当前流水标签结果表查询方式
3. 不再为弹窗单独造一套与流水查询不一致的字段命名
### 6.6 `OBJECT` 类型异常
`OBJECT` 类型记录用于卡片展示,返回摘要结构,不返回整对象平铺结构。
每条记录建议包含:
- `title`
- `subtitle`
- `riskTags`
- `summary`
- `extraFields`
其中:
- `title`:对象主识别名称
- `subtitle`:对象类型、关系或补充说明
- `riskTags`:异常标签数组
- `summary`:一句话摘要
- `extraFields`:最多 2 到 4 个补充字段
这样可满足“卡片展示核心信息”的要求,避免对象型数据在弹窗内变成字段堆叠。
### 6.7 查询范围
无论从哪个入口进入,详情接口都返回“该人员在当前项目下的全部异常明细”。
即使入口来自 `命中模型涉及人员列表`,也:
- 顶部继续显示当前命中模型上下文
- 但异常明细不按当前模型过滤
## 7. 前端设计
### 7.1 弹窗尺寸
`ProjectAnalysisDialog.vue` 中弹窗宽度从 `1280px` 调整为 `1440px`
布局建议:
- 左侧侧栏宽度从 `320px` 微调到 `340px`
- 右侧主工作区尽量为流水表格腾出空间
### 7.2 侧栏展示
左侧侧栏拆成两类来源:
1. 真实详情接口返回:
- 姓名
- 身份证号
- 工号
- 部门
- 联系方式
- 风险等级
- 所属项目
2. 外层透传:
- 命中模型数
- 当前命中模型
- 核心异常标签
`排查记录摘要` 本轮没有真实口径,继续保留占位文案,不新增接口。
### 7.3 异常明细渲染
`ProjectAnalysisAbnormalTab.vue` 改为分组渲染:
1. `BANK_STATEMENT`
- 渲染表格
- 表头风格参考 `DetailQuery.vue`
2. `OBJECT`
- 渲染摘要卡列表
- 每张卡只展示核心字段
空数据处理:
- 空分组不展示
- 全部为空时展示统一空态
### 7.4 Mock 替换策略
`preliminaryCheck.mock.js` 中的弹窗数据构造逻辑不再承担真实详情拼装职责。
保留内容:
- 占位页签文案
- 少量默认结构常量
移出内容:
- `basicInfo`
- `abnormalDetail`
这两部分改为完全由真实接口驱动。
## 8. 状态与交互设计
### 8.1 打开时机
点击后立即打开弹窗,不等待接口先返回。
### 8.2 加载态
- 左侧真实基础信息未返回前显示骨架或 `-`
- 右侧 `异常明细` 区域显示 `v-loading` 或骨架态
- 外层透传的命中模型摘要可先展示
### 8.3 错误态
如果详情接口失败:
- 弹窗保持打开
- 右侧异常明细区域展示错误提示和重试入口
- 左侧命中模型摘要继续保留
- 未获取到的基础信息字段显示为空
### 8.4 页签行为
- 默认页签始终为 `异常明细`
- 关闭弹窗后再次打开,仍回到 `异常明细`
- 其余 4 个页签继续展示占位内容,不在本次扩展真实数据
## 9. 测试与验收要点
### 9.1 后端验收
1. 详情接口可根据 `projectId + staffIdCard` 返回真实详情
2. 人员基础信息来源于员工信息表
3. 流水型异常可返回真实流水记录和命中标签
4. `OBJECT` 类型异常可返回摘要卡结构
5. 从模型人员列表进入时,异常明细仍返回该人的全部异常
### 9.2 前端验收
1. 弹窗宽度明显加宽,流水表格可读性提升
2. 点击 `查看详情` 后弹窗立即打开
3. 左侧命中模型摘要由外层透传
4. 左侧人员基础信息展示真实数据
5. 流水型异常按表格展示
6. `OBJECT` 类型异常按摘要卡展示
7. 详情请求失败时弹窗不关闭,可重试
## 10. 结论
本方案采用“**结果总览新增专用详情接口 + 前端弹窗按类型渲染真实数据**”的最短路径实现:
1. 不污染现有列表接口
2. 不让前端并发拼多条真实接口
3. 人员基础信息、异常明细、入口模型摘要三类职责边界清晰
4. 既满足本轮真实详情接入,也为后续逐步接通更多页签留出稳定扩展位