From f9193a356457a20d5ccf3022d531eb4446599d0f Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Thu, 15 Oct 2026 17:33:36 +0800 Subject: [PATCH] fix(appointment): show readable source and preview blockers --- .../WorkCreateAppointmentForm.test.ts | 9 +++++++++ .../WorkCreateAppointmentForm.vue | 3 ++- .../appointment-calendar/workPresentation.test.ts | 15 ++++++++++++++- .../appointment-calendar/workPresentation.ts | 11 ++++++++++- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/modules/appointment-calendar/WorkCreateAppointmentForm.test.ts b/src/modules/appointment-calendar/WorkCreateAppointmentForm.test.ts index d423d9e5..11442526 100644 --- a/src/modules/appointment-calendar/WorkCreateAppointmentForm.test.ts +++ b/src/modules/appointment-calendar/WorkCreateAppointmentForm.test.ts @@ -15,6 +15,15 @@ const preview: PlanningBatchPreview = { group: { originWarehouseId: 'origin-1', let guard: LeaveGuard function render(input = sources) { return mount(WorkCreateAppointmentForm, { props: { sources: input, canWrite: true }, global: { provide: { 'appointment-work-leave-guard': (value: LeaveGuard) => { guard = value; return () => undefined } }, stubs: { ElButton: { props: ['disabled'], template: '' }, FbaAppointmentFields: { name: 'FbaAppointmentFields', props: ['model', 'disabled'], template: '' }, LoadErrorState: { props: ['message'], template: '
{{ message }}
' }, ApiErrorMeta: true } } }) } beforeEach(() => { vi.clearAllMocks(); access.write = true; vi.mocked(previewPlanningBatch).mockResolvedValue(preview); vi.mocked(createSourceAppointment).mockResolvedValue(batchContext().appointment) }) +it('shows readable preview requirements without exposing missing-field machine codes', async () => { + vi.mocked(previewPlanningBatch).mockResolvedValue({ ...preview, missingFields: ['READY_WINDOW_UNVERIFIED', 'CARGO_QUANTITY_REVIEW'] }) + const wrapper = render(); await flushPromises() + expect(wrapper.text()).toContain('货物备妥窗口待核实') + expect(wrapper.text()).toContain('货量或重复关联需要核对。') + expect(wrapper.text()).not.toContain('READY_WINDOW_UNVERIFIED') + expect(wrapper.text()).not.toContain('CARGO_QUANTITY_REVIEW') + wrapper.unmount() +}) it('previews and creates the exact canonical external source and customer without inventing times', async () => { const wrapper = render(); await flushPromises() expect(previewPlanningBatch).toHaveBeenCalledWith(sources) diff --git a/src/modules/appointment-calendar/WorkCreateAppointmentForm.vue b/src/modules/appointment-calendar/WorkCreateAppointmentForm.vue index 1d169c5a..beef2652 100644 --- a/src/modules/appointment-calendar/WorkCreateAppointmentForm.vue +++ b/src/modules/appointment-calendar/WorkCreateAppointmentForm.vue @@ -9,6 +9,7 @@ import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http' import { previewPlanningBatch, createSourceAppointment, type PlanningBatchPreview, type SourceAppointmentPayload } from './planningApi' import type { SourceReference } from './workApi' import { rejectedCommand, useWorkDraft } from './useWorkDraft' +import { workReason } from './workPresentation' const props = defineProps<{ sources: SourceReference[]; canWrite: boolean }>() const emit = defineEmits<{ saved: [] }>() const access = useAccessPreviewStore(), preview = ref{{ preview.originWarehouseName }} → {{ preview.destinationWarehouseCode }} · {{ preview.group.sourceCount }} 票 · {{ preview.group.packages ?? '箱数待核实' }}
{{ source.inboundCode || source.bookingNo || '原票业务号未提供' }}
-{{ field }}
+{{ workReason(field) }}
货物备妥窗口待核实。