2026-03-04 10:31:59 +08:00
|
|
|
<template>
|
|
|
|
|
<div class="preliminary-check-container">
|
2026-03-19 10:35:40 +08:00
|
|
|
<div v-if="pageState === 'loading'" class="preliminary-check-state">
|
2026-03-19 10:39:24 +08:00
|
|
|
<div class="state-card">
|
|
|
|
|
<el-skeleton animated :rows="6" />
|
|
|
|
|
</div>
|
2026-03-19 10:35:40 +08:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-else-if="pageState === 'empty'" class="preliminary-check-state">
|
2026-03-19 10:39:24 +08:00
|
|
|
<div class="state-card">
|
|
|
|
|
<el-empty description="暂无结果总览数据" />
|
|
|
|
|
</div>
|
2026-03-19 10:35:40 +08:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-else class="preliminary-check-page">
|
2026-03-27 14:52:12 +08:00
|
|
|
<section class="section-card risk-overview-card">
|
|
|
|
|
<div class="section-header">
|
|
|
|
|
<div>
|
|
|
|
|
<div class="section-title">风险总览</div>
|
|
|
|
|
<div class="section-subtitle">集中展示项目风险统计与命中人员总览</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<overview-stats :summary="currentData.summary" />
|
|
|
|
|
<risk-people-section
|
2026-03-29 18:44:07 +08:00
|
|
|
:project-id="projectId"
|
2026-03-27 14:52:12 +08:00
|
|
|
:section-data="currentData.riskPeople"
|
|
|
|
|
:selected-model-codes="selectedModelCodes"
|
|
|
|
|
@view-project-analysis="handleRiskPeopleProjectAnalysis"
|
|
|
|
|
/>
|
|
|
|
|
</section>
|
2026-03-23 14:08:47 +08:00
|
|
|
<risk-model-section
|
|
|
|
|
:section-data="currentData.riskModels"
|
|
|
|
|
@selection-change="handleRiskModelSelectionChange"
|
2026-03-25 14:02:45 +08:00
|
|
|
@view-project-analysis="handleRiskModelProjectAnalysis"
|
2026-03-23 14:08:47 +08:00
|
|
|
/>
|
2026-04-21 16:46:47 +08:00
|
|
|
<risk-detail-section
|
|
|
|
|
:section-data="currentData.riskDetails"
|
|
|
|
|
@evidence-confirm="$emit('evidence-confirm', $event)"
|
|
|
|
|
/>
|
2026-03-04 10:31:59 +08:00
|
|
|
</div>
|
2026-03-25 14:02:45 +08:00
|
|
|
<project-analysis-dialog
|
|
|
|
|
:visible.sync="projectAnalysisDialogVisible"
|
2026-03-25 15:26:03 +08:00
|
|
|
:project-id="projectId"
|
2026-03-25 14:02:45 +08:00
|
|
|
:person="currentProjectAnalysisPerson"
|
|
|
|
|
:source="projectAnalysisSource"
|
2026-03-25 15:26:03 +08:00
|
|
|
:model-summary="projectAnalysisModelSummary"
|
2026-03-25 14:05:30 +08:00
|
|
|
:project-name="projectInfo.projectName"
|
2026-03-25 14:02:45 +08:00
|
|
|
@close="handleProjectAnalysisDialogClose"
|
2026-04-21 16:46:47 +08:00
|
|
|
@evidence-confirm="$emit('evidence-confirm', $event)"
|
2026-03-25 14:02:45 +08:00
|
|
|
/>
|
2026-03-04 10:31:59 +08:00
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
2026-03-19 15:40:43 +08:00
|
|
|
import {
|
|
|
|
|
createOverviewLoadedData,
|
|
|
|
|
mockOverviewData,
|
|
|
|
|
mockOverviewStateData,
|
|
|
|
|
} from "./preliminaryCheck.mock";
|
|
|
|
|
import {
|
|
|
|
|
getOverviewDashboard,
|
2026-03-28 16:13:24 +08:00
|
|
|
getOverviewEmployeeCreditNegative,
|
2026-03-19 15:40:43 +08:00
|
|
|
getOverviewRiskPeople,
|
2026-03-20 11:24:32 +08:00
|
|
|
getOverviewRiskModelCards,
|
2026-03-27 17:26:47 +08:00
|
|
|
getOverviewSuspiciousTransactions,
|
2026-03-19 15:40:43 +08:00
|
|
|
} from "@/api/ccdi/projectOverview";
|
2026-03-19 10:36:45 +08:00
|
|
|
import OverviewStats from "./OverviewStats";
|
|
|
|
|
import RiskPeopleSection from "./RiskPeopleSection";
|
2026-03-19 10:37:53 +08:00
|
|
|
import RiskModelSection from "./RiskModelSection";
|
|
|
|
|
import RiskDetailSection from "./RiskDetailSection";
|
2026-03-25 14:02:45 +08:00
|
|
|
import ProjectAnalysisDialog from "./ProjectAnalysisDialog";
|
2026-03-19 10:35:40 +08:00
|
|
|
|
2026-03-04 10:31:59 +08:00
|
|
|
export default {
|
|
|
|
|
name: "PreliminaryCheck",
|
2026-03-19 10:35:40 +08:00
|
|
|
components: {
|
|
|
|
|
OverviewStats,
|
|
|
|
|
RiskPeopleSection,
|
|
|
|
|
RiskModelSection,
|
|
|
|
|
RiskDetailSection,
|
2026-03-25 14:02:45 +08:00
|
|
|
ProjectAnalysisDialog,
|
2026-03-19 10:35:40 +08:00
|
|
|
},
|
2026-03-04 10:31:59 +08:00
|
|
|
props: {
|
|
|
|
|
projectId: {
|
|
|
|
|
type: [String, Number],
|
|
|
|
|
default: null,
|
|
|
|
|
},
|
|
|
|
|
projectInfo: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: () => ({
|
|
|
|
|
projectName: "",
|
|
|
|
|
updateTime: "",
|
|
|
|
|
projectStatus: "0",
|
|
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-03-19 10:35:40 +08:00
|
|
|
data() {
|
|
|
|
|
return {
|
2026-03-19 15:40:43 +08:00
|
|
|
pageState: "loading",
|
2026-03-23 14:08:47 +08:00
|
|
|
selectedModelCodes: [],
|
2026-03-19 10:35:40 +08:00
|
|
|
mockData: mockOverviewData,
|
2026-03-19 10:39:24 +08:00
|
|
|
stateDataMap: mockOverviewStateData,
|
2026-03-19 15:40:43 +08:00
|
|
|
realData: mockOverviewData,
|
2026-03-25 14:02:45 +08:00
|
|
|
projectAnalysisDialogVisible: false,
|
|
|
|
|
currentProjectAnalysisPerson: null,
|
|
|
|
|
projectAnalysisSource: "riskPeople",
|
2026-03-25 15:26:03 +08:00
|
|
|
projectAnalysisModelSummary: {
|
|
|
|
|
modelCount: 0,
|
|
|
|
|
currentModel: "-",
|
|
|
|
|
riskTags: [],
|
|
|
|
|
},
|
2026-03-19 10:35:40 +08:00
|
|
|
};
|
|
|
|
|
},
|
2026-03-19 10:39:24 +08:00
|
|
|
computed: {
|
|
|
|
|
currentData() {
|
2026-03-19 15:40:43 +08:00
|
|
|
if (this.pageState === "loaded") {
|
|
|
|
|
return this.realData;
|
|
|
|
|
}
|
|
|
|
|
return this.stateDataMap[this.pageState] || this.realData;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
projectId(newVal) {
|
|
|
|
|
if (newVal) {
|
|
|
|
|
this.loadOverviewData();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.realData = this.stateDataMap.empty;
|
|
|
|
|
this.pageState = "empty";
|
2026-03-23 14:08:47 +08:00
|
|
|
this.selectedModelCodes = [];
|
2026-03-25 14:02:45 +08:00
|
|
|
this.resetProjectAnalysisDialog();
|
2026-03-19 15:40:43 +08:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
if (this.projectId) {
|
|
|
|
|
this.loadOverviewData();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.realData = this.stateDataMap.empty;
|
|
|
|
|
this.pageState = "empty";
|
2026-03-25 14:02:45 +08:00
|
|
|
this.resetProjectAnalysisDialog();
|
2026-03-19 15:40:43 +08:00
|
|
|
},
|
|
|
|
|
methods: {
|
2026-03-23 14:08:47 +08:00
|
|
|
handleRiskModelSelectionChange(modelCodes) {
|
|
|
|
|
this.selectedModelCodes = Array.isArray(modelCodes) ? [...modelCodes] : [];
|
|
|
|
|
},
|
2026-03-25 14:02:45 +08:00
|
|
|
handleRiskPeopleProjectAnalysis(row) {
|
|
|
|
|
this.openProjectAnalysisDialog("riskPeople", row);
|
|
|
|
|
},
|
|
|
|
|
handleRiskModelProjectAnalysis(row) {
|
|
|
|
|
this.openProjectAnalysisDialog("riskModelPeople", row);
|
|
|
|
|
},
|
|
|
|
|
openProjectAnalysisDialog(source, person) {
|
|
|
|
|
this.projectAnalysisSource = source || "riskPeople";
|
|
|
|
|
this.currentProjectAnalysisPerson = person || null;
|
2026-03-25 15:26:03 +08:00
|
|
|
this.projectAnalysisModelSummary = this.buildProjectAnalysisModelSummary(
|
|
|
|
|
this.projectAnalysisSource,
|
|
|
|
|
this.currentProjectAnalysisPerson
|
|
|
|
|
);
|
2026-03-25 14:02:45 +08:00
|
|
|
this.projectAnalysisDialogVisible = true;
|
|
|
|
|
},
|
|
|
|
|
handleProjectAnalysisDialogClose() {
|
|
|
|
|
this.projectAnalysisDialogVisible = false;
|
|
|
|
|
this.resetProjectAnalysisDialog();
|
|
|
|
|
},
|
|
|
|
|
resetProjectAnalysisDialog() {
|
|
|
|
|
this.projectAnalysisDialogVisible = false;
|
|
|
|
|
this.currentProjectAnalysisPerson = null;
|
|
|
|
|
this.projectAnalysisSource = "riskPeople";
|
2026-03-25 15:26:03 +08:00
|
|
|
this.projectAnalysisModelSummary = {
|
|
|
|
|
modelCount: 0,
|
|
|
|
|
currentModel: "-",
|
|
|
|
|
riskTags: [],
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
buildProjectAnalysisModelSummary(source, person) {
|
|
|
|
|
const safePerson = person || {};
|
|
|
|
|
const riskTags = Array.isArray(safePerson.riskPointTagList)
|
|
|
|
|
? safePerson.riskPointTagList
|
|
|
|
|
: Array.isArray(safePerson.hitTagList)
|
|
|
|
|
? safePerson.hitTagList
|
|
|
|
|
: [];
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
staffIdCard: safePerson.idNo || safePerson.staffIdCard || "",
|
|
|
|
|
modelCount: safePerson.modelCount || (Array.isArray(safePerson.modelNames) ? safePerson.modelNames.length : 0),
|
|
|
|
|
currentModel: source === "riskModelPeople"
|
|
|
|
|
? (Array.isArray(safePerson.modelNames) && safePerson.modelNames.length
|
|
|
|
|
? safePerson.modelNames.join("、")
|
|
|
|
|
: safePerson.modelName || "-")
|
|
|
|
|
: ((riskTags[0] && riskTags[0].modelName) || "-"),
|
|
|
|
|
riskTags,
|
|
|
|
|
};
|
2026-03-25 14:02:45 +08:00
|
|
|
},
|
2026-03-19 15:40:43 +08:00
|
|
|
async loadOverviewData() {
|
|
|
|
|
if (!this.projectId) {
|
|
|
|
|
this.realData = this.stateDataMap.empty;
|
|
|
|
|
this.pageState = "empty";
|
2026-03-23 14:08:47 +08:00
|
|
|
this.selectedModelCodes = [];
|
2026-03-25 14:02:45 +08:00
|
|
|
this.resetProjectAnalysisDialog();
|
2026-03-19 15:40:43 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.pageState = "loading";
|
2026-03-23 14:08:47 +08:00
|
|
|
this.selectedModelCodes = [];
|
2026-03-25 14:02:45 +08:00
|
|
|
this.resetProjectAnalysisDialog();
|
2026-03-19 15:40:43 +08:00
|
|
|
try {
|
2026-03-28 16:13:24 +08:00
|
|
|
const [dashboardRes, riskPeopleRes, riskModelCardsRes, suspiciousRes, creditNegativeRes] = await Promise.all([
|
2026-03-19 15:40:43 +08:00
|
|
|
getOverviewDashboard(this.projectId),
|
2026-03-29 18:44:07 +08:00
|
|
|
getOverviewRiskPeople({
|
|
|
|
|
projectId: this.projectId,
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
pageSize: 5,
|
|
|
|
|
}),
|
2026-03-20 11:24:32 +08:00
|
|
|
getOverviewRiskModelCards(this.projectId),
|
2026-03-27 17:26:47 +08:00
|
|
|
getOverviewSuspiciousTransactions({
|
|
|
|
|
projectId: this.projectId,
|
|
|
|
|
suspiciousType: "ALL",
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
pageSize: 5,
|
|
|
|
|
}),
|
2026-03-28 16:13:24 +08:00
|
|
|
getOverviewEmployeeCreditNegative({
|
|
|
|
|
projectId: this.projectId,
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
pageSize: 5,
|
|
|
|
|
}),
|
2026-03-19 15:40:43 +08:00
|
|
|
]);
|
|
|
|
|
const dashboardData = (dashboardRes && dashboardRes.data) || {};
|
|
|
|
|
const riskPeopleData = (riskPeopleRes && riskPeopleRes.data) || {};
|
2026-03-20 11:24:32 +08:00
|
|
|
const riskModelCardsData = (riskModelCardsRes && riskModelCardsRes.data) || {};
|
2026-03-27 17:26:47 +08:00
|
|
|
const suspiciousData = (suspiciousRes && suspiciousRes.data) || {};
|
2026-03-28 16:13:24 +08:00
|
|
|
const creditNegativeData = (creditNegativeRes && creditNegativeRes.data) || {};
|
2026-03-19 15:40:43 +08:00
|
|
|
|
|
|
|
|
this.realData = createOverviewLoadedData({
|
2026-03-20 11:24:32 +08:00
|
|
|
projectId: this.projectId,
|
2026-03-19 15:40:43 +08:00
|
|
|
dashboardData,
|
|
|
|
|
riskPeopleData,
|
2026-03-20 11:24:32 +08:00
|
|
|
riskModelCardsData,
|
2026-03-27 17:26:47 +08:00
|
|
|
suspiciousData,
|
2026-03-28 16:13:24 +08:00
|
|
|
creditNegativeData,
|
2026-03-19 15:40:43 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const hasOverviewData = Boolean(
|
|
|
|
|
(Array.isArray(dashboardData.stats) && dashboardData.stats.length) ||
|
2026-03-29 18:44:07 +08:00
|
|
|
(Array.isArray(riskPeopleData.rows) && riskPeopleData.rows.length) ||
|
2026-03-20 11:24:32 +08:00
|
|
|
(Array.isArray(riskModelCardsData.cardList) && riskModelCardsData.cardList.length)
|
2026-03-19 15:40:43 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
this.pageState = hasOverviewData ? "loaded" : "empty";
|
|
|
|
|
} catch (error) {
|
|
|
|
|
this.realData = this.stateDataMap.empty;
|
|
|
|
|
this.pageState = "empty";
|
2026-03-23 14:08:47 +08:00
|
|
|
this.selectedModelCodes = [];
|
2026-03-25 14:02:45 +08:00
|
|
|
this.resetProjectAnalysisDialog();
|
2026-03-19 15:40:43 +08:00
|
|
|
console.error("加载结果总览失败", error);
|
|
|
|
|
}
|
2026-03-19 10:39:24 +08:00
|
|
|
},
|
|
|
|
|
},
|
2026-03-04 10:31:59 +08:00
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.preliminary-check-container {
|
|
|
|
|
min-height: 400px;
|
2026-03-19 11:02:16 +08:00
|
|
|
padding: 0 0 24px;
|
2026-03-04 10:31:59 +08:00
|
|
|
}
|
|
|
|
|
|
2026-03-19 10:35:40 +08:00
|
|
|
.preliminary-check-state {
|
2026-03-19 10:39:24 +08:00
|
|
|
min-height: 400px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.state-card {
|
|
|
|
|
padding: 32px 24px;
|
2026-04-03 11:00:33 +08:00
|
|
|
border-radius: 14px;
|
2026-03-19 10:35:40 +08:00
|
|
|
background: #fff;
|
2026-04-03 11:00:33 +08:00
|
|
|
border: 1px solid var(--ccdi-border);
|
|
|
|
|
box-shadow: var(--ccdi-shadow);
|
2026-03-19 10:35:40 +08:00
|
|
|
}
|
2026-03-04 10:31:59 +08:00
|
|
|
|
2026-03-19 10:35:40 +08:00
|
|
|
.preliminary-check-page {
|
|
|
|
|
min-height: 400px;
|
2026-03-04 10:31:59 +08:00
|
|
|
}
|
2026-03-27 14:52:12 +08:00
|
|
|
|
|
|
|
|
.section-card {
|
|
|
|
|
padding: 20px;
|
2026-04-03 11:00:33 +08:00
|
|
|
border-radius: 14px;
|
2026-03-27 14:52:12 +08:00
|
|
|
background: #fff;
|
2026-04-03 11:00:33 +08:00
|
|
|
border: 1px solid var(--ccdi-border);
|
|
|
|
|
box-shadow: var(--ccdi-shadow);
|
2026-03-27 14:52:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.risk-overview-card {
|
|
|
|
|
margin-bottom: 16px;
|
2026-03-27 15:05:59 +08:00
|
|
|
padding: 24px 20px 20px;
|
2026-03-27 14:52:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.section-header {
|
2026-03-27 15:05:59 +08:00
|
|
|
margin-bottom: 18px;
|
|
|
|
|
padding-left: 12px;
|
2026-04-03 11:00:33 +08:00
|
|
|
border-left: 4px solid var(--ccdi-primary);
|
2026-03-27 14:52:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.section-title {
|
2026-03-27 15:05:59 +08:00
|
|
|
font-size: 20px;
|
|
|
|
|
line-height: 28px;
|
|
|
|
|
font-weight: 700;
|
2026-04-03 11:00:33 +08:00
|
|
|
color: var(--ccdi-text-primary);
|
2026-03-27 14:52:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.section-subtitle {
|
2026-03-27 15:05:59 +08:00
|
|
|
margin-top: 6px;
|
2026-03-27 14:52:12 +08:00
|
|
|
font-size: 12px;
|
2026-04-03 11:00:33 +08:00
|
|
|
color: var(--ccdi-text-muted);
|
2026-03-27 14:52:12 +08:00
|
|
|
}
|
2026-03-04 10:31:59 +08:00
|
|
|
</style>
|