feat(customs): show broker submission state in admin

This commit is contained in:
2026-09-28 13:21:59 +08:00
parent fad49a07a8
commit 730defabca
4 changed files with 111 additions and 13 deletions
@@ -8,6 +8,8 @@ const api = vi.hoisted(() => ({
get: vi.fn(),
start: vi.fn(),
completeAllBuy: vi.fn(),
sendToBroker: vi.fn(),
getDeclarationBatches: vi.fn(),
upload: vi.fn(),
downloadSource: vi.fn(),
downloadReceipt: vi.fn(),
@@ -23,6 +25,8 @@ vi.mock('../api/platformContainerCustoms', () => ({
downloadContainerCustomsReceipt: api.downloadReceipt,
downloadContainerCustomsFinal: api.downloadFinal,
submitContainerCustomsToBroker: vi.fn(),
sendContainerCustomsToBroker: api.sendToBroker,
getDeclarationBatches: api.getDeclarationBatches,
}))
vi.mock('@/modules/downloads', () => ({ createPlatformExportTask: vi.fn() }))
@@ -39,7 +43,9 @@ function customs(status: ContainerCustomsStatus, hasCompletion = false): Contain
inboundIds: ['2092438843630391404'], inboundCodes: ['RK-1'], frozen: true,
receipt: hasCompletion ? { fileId: '2092438843630391409', fileName: '报关行回执.pdf', fileHash: 'receipt-hash', sizeBytes: 13, version: 1, uploadedAt: '2026-08-29T11:00:00' } : null,
finalDocument: hasCompletion ? { fileId: '2092438843630391410', fileName: '真实报关完税文件.pdf', fileHash: 'final-hash', sizeBytes: 14, version: 1, uploadedAt: '2026-08-29T12:00:00' } : null,
confirmationHistory: hasCompletion ? [{ id: '2092438843630391411', receiptVersion: 1, action: 'CONFIRM', reason: null, operatorName: '客户一', createdAt: '2026-08-29T11:15:00' }] : [],
}],
brokerSubmission: hasCompletion ? { id: '2092438843630391412', customsContainerId: '2092438843630391401', loadingPlanId: '2092438843630391402', batchNo: 'BS-20260829-001', status: 'SENT', sourceVersion: 3, sentByName: '平台员', sentAt: '2026-08-29T10:45:00', version: 1 } : null,
startedAt: status === 'DECLARING' || status === 'COMPLETED' ? '2026-08-29T10:30:00' : null,
completedAt: status === 'COMPLETED' ? '2026-08-29T11:30:00' : null,
}
@@ -62,6 +68,7 @@ function buttonTexts(wrapper: Awaited<ReturnType<typeof render>>) {
describe('ContainerCustomsPanel', () => {
beforeEach(() => {
vi.clearAllMocks()
api.getDeclarationBatches.mockResolvedValue([])
api.downloadSource.mockResolvedValue(new Blob(['source']))
api.downloadReceipt.mockResolvedValue(new Blob(['receipt']))
api.downloadFinal.mockResolvedValue(new Blob(['final']))
@@ -112,14 +119,17 @@ describe('ContainerCustomsPanel', () => {
it('allows completion upload and overwrite only while DECLARING with manage permission', async () => {
let wrapper = await render('DECLARING', true, false)
expect(wrapper.text()).toContain('上传报关行回执')
expect(wrapper.text()).toContain('提交')
expect(wrapper.text()).toContain('首次发送报关行')
expect(wrapper.text()).toContain('首次发送后上传回执')
expect(buttonTexts(wrapper)).not.toContain('上传报关行回执')
wrapper.unmount()
wrapper = await render('DECLARING', true, true)
expect(wrapper.text()).toContain('发送报关行执行')
expect(wrapper.text()).toContain('覆盖报关行回执')
expect(wrapper.text()).toContain('报关行回执.pdf')
expect(wrapper.text()).toContain('真实报关完税文件.pdf')
expect(wrapper.text()).toContain('确认 · 2026/8/29 11:15:00 · 客户一')
wrapper.unmount()
wrapper = await render('DECLARING', false, true)
@@ -129,6 +139,18 @@ describe('ContainerCustomsPanel', () => {
expect(buttonTexts(wrapper)).not.toContain('提交')
})
it('loads declaration batches during DECLARING after broker execution was sent', async () => {
const value = { ...customs('DECLARING', true), brokerSubmittedAt: '2026-08-29T11:20:00' }
api.get.mockResolvedValue(value)
const wrapper = mount(ContainerCustomsPanel, {
props: { loadingPlanId: '2092438843630391402', canList: true, canManage: true, departureState: 'WAITING_OTHER_GATES' },
global: { plugins: [ElementPlus] },
})
await flushPromises()
expect(api.getDeclarationBatches).toHaveBeenCalledWith('2092438843630391402')
wrapper.unmount()
})
it('keeps COMPLETED strictly read-only with both files visible and downloadable', async () => {
const wrapper = await render('COMPLETED', true, true)
expect(wrapper.text()).toContain('客户退税资料.pdf')