优化
This commit is contained in:
@@ -51,10 +51,14 @@ describe('CarrierScheduleQueryPanel loading states', () => {
|
||||
|
||||
it('shows an explicit non-fabricated empty state and performs no detail reads', async () => {
|
||||
vi.mocked(listCarrierScheduleQueries).mockResolvedValue({ records: [], page: 1, size: 200, total: 0, pages: 0 })
|
||||
const wrapper = mount(CarrierScheduleQueryPanel, { props: { oceanBookingId: '2' }, global: { plugins: [ElementPlus, pinia] } })
|
||||
const wrapper = mount(CarrierScheduleQueryPanel, { props: { oceanBookingId: '2', warehouseTimeline: [{ eventType: 'PDA_COMPLETE_LOADING', detail: 'complete-key-technical', operatorName: '仓库员', occurredAt: '2026-08-20T08:00:00' }] }, global: { plugins: [ElementPlus, pinia] } })
|
||||
await flushPromises()
|
||||
|
||||
expect(wrapper.text()).toContain('本页面不会创建或模拟任务')
|
||||
expect(wrapper.text()).toContain('货柜履约轨迹')
|
||||
expect(wrapper.text()).toContain('完成装柜')
|
||||
expect(wrapper.text()).toContain('仓内操作')
|
||||
expect(wrapper.text()).toContain('确认离仓后自动开始船节点跟踪')
|
||||
expect(wrapper.findAll('.tracking-prompt')).toHaveLength(1)
|
||||
expect(getCarrierScheduleQuery).not.toHaveBeenCalled()
|
||||
expect(getPortSchedule).not.toHaveBeenCalled()
|
||||
})
|
||||
@@ -103,9 +107,39 @@ describe('CarrierScheduleQueryPanel loading states', () => {
|
||||
expect(wrapper.text()).toContain('最新实际节点已离开国内仓库')
|
||||
expect(wrapper.text()).toContain('预计 2026-08-28 12:00')
|
||||
expect(wrapper.text()).not.toContain('最新实际节点船舶已到目的港')
|
||||
expect(wrapper.text()).toContain('异常事实')
|
||||
expect(wrapper.text()).toContain('异常')
|
||||
expect(wrapper.text()).toContain('海关扣留 · 发生')
|
||||
expect(wrapper.text()).toContain('Customs hold')
|
||||
expect(wrapper.text()).toContain('船运跟踪 · HEDE · hede-hold')
|
||||
})
|
||||
|
||||
it('merges warehouse, actual, estimated, manual and exception facts with stable ordering and deduplication', async () => {
|
||||
vi.mocked(listCarrierScheduleQueries).mockResolvedValue({ records: [{ ...queryView, query: { ...queryView.query, resultPortScheduleId: null }, expired: false }], page: 1, size: 200, total: 1, pages: 1 })
|
||||
const actual = { id: '61', providerCode: 'COSCO', providerEventId: 'actual-61', providerNodeCode: 'LOAD', standardNode: 'LOADED_ON_VESSEL' as const, nodeSequence: 30, observedAt: '2026-08-21T10:05:00', estimatedAt: null, actualAt: '2026-08-21T10:00:00', locationCode: 'CNNGB', locationName: '宁波港', sourceReference: 'actual-source', rawPayloadHash: 'e'.repeat(64), createdAt: '2026-08-21T10:06:00' }
|
||||
const estimated = { id: '62', providerCode: 'COSCO', providerEventId: 'estimate-62', providerNodeCode: 'ETA', standardNode: 'ARRIVED_DESTINATION_PORT' as const, nodeSequence: 60, observedAt: '2026-08-20T10:00:00', estimatedAt: '2026-08-21T10:00:00', actualAt: null, locationCode: 'USLAX', locationName: 'Los Angeles', sourceReference: 'estimate-source', rawPayloadHash: 'f'.repeat(64), createdAt: '2026-08-20T10:01:00' }
|
||||
const manual = { id: '63', providerCode: 'MANUAL', providerEventId: 'manual-63', providerNodeCode: 'TRANSIT', standardNode: 'IN_TRANSIT' as const, nodeSequence: 50, observedAt: '2026-08-21T09:00:00', estimatedAt: null, actualAt: '2026-08-21T09:00:00', locationCode: null, locationName: '太平洋', sourceReference: '人工核验', rawPayloadHash: 'g'.repeat(64), createdAt: '2026-08-21T09:01:00' }
|
||||
vi.mocked(getCarrierScheduleQuery).mockResolvedValue({ query: { ...queryView, query: { ...queryView.query, resultPortScheduleId: null }, expired: false }, nodes: [estimated, actual, { ...actual, id: '64' }, manual], exceptions: [{ id: '65', providerCode: 'COSCO', providerEventId: 'hold-65', providerStatus: 'Terminal hold', exceptionCode: 'TERMINAL_HOLD', active: true, observedAt: '2026-08-21T08:30:00', locationCode: 'USLAX', locationName: 'Los Angeles', sourceReference: 'hold-source', rawPayloadHash: 'h'.repeat(64), createdAt: '2026-08-21T08:31:00' }], histories: [{ id: '66', action: 'MANUAL_NODE', fromVersion: 1, toVersion: 2, reason: '人工核验', operatorId: '1', operatorName: '管理员', createdAt: '2026-08-21T09:01:00' }] })
|
||||
const wrapper = mount(CarrierScheduleQueryPanel, { props: { oceanBookingId: '2', warehouseTimeline: [{ eventType: 'PDA_COMPLETE_LOADING', detail: '装柜完成', operatorName: '仓库员', occurredAt: '2026-08-20T08:00:00' }] }, global: { plugins: [ElementPlus, pinia] } })
|
||||
await flushPromises()
|
||||
const rows = wrapper.findAll('.fulfillment-timeline li')
|
||||
expect(rows.filter((row) => row.text().includes('已装船'))).toHaveLength(1)
|
||||
expect(rows[0]?.text()).toContain('已装船')
|
||||
expect(rows[1]?.text()).toContain('预计 2026-08-21 10:00')
|
||||
expect(rows[1]?.text()).toContain('船运节点')
|
||||
expect(rows.map((row) => row.text()).join('|')).toContain('人工补录')
|
||||
expect(rows.map((row) => row.text()).join('|')).toContain('码头扣留 · 发生')
|
||||
expect(wrapper.text()).toContain('查询任务摘要、异常与变更历史')
|
||||
expect(wrapper.text()).toContain('人工补录标准节点')
|
||||
})
|
||||
|
||||
it('hides the manual action without the frozen permission while retaining fulfillment facts', async () => {
|
||||
useAuthStore().permissions = []
|
||||
vi.mocked(listCarrierScheduleQueries).mockResolvedValue({ records: [{ ...queryView, query: { ...queryView.query, resultPortScheduleId: null }, expired: false }], page: 1, size: 200, total: 1, pages: 1 })
|
||||
vi.mocked(getCarrierScheduleQuery).mockResolvedValue({ query: { ...queryView, query: { ...queryView.query, resultPortScheduleId: null }, expired: false }, nodes: [], exceptions: [], histories: [] })
|
||||
const wrapper = mount(CarrierScheduleQueryPanel, { props: { oceanBookingId: '2', warehouseTimeline: [{ eventType: 'PDA_BATCH', detail: '拣货结果已提交', operatorName: '仓库员', occurredAt: '2026-08-20T07:00:00' }] }, global: { plugins: [ElementPlus, pinia] } })
|
||||
await flushPromises()
|
||||
expect(wrapper.text()).toContain('提交拣货结果')
|
||||
expect(wrapper.findAll('button').some((button) => button.text().includes('人工补录节点'))).toBe(false)
|
||||
})
|
||||
|
||||
it('keeps the form context and dialog-scoped idempotency key when a conflict is retried', async () => {
|
||||
|
||||
Reference in New Issue
Block a user