diff --git a/web-admin/src/utils/collection-ledger-export.test.ts b/web-admin/src/utils/collection-ledger-export.test.ts index fba8db49..039a6d45 100644 --- a/web-admin/src/utils/collection-ledger-export.test.ts +++ b/web-admin/src/utils/collection-ledger-export.test.ts @@ -154,6 +154,38 @@ describe('buildResearchLedgerRows', () => { assert.equal(row[20], '顺产') assert.equal(row[23], '1') }) + + it('maps sdfq void type code to 属地废弃 labels', () => { + const flat = { + protocol: { + donationStatus: 'yzf', + voidType: 'sdfq', + voidDesc: '', + monthlyVerifyNo: '' + }, + sampleIndex: 0, + sampleCollectTime: '2025-08-29 12:27:00', + motherName: '测试', + sampleTypeName: '围产期造血干细胞', + regionName: '亳州', + hospitalName: '涡阳县人民医院', + labStorageCode: 'A0000002', + salesUserName: '', + regionManagerUserName: '', + transportType: '', + newbornDeliveryTime: '', + newbornSex: '', + newbornWeightGram: '', + deliveryMode: '', + birthOrder: '', + maternalBloodCollectTime: '', + consentFormUrls: '', + remark: '' + } as unknown as ProtocolAuditFlatRow + const [row] = buildResearchLedgerRows([flat]) + assert.equal(row[6], '已作废(属地废弃)') + assert.equal(row[7], '属地废弃') + }) }) describe('buildCustomerServiceLedgerRows', () => { diff --git a/web-admin/src/utils/collection-ledger-export.ts b/web-admin/src/utils/collection-ledger-export.ts index ae5836f2..f57cffd8 100644 --- a/web-admin/src/utils/collection-ledger-export.ts +++ b/web-admin/src/utils/collection-ledger-export.ts @@ -166,12 +166,16 @@ const PROTOCOL_STATUS: Record = { zckc: '转细胞存储' } +/** 作废类型兜底;与 void-type-dict 默认项一致,并覆盖误写入作废类型的状态码。 */ const VOID_TYPE: Record = { khhc: '客户毁存', jcbhg: '检测不合格', sysfq: '实验室废弃' } +/** 导出前由字典填充;单元测试环境可为空。 */ +let runtimeVoidLabels: Record = {} + const PAY_MODE: Record = { dj: '趸交', fq: '分期', @@ -275,16 +279,37 @@ function dayText(value: unknown): string { return parts ? String(parts.day) : '' } +/** 作废类型:字典 → 本地兜底 → 协议状态码文案(如 sdfq→属地废弃)。 */ +function voidTypeText(value: unknown): string { + const code = text(value) + if (!code) return '' + return ( + runtimeVoidLabels[code] || + VOID_TYPE[code] || + PROTOCOL_STATUS[code] || + code + ) +} + function statusText(status: unknown, voidType: unknown): string { const code = text(status) const base = PROTOCOL_STATUS[code] || code if (code !== 'yzf') return base - const reason = label(VOID_TYPE, voidType) + const reason = voidTypeText(voidType) return reason ? `${base}(${reason})` : base } function voidReason(row: Row): string { - return text(row.voidDesc) || label(VOID_TYPE, row.voidType) + return text(row.voidDesc) || voidTypeText(row.voidType) +} + +/** 导出前加载作废类型字典,避免列表外的编码原样写入 Excel。 */ +export async function prepareCollectionLedgerExport(): Promise { + const { loadVoidTypeDict, getVoidTypeOptions } = await import('./void-type-dict') + await loadVoidTypeDict() + runtimeVoidLabels = Object.fromEntries( + getVoidTypeOptions().map((item) => [String(item.value), String(item.label)]) + ) } function payModeText(value: unknown, fallback = ''): string { diff --git a/web-admin/src/views/cell-storage/presign-order/index.vue b/web-admin/src/views/cell-storage/presign-order/index.vue index da268252..9d336351 100644 --- a/web-admin/src/views/cell-storage/presign-order/index.vue +++ b/web-admin/src/views/cell-storage/presign-order/index.vue @@ -206,7 +206,8 @@ buildPresignLedgerRows, fetchAllPages, PRESIGN_HEADERS, - saveCollectionLedgerWorkbook + saveCollectionLedgerWorkbook, + prepareCollectionLedgerExport } from '@/utils/collection-ledger-export' import { formatDisplayOrDash } from '@/utils/datetime-display' import { formatMoneyDisplay } from '@/utils/money-format' @@ -262,6 +263,7 @@ if (exporting.value) return exporting.value = true try { + await prepareCollectionLedgerExport() const rows = selectedRows.value.length ? selectedRows.value : await fetchAllPages((page, pageSize) => diff --git a/web-admin/src/views/cell-storage/protocol-audit/DonationProtocolTab.vue b/web-admin/src/views/cell-storage/protocol-audit/DonationProtocolTab.vue index 83e94474..606376b3 100644 --- a/web-admin/src/views/cell-storage/protocol-audit/DonationProtocolTab.vue +++ b/web-admin/src/views/cell-storage/protocol-audit/DonationProtocolTab.vue @@ -465,7 +465,8 @@ RESEARCH_HEADERS, buildResearchLedgerRows, fetchAllPages, - saveCollectionLedgerWorkbook + saveCollectionLedgerWorkbook, + prepareCollectionLedgerExport } from '@/utils/collection-ledger-export' import { flattenProtocolAuditRows, @@ -545,6 +546,7 @@ if (exporting.value) return exporting.value = true try { + await prepareCollectionLedgerExport() const rows = selectedFlatRows.value.length ? selectedFlatRows.value : flattenProtocolAuditRows( diff --git a/web-admin/src/views/cell-storage/protocol-audit/ProtocolAuditTab.vue b/web-admin/src/views/cell-storage/protocol-audit/ProtocolAuditTab.vue index afc2ff17..9e121d22 100644 --- a/web-admin/src/views/cell-storage/protocol-audit/ProtocolAuditTab.vue +++ b/web-admin/src/views/cell-storage/protocol-audit/ProtocolAuditTab.vue @@ -433,7 +433,8 @@ CELL_STORAGE_HEADERS, buildCellStorageLedgerRows, fetchAllPages, - saveCollectionLedgerWorkbook + saveCollectionLedgerWorkbook, + prepareCollectionLedgerExport } from '@/utils/collection-ledger-export' import { flattenProtocolAuditRows, @@ -510,6 +511,7 @@ if (exporting.value) return exporting.value = true try { + await prepareCollectionLedgerExport() const rows = selectedFlatRows.value.length ? selectedFlatRows.value : flattenProtocolAuditRows( diff --git a/web-admin/src/views/cell-storage/sample-info/UnifiedSampleInfoPage.vue b/web-admin/src/views/cell-storage/sample-info/UnifiedSampleInfoPage.vue index a124b6c4..8ea14bda 100644 --- a/web-admin/src/views/cell-storage/sample-info/UnifiedSampleInfoPage.vue +++ b/web-admin/src/views/cell-storage/sample-info/UnifiedSampleInfoPage.vue @@ -525,7 +525,8 @@ CUSTOMER_SERVICE_HEADERS, buildCustomerServiceLedgerRows, fetchAllPages, - saveCollectionLedgerWorkbook + saveCollectionLedgerWorkbook, + prepareCollectionLedgerExport } from '@/utils/collection-ledger-export' defineOptions({ name: 'UnifiedSampleInfoPage' }) @@ -653,6 +654,7 @@ if (exporting.value || !isCellStorage.value) return exporting.value = true try { + await prepareCollectionLedgerExport() const rows = selectedRows.value.length ? selectedRows.value : await fetchAllPages((page, pageSize) =>