实现结果总览详情资产和征信页签
This commit is contained in:
@@ -26,7 +26,7 @@ export function listCreditInfo(query) {
|
||||
|
||||
export function getCreditInfoDetail(personId) {
|
||||
return request({
|
||||
url: '/ccdi/creditInfo/' + personId,
|
||||
url: '/ccdi/creditInfo/' + encodeURIComponent(personId),
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<div class="credit-info-detail" v-loading="loading">
|
||||
<div class="section-title">征信摘要</div>
|
||||
<el-row :gutter="16" class="detail-summary">
|
||||
<el-col :span="8">征信查询日期:{{ formatQueryDate(detail.queryDate) }}</el-col>
|
||||
<el-col :span="8">负债笔数:{{ detail.debtCount || 0 }}</el-col>
|
||||
<el-col :span="8">负债总额:{{ formatAmount(detail.debtTotalAmount) }}</el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="section-title">负面信息</div>
|
||||
<el-row :gutter="16" class="detail-summary">
|
||||
<el-col :span="8">民事案件笔数:{{ detail.negativeInfo.civilCnt || 0 }}</el-col>
|
||||
<el-col :span="8">强制执行笔数:{{ detail.negativeInfo.enforceCnt || 0 }}</el-col>
|
||||
<el-col :span="8">行政处罚笔数:{{ detail.negativeInfo.admCnt || 0 }}</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16" class="detail-summary">
|
||||
<el-col :span="8">民事案件金额:{{ formatAmount(detail.negativeInfo.civilLmt) }}</el-col>
|
||||
<el-col :span="8">强制执行金额:{{ formatAmount(detail.negativeInfo.enforceLmt) }}</el-col>
|
||||
<el-col :span="8">行政处罚金额:{{ formatAmount(detail.negativeInfo.admLmt) }}</el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="section-title">负债信息</div>
|
||||
<el-table :data="detail.debts || []" size="mini">
|
||||
<template slot="empty">
|
||||
<el-empty :image-size="80" description="暂无征信负债信息" />
|
||||
</template>
|
||||
<el-table-column label="负债大类" prop="debtMainType" min-width="120" />
|
||||
<el-table-column label="负债小类" prop="debtSubType" min-width="120" />
|
||||
<el-table-column label="债权人类型" prop="creditorType" min-width="120" />
|
||||
<el-table-column label="负债名称" prop="debtName" min-width="180" />
|
||||
<el-table-column label="负债本金余额" min-width="120">
|
||||
<template slot-scope="scope">
|
||||
{{ formatAmount(scope.row.principalBalance) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="负债总额" min-width="120">
|
||||
<template slot-scope="scope">
|
||||
{{ formatAmount(scope.row.debtTotalAmount) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="负债状态" prop="debtStatus" min-width="120" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { parseTime } from "@/utils/ruoyi";
|
||||
|
||||
export default {
|
||||
name: "CreditInfoDetail",
|
||||
props: {
|
||||
detail: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
queryDate: undefined,
|
||||
debtCount: 0,
|
||||
debtTotalAmount: 0,
|
||||
negativeInfo: {},
|
||||
debts: [],
|
||||
}),
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
formatQueryDate(value) {
|
||||
if (!value) {
|
||||
return "-";
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
const matched = value.match(/^(\d{4}-\d{2}-\d{2})/);
|
||||
if (matched) {
|
||||
return matched[1];
|
||||
}
|
||||
}
|
||||
return parseTime(value, "{y}-{m}-{d}") || "-";
|
||||
},
|
||||
formatAmount(value) {
|
||||
const amount = Number(value || 0);
|
||||
if (!Number.isFinite(amount)) {
|
||||
return "0";
|
||||
}
|
||||
return amount.toLocaleString("zh-CN", {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.credit-info-detail {
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
margin-bottom: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.section-title:not(:first-child) {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.detail-summary {
|
||||
margin-bottom: 16px;
|
||||
line-height: 32px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,25 @@
|
||||
function sumDebtTotalAmount(debts) {
|
||||
if (!Array.isArray(debts)) {
|
||||
return 0;
|
||||
}
|
||||
return debts.reduce((total, item) => total + Number(item.debtTotalAmount || 0), 0);
|
||||
}
|
||||
|
||||
export function normalizeCreditDetail(data = {}, row = {}) {
|
||||
const negativeInfo = data.negativeInfo || {};
|
||||
const debts = Array.isArray(data.debtList) ? data.debtList : [];
|
||||
return {
|
||||
personId: data.personId || row.idCard || "",
|
||||
personName: data.personName || row.name || "",
|
||||
idCard: data.idCard || data.personId || row.idCard || "",
|
||||
queryDate: data.queryDate || negativeInfo.queryDate,
|
||||
debtCount: debts.length,
|
||||
debtTotalAmount: sumDebtTotalAmount(debts),
|
||||
negativeInfo,
|
||||
debts,
|
||||
};
|
||||
}
|
||||
|
||||
export function createEmptyCreditDetail() {
|
||||
return normalizeCreditDetail();
|
||||
}
|
||||
@@ -122,35 +122,7 @@
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="征信详情" :visible.sync="detailDialogVisible" width="960px" append-to-body>
|
||||
<div class="section-title">征信摘要</div>
|
||||
<el-row :gutter="16" class="detail-summary">
|
||||
<el-col :span="8">征信查询日期:{{ formatQueryDate(detailForm.queryDate) }}</el-col>
|
||||
<el-col :span="8">负债笔数:{{ detailForm.debtCount || 0 }}</el-col>
|
||||
<el-col :span="8">负债总额:{{ detailForm.debtTotalAmount || 0 }}</el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="section-title">负面信息</div>
|
||||
<el-row :gutter="16" class="detail-summary">
|
||||
<el-col :span="8">民事案件笔数:{{ detailForm.civilCnt || 0 }}</el-col>
|
||||
<el-col :span="8">强制执行笔数:{{ detailForm.enforceCnt || 0 }}</el-col>
|
||||
<el-col :span="8">行政处罚笔数:{{ detailForm.admCnt || 0 }}</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16" class="detail-summary">
|
||||
<el-col :span="8">民事案件金额:{{ detailForm.negativeInfo.civilLmt || 0 }}</el-col>
|
||||
<el-col :span="8">强制执行金额:{{ detailForm.negativeInfo.enforceLmt || 0 }}</el-col>
|
||||
<el-col :span="8">行政处罚金额:{{ detailForm.negativeInfo.admLmt || 0 }}</el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="section-title">负债信息</div>
|
||||
<el-table :data="detailForm.debts || []" size="mini">
|
||||
<el-table-column label="负债大类" prop="debtMainType" min-width="120" />
|
||||
<el-table-column label="负债小类" prop="debtSubType" min-width="120" />
|
||||
<el-table-column label="债权人类型" prop="creditorType" min-width="120" />
|
||||
<el-table-column label="负债名称" prop="debtName" min-width="180" />
|
||||
<el-table-column label="负债本金余额" prop="principalBalance" min-width="120" />
|
||||
<el-table-column label="负债总额" prop="debtTotalAmount" min-width="120" />
|
||||
<el-table-column label="负债状态" prop="debtStatus" min-width="120" />
|
||||
</el-table>
|
||||
<credit-info-detail :detail="detailForm" />
|
||||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
||||
@@ -166,9 +138,14 @@ import {
|
||||
listCreditInfo,
|
||||
uploadCreditHtml,
|
||||
} from "@/api/ccdiCreditInfo";
|
||||
import CreditInfoDetail from "./components/CreditInfoDetail.vue";
|
||||
import { createEmptyCreditDetail, normalizeCreditDetail } from "./components/creditDetailViewModel.js";
|
||||
|
||||
export default {
|
||||
name: "CcdiCreditInfo",
|
||||
components: {
|
||||
CreditInfoDetail,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
@@ -185,16 +162,7 @@ export default {
|
||||
},
|
||||
failureList: [],
|
||||
detailDialogVisible: false,
|
||||
detailForm: {
|
||||
queryDate: undefined,
|
||||
debtCount: 0,
|
||||
debtTotalAmount: 0,
|
||||
civilCnt: 0,
|
||||
enforceCnt: 0,
|
||||
admCnt: 0,
|
||||
negativeInfo: {},
|
||||
debts: [],
|
||||
},
|
||||
detailForm: createEmptyCreditDetail(),
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
@@ -289,19 +257,7 @@ export default {
|
||||
handleDetail(row) {
|
||||
return getCreditInfoDetail(row.idCard).then((response) => {
|
||||
const data = response.data || {};
|
||||
const negativeInfo = data.negativeInfo || {};
|
||||
this.detailForm = {
|
||||
personId: data.personId || row.idCard,
|
||||
personName: data.personName || row.name,
|
||||
queryDate: data.queryDate || negativeInfo.queryDate || row.queryDate,
|
||||
debtCount: row.debtCount || (data.debtList || []).length,
|
||||
debtTotalAmount: row.debtTotalAmount || 0,
|
||||
civilCnt: negativeInfo.civilCnt || row.civilCnt || 0,
|
||||
enforceCnt: negativeInfo.enforceCnt || row.enforceCnt || 0,
|
||||
admCnt: negativeInfo.admCnt || row.admCnt || 0,
|
||||
negativeInfo,
|
||||
debts: data.debtList || [],
|
||||
};
|
||||
this.detailForm = normalizeCreditDetail(data, row);
|
||||
this.detailDialogVisible = true;
|
||||
});
|
||||
},
|
||||
|
||||
@@ -54,10 +54,46 @@
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="资产分析" name="assetAnalysis">
|
||||
<project-analysis-placeholder-tab :tab-data="getTabData('assetAnalysis')" />
|
||||
<div class="project-analysis-tab-panel">
|
||||
<el-alert
|
||||
v-if="assetError"
|
||||
:closable="false"
|
||||
class="project-analysis-layout__alert"
|
||||
type="error"
|
||||
show-icon
|
||||
:title="assetError"
|
||||
>
|
||||
<template slot="default">
|
||||
<el-button type="text" size="mini" @click="fetchAssetDetailData">重试</el-button>
|
||||
</template>
|
||||
</el-alert>
|
||||
<family-asset-liability-detail
|
||||
v-else
|
||||
:detail="assetDetail"
|
||||
:loading="assetLoading"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="征信摘要" name="creditSummary">
|
||||
<project-analysis-placeholder-tab :tab-data="getTabData('creditSummary')" />
|
||||
<el-tab-pane label="征信详情" name="creditDetail">
|
||||
<div class="project-analysis-tab-panel">
|
||||
<el-alert
|
||||
v-if="creditError"
|
||||
:closable="false"
|
||||
class="project-analysis-layout__alert"
|
||||
type="error"
|
||||
show-icon
|
||||
:title="creditError"
|
||||
>
|
||||
<template slot="default">
|
||||
<el-button type="text" size="mini" @click="fetchCreditDetailData">重试</el-button>
|
||||
</template>
|
||||
</el-alert>
|
||||
<credit-info-detail
|
||||
v-else
|
||||
:detail="creditDetail"
|
||||
:loading="creditLoading"
|
||||
/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="关系图谱" name="relationshipGraph">
|
||||
<project-analysis-fund-flow-tab
|
||||
@@ -87,19 +123,24 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCreditInfoDetail } from "@/api/ccdiCreditInfo";
|
||||
import { getFamilyAssetLiabilityDetail } from "@/api/ccdi/projectSpecialCheck";
|
||||
import { getOverviewPersonAnalysisDetail } from "@/api/ccdi/projectOverview";
|
||||
import CreditInfoDetail from "@/views/ccdiCreditInfo/components/CreditInfoDetail.vue";
|
||||
import { createEmptyCreditDetail, normalizeCreditDetail } from "@/views/ccdiCreditInfo/components/creditDetailViewModel.js";
|
||||
import FamilyAssetLiabilityDetail from "./FamilyAssetLiabilityDetail";
|
||||
import ProjectAnalysisAbnormalTab from "./ProjectAnalysisAbnormalTab";
|
||||
import ProjectAnalysisFundFlowTab from "./ProjectAnalysisFundFlowTab";
|
||||
import ProjectAnalysisPlaceholderTab from "./ProjectAnalysisPlaceholderTab";
|
||||
import ProjectAnalysisSidebar from "./ProjectAnalysisSidebar";
|
||||
import { buildProjectAnalysisDialogData } from "./preliminaryCheck.mock";
|
||||
|
||||
export default {
|
||||
name: "ProjectAnalysisDialog",
|
||||
components: {
|
||||
CreditInfoDetail,
|
||||
FamilyAssetLiabilityDetail,
|
||||
ProjectAnalysisAbnormalTab,
|
||||
ProjectAnalysisFundFlowTab,
|
||||
ProjectAnalysisPlaceholderTab,
|
||||
ProjectAnalysisSidebar,
|
||||
},
|
||||
props: {
|
||||
@@ -137,6 +178,14 @@ export default {
|
||||
detailLoading: false,
|
||||
detailError: "",
|
||||
detailData: null,
|
||||
assetLoading: false,
|
||||
assetError: "",
|
||||
assetDetail: null,
|
||||
assetLoaded: false,
|
||||
creditLoading: false,
|
||||
creditError: "",
|
||||
creditDetail: createEmptyCreditDetail(),
|
||||
creditLoaded: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -175,6 +224,14 @@ export default {
|
||||
this.fetchDetailData();
|
||||
}
|
||||
},
|
||||
projectId() {
|
||||
this.resetAssetDetailState();
|
||||
this.resetCreditDetailState();
|
||||
},
|
||||
person() {
|
||||
this.resetAssetDetailState();
|
||||
this.resetCreditDetailState();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
resetDialogState() {
|
||||
@@ -182,6 +239,20 @@ export default {
|
||||
this.detailLoading = false;
|
||||
this.detailError = "";
|
||||
this.detailData = null;
|
||||
this.resetAssetDetailState();
|
||||
this.resetCreditDetailState();
|
||||
},
|
||||
resetAssetDetailState() {
|
||||
this.assetLoading = false;
|
||||
this.assetError = "";
|
||||
this.assetDetail = null;
|
||||
this.assetLoaded = false;
|
||||
},
|
||||
resetCreditDetailState() {
|
||||
this.creditLoading = false;
|
||||
this.creditError = "";
|
||||
this.creditDetail = createEmptyCreditDetail();
|
||||
this.creditLoaded = false;
|
||||
},
|
||||
resolveStaffIdCard() {
|
||||
return (this.modelSummary && this.modelSummary.staffIdCard)
|
||||
@@ -212,6 +283,55 @@ export default {
|
||||
handleRetryDetail() {
|
||||
this.fetchDetailData();
|
||||
},
|
||||
async fetchAssetDetailData() {
|
||||
if (this.assetLoaded || this.assetLoading) {
|
||||
return;
|
||||
}
|
||||
const staffIdCard = this.resolveStaffIdCard();
|
||||
if (!this.projectId || !staffIdCard) {
|
||||
this.assetError = "缺少项目或人员身份证号,无法加载资产详情";
|
||||
return;
|
||||
}
|
||||
this.assetLoading = true;
|
||||
this.assetError = "";
|
||||
try {
|
||||
const response = await getFamilyAssetLiabilityDetail(this.projectId, staffIdCard);
|
||||
this.assetDetail = (response && response.data) || {};
|
||||
this.assetLoaded = true;
|
||||
} catch (error) {
|
||||
this.assetDetail = null;
|
||||
this.assetLoaded = false;
|
||||
this.assetError = "资产详情加载失败,请稍后重试";
|
||||
console.error("加载资产详情失败", error);
|
||||
} finally {
|
||||
this.assetLoading = false;
|
||||
}
|
||||
},
|
||||
async fetchCreditDetailData() {
|
||||
if (this.creditLoaded || this.creditLoading) {
|
||||
return;
|
||||
}
|
||||
const staffIdCard = this.resolveStaffIdCard();
|
||||
if (!staffIdCard) {
|
||||
this.creditError = "缺少人员身份证号,无法加载征信详情";
|
||||
return;
|
||||
}
|
||||
this.creditLoading = true;
|
||||
this.creditError = "";
|
||||
try {
|
||||
const response = await getCreditInfoDetail(staffIdCard);
|
||||
const data = (response && response.data) || {};
|
||||
this.creditDetail = normalizeCreditDetail(data);
|
||||
this.creditLoaded = true;
|
||||
} catch (error) {
|
||||
this.creditDetail = createEmptyCreditDetail();
|
||||
this.creditLoaded = false;
|
||||
this.creditError = "征信详情加载失败,请稍后重试";
|
||||
console.error("加载征信详情失败", error);
|
||||
} finally {
|
||||
this.creditLoading = false;
|
||||
}
|
||||
},
|
||||
getTabData(tabKey) {
|
||||
return (
|
||||
this.dialogData.tabs.find((item) => item.key === tabKey) || {
|
||||
@@ -225,6 +345,12 @@ export default {
|
||||
this.$emit("close");
|
||||
},
|
||||
handleTabChange() {
|
||||
if (this.activeTab === "assetAnalysis") {
|
||||
this.fetchAssetDetailData();
|
||||
}
|
||||
if (this.activeTab === "creditDetail") {
|
||||
this.fetchCreditDetailData();
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
const tabRef = this.activeTab === "relationshipGraph"
|
||||
? this.$refs.relationshipGraphTab
|
||||
|
||||
@@ -193,12 +193,12 @@ export const projectAnalysisTabs = [
|
||||
{
|
||||
key: "assetAnalysis",
|
||||
label: "资产分析",
|
||||
description: "静态承载资产分析页签内容,本轮不接入新接口。",
|
||||
description: "展示员工家庭资产负债专项核查资产详情。",
|
||||
},
|
||||
{
|
||||
key: "creditSummary",
|
||||
label: "征信摘要",
|
||||
description: "静态承载征信摘要页签内容,本轮不接入新接口。",
|
||||
key: "creditDetail",
|
||||
label: "征信详情",
|
||||
description: "展示征信信息维护中的征信详情。",
|
||||
},
|
||||
{
|
||||
key: "relationshipGraph",
|
||||
|
||||
Reference in New Issue
Block a user