调整异常对象逐卡展示口径
This commit is contained in:
@@ -440,8 +440,8 @@
|
||||
when tr.object_type = 'STAFF_ID_CARD' then '员工对象'
|
||||
else tr.object_type
|
||||
end) as subtitle,
|
||||
group_concat(distinct tr.reason_detail order by tr.rule_code asc separator ';') as reasonDetail,
|
||||
group_concat(distinct tr.rule_name order by tr.rule_code asc separator '、') as summary
|
||||
max(tr.reason_detail) as reasonDetail,
|
||||
max(tr.rule_name) as summary
|
||||
from ccdi_bank_statement_tag_result tr
|
||||
left join ccdi_base_staff staff
|
||||
on tr.object_type = 'STAFF_ID_CARD'
|
||||
@@ -461,8 +461,8 @@
|
||||
and relation_scope.relation_cert_no = tr.object_key
|
||||
)
|
||||
)
|
||||
group by coalesce(tr.object_key, tr.object_type)
|
||||
order by title asc
|
||||
group by coalesce(tr.object_key, tr.object_type), tr.rule_code
|
||||
order by title asc, tr.rule_code asc
|
||||
</select>
|
||||
|
||||
<select id="selectRiskCountSummaryByProjectId" resultType="map">
|
||||
|
||||
@@ -64,6 +64,10 @@ class CcdiProjectOverviewMapperSqlTest {
|
||||
assertTrue(objectRowsSql.contains("tr.object_type"), objectRowsSql);
|
||||
assertTrue(objectRowsSql.contains("tr.reason_detail"), objectRowsSql);
|
||||
assertTrue(objectRowsSql.contains("as reasonDetail"), objectRowsSql);
|
||||
assertTrue(objectRowsSql.contains("tr.rule_code"), objectRowsSql);
|
||||
assertTrue(objectRowsSql.contains("group by coalesce(tr.object_key, tr.object_type), tr.rule_code"), objectRowsSql);
|
||||
assertFalse(objectRowsSql.contains("group_concat(distinct tr.reason_detail"), objectRowsSql);
|
||||
assertFalse(objectRowsSql.contains("group_concat(distinct tr.rule_name"), objectRowsSql);
|
||||
assertTrue(objectRowsSql.contains("tr.staff_id_card = #{staffIdCard}") || objectRowsSql.contains("#{staffIdCard}"), objectRowsSql);
|
||||
}
|
||||
|
||||
|
||||
@@ -191,9 +191,15 @@ class CcdiProjectOverviewServiceImplTest {
|
||||
objectRow.setSubtitle("关联人员");
|
||||
objectRow.setRiskTags(List.of("频繁往来"));
|
||||
objectRow.setReasonDetail("命中近30日高频往来规则,存在多笔短周期回流");
|
||||
objectRow.setSummary("与项目关键人员存在异常资金往来");
|
||||
objectRow.setSummary("高频往来");
|
||||
CcdiProjectPersonAnalysisObjectRecordVO objectRowTwo = new CcdiProjectPersonAnalysisObjectRecordVO();
|
||||
objectRowTwo.setTitle("张三");
|
||||
objectRowTwo.setSubtitle("关联人员");
|
||||
objectRowTwo.setRiskTags(List.of("异常关联"));
|
||||
objectRowTwo.setReasonDetail("命中跨主体异常关联规则,存在关键时间点往来");
|
||||
objectRowTwo.setSummary("跨主体关联");
|
||||
when(overviewMapper.selectPersonAnalysisObjectRows(40L, "330000000000000001"))
|
||||
.thenReturn(List.of(objectRow));
|
||||
.thenReturn(List.of(objectRow, objectRowTwo));
|
||||
|
||||
CcdiProjectPersonAnalysisDetailVO result = service.getPersonAnalysisDetail(buildPersonAnalysisDetailQuery(40L));
|
||||
|
||||
@@ -208,6 +214,7 @@ class CcdiProjectOverviewServiceImplTest {
|
||||
List<?> statementRecords = result.getAbnormalDetail().getGroups().get(0).getRecords();
|
||||
assertEquals(1, ((CcdiBankStatementListVO) statementRecords.getFirst()).getHitTags().size());
|
||||
List<?> objectRecords = result.getAbnormalDetail().getGroups().get(1).getRecords();
|
||||
assertEquals(2, objectRecords.size());
|
||||
assertEquals(
|
||||
"命中近30日高频往来规则,存在多笔短周期回流",
|
||||
((CcdiProjectPersonAnalysisObjectRecordVO) objectRecords.getFirst()).getReasonDetail()
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# 结果总览查看详情弹窗对象异常逐卡展示实施记录
|
||||
|
||||
## 变更日期
|
||||
|
||||
- 2026-03-25
|
||||
|
||||
## 变更范围
|
||||
|
||||
- 后端:`ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectOverviewMapper.xml`
|
||||
- 后端测试:`ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewMapperSqlTest.java`
|
||||
- 前端 Mock:`ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js`
|
||||
|
||||
## 实施内容
|
||||
|
||||
### 1. 对象异常查询改为按对象 + 规则拆卡
|
||||
|
||||
- `selectPersonAnalysisObjectRows` 不再按对象维度聚合全部异常。
|
||||
- 查询改为按 `coalesce(tr.object_key, tr.object_type) + tr.rule_code` 分组。
|
||||
- `summary` 改为当前规则名称。
|
||||
- `reasonDetail` 改为当前规则对应的异常原因快照。
|
||||
|
||||
### 2. 异常对象摘要卡片展示口径调整
|
||||
|
||||
- 保持前端对象卡片渲染结构不变,继续一条记录对应一张卡。
|
||||
- 由于后端返回已拆成“对象 + 规则”一条一张卡,页面自然表现为“每种对象异常,一个卡片”。
|
||||
|
||||
### 3. Mock 与测试同步
|
||||
|
||||
- 更新前端 Mock 数据,将同一对象的多种异常拆成多张卡片样例。
|
||||
- 更新后端 SQL 测试,校验对象异常查询已按 `tr.rule_code` 分组,且不再使用 `group_concat` 合并 `rule_name` 与 `reason_detail`。
|
||||
|
||||
## 结果
|
||||
|
||||
- 同一对象命中多种对象异常时,弹窗中的异常对象摘要已按“每种对象异常一个卡片”展示。
|
||||
- 现有对象卡片布局与字段展示方式保持不变。
|
||||
@@ -0,0 +1,33 @@
|
||||
# 结果总览查看详情弹窗对象异常逐卡展示验证记录
|
||||
|
||||
## 验证日期
|
||||
|
||||
- 2026-03-25
|
||||
|
||||
## 验证命令
|
||||
|
||||
```bash
|
||||
cd /Users/wkc/Desktop/ccdi/ccdi
|
||||
mvn test -pl ccdi-project -Dtest=CcdiProjectOverviewMapperSqlTest
|
||||
|
||||
cd /Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui
|
||||
node tests/unit/project-analysis-dialog-abnormal-tab.test.js
|
||||
node tests/unit/project-analysis-dialog-source-highlight.test.js
|
||||
npm run build:prod
|
||||
```
|
||||
|
||||
## 验证结果
|
||||
|
||||
- 后端 `CcdiProjectOverviewMapperSqlTest` 通过,确认对象异常查询已按 `tr.rule_code` 拆分。
|
||||
- 前端对象卡片相关单测通过。
|
||||
- 前端生产构建成功。
|
||||
- 构建过程中仅有项目既有的静态资源体积告警,无新增错误。
|
||||
|
||||
## 附加说明
|
||||
|
||||
- 本次需求的核心变化在对象异常查询分组口径,已通过 SQL 断言验证。
|
||||
- `CcdiProjectOverviewServiceImplTest` 在当前环境下仍受 Mockito Inline MockMaker 自附着限制影响,未作为本次验证主证据。
|
||||
|
||||
## 结论
|
||||
|
||||
- 异常对象摘要已实现“每种对象异常一个卡片”,相关前后端链路验证通过。
|
||||
@@ -283,16 +283,38 @@ export function buildProjectAnalysisDialogData({ person, source = "riskPeople",
|
||||
groupCode: "RELATED_OBJECT",
|
||||
groupName: "异常对象摘要",
|
||||
groupType: "OBJECT",
|
||||
records: projectAnalysisRelatedTradeTemplate.map((item, index) => ({
|
||||
title: item.title,
|
||||
subtitle: projectAnalysisFrequentTransferTemplate[index]
|
||||
? projectAnalysisFrequentTransferTemplate[index].accountNo
|
||||
: "异常对象",
|
||||
riskTags: [],
|
||||
reasonDetail: "命中对象型异常规则,系统已截取对应原因快照用于辅助研判。",
|
||||
summary: item.description,
|
||||
extraFields: [],
|
||||
})),
|
||||
records: [
|
||||
{
|
||||
title: projectAnalysisRelatedTradeTemplate[0].title,
|
||||
subtitle: projectAnalysisFrequentTransferTemplate[0]
|
||||
? projectAnalysisFrequentTransferTemplate[0].accountNo
|
||||
: "异常对象",
|
||||
riskTags: [],
|
||||
reasonDetail: "命中高频往来异常规则,系统已截取对象型异常原因快照用于辅助研判。",
|
||||
summary: "高频往来",
|
||||
extraFields: [],
|
||||
},
|
||||
{
|
||||
title: projectAnalysisRelatedTradeTemplate[0].title,
|
||||
subtitle: projectAnalysisFrequentTransferTemplate[0]
|
||||
? projectAnalysisFrequentTransferTemplate[0].accountNo
|
||||
: "异常对象",
|
||||
riskTags: [],
|
||||
reasonDetail: "命中关键时间点异常关联规则,系统已截取对象型异常原因快照用于辅助研判。",
|
||||
summary: "关键时间点异常关联",
|
||||
extraFields: [],
|
||||
},
|
||||
{
|
||||
title: projectAnalysisRelatedTradeTemplate[1].title,
|
||||
subtitle: projectAnalysisFrequentTransferTemplate[1]
|
||||
? projectAnalysisFrequentTransferTemplate[1].accountNo
|
||||
: "异常对象",
|
||||
riskTags: [],
|
||||
reasonDetail: "命中项目相关交易异常规则,系统已截取对象型异常原因快照用于辅助研判。",
|
||||
summary: "项目相关交易",
|
||||
extraFields: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user