From 12424281c79c8b0e93eec8b59665db55bd00a542 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Wed, 2 Sep 2026 20:25:45 +0800 Subject: [PATCH] feat(finance): link bill lines to inbound details --- src/modules/finance/api/adapters.ts | 2 ++ src/modules/finance/contracts.ts | 1 + src/modules/finance/views/FinanceBillsView.test.mjs | 8 ++++++-- src/modules/finance/views/FinanceBillsView.vue | 13 ++++++++++++- src/modules/first-leg/public.ts | 1 + 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/modules/finance/api/adapters.ts b/src/modules/finance/api/adapters.ts index 33ea5c8..10aaa1a 100644 --- a/src/modules/finance/api/adapters.ts +++ b/src/modules/finance/api/adapters.ts @@ -34,6 +34,7 @@ export interface FinanceBillLineWire { sourceVersion: number orderId: WireScalar | null inboundId: WireScalar | null + inboundCode: string | null feeItemCode: string feeItemName: string amount: WireScalar @@ -89,6 +90,7 @@ function mapBillLine(line: FinanceBillLineWire): FinanceBillLine { return { id: text(line.id), orderId: line.orderId == null ? null : text(line.orderId), + inboundCode: line.inboundCode?.trim() || null, feeNo: `${line.sourceType}:${text(line.sourceId)}/v${line.sourceVersion}`, feeName: line.feeItemName, amount: text(line.amount), diff --git a/src/modules/finance/contracts.ts b/src/modules/finance/contracts.ts index 0eaafac..142ac2f 100644 --- a/src/modules/finance/contracts.ts +++ b/src/modules/finance/contracts.ts @@ -39,6 +39,7 @@ export interface FinanceCustomerConfirmationResult { export interface FinanceBillLine { id: string orderId: string | null + inboundCode: string | null feeNo: string | null feeName: string amount: string diff --git a/src/modules/finance/views/FinanceBillsView.test.mjs b/src/modules/finance/views/FinanceBillsView.test.mjs index 5437514..43818db 100644 --- a/src/modules/finance/views/FinanceBillsView.test.mjs +++ b/src/modules/finance/views/FinanceBillsView.test.mjs @@ -92,7 +92,7 @@ test('maps nested bill detail and customer-safe receipt allocations', () => { receivedAmount: '40.00', outstandingAmount: '60.00', version: 3, customerConfirmationStatus: 'PENDING_CONFIRMATION', customerConfirmedByName: null, customerConfirmedAt: null, }, - lines: [{ id: 21, sourceType: 'INBOUND_FEE', sourceId: 81, sourceVersion: 3, orderId: 31, inboundId: 41, feeItemCode: 'FREIGHT', feeItemName: '运费', amount: '100.00', currency: 'CNY' }], + lines: [{ id: 21, sourceType: 'INBOUND_FEE', sourceId: 81, sourceVersion: 3, orderId: 31, inboundId: 41, inboundCode: 'NYEXX2608180003', feeItemCode: 'FREIGHT', feeItemName: '运费', amount: '100.00', currency: 'CNY' }], }) const receipts = financeAdapters.mapFinanceReceipts([{ id: 51, receiptNo: 'RCPT-51', receivedAmount: '40.00', receivedAt: '2026-08-12T10:00:00', @@ -101,7 +101,7 @@ test('maps nested bill detail and customer-safe receipt allocations', () => { }], '2') assert.equal(detail.billNo, 'B-2') - assert.deepEqual(detail.lines[0], { id: '21', orderId: '31', feeNo: 'INBOUND_FEE:81/v3', feeName: '运费', amount: '100.00', currencyCode: 'CNY' }) + assert.deepEqual(detail.lines[0], { id: '21', orderId: '31', inboundCode: 'NYEXX2608180003', feeNo: 'INBOUND_FEE:81/v3', feeName: '运费', amount: '100.00', currencyCode: 'CNY' }) assert.deepEqual(receipts[0], { id: '51', receiptNo: 'RCPT-51', receivedAt: '2026-08-12T10:00:00', amount: '40.00', currencyCode: 'CNY', method: 'BANK_TRANSFER', allocatedAmount: '40.00' }) }) @@ -122,6 +122,10 @@ test('keeps actions first and exposes list, balance, detail, confirmation, recei } assert.match(viewSource, /BANK_TRANSFER: '银行转账'/) assert.match(viewSource, /paymentMethodLabel\(row\.method\)/) + assert.match(viewSource, /label="入仓码"/) + assert.match(viewSource, /openInboundAssociation\(row\.inboundCode\)/) + assert.match(viewSource, /InboundCodeAssociationDialog/) + assert.match(viewSource, /:inbound-code="inboundAssociationCode"/) assert.match(viewSource, /auth\.hasPermission\('finance:bill:confirm'\)/) assert.match(viewSource, /row\.customerConfirmationStatus === 'PENDING_CONFIRMATION' && canConfirm/) assert.match(viewSource, /size="small" type="success" plain/) diff --git a/src/modules/finance/views/FinanceBillsView.vue b/src/modules/finance/views/FinanceBillsView.vue index 95fd113..d4f46df 100644 --- a/src/modules/finance/views/FinanceBillsView.vue +++ b/src/modules/finance/views/FinanceBillsView.vue @@ -4,6 +4,7 @@ import { CircleDollarSign, Eye, RefreshCcw, Search } from '@lucide/vue' import { ElMessage, ElMessageBox } from 'element-plus' import { ApiError } from '@/api/http' import { useAuthStore } from '@/modules/auth/public' +import { InboundCodeAssociationDialog } from '@/modules/first-leg/public' import { confirmMerchantFinanceStatement, getMerchantFinanceBill, getMerchantFinanceBills, getMerchantFinanceReceipts } from '../api/finance' import type { FinanceBillDetail, FinanceBillQuery, FinanceBillStatus, FinanceBillSummary, FinanceCustomerConfirmationStatus } from '../contracts' @@ -16,6 +17,8 @@ const bills = ref([]) const detail = ref(null) const selectedBillId = ref('') const detailVisible = ref(false) +const inboundAssociationVisible = ref(false) +const inboundAssociationCode = ref('') const confirmingBillId = ref('') const confirmationKeys = new Map() const page = ref(1) @@ -160,6 +163,13 @@ function handlePageChange(nextPage: number) { void loadBills(nextPage) } +function openInboundAssociation(inboundCode: string | null) { + const code = inboundCode?.trim() + if (!code) return + inboundAssociationCode.value = code + inboundAssociationVisible.value = true +} + onMounted(() => { void loadBills(1) }) @@ -211,12 +221,13 @@ onMounted(() => { void loadBills(1) }) + diff --git a/src/modules/first-leg/public.ts b/src/modules/first-leg/public.ts index a7a171b..50e9e80 100644 --- a/src/modules/first-leg/public.ts +++ b/src/modules/first-leg/public.ts @@ -1,2 +1,3 @@ export { useFirstLegOrdersStore } from './store/firstLegOrders' export { getFirstLegStatusLabel, getFirstLegStatusTone } from './utils/firstLegOrder' +export { default as InboundCodeAssociationDialog } from './components/InboundCodeAssociationDialog.vue'