diff --git a/src/modules/appointment-calendar/AppointmentCalendarView.test.ts b/src/modules/appointment-calendar/AppointmentCalendarView.test.ts index 5740c46c..365c3e15 100644 --- a/src/modules/appointment-calendar/AppointmentCalendarView.test.ts +++ b/src/modules/appointment-calendar/AppointmentCalendarView.test.ts @@ -70,6 +70,18 @@ describe('appointment calendar data integration', () => { vi.mocked(createFbaAppointment).mockResolvedValue({ version: 0, id: '1', appointmentNo: 'APT-AB', plannedDate: '2026-10-09', appointmentAt: null, originWarehouseId: '100', appointmentStatus: 'PENDING', selectedCount: 2, fbaWarehouseCode: 'ONT8', items: [] }) }) + it('uses the dedicated cancellation dialog for an undated appointment instead of editing its status', async () => { + const record = { version: 3, id: '1', appointmentNo: 'AP-UNDATED', originWarehouseId: '100', appointmentStatus: 'PENDING', selectedCount: 1, fbaWarehouseCode: 'ABE3', items: [] } + vi.mocked(listUnscheduledAppointments).mockResolvedValue({records: [record], total: 1}) + vi.mocked(getFbaAppointment).mockResolvedValue(record) + const wrapper=render(); await flushPromises() + await wrapper.findAll('button').find(button=>button.text()==='查看 / 继续')!.trigger('click'); await flushPromises() + expect(wrapper.find('option[value="CANCELLED"]').exists()).toBe(false) + await wrapper.get('[data-cancel-editing]').trigger('click'); await flushPromises() + expect(wrapper.findComponent({name:'AppointmentCancellationDialog'}).attributes('appointment-no')).toBe('AP-UNDATED') + expect(wrapper.find('[data-save]').exists()).toBe(false) + expect(updateFbaAppointment).not.toHaveBeenCalled(); wrapper.unmount() + }) it('loads cancellation records only after expansion and opens cancelled appointments read-only', async () => { const record = { version: 1, id: '1', appointmentNo: 'AP-CANCEL', originWarehouseId: '100', appointmentStatus: 'CANCELLED', selectedCount: 1, fbaWarehouseCode: 'ABE3', items: [] } vi.mocked(getFbaAppointment).mockResolvedValue(record) diff --git a/src/modules/appointment-calendar/AppointmentCalendarView.vue b/src/modules/appointment-calendar/AppointmentCalendarView.vue index b1015197..8dffe02a 100644 --- a/src/modules/appointment-calendar/AppointmentCalendarView.vue +++ b/src/modules/appointment-calendar/AppointmentCalendarView.vue @@ -354,6 +354,11 @@ function remove(event: CalendarEvent) { if (!access.can('platform:appointment:delete') || loading.value || !canLeave()) return cancellationTarget.value = appointments.value.find(item => item.appointmentNo === event.key) || null } +function cancelEditing() { + if (!editing.value || editing.value.appointmentStatus === 'CANCELLED' || !access.can('platform:appointment:delete') || !canLeave()) return + cancellationTarget.value = editing.value + dialogOpen.value = false +} async function cancelled() { cancellationTarget.value = null; ++cancellationsRevision.value ElMessage.success('预约已取消,可在取消记录中查看原因与原记录') @@ -439,6 +444,7 @@ onBeforeUnmount(() => { ++unscheduledRequest; ++calendarRequest; ++candidateRequ

输入更完整的仓库编码或名称,缩小搜索范围。

+ 取消预约