调整风险人员总览核心异常点标签展示
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
# 风险人员总览核心异常点标签化展示实施记录
|
||||
|
||||
## 本次改动
|
||||
|
||||
- 将风险人员总览中的“核心异常点”从纯文本展示改为标签列表展示,样式与“命中模型涉及人员”的异常标签保持一致。
|
||||
- 调整 [`RiskPeopleSection.vue`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiProject/components/detail/RiskPeopleSection.vue):
|
||||
- 新增 `riskPointTagList` 归一化逻辑。
|
||||
- 兼容后端返回标签数组、字符串数组、以及历史 `riskPoint` 拼接字符串三种输入形式。
|
||||
- 按风险等级映射 `el-tag` 颜色,空值场景显示 `-`。
|
||||
- 调整 [`preliminaryCheck.mock.js`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js),补充标签列 mock 数据。
|
||||
- 新增 [`preliminary-check-risk-people-hit-tags.test.js`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/tests/unit/preliminary-check-risk-people-hit-tags.test.js) 锁定核心异常点标签化渲染结构。
|
||||
|
||||
## 实现说明
|
||||
|
||||
- 不修改后端接口口径,展示层在前端做最小归一化处理。
|
||||
- 若接口继续返回 `riskPoint` 字符串,则按 `、`、`,`、`,`、`;`、`;` 拆分为多个标签。
|
||||
- 若接口后续直接返回 `riskPointTagList`,则优先使用该字段,避免重复拆分。
|
||||
|
||||
## 验证情况
|
||||
|
||||
- 前端单测:
|
||||
- `node ruoyi-ui/tests/unit/preliminary-check-risk-people-hit-tags.test.js`
|
||||
- `node ruoyi-ui/tests/unit/preliminary-check-risk-people-binding.test.js`
|
||||
- `node ruoyi-ui/tests/unit/preliminary-check-summary-and-people.test.js`
|
||||
|
||||
## 未包含内容
|
||||
|
||||
- 未调整风险人员总览接口返回结构
|
||||
- 未改动风险等级口径与统计逻辑
|
||||
- 未改动“命中模型涉及人员”区块的接口或交互
|
||||
@@ -10,7 +10,7 @@
|
||||
<el-button size="mini" type="text">导出</el-button>
|
||||
</div>
|
||||
|
||||
<el-table :data="sectionData.overviewList || []" class="people-table">
|
||||
<el-table :data="overviewList" class="people-table">
|
||||
<el-table-column type="index" label="序号" width="60" />
|
||||
<el-table-column prop="name" label="姓名" min-width="100" />
|
||||
<el-table-column prop="idNo" label="身份证号" min-width="180" />
|
||||
@@ -24,7 +24,25 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="modelCount" label="命中模型数" min-width="110" />
|
||||
<el-table-column prop="riskPoint" label="核心异常点" min-width="220" />
|
||||
<el-table-column label="核心异常点" min-width="220">
|
||||
<template slot-scope="scope">
|
||||
<div
|
||||
v-if="scope.row.riskPointTagList && scope.row.riskPointTagList.length"
|
||||
class="risk-point-tag-list"
|
||||
>
|
||||
<el-tag
|
||||
v-for="(tag, index) in scope.row.riskPointTagList"
|
||||
:key="`${scope.row.idNo || scope.row.name || index}-risk-point-${index}`"
|
||||
size="mini"
|
||||
effect="plain"
|
||||
:type="mapRiskLevelToTagType(tag.riskLevel)"
|
||||
>
|
||||
{{ tag.ruleName }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<span v-else class="empty-text">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" align="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="mini">{{ scope.row.actionLabel || "查看详情" }}</el-button>
|
||||
@@ -37,6 +55,52 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
function normalizeRiskPointTags(tags, riskPoint, riskLevel) {
|
||||
if (Array.isArray(tags) && tags.length) {
|
||||
return tags
|
||||
.map((item) => {
|
||||
if (typeof item === "string") {
|
||||
return {
|
||||
ruleName: item.trim(),
|
||||
riskLevel,
|
||||
};
|
||||
}
|
||||
if (item && typeof item === "object") {
|
||||
return {
|
||||
ruleName: item.ruleName || item.label || item.name || "",
|
||||
riskLevel: item.riskLevel || riskLevel,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter((item) => item && item.ruleName);
|
||||
}
|
||||
|
||||
if (!riskPoint) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return String(riskPoint)
|
||||
.split(/[、,,;;]/)
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean)
|
||||
.map((item) => ({
|
||||
ruleName: item,
|
||||
riskLevel,
|
||||
}));
|
||||
}
|
||||
|
||||
function normalizeOverviewRows(rows) {
|
||||
if (!Array.isArray(rows)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return rows.map((item) => ({
|
||||
...item,
|
||||
riskPointTagList: normalizeRiskPointTags(item.riskPointTagList, item.riskPoint, item.riskLevelType),
|
||||
}));
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "RiskPeopleSection",
|
||||
props: {
|
||||
@@ -45,6 +109,23 @@ export default {
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
overviewList() {
|
||||
return normalizeOverviewRows(this.sectionData.overviewList);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
mapRiskLevelToTagType(riskLevel) {
|
||||
const level = String(riskLevel || "").toUpperCase();
|
||||
if (level === "HIGH" || level === "DANGER") {
|
||||
return "danger";
|
||||
}
|
||||
if (level === "MEDIUM" || level === "WARNING") {
|
||||
return "warning";
|
||||
}
|
||||
return "info";
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -88,4 +169,14 @@ export default {
|
||||
background: #f8fafc;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.risk-point-tag-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
color: #94a3b8;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -22,6 +22,10 @@ export const mockOverviewData = {
|
||||
riskLevelType: "danger",
|
||||
modelCount: 3,
|
||||
riskPoint: "跨地域转账频繁交易",
|
||||
riskPointTagList: [
|
||||
{ ruleName: "跨地域转账", riskLevel: "HIGH" },
|
||||
{ ruleName: "频繁交易", riskLevel: "HIGH" },
|
||||
],
|
||||
actionLabel: "查看详情",
|
||||
},
|
||||
{
|
||||
@@ -33,6 +37,10 @@ export const mockOverviewData = {
|
||||
riskLevelType: "warning",
|
||||
modelCount: 2,
|
||||
riskPoint: "多工资转入频繁交易",
|
||||
riskPointTagList: [
|
||||
{ ruleName: "多工资转入", riskLevel: "MEDIUM" },
|
||||
{ ruleName: "频繁交易", riskLevel: "MEDIUM" },
|
||||
],
|
||||
actionLabel: "查看详情",
|
||||
},
|
||||
{
|
||||
@@ -44,6 +52,9 @@ export const mockOverviewData = {
|
||||
riskLevelType: "info",
|
||||
modelCount: 1,
|
||||
riskPoint: "频繁小额转账",
|
||||
riskPointTagList: [
|
||||
{ ruleName: "频繁小额转账", riskLevel: "LOW" },
|
||||
],
|
||||
actionLabel: "查看详情",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
const assert = require("assert");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const source = fs.readFileSync(
|
||||
path.resolve(__dirname, "../../src/views/ccdiProject/components/detail/RiskPeopleSection.vue"),
|
||||
"utf8"
|
||||
);
|
||||
|
||||
[
|
||||
"risk-point-tag-list",
|
||||
"scope.row.riskPointTagList",
|
||||
"normalizeRiskPointTags",
|
||||
":type=\"mapRiskLevelToTagType(tag.riskLevel)\"",
|
||||
].forEach((token) => assert(source.includes(token), token));
|
||||
|
||||
assert(!source.includes('<el-table-column prop="riskPoint" label="核心异常点" min-width="220" />'));
|
||||
Reference in New Issue
Block a user