完善外部人员预警与项目分析上线内容

This commit is contained in:
wjj
2026-06-30 10:23:55 +08:00
parent 4e90e22ee2
commit 5e4bfca05b
77 changed files with 5788 additions and 333 deletions

View File

@@ -1,10 +1,18 @@
<template>
<section class="risk-people-section">
<div class="section-toolbar">
<el-button size="mini" type="text" @click="handleRiskPeopleExport">导出</el-button>
<el-tabs v-model="activeTab" class="people-tabs" @tab-click="handleTabChange">
<el-tab-pane label="员工风险人员" name="employee" />
<el-tab-pane v-if="hasExternalWarnings" :label="externalTabLabel" name="external" />
</el-tabs>
</div>
<el-table v-loading="tableLoading" :data="overviewList" class="people-table">
<el-table
v-if="activeTab === 'employee'"
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" />
@@ -46,11 +54,69 @@
</template>
</el-table-column>
</el-table>
<el-table
v-else
v-loading="externalLoading"
:data="externalRows"
class="people-table"
>
<template slot="empty">
<el-empty :image-size="80" description="当前项目暂无外部人员预警" />
</template>
<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="subjectType" label="主体类型" min-width="110">
<template slot-scope="scope">
<el-tag size="mini" effect="plain">{{ scope.row.subjectType || "外部人员" }}</el-tag>
</template>
</el-table-column>
<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 label="核心异常点" min-width="260">
<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}-external-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">{{ scope.row.riskPoint || "-" }}</span>
</template>
</el-table-column>
<el-table-column prop="relatedObject" label="涉及对象" min-width="140" />
<el-table-column label="最近交易时间" min-width="170">
<template slot-scope="scope">
<span>{{ formatLatestTradeTime(scope.row) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="100" align="right">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="handleViewExternal(scope.row)">
查看详情
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="pageNum"
:limit.sync="pageSize"
v-show="currentTotal > 0"
:total="currentTotal"
:page.sync="currentPageNum"
:limit.sync="currentPageSize"
:page-sizes="[5]"
layout="total, prev, pager, next, jumper"
@pagination="handlePageChange"
@@ -59,7 +125,10 @@
</template>
<script>
import { getOverviewRiskPeople } from "@/api/ccdi/projectOverview";
import {
getOverviewExternalPersons,
getOverviewRiskPeople,
} from "@/api/ccdi/projectOverview";
// 历史静态回归锚点scope.row.actionLabel || "查看详情"
const CORE_TAG_PALETTE = {
@@ -157,10 +226,13 @@ function normalizeOverviewRows(rows) {
return [];
}
return rows.map((item) => ({
...item,
riskPointTagList: normalizeRiskPointTags(item.riskPointTagList, item.riskPoint, item.riskLevelType),
}));
return rows.map((item) => {
const riskPointTagList = normalizeRiskPointTags(item.riskPointTagList, item.riskPoint, item.riskLevelType);
return {
...item,
riskPointTagList,
};
});
}
export default {
@@ -182,12 +254,51 @@ export default {
total: 0,
tableLoading: false,
localRows: [],
activeTab: "employee",
externalRows: [],
externalTotal: 0,
externalPageNum: 1,
externalPageSize: 5,
externalLoading: false,
};
},
computed: {
overviewList() {
return this.localRows;
},
externalTabLabel() {
return `外部人员预警(${this.externalTotal})`;
},
hasExternalWarnings() {
return this.externalTotal > 0;
},
currentTotal() {
return this.activeTab === "external" ? this.externalTotal : this.total;
},
currentPageNum: {
get() {
return this.activeTab === "external" ? this.externalPageNum : this.pageNum;
},
set(value) {
if (this.activeTab === "external") {
this.externalPageNum = value;
return;
}
this.pageNum = value;
},
},
currentPageSize: {
get() {
return this.activeTab === "external" ? this.externalPageSize : this.pageSize;
},
set(value) {
if (this.activeTab === "external") {
this.externalPageSize = value;
return;
}
this.pageSize = value;
},
},
},
watch: {
sectionData: {
@@ -198,6 +309,7 @@ export default {
this.total = (this.sectionData && this.sectionData.total) || 0;
this.pageNum = (this.sectionData && this.sectionData.pageNum) || 1;
this.pageSize = (this.sectionData && this.sectionData.pageSize) || 5;
this.loadExternalPage(1);
},
},
},
@@ -205,22 +317,33 @@ export default {
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);
},
handleViewExternal(row) {
this.$emit("view-external-detail", row);
},
formatLatestTradeTime(row) {
const value = row && row.latestTradeTime ? String(row.latestTradeTime) : "";
if (!value || value === row.actionLabel) {
return "-";
}
return value;
},
handleTabChange() {
if (this.activeTab === "external" && !this.hasExternalWarnings) {
this.activeTab = "employee";
}
this.emitScopeSummary();
if (this.activeTab === "external" && !this.externalRows.length) {
this.loadExternalPage(1);
}
},
handlePageChange({ page }) {
if (this.activeTab === "external") {
this.loadExternalPage(page);
return;
}
this.loadRiskPeoplePage(page);
},
async loadRiskPeoplePage(pageNum) {
@@ -243,6 +366,44 @@ export default {
this.tableLoading = false;
}
},
async loadExternalPage(pageNum) {
if (!this.projectId) {
this.externalRows = [];
this.externalTotal = 0;
return;
}
this.externalLoading = true;
try {
const response = await getOverviewExternalPersons({
projectId: this.projectId,
pageNum,
pageSize: 5,
});
const data = (response && response.data) || {};
this.externalRows = normalizeOverviewRows(data.rows);
this.externalTotal = data.total || 0;
this.externalPageNum = data.pageNum || pageNum;
this.externalPageSize = data.pageSize || 5;
if (!this.hasExternalWarnings && this.activeTab === "external") {
this.activeTab = "employee";
}
this.emitScopeSummary();
} finally {
this.externalLoading = false;
}
},
emitScopeSummary() {
this.$emit("scope-summary-change", {
activeTab: this.activeTab,
employee: {
total: this.total,
},
external: {
total: this.externalTotal,
rows: this.externalRows,
},
});
},
},
};
</script>
@@ -256,11 +417,19 @@ export default {
.section-toolbar {
display: flex;
justify-content: flex-end;
justify-content: space-between;
align-items: center;
margin-bottom: 14px;
}
.people-tabs {
flex: 1;
:deep(.el-tabs__header) {
margin: 0;
}
}
.people-table {
border-radius: 12px;
overflow: hidden;