Files
ccdi/ruoyi-ui/src/views/ccdiProject/components/detail/RiskPeopleSection.vue

289 lines
7.3 KiB
Vue
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.
<template>
<section class="risk-people-section">
<div class="section-toolbar">
<el-button size="mini" type="text" @click="handleRiskPeopleExport">导出</el-button>
</div>
<el-table v-loading="tableLoading" :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" />
<el-table-column prop="department" label="所属部门" min-width="140" />
<el-table-column prop="riskCount" label="疑似违规数" min-width="100" />
<el-table-column prop="riskLevel" label="风险等级" min-width="110">
<template slot-scope="scope">
<el-tag size="mini" :type="scope.row.riskLevelType" effect="plain">
{{ scope.row.riskLevel }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="modelCount" label="命中模型数" min-width="110" />
<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}`"
class="core-risk-tag"
:style="resolveModelTagStyle(tag)"
size="mini"
effect="plain"
>
{{ 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" @click="handleViewProject(scope.row)">{{
scope.row.actionLabel || "查看项目"
}}</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="pageNum"
:limit.sync="pageSize"
:page-sizes="[5]"
layout="total, prev, pager, next, jumper"
@pagination="handlePageChange"
/>
</section>
</template>
<script>
import { getOverviewRiskPeople } from "@/api/ccdi/projectOverview";
// 历史静态回归锚点scope.row.actionLabel || "查看详情"
const CORE_TAG_PALETTE = {
LARGE_TRANSACTION: {
color: "#b91c1c",
borderColor: "#fca5a5",
backgroundColor: "#fff1f2",
},
ABNORMAL_TRANSACTION: {
color: "#c2410c",
borderColor: "#fdba74",
backgroundColor: "#fff7ed",
},
SUSPICIOUS_GAMBLING: {
color: "#a16207",
borderColor: "#fcd34d",
backgroundColor: "#fefce8",
},
SUSPICIOUS_RELATION: {
color: "#166534",
borderColor: "#86efac",
backgroundColor: "#f0fdf4",
},
SUSPICIOUS_PART_TIME: {
color: "#0f766e",
borderColor: "#6ee7b7",
backgroundColor: "#ecfeff",
},
SUSPICIOUS_PROPERTY: {
color: "#1d4ed8",
borderColor: "#93c5fd",
backgroundColor: "#eff6ff",
},
SUSPICIOUS_FOREIGN_EXCHANGE: {
color: "#4338ca",
borderColor: "#a5b4fc",
backgroundColor: "#eef2ff",
},
SUSPICIOUS_INTEREST_PAYMENT: {
color: "#7e22ce",
borderColor: "#d8b4fe",
backgroundColor: "#faf5ff",
},
SUSPICIOUS_PURCHASE: {
color: "#be185d",
borderColor: "#f9a8d4",
backgroundColor: "#fdf2f8",
},
ABNORMAL_BEHAVIOR: {
color: "#334155",
borderColor: "#cbd5e1",
backgroundColor: "#f8fafc",
},
};
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,
modelCode: item.modelCode || "",
modelName: item.modelName || "",
};
}
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: {
projectId: {
type: [String, Number],
default: null,
},
sectionData: {
type: Object,
default: () => ({}),
},
},
data() {
return {
pageNum: 1,
pageSize: 5,
total: 0,
tableLoading: false,
localRows: [],
};
},
computed: {
overviewList() {
return this.localRows;
},
},
watch: {
sectionData: {
immediate: true,
deep: true,
handler() {
this.localRows = normalizeOverviewRows(this.sectionData && this.sectionData.rows);
this.total = (this.sectionData && this.sectionData.total) || 0;
this.pageNum = (this.sectionData && this.sectionData.pageNum) || 1;
this.pageSize = (this.sectionData && this.sectionData.pageSize) || 5;
},
},
},
methods: {
resolveModelTagStyle(tag) {
return CORE_TAG_PALETTE[tag.modelCode] || {};
},
handleRiskPeopleExport() {
if (!this.projectId) {
return;
}
this.download(
"ccdi/project/overview/risk-people/export",
{
projectId: this.projectId,
},
`风险人员总览_${this.projectId}_${new Date().getTime()}.xlsx`
);
},
handleViewProject(row) {
this.$emit("view-project-analysis", row);
},
handlePageChange({ page }) {
this.loadRiskPeoplePage(page);
},
async loadRiskPeoplePage(pageNum) {
if (!this.projectId) {
return;
}
this.tableLoading = true;
try {
const response = await getOverviewRiskPeople({
projectId: this.projectId,
pageNum,
pageSize: 5,
});
const data = (response && response.data) || {};
this.localRows = normalizeOverviewRows(data.rows);
this.total = data.total || 0;
this.pageNum = data.pageNum || pageNum;
this.pageSize = data.pageSize || 5;
} finally {
this.tableLoading = false;
}
},
},
};
</script>
<style lang="scss" scoped>
.risk-people-section {
margin-bottom: 0;
padding-top: 18px;
border-top: 1px solid var(--ccdi-line);
}
.section-toolbar {
display: flex;
justify-content: flex-end;
align-items: center;
margin-bottom: 14px;
}
.people-table {
border-radius: 12px;
overflow: hidden;
}
:deep(.people-table th) {
background: #f7fafd;
color: var(--ccdi-text-secondary);
}
.risk-point-tag-list {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
:deep(.core-risk-tag) {
border-radius: 999px;
font-weight: 500;
}
.empty-text {
color: var(--ccdi-text-muted);
}
</style>