refactor: 优化估值审核详情页表格显示,改用NDataTable组件解决表头显示问题

This commit is contained in:
Wei_佳 2025-11-14 11:25:29 +08:00
parent b63306890d
commit 60b2a2777d

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { computed, ref, watch } from 'vue' import { computed, ref, watch, h } from 'vue'
import { import {
NButton, NButton,
NTag, NTag,
@ -8,6 +8,7 @@ import {
NSpin, NSpin,
NImage, NImage,
NImageGroup, NImageGroup,
NDataTable,
} from 'naive-ui' } from 'naive-ui'
import { formatDate } from '@/utils' import { formatDate } from '@/utils'
@ -45,11 +46,12 @@ watch(
const detailSections = computed(() => { const detailSections = computed(() => {
const detail = props.detailData const detail = props.detailData
if (!detail) return [] if (!detail) return []
return [
const sections = [
{ {
key: 'basic', key: 'basic',
title: '基础信息', title: '基础信息',
columns: [ fields: [
{ label: '资产名称', type: 'text', value: detail.asset_name || '-' }, { label: '资产名称', type: 'text', value: detail.asset_name || '-' },
{ label: '所属机构', type: 'text', value: detail.institution || '-' }, { label: '所属机构', type: 'text', value: detail.institution || '-' },
{ label: '所属行业', type: 'text', value: detail.industry || '-' }, { label: '所属行业', type: 'text', value: detail.industry || '-' },
@ -58,7 +60,7 @@ const detailSections = computed(() => {
{ {
key: 'finance', key: 'finance',
title: '财务状况', title: '财务状况',
columns: [ fields: [
{ label: '近12个月机构营收/万元', type: 'text', value: formatNumberValue(detail.annual_revenue) }, { label: '近12个月机构营收/万元', type: 'text', value: formatNumberValue(detail.annual_revenue) },
{ label: '近12个月机构研发投入/万元', type: 'text', value: formatNumberValue(detail.rd_investment) }, { label: '近12个月机构研发投入/万元', type: 'text', value: formatNumberValue(detail.rd_investment) },
{ label: '近三年机构收益/万元', type: 'list', value: formatThreeYearIncome(detail.three_year_income) }, { label: '近三年机构收益/万元', type: 'list', value: formatThreeYearIncome(detail.three_year_income) },
@ -68,7 +70,7 @@ const detailSections = computed(() => {
{ {
key: 'tech', key: 'tech',
title: '非遗等级与技术', title: '非遗等级与技术',
columns: [ fields: [
{ label: '非遗传承人等级', type: 'text', value: detail.inheritor_level || '-' }, { label: '非遗传承人等级', type: 'text', value: detail.inheritor_level || '-' },
{ label: '非遗传承人年龄水平及数量', type: 'list', value: formatAgeDistribution(detail.inheritor_age_count) }, { label: '非遗传承人年龄水平及数量', type: 'list', value: formatAgeDistribution(detail.inheritor_age_count) },
{ label: '非遗传承人等级证书', type: 'images', value: detail.inheritor_certificates || [] }, { label: '非遗传承人等级证书', type: 'images', value: detail.inheritor_certificates || [] },
@ -85,7 +87,7 @@ const detailSections = computed(() => {
{ {
key: 'promotion', key: 'promotion',
title: '非遗应用与推广', title: '非遗应用与推广',
columns: [ fields: [
{ label: '非遗资产应用成熟度', type: 'text', value: detail.application_maturity || detail.implementation_stage || '-' }, { label: '非遗资产应用成熟度', type: 'text', value: detail.application_maturity || detail.implementation_stage || '-' },
{ label: '非遗资产应用覆盖范围', type: 'text', value: detail.application_coverage || detail.coverage_area || '-' }, { label: '非遗资产应用覆盖范围', type: 'text', value: detail.application_coverage || detail.coverage_area || '-' },
{ label: '非遗资产跨界合作深度', type: 'text', value: detail.cooperation_depth || detail.collaboration_type || '-' }, { label: '非遗资产跨界合作深度', type: 'text', value: detail.cooperation_depth || detail.collaboration_type || '-' },
@ -96,7 +98,7 @@ const detailSections = computed(() => {
{ {
key: 'products', key: 'products',
title: '非遗资产衍生商品信息', title: '非遗资产衍生商品信息',
columns: [ fields: [
{ label: '代表产品近12个月销售数量', type: 'text', value: formatNumberValue(detail.sales_volume) }, { label: '代表产品近12个月销售数量', type: 'text', value: formatNumberValue(detail.sales_volume) },
{ label: '商品链接浏览量', type: 'text', value: formatNumberValue(detail.link_views) }, { label: '商品链接浏览量', type: 'text', value: formatNumberValue(detail.link_views) },
{ label: '发行量', type: 'text', value: detail.circulation || detail.scarcity_level || '-' }, { label: '发行量', type: 'text', value: detail.circulation || detail.scarcity_level || '-' },
@ -106,6 +108,73 @@ const detailSections = computed(() => {
], ],
}, },
] ]
// section NDataTable columns data
return sections.map(section => {
const columns = [
{
title: '字段名',
key: 'fieldName',
width: 120,
align: 'center',
fixed: 'left',
},
...section.fields.map(field => ({
title: field.label,
key: field.label,
width: 200,
ellipsis: {
tooltip: true,
},
render: (row) => {
const fieldData = row[field.label]
if (!fieldData) return '-'
if (fieldData.type === 'list') {
if (fieldData.value && fieldData.value.length) {
return h('div', { class: 'cell-multi' },
fieldData.value.map(item => h('span', item))
)
}
return '-'
} else if (fieldData.type === 'images') {
if (fieldData.value && fieldData.value.length) {
return h(NImageGroup, {}, () =>
fieldData.value.map(img =>
h(NImage, {
src: img,
width: 72,
height: 48,
objectFit: 'cover',
style: 'margin-right: 8px;'
})
)
)
}
return '-'
} else {
return fieldData.value || '-'
}
}
})),
]
const data = [
{
fieldName: '用户输入',
...section.fields.reduce((acc, field) => {
acc[field.label] = field
return acc
}, {}),
},
]
return {
...section,
columns,
data,
}
})
}) })
const calcFlow = computed(() => props.detailData?.calculation_result?.flow || []) const calcFlow = computed(() => props.detailData?.calculation_result?.flow || [])
@ -152,47 +221,17 @@ const calcFlow = computed(() => props.detailData?.calculation_result?.flow || []
<span class="dot" /> <span class="dot" />
<span>{{ section.title }}</span> <span>{{ section.title }}</span>
</div> </div>
<div class="table-wrapper"> <NDataTable
<table class="info-table"> :columns="section.columns"
<thead> :data="section.data"
<tr> :bordered="true"
<th class="first-col">字段名</th> :single-line="false"
<th v-for="column in section.columns" :key="column.label"> :scroll-x="section.fields.length * 200 + 120"
{{ column.label }} >
</th> <template #empty>
</tr> <span>暂无数据</span>
</thead> </template>
<tbody> </NDataTable>
<tr>
<td class="first-col">用户输入</td>
<td v-for="column in section.columns" :key="column.label">
<div v-if="column.type === 'list'" class="cell-multi">
<template v-if="column.value && column.value.length">
<span v-for="(item, idx) in column.value" :key="idx">{{ item }}</span>
</template>
<span v-else>-</span>
</div>
<div v-else-if="column.type === 'images'">
<template v-if="column.value && column.value.length">
<NImageGroup>
<NImage
v-for="(img, idx) in column.value"
:key="idx"
width="72"
height="48"
:src="img"
object-fit="cover"
/>
</NImageGroup>
</template>
<span v-else>-</span>
</div>
<span v-else>{{ column.value || '-' }}</span>
</td>
</tr>
</tbody>
</table>
</div>
</div> </div>
</NSpin> </NSpin>
</NTabPane> </NTabPane>
@ -305,36 +344,24 @@ const calcFlow = computed(() => props.detailData?.calculation_result?.flow || []
background: #409eff; background: #409eff;
} }
.table-wrapper { .detail-section :deep(.n-data-table) {
overflow-x: auto;
}
.info-table {
width: 100%;
border-collapse: collapse;
background: #f9fafe; background: #f9fafe;
table-layout: fixed;
} }
.info-table th, .detail-section :deep(.n-data-table-th) {
.info-table td {
border: 1px solid #e5e6eb;
padding: 12px;
text-align: left;
min-width: 140px;
word-break: break-word;
}
.info-table .first-col {
width: 120px;
text-align: center;
background: #f1f2f5; background: #f1f2f5;
font-weight: 600; font-weight: 600;
} }
.info-table th:not(.first-col), .detail-section :deep(.n-data-table-th:first-child) {
.info-table td:not(.first-col) { background: #f1f2f5;
width: 180px; text-align: center;
}
.detail-section :deep(.n-data-table-td:first-child) {
background: #f1f2f5;
text-align: center;
font-weight: 600;
} }
.cell-multi { .cell-multi {