From 241c269e372042a410ffeac50fa257ffb8c4fb9b Mon Sep 17 00:00:00 2001 From: zou Date: Fri, 4 Sep 2026 15:56:04 +0800 Subject: [PATCH] =?UTF-8?q?fix(inquiry):=20=E5=90=8E=E5=8F=B0=E8=AF=A2?= =?UTF-8?q?=E4=BB=B7=E8=AF=A6=E6=83=85=E5=AF=B9=E9=BD=90=E6=96=B0=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E2=80=94=E2=80=94=E8=AF=A2=E4=BB=B7=E4=B8=BB=E4=BD=93?= =?UTF-8?q?=3DinquiryParty=E3=80=81=E9=87=87=E8=B4=AD=E7=B1=BB=E5=9E=8B/?= =?UTF-8?q?=E6=8A=A5=E4=BB=B7=E6=96=B9=E5=BC=8F/=E6=8A=A5=E4=BB=B7?= =?UTF-8?q?=E8=A6=81=E6=B1=82/=E4=BB=98=E6=AC=BE/=E5=8F=91=E7=A5=A8/?= =?UTF-8?q?=E6=88=AA=E6=AD=A2=E5=85=A8=E5=AD=97=E6=AE=B5=E3=80=81=E5=95=86?= =?UTF-8?q?=E5=93=81=E6=98=8E=E7=BB=86=E8=A1=A8=E3=80=81=E6=8A=A5=E4=BB=B7?= =?UTF-8?q?=E6=8C=89=E4=BC=81=E4=B8=9A=E5=88=86=E7=BB=84(getQuotationById)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/inquiry/InquiryDetailView.vue | 192 ++++++++++++++++------ 1 file changed, 142 insertions(+), 50 deletions(-) diff --git a/src/modules/inquiry/InquiryDetailView.vue b/src/modules/inquiry/InquiryDetailView.vue index f11064f..e50d5c7 100644 --- a/src/modules/inquiry/InquiryDetailView.vue +++ b/src/modules/inquiry/InquiryDetailView.vue @@ -32,6 +32,16 @@ interface Inquiry { fileList: { url: string; imagesName: string }[] // 报价列表 quotationList: Quotation[] + // 新结构(与发布询价信息一致) + procurementTypeName?: string + quotationTypeName?: string + quotationDemandName?: string + paymentMethodName?: string + invoiceTypeName?: string + inquiryValidDate?: string + publishDate?: string + note?: string + detailList?: any[] raw: any } @@ -93,29 +103,44 @@ const detail = ref(null) const loading = ref(true) const inquiryId = computed(() => String(route.params.id || '')) +const PROC_TYPE: Record = { 1: '定量采购', 2: '框架采购' } +const DEMAND: Record = { 1: '不允许部分报价', 2: '允许部分报价' } +const INVOICE: Record = { 1: '普通发票', 2: '增值税专用发票', 3: '无' } +const QUOTE_TYPE: Record = { 1: '公开报价', 2: '邀请报价' } +const mapLabel = (m: Record, v: any) => (v == null ? '--' : m[Number(v)] || String(v)) +const mapLabel1 = (m: Record, v: any) => (v == null ? '--' : m[Number(v)] || String(v)) + async function load() { loading.value = true try { const resp: any = await httpGet('/supplier/inquiry/getById', { id: inquiryId.value }) if (resp && resp.id) { + const first = resp.inquiryDetailList?.[0] || {} detail.value = { ...FALLBACK, ...resp, id: String(resp.id || inquiryId.value), title: resp.title || FALLBACK.title, - productName: resp.productName || resp.product || FALLBACK.productName, - productBrand: resp.brand || resp.productBrand || FALLBACK.productBrand, - specification: resp.specification || resp.spec || FALLBACK.specification, - unit: resp.unit || FALLBACK.unit, - quantity: resp.purchaseQuantity || resp.quantity || FALLBACK.quantity, - shippingAddress: resp.shippingAddress || resp.address || FALLBACK.shippingAddress, - deliveryDate: resp.deliveryDate || FALLBACK.deliveryDate, - priceValidDate: resp.priceValidDate || FALLBACK.priceValidDate, - enterpriseName: resp.inquiryEnterpriseName || resp.enterpriseName || FALLBACK.enterpriseName, - fileList: resp.fileList || FALLBACK.fileList, - quotationList: resp.quotationList || FALLBACK.quotationList, + productName: first.productName || '--', + productBrand: first.productBrand || '--', + specification: first.specification || '--', + unit: first.unit || '--', + quantity: resp.purchaseQuantity ?? '--', + // 新结构字段:与发布询价信息一致 + procurementTypeName: mapLabel(PROC_TYPE, resp.procurementType), + quotationTypeName: mapLabel(QUOTE_TYPE, resp.quotationType), + quotationDemandName: mapLabel(DEMAND, resp.quotationDemand), + paymentMethodName: resp.paymentMethodName || '--', + invoiceTypeName: mapLabel(INVOICE, resp.invoiceType), + inquiryValidDate: resp.inquiryValidDate || '--', + note: resp.note || '', + enterpriseName: resp.inquiryParty || resp.inquiryEnterpriseName || FALLBACK.enterpriseName, + detailList: resp.inquiryDetailList || [], + fileList: resetFiles(resp), raw: resp, } + // 报价回复:按企业分组(getQuotationById 返回逐商品报价行) + await loadQuotes(resp.orderId || resp.id) } else { detail.value = { ...FALLBACK, id: inquiryId.value } } @@ -126,6 +151,34 @@ async function load() { } } +// 附件:发布时 images 为 URL 数组 + imageNames 名称数组 +function resetFiles(resp: any): any[] { + const urls: string[] = resp.images || [] + const names: string[] = resp.imageNames || [] + return urls.map((u: string, i: number) => ({ url: u, imagesName: names[i] || ('附件' + (i + 1)) })) +} + +const quoteGroups = ref([]) +const quoteLoading = ref(false) +async function loadQuotes(orderId: any) { + quoteLoading.value = true + try { + const res: any = await httpPost('/supplier/inquiry/getQuotationById', { orderId: String(orderId) }) + const rows = (res && (Array.isArray(res) ? res : [])) || [] + const groups: any[] = [] + for (const q of rows) { + const name = q.quotationEnterpriseName || '未报价' + let g = groups.find(x => x.name === name) + if (!g) { g = { name, rows: [], count: 0, total: 0, date: '', list: [] }; groups.push(g) } + g.rows.push(q) + g.count++ + g.total += Number(q.unitPriceTaxIncluded || q.unitPrice || 0) * Number(q.quantity || 0) + if (q.quotationDate && !g.date) g.date = q.quotationDate + } + quoteGroups.value = groups + } catch { quoteGroups.value = [] } finally { quoteLoading.value = false } +} + // === 审核操作: apprStatus 2=通过 3=驳回 === const auditLoading = ref(false) async function onAudit(status: number) { @@ -203,19 +256,41 @@ watch(inquiryId, load)

询价信息

- {{ detail.productName }} - {{ detail.productBrand || '--' }} - {{ detail.specification || '--' }} - {{ detail.unit }} - {{ detail.quantity }} + {{ detail.enterpriseName }} + {{ detail.procurementTypeName }} + {{ detail.quotationTypeName }} + {{ detail.quantity }} + {{ detail.quotationDemandName }} + {{ detail.paymentMethodName }} + {{ detail.invoiceTypeName }} + {{ detail.inquiryValidDate }} {{ detail.deliveryDate || '--' }} - {{ detail.priceValidDate || '--' }} + {{ detail.createDate || detail.publishDate || '--' }} {{ detail.shippingAddress || '--' }} - {{ detail.detailNote || '--' }} - {{ detail.enterpriseName }} + {{ detail.note || detail.detailNote || '--' }}
+ +
+

商品明细 ({{ (detail.detailList || []).length }})

+ + + + + + + + + + + + + + + +
+

询价附件

@@ -228,39 +303,46 @@ watch(inquiryId, load)
- +
-

报价列表 ({{ detail.quotationList.length }})

- - - - - - - - - - - - - - - - - - +

报价列表 ({{ quoteGroups.reduce((a, g) => a + g.count, 0) }})

+
加载报价中...
+
暂无报价回复
+
+
+
+ {{ g.name }} + 已报价 + 待报价 + {{ g.count }} 项{{ g.date ? ' · ' + g.date : '' }} +
+ + + + + + + + + + + + + + + + + + + + +
+
+ +
报价详情可在前台「我的询价-询价详情-企业报价回复」查看
- + + @@ -279,4 +361,14 @@ watch(inquiryId, load) .rr-files { padding: 16px 20px; display: flex; flex-direction: column; gap: 8px; } .rr-file-item { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: var(--bg-soft); border-radius: var(--radius); } .rr-file-name { flex: 1; color: var(--ink); font-size: 13px; } + +.rr-quote-groups { display: flex; flex-direction: column; gap: 12px; } +.rr-quote-group { border: 1px solid var(--el-border-color); border-radius: 8px; overflow: hidden; } +.rr-quote-group-head { display: flex; align-items: center; gap: 8px; padding: 10px 14px; background: var(--el-fill-color-light); font-size: 13px; flex-wrap: wrap; } +.rr-quote-meta { margin-left: auto; color: var(--el-text-color-secondary); font-size: 12px; } +.rr-tag { font-size: 11px; padding: 1px 8px; border-radius: 10px; background: var(--el-color-info-light-9); color: var(--el-text-color-secondary); } +.rr-tag-green { background: #f0f9eb; color: #67c23a; } +.rr-empty { padding: 24px; text-align: center; color: var(--el-text-color-secondary); font-size: 13px; } +.rr-tip { font-size: 12px; color: var(--el-text-color-secondary); } +.mt10 { margin-top: 10px; }