From 0cb8a5c2b2392aed6d62ce353b7587e0e2921cd5 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Sat, 10 Oct 2026 15:33:10 +0800 Subject: [PATCH 1/2] fix: align appointment procurement and carpool workflows with agreed views --- .../AppointmentCalendarPanel.test.ts | 18 +++++- .../AppointmentCalendarPanel.vue | 18 ++++-- .../AppointmentCalendarView.test.ts | 32 +++++++++- .../AppointmentCalendarView.vue | 32 ++++++---- .../AppointmentContainerPanel.vue | 55 ++++++++++++---- .../AppointmentImpactDialog.test.ts | 38 +++++++++++ .../AppointmentImpactDialog.vue | 63 +++++++++++++++++++ .../AppointmentTableRendering.test.ts | 30 ++++++++- .../appointment-calendar/PROTOTYPE_MATRIX.md | 5 ++ src/modules/appointment-calendar/impactApi.ts | 31 +++++++++ .../appointment-calendar/planningApi.test.ts | 10 ++- .../appointment-calendar/planningApi.ts | 2 + .../components/ProcurementNodeActions.test.ts | 21 ++++++- .../components/ProcurementNodeActions.vue | 18 +++++- .../overseas-master-data/PROTOTYPE_MATRIX.md | 2 + .../components/CapacityInquiryDialog.vue | 45 +++++++++---- .../pages/CapacityOffersBehavior.test.ts | 40 ++++++++++-- .../pages/CapacityOffersView.vue | 5 +- 18 files changed, 407 insertions(+), 58 deletions(-) create mode 100644 src/modules/appointment-calendar/AppointmentImpactDialog.test.ts create mode 100644 src/modules/appointment-calendar/AppointmentImpactDialog.vue create mode 100644 src/modules/appointment-calendar/impactApi.ts diff --git a/src/modules/appointment-calendar/AppointmentCalendarPanel.test.ts b/src/modules/appointment-calendar/AppointmentCalendarPanel.test.ts index aeec06bc..6d522a2a 100644 --- a/src/modules/appointment-calendar/AppointmentCalendarPanel.test.ts +++ b/src/modules/appointment-calendar/AppointmentCalendarPanel.test.ts @@ -10,11 +10,26 @@ describe('appointment calendar interactions', () => { global: { stubs: { ElButton: { template: '' } }, directives: { loading: {} } }, }) + it('hides optional references by default and counts only appointments after enabling them', async () => { + const wrapper = render() + await wrapper.setProps({ events: [ + { key: 'a', type: 'delivery', date: '2026-09-24', time: '09:00', title: '收货预约', fields: [] }, + { key: 'b', type: 'arrival', date: '2026-09-24', time: '08:00', title: '到港参考', fields: [] }, + { key: 'c', type: 'trip', date: '2026-09-24', time: '07:00', title: '运输计划', fields: [] }, + ] }) + expect(wrapper.findAll('.detail-event')).toHaveLength(1) + const switches = wrapper.get('[aria-label="参考图层"]').findAll('input') + await switches[0]!.setValue(true); await switches[1]!.setValue(true) + expect(wrapper.findAll('.detail-event')).toHaveLength(3) + expect(wrapper.get('[aria-label="当天安排"] header').text()).toContain('1 项预约') + expect(wrapper.get('[aria-label="当天安排"] header').text()).toContain('2 条参考计划') + expect(wrapper.emitted('range')).toBeUndefined() + }) it('selects an already loaded date without requesting data again', async () => { const wrapper = render() await wrapper.get('[aria-label="2026-09-25,0 项安排"]').trigger('click') expect(wrapper.emitted('range')).toBeUndefined() - expect(wrapper.get('[aria-label="当天安排"]').text()).toContain('当天暂无到港或送仓预约') + expect(wrapper.get('[aria-label="当天安排"]').text()).toContain('当天暂无预约') }) it('shows an overnight slot on both days without fetching again and excludes midnight ends', async () => { @@ -44,6 +59,7 @@ describe('appointment calendar interactions', () => { key: `arrival-${index}`, type: 'arrival' as const, date: '2026-09-24', time: '09:00', title: `船舶 ${index}`, fields: [], })) }) + await wrapper.get('[aria-label="参考图层"] input').setValue(true) for (const view of ['month', 'week']) { if (view === 'week') await wrapper.get('[aria-label="预约视图"]').findAll('button')[1]!.trigger('click') const day = wrapper.get('[aria-label="2026-09-24,233 项安排"]') diff --git a/src/modules/appointment-calendar/AppointmentCalendarPanel.vue b/src/modules/appointment-calendar/AppointmentCalendarPanel.vue index 4b44c3a9..493ec391 100644 --- a/src/modules/appointment-calendar/AppointmentCalendarPanel.vue +++ b/src/modules/appointment-calendar/AppointmentCalendarPanel.vue @@ -27,18 +27,22 @@ const props = withDefaults(defineProps<{ initialDate?: string }>(), { loading: false, incomplete: false, canCreate: false, initialDate: '' }) const emit = defineEmits<{ + layers: [layers: { arrivals: boolean; trips: boolean }] range: [range: { from: string; to: string }] create: [date: string] edit: [event: CalendarEvent] delete: [event: CalendarEvent] open: [event: CalendarEvent] }>() +const showArrivals = ref(false), showTrips = ref(false) +function updateLayers() { emit('layers', { arrivals: showArrivals.value, trips: showTrips.value }) } +const visibleEvents = computed(() => props.events.filter(event => (event.type !== 'arrival' || showArrivals.value) && (event.type !== 'trip' || showTrips.value))) const selectedDate = ref(props.initialDate || dateKey(new Date())) const mode = ref('month') const dates = computed(() => calendarDates(selectedDate.value, mode.value)) const grouped = computed(() => { const result = new Map() - for (const event of props.events) { + for (const event of visibleEvents.value) { for (const date of dates.value) { if (!occursOnDate(event.date, event.endAt, date)) continue const group = result.get(date) || [] @@ -50,6 +54,7 @@ const grouped = computed(() => { return result }) const selectedEvents = computed(() => grouped.value.get(selectedDate.value) || []) +const appointmentCount = computed(() => selectedEvents.value.filter(event => event.type === 'delivery' || event.type === 'pickup').length) const weekdays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] const eventTypeLabels = { arrival: '船舶到港', delivery: '预约送仓', pickup: '预约提柜', trip: '用车计划' } const heading = computed(() => mode.value === 'month' @@ -72,11 +77,12 @@ defineExpose({ selectedDate, mode })