From 3f019c9ac5bfa68c0fb00276da8ed8148dffccc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com> Date: Wed, 21 Oct 2026 17:37:48 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=A2=E5=95=86=E6=A1=A3=E6=A1=88?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E9=A3=8E=E9=99=A9=E5=88=97=E4=B8=8E=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E5=AE=A2=E5=95=86=E5=90=8D=E7=A7=B0=E9=A3=8E=E9=99=A9?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 列表新增客商风险列(批量查询,标签按后端 riskLevelName 转义,悬浮显示风险项明细);客商档案表单名称框下高风险/黑名单红字提示(失焦/回显/OCR/金蝶回填触发,查询失败静默) --- src/api/business/hcs.js | 18 +++++ src/views/vehicle/customer-archive.vue | 103 +++++++++++++++++++++++++ 2 files changed, 121 insertions(+) diff --git a/src/api/business/hcs.js b/src/api/business/hcs.js index 8ccfd1b..47012a2 100644 --- a/src/api/business/hcs.js +++ b/src/api/business/hcs.js @@ -40,6 +40,24 @@ export const getRisk = customerCode => timeout: 30000, }); +// 客商风险批量查询(客商列表页展示用):入参编号数组,后端逐个查 C101-1,单个失败跳过 +export const getRiskBatch = customerCodes => + request({ + url: `${baseUrl}/risk/batch`, + method: 'get', + params: { customerCodes: (customerCodes || []).join(',') }, + timeout: 60000, + }); + +// 客商风险按名称查询(客商档案表单展示用):名称反查编号后口径同编号查询 +export const getRiskByName = customerName => + request({ + url: `${baseUrl}/risk/by-name`, + method: 'get', + params: { customerName }, + timeout: 30000, + }); + export const uploadAttachment = formData => request({ url: `${baseUrl}/attachment/upload`, diff --git a/src/views/vehicle/customer-archive.vue b/src/views/vehicle/customer-archive.vue index 52ef5a6..6805c42 100644 --- a/src/views/vehicle/customer-archive.vue +++ b/src/views/vehicle/customer-archive.vue @@ -47,6 +47,29 @@ {{ row.customerCode }} + + + + {{ customerRiskMap[row.customerCode].riskTip || '该客商为高风险/黑名单客商' }} + + + {{ customerRiskLabel(customerRiskMap[row.customerCode]) }} + + + + {{ customerRiskLabel(customerRiskMap[row.customerCode]) }} + + - + + + + {{ archiveNameRiskTip || '该客商为高风险/黑名单客商' }} + + 高风险/黑名单客商 + @@ -1557,6 +1592,7 @@ import { queryKingdeeCustomer, syncKingdee, } from '@/api/vehicle/customer-archive'; +import { getRiskBatch, getRiskByName } from '@/api/business/hcs'; import { getList as getCreditScoreQuantificationList, getDetail as getCreditScoreQuantificationDetail, @@ -1662,6 +1698,9 @@ export default { deptSearchInitialized: false, loading: true, data: [], + customerRiskMap: {}, + archiveNameRisky: false, + archiveNameRiskTip: '', page: { pageSize: 10, pageSizes: [10, 20, 50, 100], @@ -1920,6 +1959,12 @@ export default { { label: '内部组织', value: 'internal' }, ], }, + { + label: '客商风险', + prop: 'customerRisk', + slot: true, + minWidth: 100, + }, { label: '客户性质', prop: 'customerNature', @@ -2464,6 +2509,7 @@ export default { form.kingdeeStatus = 'exist'; // 工商信息以金蝶为准,直接覆盖(后续字段锁定) if (customer.name) form.fullName = customer.name; + if (customer.name) this.checkArchiveNameRisk(); if (customer.artificialperson) form.legalPerson = customer.artificialperson; if (customer.bizpartnerAddress) form.registeredDetailAddress = customer.bizpartnerAddress; if (customer.regcapital) { @@ -3888,6 +3934,7 @@ export default { const scope = this.getBusinessLicenseOcrValue(result, ['经营范围']); if (code) this.archiveForm.unifiedCreditCode = code.replace(/\s/g, '').toUpperCase(); if (name) this.archiveForm.fullName = name; + if (name) this.checkArchiveNameRisk(); if (legalPerson) this.archiveForm.legalPerson = legalPerson; if (address) { this.archiveForm.registeredAddress = address; @@ -4271,6 +4318,7 @@ export default { this.selectedQualificationFiles = []; if (this.isPublicViewPage) this.ensurePublicViewOptions(this.archiveForm); this.applyFixedOwnerDept(); + this.checkArchiveNameRisk(); this.archiveBox = true; this.loadChangeRecords(); if (this.reviewMode) this.openReviewScore(); @@ -4289,6 +4337,7 @@ export default { this.ocrQualificationUploadFiles = []; this.selectedQualificationFiles = []; this.applyFixedOwnerDept(); + this.checkArchiveNameRisk(); this.archiveBox = true; }, resetArchive() { @@ -5306,12 +5355,52 @@ export default { const pageData = res.data.data; this.page.total = pageData.total; this.data = pageData.records; + this.loadCustomerRisk(this.data); this.selectionClear(); }) .finally(() => { this.loading = false; }); }, + // 客商风险标签文案:后端 riskLevelName 转义(黑名单/高风险/中风险/低风险),缺失时兜底 + customerRiskLabel(risk) { + if (!risk) return ''; + return risk.riskLevelName || (risk.risky ? '风险客商' : '正常'); + }, + // 客商名称风险校验(C101-1,仅展示不作为安全边界):名称失焦/回显时查询, + // risky 在名称框下展示红色提示,悬浮见风险项明细;查询失败静默不阻断填写,提交链路由后端强校验兜底 + checkArchiveNameRisk() { + this.archiveNameRisky = false; + this.archiveNameRiskTip = ''; + const customerName = String(this.archiveForm.fullName || '').trim(); + if (!customerName) return; + getRiskByName(customerName) + .then(res => { + const risk = (res.data && res.data.data) || {}; + this.archiveNameRisky = risk.risky === true; + this.archiveNameRiskTip = risk.riskTip || ''; + }) + .catch(() => { + // 忽略风险查询异常,表单正常填写 + }); + }, + // 客商列表风险批量查询(C101-1,仅展示不作为安全边界):失败静默,行内显示"-",提交链路由后端强校验兜底 + loadCustomerRisk(rows) { + this.customerRiskMap = {}; + const customerCodes = [...new Set(rows.map(row => row.customerCode).filter(Boolean))]; + if (!customerCodes.length) return; + getRiskBatch(customerCodes) + .then(res => { + const riskMap = {}; + ((res.data && res.data.data) || []).forEach(risk => { + if (risk && risk.customerCode) riskMap[risk.customerCode] = risk; + }); + this.customerRiskMap = riskMap; + }) + .catch(() => { + // 忽略风险查询异常,列表正常展示 + }); + }, handleExport() { this.$confirm('是否导出客商档案数据?', '提示', { confirmButtonText: '确定', @@ -5376,6 +5465,20 @@ export default { color: var(--el-color-danger); } +// 风险客商悬浮提示:popper 挂在 body 下,需用 :global 约束宽度 +:global(.customer-risk-popper) { + max-width: 360px; + line-height: 1.6; +} + +// 客商名称框下方的高风险/黑名单提示(对齐表单错误文案形态) +.archive-name-risk { + color: var(--el-color-danger); + font-size: 12px; + line-height: 1.5; + cursor: default; +} + .fund-use-risk-none { color: #c0c4cc; }