From 6718b51fb9b56ee237acaf34c7b4a41a994ad15e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=A5=E6=8B=99=5F233?= <342879248@qq.com> Date: Wed, 10 Dec 2025 16:23:24 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=96=B0=E5=A2=9E7=E5=A4=A9=E6=B5=8F?= =?UTF-8?q?=E8=A7=88=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../audit/components/AuditDetail.vue | 280 +++++++++++------- web/src/views/valuation/audit/utils.js | 2 +- 2 files changed, 182 insertions(+), 100 deletions(-) diff --git a/web/src/views/valuation/audit/components/AuditDetail.vue b/web/src/views/valuation/audit/components/AuditDetail.vue index cefbecd..6c2048d 100644 --- a/web/src/views/valuation/audit/components/AuditDetail.vue +++ b/web/src/views/valuation/audit/components/AuditDetail.vue @@ -46,7 +46,8 @@ const activeDetailTab = ref('audit') const reportLoading = ref(false) const reportContent = ref('') -const pickFilledValue = (...values) => values.find((val) => val !== undefined && val !== null && val !== '') +const pickFilledValue = (...values) => + values.find((val) => val !== undefined && val !== null && val !== '') const formatEnumField = (key, ...values) => formatEnumByKey(pickFilledValue(...values), key) // 证书弹窗相关状态 @@ -72,7 +73,7 @@ watch(activeDetailTab, async (newTab) => { // 获取报告内容 const fetchReport = async () => { if (!props.detailData?.id) return - + reportLoading.value = true try { const response = await api.getValuationReport({ valuation_id: props.detailData.id }) @@ -89,7 +90,7 @@ const fetchReport = async () => { const detailSections = computed(() => { const detail = props.detailData if (!detail) return [] - + const sections = [ { key: 'basic', @@ -97,7 +98,11 @@ const detailSections = computed(() => { fields: [ { label: '资产名称', type: 'text', value: detail.asset_name || '-' }, { label: '所属机构/权利人', type: 'text', value: detail.institution || '-' }, - { label: '统一社会信用代码/身份证号', type: 'text', value: detail.credit_code_or_id || '-' }, + { + label: '统一社会信用代码/身份证号', + type: 'text', + value: detail.credit_code_or_id || '-', + }, { label: '所属行业', type: 'text', value: detail.industry || '-' }, { label: '业务/传承介绍', type: 'text', value: detail.biz_intro || '-' }, ], @@ -106,17 +111,37 @@ const detailSections = computed(() => { key: 'finance', title: '财务状况', 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) }, - { label: '资产受资助情况', type: 'text', value: formatEnumField('fundingStatus', detail.funding_status) }, + { + 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: formatEnumField('fundingStatus', detail.funding_status), + }, ], }, { key: 'tech', title: '非遗等级与技术', fields: [ - { label: '非遗传承人等级', type: 'text', value: formatEnumField('inheritorLevel', detail.inheritor_level) }, + { + label: '非遗传承人等级', + type: 'text', + value: formatEnumField('inheritorLevel', detail.inheritor_level), + }, { label: '非遗传承人年龄水平及数量', type: 'list', @@ -126,10 +151,22 @@ const detailSections = computed(() => { { label: '非遗等级', type: 'text', - value: formatEnumField('heritageLevel', detail.heritage_level, detail.heritage_asset_level), + 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), }, - { label: '非遗资产所用专利的申请号', type: 'text', value: detail.patent_application_no || '-' }, - { label: '非遗资产历史证明证据及数量', type: 'list', value: formatHistoricalEvidence(detail.historical_evidence) }, { label: '非遗资产所用专利/纹样图片', type: 'images', @@ -144,50 +181,86 @@ const detailSections = computed(() => { { label: '非遗资产应用成熟度', type: 'text', - value: formatEnumField('applicationMaturity', detail.application_maturity, detail.implementation_stage), + value: formatEnumField( + 'applicationMaturity', + detail.application_maturity, + detail.implementation_stage + ), }, { label: '非遗资产应用覆盖范围', type: 'text', - value: formatEnumField('applicationCoverage', detail.application_coverage, detail.coverage_area), + value: formatEnumField( + 'applicationCoverage', + detail.application_coverage, + detail.coverage_area + ), }, { label: '非遗资产跨界合作深度', type: 'text', - value: formatEnumField('cooperationDepth', detail.cooperation_depth, detail.collaboration_type), + value: formatEnumField( + 'cooperationDepth', + detail.cooperation_depth, + detail.collaboration_type + ), }, { label: '近12个月线下相关宣讲活动次数', type: 'text', value: formatNumberValue(detail.offline_activities ?? detail.offline_teaching_count), }, - { label: '线上相关宣传账号信息', type: 'list', value: formatPlatformAccounts(detail.platform_accounts) }, + { + label: '线上相关宣传账号信息', + type: 'list', + value: formatPlatformAccounts(detail.platform_accounts), + }, ], }, { key: 'products', title: '非遗资产衍生商品信息', 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: formatEnumField('circulation', detail.circulation, detail.scarcity_level) }, + { + 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), + value: formatEnumField( + 'marketActivity', + detail.last_market_activity, + detail.market_activity_time + ), }, { label: '月交易额水平', type: 'text', - value: formatEnumField('monthlyTransaction', detail.monthly_transaction, detail.monthly_transaction_amount), + value: formatEnumField( + 'monthlyTransaction', + detail.monthly_transaction, + detail.monthly_transaction_amount + ), + }, + { + label: '近30天价格区间', + type: 'text', + value: formatPriceRange(detail.price_fluctuation), }, - { label: '近30天价格区间', type: 'text', value: formatPriceRange(detail.price_fluctuation) }, ], }, ] // 为每个 section 生成 NDataTable 需要的 columns 和 data - return sections.map(section => { + return sections.map((section) => { const columns = [ { title: '字段名', @@ -196,55 +269,65 @@ const detailSections = computed(() => { align: 'center', fixed: 'left', }, - ...section.fields.map(field => ({ + ...section.fields.map((field) => ({ title: field.label, key: field.label, width: 200, - ellipsis: ['list', 'images'].includes(field.type) ? false : { - tooltip: { - style: { maxWidth: '600px', maxHeight: '400px', overflow: 'auto' } - }, - }, + ellipsis: ['list', 'images'].includes(field.type) + ? false + : { + tooltip: { + style: { maxWidth: '600px', maxHeight: '400px', overflow: 'auto' }, + }, + }, render: (row) => { const fieldData = row[field.label] if (!fieldData) return '-' - + if (fieldData.type === 'list') { if (fieldData.value && fieldData.value.length) { - return h('div', { style: 'display: flex; flex-direction: column; gap: 4px;' }, - fieldData.value.map(item => h('span', item)) + return h( + 'div', + { style: 'display: flex; flex-direction: column; gap: 4px;' }, + fieldData.value.map((item) => h('span', item)) ) } return '-' } else if (fieldData.type === 'images') { if (fieldData.value && fieldData.value.length) { - const createImages = () => h(NImageGroup, {}, () => - fieldData.value.map(img => - h(NImage, { - src: img, - width: 72, - height: 48, - objectFit: 'cover', - style: 'margin-right: 8px;' - }) + const createImages = () => + h(NImageGroup, {}, () => + fieldData.value.map((img) => + h(NImage, { + src: img, + width: 72, + height: 48, + objectFit: 'cover', + style: 'margin-right: 8px;', + }) + ) ) - ) - return h(NPopover, { - trigger: 'hover', - displayDirective: 'show', - keepAliveOnHover: true, - style: { maxWidth: '600px', maxHeight: '400px', overflow: 'auto' } - }, { - trigger: () => h('div', { style: 'display: flex; overflow: hidden;' }, createImages()), - default: () => createImages() - }) + return h( + NPopover, + { + trigger: 'hover', + displayDirective: 'show', + keepAliveOnHover: true, + style: { maxWidth: '600px', maxHeight: '400px', overflow: 'auto' }, + }, + { + trigger: () => + h('div', { style: 'display: flex; overflow: hidden;' }, createImages()), + default: () => createImages(), + } + ) } return '-' } else { return fieldData.value || '-' } - } + }, })), ] @@ -268,64 +351,64 @@ const detailSections = computed(() => { const calcFlow = computed(() => props.detailData?.calculation_result?.flow || []) - - const renderedFlowHtml = computed(() => { return marked.parse(reportContent.value || mockReportMarkdown) }) - // 证书相关功能 const handleUploadCertificate = () => { certificateModalMode.value = 'upload' certificateData.value = { - detailData: props.detailData + detailData: props.detailData, } certificateModalVisible.value = true } const handleViewCertificate = () => { certificateModalMode.value = 'view' - + const formatFiles = (urlData) => { if (!urlData) return [] // Handle string (single or comma-separated) - const urls = typeof urlData === 'string' ? urlData.split(',') : (Array.isArray(urlData) ? urlData : []) - - return urls.filter(u => u).map((url, index) => ({ - id: String(index), - name: url.substring(url.lastIndexOf('/') + 1) || 'unknown', - status: 'finished', - url: url - })) + const urls = + typeof urlData === 'string' ? urlData.split(',') : Array.isArray(urlData) ? urlData : [] + + return urls + .filter((u) => u) + .map((url, index) => ({ + id: String(index), + name: url.substring(url.lastIndexOf('/') + 1) || 'unknown', + status: 'finished', + url: url, + })) } certificateData.value = { reportFiles: formatFiles(props.detailData?.report_url), certificateFiles: formatFiles(props.detailData?.certificate_url), - detailData: props.detailData + detailData: props.detailData, } certificateModalVisible.value = true } const handleCertificateConfirm = async (data) => { console.log('证书数据:', data) - + try { - const certificateUrl = data.certificateFiles?.map(f => f.url).filter(Boolean) || [] - const reportUrl = data.reportFiles?.map(f => f.url).filter(Boolean) || [] - + const certificateUrl = data.certificateFiles?.map((f) => f.url).filter(Boolean) || [] + const reportUrl = data.reportFiles?.map((f) => f.url).filter(Boolean) || [] + // 现在改为只能上传 1 张 const payload = { ...props.detailData, certificate_url: certificateUrl?.[0], report_url: reportUrl?.[0], - status: 'success' + status: 'success', } - console.log("🔥🔥🔥🔥🔥🔥🔥 ~ handleCertificateConfirm ~ payload:", payload); + console.log('🔥🔥🔥🔥🔥🔥🔥 ~ handleCertificateConfirm ~ payload:', payload) await api.updateValuation(payload) - + $message.success('上传并通知成功') certificateModalVisible.value = false emit('back') // 或者 emit('refresh') 取决于需求,这里假设返回列表或刷新 @@ -359,12 +442,7 @@ const handleCertificateConfirm = async (data) => { - +
@@ -395,19 +473,11 @@ const handleCertificateConfirm = async (data) => {
- + 上传证书 - + 查看证书 @@ -441,7 +511,7 @@ const handleCertificateConfirm = async (data) => { display: flex; justify-content: space-between; gap: 16px; - margin: -16px 0px 10px ; + margin: -16px 0px 10px; } .back-btn { @@ -556,8 +626,8 @@ const handleCertificateConfirm = async (data) => { line-height: 1.6; color: #333; } -.markdown-body :deep(h1), -.markdown-body :deep(h2), +.markdown-body :deep(h1), +.markdown-body :deep(h2), .markdown-body :deep(h3), .markdown-body :deep(h4), .markdown-body :deep(h5), @@ -567,10 +637,23 @@ const handleCertificateConfirm = async (data) => { font-weight: 600; line-height: 1.25; } -.markdown-body :deep(h1) { font-size: 2em; border-bottom: 1px solid #eaecef; padding-bottom: .3em; } -.markdown-body :deep(h2) { font-size: 1.5em; border-bottom: 1px solid #eaecef; padding-bottom: .3em; } -.markdown-body :deep(h3) { font-size: 1.25em; } -.markdown-body :deep(p) { margin-top: 0; margin-bottom: 16px; } +.markdown-body :deep(h1) { + font-size: 2em; + border-bottom: 1px solid #eaecef; + padding-bottom: 0.3em; +} +.markdown-body :deep(h2) { + font-size: 1.5em; + border-bottom: 1px solid #eaecef; + padding-bottom: 0.3em; +} +.markdown-body :deep(h3) { + font-size: 1.25em; +} +.markdown-body :deep(p) { + margin-top: 0; + margin-bottom: 16px; +} .markdown-body :deep(blockquote) { margin: 0 0 16px; padding: 0 1em; @@ -592,7 +675,8 @@ const handleCertificateConfirm = async (data) => { .markdown-body :deep(table tr:nth-child(2n)) { background-color: #f6f8fa; } -.markdown-body :deep(table th), .markdown-body :deep(table td) { +.markdown-body :deep(table th), +.markdown-body :deep(table td) { padding: 6px 13px; border: 1px solid #dfe2e5; } @@ -603,7 +687,7 @@ const handleCertificateConfirm = async (data) => { padding: 0.2em 0.4em; margin: 0; font-size: 85%; - background-color: rgba(27,31,35,0.05); + background-color: rgba(27, 31, 35, 0.05); border-radius: 3px; } .markdown-body :deep(pre) { @@ -767,6 +851,4 @@ const handleCertificateConfirm = async (data) => { color: #999; padding: 40px 0; } - - diff --git a/web/src/views/valuation/audit/utils.js b/web/src/views/valuation/audit/utils.js index b6fa487..46c1d6c 100644 --- a/web/src/views/valuation/audit/utils.js +++ b/web/src/views/valuation/audit/utils.js @@ -148,7 +148,7 @@ export const formatPlatformAccounts = (accounts = {}) => { if (!info) return `${label}:-` return `${label}:${info.account || '-'}(赞${formatNumberValue(info.likes)} / 评${formatNumberValue( info.comments - )} / 转${formatNumberValue(info.shares)})` + )} / 转${formatNumberValue(info.shares)}/ 七日浏览量${formatNumberValue(info.views)})` }) return list.length ? list : ['暂无账号信息'] }