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

212 lines
5.7 KiB
Vue

<template>
<section class="family-asset-liability-section">
<div class="section-card">
<div class="block-header">
<div>
<div class="block-title">{{ title }}</div>
<div class="block-subtitle">{{ subtitle }}</div>
</div>
</div>
<el-table
ref="familyTable"
v-loading="loading"
:data="rows"
class="family-table"
row-key="staffIdCard"
:expand-row-keys="expandedRowKeys"
>
<template slot="empty">
<el-empty :image-size="80" description="暂无员工家庭资产负债核查数据" />
</template>
<el-table-column type="expand" width="1">
<template slot-scope="scope">
<family-asset-liability-detail
:detail="detailCache[scope.row.staffIdCard]"
:loading="Boolean(detailLoadingMap[scope.row.staffIdCard])"
/>
</template>
</el-table-column>
<el-table-column type="index" label="序号" width="60" />
<el-table-column prop="staffName" label="姓名" min-width="100" />
<el-table-column prop="staffIdCard" label="身份证号" min-width="180" />
<el-table-column prop="deptName" label="所属部门" min-width="140" />
<el-table-column label="家庭总年收入" min-width="140">
<template slot-scope="scope">
<span>{{ formatAmount(scope.row.totalIncome) }}</span>
</template>
</el-table-column>
<el-table-column label="家庭总资产" min-width="140">
<template slot-scope="scope">
<span>{{ formatAmount(scope.row.totalAsset) }}</span>
</template>
</el-table-column>
<el-table-column label="家庭总负债" min-width="140">
<template slot-scope="scope">
<span>{{ formatAmount(scope.row.totalDebt) }}</span>
</template>
</el-table-column>
<el-table-column label="风险情况" min-width="120">
<template slot-scope="scope">
<el-tag size="mini" effect="plain" :type="resolveRiskTagType(scope.row.riskLevelCode)">
{{ scope.row.riskLevelName || "-" }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="100" align="right">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="handleToggleDetail(scope.row)">
查看详情
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</section>
</template>
<script>
import { getFamilyAssetLiabilityDetail } from "@/api/ccdi/projectSpecialCheck";
import FamilyAssetLiabilityDetail from "./FamilyAssetLiabilityDetail";
export default {
name: "FamilyAssetLiabilitySection",
components: {
FamilyAssetLiabilityDetail,
},
props: {
rows: {
type: Array,
default: () => [],
},
loading: {
type: Boolean,
default: false,
},
projectId: {
type: [String, Number],
default: null,
},
title: {
type: String,
default: "员工家庭资产负债专项核查",
},
subtitle: {
type: String,
default: "展示项目内员工家庭收入、资产、负债与风险情况",
},
},
data() {
return {
expandedStaffIdCard: "",
detailCache: {},
detailLoadingMap: {},
};
},
computed: {
expandedRowKeys() {
return this.expandedStaffIdCard ? [this.expandedStaffIdCard] : [];
},
},
watch: {
projectId() {
this.resetDetailState();
},
},
methods: {
resolveRiskTagType(riskLevelCode) {
const riskTagTypeMap = {
NORMAL: "success",
RISK: "warning",
HIGH: "danger",
MISSING_INFO: "info",
};
return riskTagTypeMap[riskLevelCode] || "info";
},
formatAmount(value) {
const amount = Number(value || 0);
return `${amount.toLocaleString("zh-CN", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})} 元`;
},
async handleToggleDetail(row) {
if (!row || !row.staffIdCard) {
return;
}
if (this.expandedStaffIdCard === row.staffIdCard) {
this.expandedStaffIdCard = "";
return;
}
this.expandedStaffIdCard = row.staffIdCard;
if (!this.detailCache[row.staffIdCard]) {
await this.loadFamilyDetail(row);
}
},
async loadFamilyDetail(row) {
const staffIdCard = row.staffIdCard;
this.$set(this.detailLoadingMap, staffIdCard, true);
try {
const response = await getFamilyAssetLiabilityDetail(this.projectId, staffIdCard);
const detail = (response && response.data) || {};
this.$set(this.detailCache, staffIdCard, detail);
} catch (error) {
this.$set(this.detailCache, staffIdCard, null);
console.error("加载员工家庭资产负债详情失败", error);
} finally {
this.$set(this.detailLoadingMap, staffIdCard, false);
}
},
resetDetailState() {
this.expandedStaffIdCard = "";
this.detailCache = {};
this.detailLoadingMap = {};
},
},
};
</script>
<style lang="scss" scoped>
.family-asset-liability-section {
margin-bottom: 16px;
}
.section-card {
padding: 20px;
border-radius: 0;
background: #fff;
box-shadow: 0 8px 24px rgba(15, 23, 42, 0.06);
}
.block-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 14px;
}
.block-title {
font-size: 16px;
font-weight: 600;
color: #1f2937;
}
.block-subtitle {
margin-top: 4px;
font-size: 12px;
color: #94a3b8;
}
.family-table {
border-radius: 12px;
overflow: hidden;
}
:deep(.family-table th) {
background: #f8fafc;
color: #64748b;
}
</style>