From b63306890dde3eda7e163df704b62be3b881f9ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wei=5F=E4=BD=B3?= Date: Thu, 13 Nov 2025 18:47:53 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E5=AE=A1?= =?UTF-8?q?=E6=A0=B8=E5=88=97=E8=A1=A8=E9=A1=B5=E9=9D=A2=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E8=AF=A6=E6=83=85=E9=A1=B5=E9=9D=A2=E5=92=8C=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/api/index.js | 431 +++++++++++----- .../audit/components/AuditDetail.vue | 422 ++++++++++++++++ web/src/views/valuation/audit/constants.js | 12 + web/src/views/valuation/audit/index.vue | 466 ++++++++---------- web/src/views/valuation/audit/utils.js | 69 +++ 5 files changed, 1011 insertions(+), 389 deletions(-) create mode 100644 web/src/views/valuation/audit/components/AuditDetail.vue create mode 100644 web/src/views/valuation/audit/constants.js create mode 100644 web/src/views/valuation/audit/utils.js diff --git a/web/src/api/index.js b/web/src/api/index.js index 448b746..c847945 100644 --- a/web/src/api/index.js +++ b/web/src/api/index.js @@ -1,5 +1,281 @@ import { request } from '@/utils' +const baseValuationDetail = { + valuation_result: 1180000, + created_at: '2024-11-10T09:30:00Z', + reviewed_at: null, + status: 'pending', + admin_notes: null, + asset_name: '蜀绣传承精品', + institution: '天府非遗文化发展有限公司', + industry: '文化创意', + annual_revenue: 980000, + rd_investment: 165000, + three_year_income: [890000, 975000, 1180000], + funding_status: '国家资助', + inheritor_level: '市级传承人', + inheritor_age_count: [4, 6, 2], + inheritor_certificates: [ + 'https://dummyimage.com/120x80/edf2ff/409eff&text=证书A1', + 'https://dummyimage.com/120x80/fef6f0/f0a020&text=证书A2', + ], + heritage_level: '国家级非遗', + heritage_asset_level: '一级保护', + patent_application_no: '1111111,2222222', + historical_evidence: { + artifacts: 1, + ancient_literature: 2, + inheritor_testimony: 0, + modern_research: 3, + }, + patent_certificates: ['https://dummyimage.com/120x80/e8f5e9/34a853&text=专利1'], + pattern_images: ['https://dummyimage.com/120x80/f3e8ff/9c27b0&text=纹样1'], + application_maturity: '推广阶段', + application_coverage: '全国覆盖', + cooperation_depth: '品牌联名', + offline_activities: 4, + platform_accounts: { + bilibili: { account: 'B站@蜀绣', likes: 1260, comments: 320, shares: 188 }, + }, + sales_volume: 5200, + link_views: 86500, + circulation: '500-1000份', + last_market_activity: '近3个月', + monthly_transaction: '50-100万元', + price_fluctuation: [1200, 3200], + model_value_b: 1250000, + market_value_c: 1180000, + final_value_ab: 1220000, + dynamic_pledge_rate: 0.62, + calculation_result: { + flow: [ + { + title: '基础估值', + description: '基于近三年收益与研发投入的模型估值', + value: '¥1,250,000', + }, + { + title: '市场对标', + description: '结合同类资产市场成交价修正', + value: '¥1,180,000', + }, + { + title: '综合校准', + description: '叠加ESG、政策匹配度得出最终估值', + value: '¥1,220,000', + }, + ], + }, +} + +const valuationRecords = [ + { + id: 2001, + phone: '13800138001', + wechat: 'zhangsan_wx', + }, + { + id: 2002, + phone: '13800138002', + wechat: 'lisi2024', + valuation_result: 880000, + created_at: '2024-11-09T14:20:00Z', + reviewed_at: '2024-11-09T16:45:00Z', + status: 'approved', + admin_notes: '评估结果合理,已通过审核', + asset_name: '景泰蓝掐丝珐琅', + institution: '京华非遗研究院', + application_maturity: '成熟期', + application_coverage: '华北地区', + cooperation_depth: '科技载体', + platform_accounts: { + douyin: { account: '抖音@景泰蓝工坊', likes: 2350, comments: 610, shares: 302 }, + }, + price_fluctuation: [980, 2680], + calculation_result: { + flow: [ + { + title: '基础估值', + description: '模型估算品牌溢价后得出结果', + value: '¥900,000', + }, + { + title: '市场对标', + description: '对比近六个月文博拍卖价格', + value: '¥860,000', + }, + { + title: '综合校准', + description: '结合政策扶持与线上声量校准', + value: '¥880,000', + }, + ], + }, + }, + { + id: 2003, + phone: '13800138003', + wechat: 'wangwu_user', + valuation_result: 2100000, + created_at: '2024-11-08T16:45:00Z', + reviewed_at: '2024-11-08T18:30:00Z', + status: 'approved', + admin_notes: '评估价格偏高,但审核通过', + asset_name: '苗绣银饰', + institution: '黔锦民族文化有限公司', + industry: '民族工艺', + funding_status: '地方配套资金', + inheritor_level: '国家级代表性传承人', + inheritor_age_count: [2, 3, 1], + application_coverage: '西南片区', + platform_accounts: { + kuaishou: { account: '快手@苗绣手作', likes: 1800, comments: 420, shares: 210 }, + }, + price_fluctuation: [2600, 5200], + }, + { + id: 2004, + phone: '13800138004', + wechat: 'zhaoliu_vip', + valuation_result: 560000, + created_at: '2024-11-07T11:15:00Z', + status: 'pending', + asset_name: '景德镇青花', + institution: '景尚文化传播有限公司', + industry: '陶瓷制造', + funding_status: '社会资本', + platform_accounts: { + bilibili: { account: 'B站@青花研习社', likes: 860, comments: 146, shares: 98 }, + }, + price_fluctuation: [560, 1200], + }, + { + id: 2005, + phone: '13800138005', + wechat: 'sunqi888', + valuation_result: 1680000, + created_at: '2024-11-06T08:30:00Z', + reviewed_at: '2024-11-06T10:15:00Z', + status: 'approved', + admin_notes: '评估数据完整,审核通过', + asset_name: '藏医药香丸', + institution: '高原本草研究中心', + industry: '中医药', + application_coverage: '西藏及周边', + cooperation_depth: '国家外交礼品', + platform_accounts: { + douyin: { account: '抖音@藏医手作', likes: 3120, comments: 815, shares: 356 }, + }, + price_fluctuation: [3200, 7600], + }, + { + id: 2006, + phone: '13800138006', + wechat: 'zhouba2024', + valuation_result: 950000, + created_at: '2024-11-05T13:20:00Z', + status: 'pending', + asset_name: '苏绣屏风', + institution: '苏澜绣坊', + funding_status: '企业自筹', + platform_accounts: { + bilibili: { account: 'B站@苏绣博物馆', likes: 980, comments: 240, shares: 130 }, + }, + price_fluctuation: [1500, 3600], + }, + { + id: 2007, + phone: '13800138007', + wechat: 'wujiu_user', + valuation_result: 3200000, + created_at: '2024-11-04T15:45:00Z', + reviewed_at: '2024-11-04T17:20:00Z', + status: 'approved', + admin_notes: '高价值资产,评估结果准确', + asset_name: '宋锦织造', + institution: '苏州织造研究所', + funding_status: '国家重点补贴', + inheritor_age_count: [6, 8, 4], + application_maturity: '成熟期', + cooperation_depth: '科技载体', + platform_accounts: { + douyin: { account: '抖音@宋锦织造', likes: 4800, comments: 1020, shares: 520 }, + }, + }, + { + id: 2008, + phone: '13800138008', + wechat: 'zhengshi_vip', + valuation_result: 750000, + created_at: '2024-11-03T10:10:00Z', + reviewed_at: '2024-11-03T12:00:00Z', + status: 'approved', + admin_notes: '评估流程规范,结果可信', + asset_name: '黄梅挑花', + institution: '徽楚非遗中心', + cooperation_depth: '品牌联名', + price_fluctuation: [980, 1800], + }, + { + id: 2009, + phone: '13800138009', + wechat: 'chenjun2024', + valuation_result: 1890000, + created_at: '2024-11-02T14:30:00Z', + status: 'pending', + asset_name: '黎锦织造', + institution: '海南黎锦工坊', + funding_status: '国家资助', + application_coverage: '华南地区', + }, + { + id: 2010, + phone: '13800138010', + wechat: 'liuxia_user', + valuation_result: 430000, + created_at: '2024-11-01T11:45:00Z', + reviewed_at: '2024-11-01T13:30:00Z', + status: 'approved', + admin_notes: '低价值资产,评估合理', + asset_name: '大漆工艺', + institution: '榫卯器物社', + funding_status: '地方专项', + cooperation_depth: '品牌联名', + platform_accounts: { + bilibili: { account: 'B站@大漆工坊', likes: 420, comments: 75, shares: 33 }, + }, + }, + { + id: 2011, + phone: '13800138011', + wechat: 'zhaolei2024', + valuation_result: 2100000, + created_at: '2024-10-31T09:20:00Z', + reviewed_at: '2024-10-31T11:00:00Z', + status: 'approved', + admin_notes: '评估报告详细,数据支撑充分', + asset_name: '龙泉青瓷', + institution: '浙瓷非遗研究院', + cooperation_depth: '科技载体', + }, + { + id: 2012, + phone: '13800138012', + wechat: 'sunmei_vip', + valuation_result: 680000, + created_at: '2024-10-30T16:15:00Z', + status: 'pending', + asset_name: '侗锦织造', + institution: '黔东南侗锦合作社', + funding_status: '社会资本', + }, +] + +const mockValuationDetails = valuationRecords.map((record) => ({ + ...baseValuationDetail, + ...record, +})) + export default { login: (data) => request.post('/base/access_token', data, { noNeedToken: true }), getUserInfo: () => request.get('/base/userinfo'), @@ -127,8 +403,8 @@ export default { } // 分页处理 - const page = params.page || 1 - const pageSize = params.page_size || 10 + const page = Number(params.page) || 1 + const pageSize = Number(params.page_size) || 10 const startIndex = (page - 1) * pageSize const endIndex = startIndex + pageSize const paginatedUsers = filteredUsers.slice(startIndex, endIndex) @@ -374,132 +650,8 @@ export default { sendInvoice: (data = {}) => request.post('/invoice/send', data), // valuation (估值评估) getValuationList: (params = {}) => { - // Mock 数据 - const mockValuations = [ - { - id: 2001, - phone: '13800138001', - wechat: 'zhangsan_wx', - valuation_result: 1250000.00, - created_at: '2024-11-10T09:30:00Z', - reviewed_at: null, - status: 'pending', - admin_notes: null - }, - { - id: 2002, - phone: '13800138002', - wechat: 'lisi2024', - valuation_result: 880000.00, - created_at: '2024-11-09T14:20:00Z', - reviewed_at: '2024-11-09T16:45:00Z', - status: 'approved', - admin_notes: '评估结果合理,已通过审核' - }, - { - id: 2003, - phone: '13800138003', - wechat: 'wangwu_user', - valuation_result: 2100000.00, - created_at: '2024-11-08T16:45:00Z', - reviewed_at: '2024-11-08T18:30:00Z', - status: 'approved', - admin_notes: '评估价格偏高,但审核通过' - }, - { - id: 2004, - phone: '13800138004', - wechat: 'zhaoliu_vip', - valuation_result: 560000.00, - created_at: '2024-11-07T11:15:00Z', - reviewed_at: null, - status: 'pending', - admin_notes: null - }, - { - id: 2005, - phone: '13800138005', - wechat: 'sunqi888', - valuation_result: 1680000.00, - created_at: '2024-11-06T08:30:00Z', - reviewed_at: '2024-11-06T10:15:00Z', - status: 'approved', - admin_notes: '评估数据完整,审核通过' - }, - { - id: 2006, - phone: '13800138006', - wechat: 'zhouba2024', - valuation_result: 950000.00, - created_at: '2024-11-05T13:20:00Z', - reviewed_at: null, - status: 'pending', - admin_notes: null - }, - { - id: 2007, - phone: '13800138007', - wechat: 'wujiu_user', - valuation_result: 3200000.00, - created_at: '2024-11-04T15:45:00Z', - reviewed_at: '2024-11-04T17:20:00Z', - status: 'approved', - admin_notes: '高价值资产,评估结果准确' - }, - { - id: 2008, - phone: '13800138008', - wechat: 'zhengshi_vip', - valuation_result: 750000.00, - created_at: '2024-11-03T10:10:00Z', - reviewed_at: '2024-11-03T12:00:00Z', - status: 'approved', - admin_notes: '评估流程规范,结果可信' - }, - { - id: 2009, - phone: '13800138009', - wechat: 'chenjun2024', - valuation_result: 1890000.00, - created_at: '2024-11-02T14:30:00Z', - reviewed_at: null, - status: 'pending', - admin_notes: null - }, - { - id: 2010, - phone: '13800138010', - wechat: 'liuxia_user', - valuation_result: 430000.00, - created_at: '2024-11-01T11:45:00Z', - reviewed_at: '2024-11-01T13:30:00Z', - status: 'approved', - admin_notes: '低价值资产,评估合理' - }, - { - id: 2011, - phone: '13800138011', - wechat: 'zhaolei2024', - valuation_result: 2100000.00, - created_at: '2024-10-31T09:20:00Z', - reviewed_at: '2024-10-31T11:00:00Z', - status: 'approved', - admin_notes: '评估报告详细,数据支撑充分' - }, - { - id: 2012, - phone: '13800138012', - wechat: 'sunmei_vip', - valuation_result: 680000.00, - created_at: '2024-10-30T16:15:00Z', - reviewed_at: null, - status: 'pending', - admin_notes: null - } - ] - // 模拟分页和搜索 - let filteredValuations = [...mockValuations] + let filteredValuations = [...mockValuationDetails] // 手机号搜索 if (params.phone) { @@ -536,7 +688,16 @@ export default { const pageSize = params.page_size || 10 const startIndex = (page - 1) * pageSize const endIndex = startIndex + pageSize - const paginatedValuations = filteredValuations.slice(startIndex, endIndex) + const paginatedValuations = filteredValuations.slice(startIndex, endIndex).map((item) => ({ + id: item.id, + phone: item.phone, + wechat: item.wechat, + valuation_result: item.valuation_result, + created_at: item.created_at, + reviewed_at: item.reviewed_at, + status: item.status, + admin_notes: item.admin_notes, + })) // 返回 Promise 模拟异步请求 return new Promise((resolve) => { @@ -550,7 +711,19 @@ export default { }, 300) // 模拟网络延迟 }) }, - getValuationById: (params = {}) => request.get(`/valuation/${params.valuation_id}`), + getValuationById: (params = {}) => { + const id = Number(params.valuation_id || params.id) + return new Promise((resolve, reject) => { + setTimeout(() => { + const detail = mockValuationDetails.find((item) => item.id === id) + if (detail) { + resolve({ data: detail }) + } else { + reject({ code: 404, message: '未找到估值详情' }) + } + }, 200) + }) + }, createValuation: (data = {}) => request.post('/valuation', data), updateValuation: (data = {}) => request.put(`/valuation/${data.id}`, data), deleteValuation: (params = {}) => request.delete(`/valuation/${params.valuation_id}`), diff --git a/web/src/views/valuation/audit/components/AuditDetail.vue b/web/src/views/valuation/audit/components/AuditDetail.vue new file mode 100644 index 0000000..a791205 --- /dev/null +++ b/web/src/views/valuation/audit/components/AuditDetail.vue @@ -0,0 +1,422 @@ + + + + + diff --git a/web/src/views/valuation/audit/constants.js b/web/src/views/valuation/audit/constants.js new file mode 100644 index 0000000..aa23f6a --- /dev/null +++ b/web/src/views/valuation/audit/constants.js @@ -0,0 +1,12 @@ +export const STATUS_OPTIONS = [ + { label: '全部', value: '' }, + { label: '待审核', value: 'pending' }, + { label: '已完成', value: 'approved' }, +] + +export const STATUS_MAP = { + pending: { type: 'warning', text: '待审核' }, + approved: { type: 'success', text: '已完成' }, +} + +export const getStatusConfig = (status) => STATUS_MAP[status] || { type: 'default', text: '未知' } diff --git a/web/src/views/valuation/audit/index.vue b/web/src/views/valuation/audit/index.vue index 7750d79..e24c71c 100644 --- a/web/src/views/valuation/audit/index.vue +++ b/web/src/views/valuation/audit/index.vue @@ -1,16 +1,14 @@ + + - + - - - - 通过 - - - - 拒绝 - + - + -
+ + + diff --git a/web/src/views/valuation/audit/utils.js b/web/src/views/valuation/audit/utils.js new file mode 100644 index 0000000..e0522be --- /dev/null +++ b/web/src/views/valuation/audit/utils.js @@ -0,0 +1,69 @@ +const platformLabelMap = { + bilibili: 'B站账号', + douyin: '抖音账号', + kuaishou: '快手账号', + qita: '其他账号', +} + +export const formatAmount = (amount) => { + if (!amount && amount !== 0) return '-' + return `¥${Number(amount).toLocaleString('zh-CN', { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })}` +} + +export const formatNumberValue = (value, decimals = 0) => { + if (value === null || value === undefined || value === '') return '-' + if (typeof value === 'number') { + return Number(value).toLocaleString('zh-CN', { + minimumFractionDigits: decimals, + maximumFractionDigits: decimals, + }) + } + return value +} + +export const formatPercent = (value) => { + if (value === null || value === undefined || Number.isNaN(Number(value))) return '-' + return `${(Number(value) * 100).toFixed(2)}%` +} + +export const formatThreeYearIncome = (list = []) => { + if (!Array.isArray(list) || !list.length) return ['暂无数据'] + return list.map((item, index) => `第${index + 1}年:${formatNumberValue(item)}`) +} + +export const formatAgeDistribution = (list = []) => { + return [ + { label: '≤50岁', value: list?.[0] }, + { label: '50-70岁', value: list?.[1] }, + { label: '≥70岁', value: list?.[2] }, + ].map((bucket) => `${bucket.label}:${formatNumberValue(bucket.value)}`) +} + +export const formatHistoricalEvidence = (evidence = {}) => { + const mapping = [ + { key: 'artifacts', label: '出土实物' }, + { key: 'ancient_literature', label: '古代文献' }, + { key: 'inheritor_testimony', label: '传承人佐证' }, + { key: 'modern_research', label: '现代研究' }, + ] + return mapping.map(({ key, label }) => `${label}:${formatNumberValue(evidence?.[key])}`) +} + +export const formatPlatformAccounts = (accounts = {}) => { + const list = Object.entries(accounts || {}).map(([platform, info]) => { + const label = platformLabelMap[platform] || platform + if (!info) return `${label}:-` + return `${label}:${info.account || '-'}(赞${formatNumberValue(info.likes)} / 评${formatNumberValue( + info.comments + )} / 转${formatNumberValue(info.shares)})` + }) + return list.length ? list : ['暂无账号信息'] +} + +export const formatPriceRange = (range = []) => { + if (!Array.isArray(range) || range.length < 2) return '-' + return `${formatAmount(range[0])} - ${formatAmount(range[1])}` +}