From f6a84442d18e8600b1e7370b0cffa17899df7d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wei=5F=E4=BD=B3?= Date: Wed, 26 Nov 2025 18:35:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=A1=E8=AE=A1=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E9=A1=B5=E5=BC=95=E5=85=A5=E6=9E=9A=E4=B8=BE=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=E5=B7=A5=E5=85=B7=EF=BC=8C=E7=BB=9F=E4=B8=80=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=9E=9A=E4=B8=BE=E5=AD=97=E6=AE=B5=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E5=B9=B6=E5=85=BC=E5=AE=B9=E5=A4=9A=E6=BA=90=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../audit/components/AuditDetail.vue | 46 ++++++-- web/src/views/valuation/audit/utils.js | 106 ++++++++++++++++-- 2 files changed, 135 insertions(+), 17 deletions(-) diff --git a/web/src/views/valuation/audit/components/AuditDetail.vue b/web/src/views/valuation/audit/components/AuditDetail.vue index b8832c4..b8302c5 100644 --- a/web/src/views/valuation/audit/components/AuditDetail.vue +++ b/web/src/views/valuation/audit/components/AuditDetail.vue @@ -28,6 +28,7 @@ import { formatPriceRange, formatThreeYearIncome, formatNumberValue, + formatEnumByKey, } from '../utils' import { mockReportMarkdown } from './mockData.js' @@ -42,6 +43,9 @@ const $message = useMessage() const activeDetailTab = ref('audit') +const pickFilledValue = (...values) => values.find((val) => val !== undefined && val !== null && val !== '') +const formatEnumField = (key, ...values) => formatEnumByKey(pickFilledValue(...values), key) + // 证书弹窗相关状态 const certificateModalVisible = ref(false) const certificateModalMode = ref('upload') // 'upload' 或 'view' @@ -77,21 +81,25 @@ const detailSections = computed(() => { { 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) }, - { label: '资产受资助情况', type: 'text', value: detail.funding_status || '-' }, + { label: '资产受资助情况', type: 'text', value: formatEnumField('fundingStatus', detail.funding_status) }, ], }, { key: 'tech', title: '非遗等级与技术', fields: [ - { label: '非遗传承人等级', type: 'text', value: detail.inheritor_level || '-' }, + { label: '非遗传承人等级', type: 'text', value: formatEnumField('inheritorLevel', detail.inheritor_level) }, { label: '非遗传承人年龄水平及数量', type: 'list', value: formatAgeDistribution(detail.inheritor_age_count || detail.inheritor_ages), }, { label: '非遗传承人等级证书', type: 'images', value: detail.inheritor_certificates || [] }, - { label: '非遗等级', type: 'text', value: detail.heritage_level || detail.heritage_asset_level || '-' }, + { + label: '非遗等级', + type: 'text', + value: formatEnumField('heritageLevel', detail.heritage_level, detail.heritage_asset_level), + }, { label: '非遗资产所用专利的申请号', type: 'text', value: detail.patent_application_no || '-' }, { label: '非遗资产历史证明证据及数量', type: 'list', value: formatHistoricalEvidence(detail.historical_evidence) }, { @@ -105,9 +113,21 @@ const detailSections = computed(() => { key: 'promotion', title: '非遗应用与推广', 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 || '-' }, + { + label: '非遗资产应用成熟度', + type: 'text', + value: formatEnumField('applicationMaturity', detail.application_maturity, detail.implementation_stage), + }, + { + label: '非遗资产应用覆盖范围', + type: 'text', + value: formatEnumField('applicationCoverage', detail.application_coverage, detail.coverage_area), + }, + { + label: '非遗资产跨界合作深度', + type: 'text', + value: formatEnumField('cooperationDepth', detail.cooperation_depth, detail.collaboration_type), + }, { label: '近12个月线下相关宣讲活动次数', type: 'text', @@ -122,9 +142,17 @@ const detailSections = computed(() => { 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 || '-' }, - { label: '最近一次市场活动时间', type: 'text', value: detail.last_market_activity || detail.market_activity_time || '-' }, - { label: '月交易额水平', type: 'text', value: detail.monthly_transaction || detail.monthly_transaction_amount || '-' }, + { label: '发行量', type: 'text', value: formatEnumField('circulation', detail.circulation, detail.scarcity_level) }, + { + label: '最近一次市场活动时间', + type: 'text', + value: formatEnumField('marketActivity', detail.last_market_activity, detail.market_activity_time), + }, + { + label: '月交易额水平', + type: 'text', + value: formatEnumField('monthlyTransaction', detail.monthly_transaction, detail.monthly_transaction_amount), + }, { label: '近30天价格区间', type: 'text', value: formatPriceRange(detail.price_fluctuation) }, ], }, diff --git a/web/src/views/valuation/audit/utils.js b/web/src/views/valuation/audit/utils.js index e0522be..74c89df 100644 --- a/web/src/views/valuation/audit/utils.js +++ b/web/src/views/valuation/audit/utils.js @@ -5,6 +5,84 @@ const platformLabelMap = { qita: '其他账号', } +// 估值表单枚举(与 web1/src/views/pages/index.vue 保持一致) +export const auditEnumOptions = { + fundingStatus: [ + { label: '国家级资助', value: '0' }, + { label: '省级资助', value: '1' }, + { label: '无资助', value: '2' }, + ], + inheritorLevel: [ + { label: '国家级传承人', value: '0' }, + { label: '省级传承人', value: '1' }, + { label: '市级传承人', value: '2' }, + ], + heritageLevel: [ + { label: '国家级非遗', value: '0' }, + { label: '省级非遗', value: '1' }, + { label: '纳入《国家文化数字化战略清单》', value: '2' }, + { label: '无', value: '3' }, + ], + applicationMaturity: [ + { label: '成熟应用', value: '0' }, + { label: '推广阶段', value: '1' }, + { label: '试点阶段', value: '2' }, + ], + applicationCoverage: [ + { label: '全球覆盖', value: '0' }, + { label: '全国覆盖', value: '1' }, + { label: '区域覆盖', value: '2' }, + ], + cooperationDepth: [ + { label: '无', value: '0' }, + { label: '品牌联名', value: '1' }, + { label: '科技载体', value: '2' }, + { label: '国家外交礼品', value: '3' }, + ], + marketActivity: [ + { label: '近一周', value: '0' }, + { label: '近一月', value: '1' }, + { label: '近一年', value: '2' }, + { label: '其他', value: '3' }, + ], + monthlyTransaction: [ + { label: '月交易额<100万元', value: '0' }, + { label: '月交易额>100万<500万', value: '1' }, + { label: '月交易额≥500万', value: '2' }, + ], + circulation: [ + { + label: '孤品:全球唯一,不可复制(如特定版权、唯一实物)', + value: '孤品:全球唯一,不可复制(如特定版权、唯一实物)', + }, + { label: '限量:总发行份数 ≤100份', value: '限量:总发行份数 ≤100份' }, + { + label: '稀有:总发行份数∈[100, 1000]份,或二级市场流通率 < 5%', + value: '稀有:总发行份数∈[100, 1000]份,或二级市场流通率 < 5%', + }, + { + label: '流通:总发行份数 >1000份,或二级市场流通率 ≥ 5%', + value: '流通:总发行份数 >1000份,或二级市场流通率 ≥ 5%', + }, + ], +} + +const normalizeEnumValue = (value) => { + if (value === null || value === undefined) return '' + return String(value) +} + +export const formatEnumValue = (value, options = []) => { + const normalized = normalizeEnumValue(value) + if (!normalized) return '-' + const matched = options.find( + (opt) => normalizeEnumValue(opt.value) === normalized || opt.label === value + ) + return matched?.label ?? value +} + +export const formatEnumByKey = (value, key) => formatEnumValue(value, auditEnumOptions[key] || []) + export const formatAmount = (amount) => { if (!amount && amount !== 0) return '-' return `¥${Number(amount).toLocaleString('zh-CN', { @@ -13,15 +91,23 @@ export const formatAmount = (amount) => { })}` } -export const formatNumberValue = (value, decimals = 0) => { +export const formatNumberValue = (value, decimals = null) => { if (value === null || value === undefined || value === '') return '-' - if (typeof value === 'number') { - return Number(value).toLocaleString('zh-CN', { - minimumFractionDigits: decimals, - maximumFractionDigits: decimals, - }) + + const numValue = Number(value) + if (isNaN(numValue)) return value + + // 如果没有指定小数位数,自动判断 + if (decimals === null) { + // 检查是否有小数部分 + const hasDecimal = numValue % 1 !== 0 + decimals = hasDecimal ? 2 : 0 } - return value + + return numValue.toLocaleString('zh-CN', { + minimumFractionDigits: decimals, + maximumFractionDigits: decimals, + }) } export const formatPercent = (value) => { @@ -31,7 +117,11 @@ export const formatPercent = (value) => { export const formatThreeYearIncome = (list = []) => { if (!Array.isArray(list) || !list.length) return ['暂无数据'] - return list.map((item, index) => `第${index + 1}年:${formatNumberValue(item)}`) + return list.map((item, index) => { + // 自动检测并保留小数 + const formattedValue = formatNumberValue(item) + return `第${index + 1}年:${formattedValue}` + }) } export const formatAgeDistribution = (list = []) => {