refactor: 优化估值审核详情页表格显示,改用NDataTable组件解决表头显示问题
This commit is contained in:
parent
b63306890d
commit
60b2a2777d
@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { computed, ref, watch, h } from 'vue'
|
||||
import {
|
||||
NButton,
|
||||
NTag,
|
||||
@ -8,6 +8,7 @@ import {
|
||||
NSpin,
|
||||
NImage,
|
||||
NImageGroup,
|
||||
NDataTable,
|
||||
} from 'naive-ui'
|
||||
|
||||
import { formatDate } from '@/utils'
|
||||
@ -45,11 +46,12 @@ watch(
|
||||
const detailSections = computed(() => {
|
||||
const detail = props.detailData
|
||||
if (!detail) return []
|
||||
return [
|
||||
|
||||
const sections = [
|
||||
{
|
||||
key: 'basic',
|
||||
title: '基础信息',
|
||||
columns: [
|
||||
fields: [
|
||||
{ label: '资产名称', type: 'text', value: detail.asset_name || '-' },
|
||||
{ label: '所属机构', type: 'text', value: detail.institution || '-' },
|
||||
{ label: '所属行业', type: 'text', value: detail.industry || '-' },
|
||||
@ -58,7 +60,7 @@ const detailSections = computed(() => {
|
||||
{
|
||||
key: 'finance',
|
||||
title: '财务状况',
|
||||
columns: [
|
||||
fields: [
|
||||
{ label: '近12个月机构营收/万元', type: 'text', value: formatNumberValue(detail.annual_revenue) },
|
||||
{ label: '近12个月机构研发投入/万元', type: 'text', value: formatNumberValue(detail.rd_investment) },
|
||||
{ label: '近三年机构收益/万元', type: 'list', value: formatThreeYearIncome(detail.three_year_income) },
|
||||
@ -68,7 +70,7 @@ const detailSections = computed(() => {
|
||||
{
|
||||
key: 'tech',
|
||||
title: '非遗等级与技术',
|
||||
columns: [
|
||||
fields: [
|
||||
{ label: '非遗传承人等级', type: 'text', value: detail.inheritor_level || '-' },
|
||||
{ label: '非遗传承人年龄水平及数量', type: 'list', value: formatAgeDistribution(detail.inheritor_age_count) },
|
||||
{ label: '非遗传承人等级证书', type: 'images', value: detail.inheritor_certificates || [] },
|
||||
@ -85,7 +87,7 @@ const detailSections = computed(() => {
|
||||
{
|
||||
key: 'promotion',
|
||||
title: '非遗应用与推广',
|
||||
columns: [
|
||||
fields: [
|
||||
{ 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.cooperation_depth || detail.collaboration_type || '-' },
|
||||
@ -96,7 +98,7 @@ const detailSections = computed(() => {
|
||||
{
|
||||
key: 'products',
|
||||
title: '非遗资产衍生商品信息',
|
||||
columns: [
|
||||
fields: [
|
||||
{ label: '代表产品近12个月销售数量', type: 'text', value: formatNumberValue(detail.sales_volume) },
|
||||
{ label: '商品链接浏览量', type: 'text', value: formatNumberValue(detail.link_views) },
|
||||
{ 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 || [])
|
||||
@ -152,47 +221,17 @@ const calcFlow = computed(() => props.detailData?.calculation_result?.flow || []
|
||||
<span class="dot" />
|
||||
<span>{{ section.title }}</span>
|
||||
</div>
|
||||
<div class="table-wrapper">
|
||||
<table class="info-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="first-col">字段名</th>
|
||||
<th v-for="column in section.columns" :key="column.label">
|
||||
{{ column.label }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<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>
|
||||
<NDataTable
|
||||
:columns="section.columns"
|
||||
:data="section.data"
|
||||
:bordered="true"
|
||||
:single-line="false"
|
||||
:scroll-x="section.fields.length * 200 + 120"
|
||||
>
|
||||
<template #empty>
|
||||
<span>暂无数据</span>
|
||||
</template>
|
||||
</NDataTable>
|
||||
</div>
|
||||
</NSpin>
|
||||
</NTabPane>
|
||||
@ -305,36 +344,24 @@ const calcFlow = computed(() => props.detailData?.calculation_result?.flow || []
|
||||
background: #409eff;
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.info-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
.detail-section :deep(.n-data-table) {
|
||||
background: #f9fafe;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.info-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;
|
||||
.detail-section :deep(.n-data-table-th) {
|
||||
background: #f1f2f5;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.info-table th:not(.first-col),
|
||||
.info-table td:not(.first-col) {
|
||||
width: 180px;
|
||||
.detail-section :deep(.n-data-table-th:first-child) {
|
||||
background: #f1f2f5;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.detail-section :deep(.n-data-table-td:first-child) {
|
||||
background: #f1f2f5;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.cell-multi {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user