From fab333fbb722e030507d4dd51abdea5d42cedcf4 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 25 May 2026 01:07:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(mes)=EF=BC=9A=E8=BF=81=E7=A7=BB=E3=80=90?= =?UTF-8?q?=E6=8E=92=E7=8F=AD=E6=97=A5=E5=8E=86=E3=80=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/calendar-date-cell.vue | 135 ++++++++++++++++++ .../calendar/components/calendar-legend.vue | 38 +++++ .../calendar/components/calendar-panel.vue | 106 ++++++++++++++ .../cal/calendar/components/use-calendar.ts | 99 +++++++++++++ .../src/views/mes/cal/calendar/index.vue | 42 ++++++ .../mes/cal/calendar/modules/team-view.vue | 84 +++++++++++ .../mes/cal/calendar/modules/type-view.vue | 85 +++++++++++ .../mes/cal/calendar/modules/user-view.vue | 93 ++++++++++++ .../components/calendar-date-cell.vue | 135 ++++++++++++++++++ .../calendar/components/calendar-legend.vue | 38 +++++ .../calendar/components/calendar-panel.vue | 60 ++++++++ .../cal/calendar/components/use-calendar.ts | 99 +++++++++++++ .../src/views/mes/cal/calendar/index.vue | 42 ++++++ .../mes/cal/calendar/modules/team-view.vue | 84 +++++++++++ .../mes/cal/calendar/modules/type-view.vue | 85 +++++++++++ .../mes/cal/calendar/modules/user-view.vue | 98 +++++++++++++ 16 files changed, 1323 insertions(+) create mode 100644 apps/web-antd/src/views/mes/cal/calendar/components/calendar-date-cell.vue create mode 100644 apps/web-antd/src/views/mes/cal/calendar/components/calendar-legend.vue create mode 100644 apps/web-antd/src/views/mes/cal/calendar/components/calendar-panel.vue create mode 100644 apps/web-antd/src/views/mes/cal/calendar/components/use-calendar.ts create mode 100644 apps/web-antd/src/views/mes/cal/calendar/index.vue create mode 100644 apps/web-antd/src/views/mes/cal/calendar/modules/team-view.vue create mode 100644 apps/web-antd/src/views/mes/cal/calendar/modules/type-view.vue create mode 100644 apps/web-antd/src/views/mes/cal/calendar/modules/user-view.vue create mode 100644 apps/web-ele/src/views/mes/cal/calendar/components/calendar-date-cell.vue create mode 100644 apps/web-ele/src/views/mes/cal/calendar/components/calendar-legend.vue create mode 100644 apps/web-ele/src/views/mes/cal/calendar/components/calendar-panel.vue create mode 100644 apps/web-ele/src/views/mes/cal/calendar/components/use-calendar.ts create mode 100644 apps/web-ele/src/views/mes/cal/calendar/index.vue create mode 100644 apps/web-ele/src/views/mes/cal/calendar/modules/team-view.vue create mode 100644 apps/web-ele/src/views/mes/cal/calendar/modules/type-view.vue create mode 100644 apps/web-ele/src/views/mes/cal/calendar/modules/user-view.vue diff --git a/apps/web-antd/src/views/mes/cal/calendar/components/calendar-date-cell.vue b/apps/web-antd/src/views/mes/cal/calendar/components/calendar-date-cell.vue new file mode 100644 index 000000000..e8d162119 --- /dev/null +++ b/apps/web-antd/src/views/mes/cal/calendar/components/calendar-date-cell.vue @@ -0,0 +1,135 @@ + + + diff --git a/apps/web-antd/src/views/mes/cal/calendar/components/calendar-legend.vue b/apps/web-antd/src/views/mes/cal/calendar/components/calendar-legend.vue new file mode 100644 index 000000000..3c7def7fb --- /dev/null +++ b/apps/web-antd/src/views/mes/cal/calendar/components/calendar-legend.vue @@ -0,0 +1,38 @@ + + + diff --git a/apps/web-antd/src/views/mes/cal/calendar/components/calendar-panel.vue b/apps/web-antd/src/views/mes/cal/calendar/components/calendar-panel.vue new file mode 100644 index 000000000..55fd9049a --- /dev/null +++ b/apps/web-antd/src/views/mes/cal/calendar/components/calendar-panel.vue @@ -0,0 +1,106 @@ + + + + + + diff --git a/apps/web-antd/src/views/mes/cal/calendar/components/use-calendar.ts b/apps/web-antd/src/views/mes/cal/calendar/components/use-calendar.ts new file mode 100644 index 000000000..381e7f5bd --- /dev/null +++ b/apps/web-antd/src/views/mes/cal/calendar/components/use-calendar.ts @@ -0,0 +1,99 @@ +import type { Dayjs } from 'dayjs'; + +import type { MesCalCalendarApi } from '#/api/mes/cal/calendar'; + +import { ref, watch } from 'vue'; + +import dayjs from 'dayjs'; + +import { getCalendarList } from '#/api/mes/cal/calendar'; +import { getHolidayList } from '#/api/mes/cal/holiday'; +import { HolidayType } from '#/views/mes/utils/constants'; + +/** + * 排班日历通用 composable + * + * 封装日历组件中通用的响应式状态、假期加载、排班查询、月份切换逻辑 + */ +export function useCalendar() { + const loading = ref(false); + const currentDate = ref(dayjs()); + const calendarDayMap = ref>( + new Map(), + ); + const holidaySet = ref(new Set()); + + /** 计算当前月份的起止时间 */ + function getMonthRange() { + const startDay = currentDate.value + .startOf('month') + .format('YYYY-MM-DD 00:00:00'); + const endDay = currentDate.value + .endOf('month') + .format('YYYY-MM-DD 23:59:59'); + return { endDay, startDay }; + } + + /** + * 获取节假日列表,按当前月份范围加载 + * + * 失败(无权限 / 接口异常)时不抛出,仅清空当月假期标记, + * 避免阻断使用方的主数据初始化 + */ + async function loadHolidays() { + const { endDay, startDay } = getMonthRange(); + const days = new Set(); + try { + const list = await getHolidayList({ endDay, startDay }); + for (const item of list || []) { + const day = item.day ? dayjs(item.day).format('YYYY-MM-DD') : ''; + if (day && item.type === HolidayType.HOLIDAY) { + days.add(day); + } + } + } catch { + // 没有 mes:cal-holiday:query 权限或接口异常时,仅忽略假期标记 + } + holidaySet.value = days; + } + + /** 查询排班日历,params 由调用方提供 queryType 相关参数 */ + async function fetchCalendar(params: Record) { + loading.value = true; + try { + const { endDay, startDay } = getMonthRange(); + const list = await getCalendarList({ ...params, endDay, startDay }); + const map = new Map(); + for (const item of list || []) { + const day = item.day ? dayjs(item.day).format('YYYY-MM-DD') : ''; + if (day) { + map.set(day, { ...item, day }); + } + } + calendarDayMap.value = map; + } finally { + loading.value = false; + } + } + + /** 监听月份切换,调用回调刷新数据 */ + function watchMonth(callback: () => void) { + watch( + () => currentDate.value.format('YYYY-MM'), + () => { + void loadHolidays(); + callback(); + }, + ); + } + + return { + calendarDayMap, + currentDate, + fetchCalendar, + holidaySet, + loadHolidays, + loading, + watchMonth, + }; +} diff --git a/apps/web-antd/src/views/mes/cal/calendar/index.vue b/apps/web-antd/src/views/mes/cal/calendar/index.vue new file mode 100644 index 000000000..1b9895b85 --- /dev/null +++ b/apps/web-antd/src/views/mes/cal/calendar/index.vue @@ -0,0 +1,42 @@ + + + diff --git a/apps/web-antd/src/views/mes/cal/calendar/modules/team-view.vue b/apps/web-antd/src/views/mes/cal/calendar/modules/team-view.vue new file mode 100644 index 000000000..7637c755b --- /dev/null +++ b/apps/web-antd/src/views/mes/cal/calendar/modules/team-view.vue @@ -0,0 +1,84 @@ + + + diff --git a/apps/web-antd/src/views/mes/cal/calendar/modules/type-view.vue b/apps/web-antd/src/views/mes/cal/calendar/modules/type-view.vue new file mode 100644 index 000000000..2919e0755 --- /dev/null +++ b/apps/web-antd/src/views/mes/cal/calendar/modules/type-view.vue @@ -0,0 +1,85 @@ + + + diff --git a/apps/web-antd/src/views/mes/cal/calendar/modules/user-view.vue b/apps/web-antd/src/views/mes/cal/calendar/modules/user-view.vue new file mode 100644 index 000000000..e42bd2342 --- /dev/null +++ b/apps/web-antd/src/views/mes/cal/calendar/modules/user-view.vue @@ -0,0 +1,93 @@ + + + diff --git a/apps/web-ele/src/views/mes/cal/calendar/components/calendar-date-cell.vue b/apps/web-ele/src/views/mes/cal/calendar/components/calendar-date-cell.vue new file mode 100644 index 000000000..2b9322bc0 --- /dev/null +++ b/apps/web-ele/src/views/mes/cal/calendar/components/calendar-date-cell.vue @@ -0,0 +1,135 @@ + + + diff --git a/apps/web-ele/src/views/mes/cal/calendar/components/calendar-legend.vue b/apps/web-ele/src/views/mes/cal/calendar/components/calendar-legend.vue new file mode 100644 index 000000000..21e32812e --- /dev/null +++ b/apps/web-ele/src/views/mes/cal/calendar/components/calendar-legend.vue @@ -0,0 +1,38 @@ + + + diff --git a/apps/web-ele/src/views/mes/cal/calendar/components/calendar-panel.vue b/apps/web-ele/src/views/mes/cal/calendar/components/calendar-panel.vue new file mode 100644 index 000000000..207061e0e --- /dev/null +++ b/apps/web-ele/src/views/mes/cal/calendar/components/calendar-panel.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/apps/web-ele/src/views/mes/cal/calendar/components/use-calendar.ts b/apps/web-ele/src/views/mes/cal/calendar/components/use-calendar.ts new file mode 100644 index 000000000..381e7f5bd --- /dev/null +++ b/apps/web-ele/src/views/mes/cal/calendar/components/use-calendar.ts @@ -0,0 +1,99 @@ +import type { Dayjs } from 'dayjs'; + +import type { MesCalCalendarApi } from '#/api/mes/cal/calendar'; + +import { ref, watch } from 'vue'; + +import dayjs from 'dayjs'; + +import { getCalendarList } from '#/api/mes/cal/calendar'; +import { getHolidayList } from '#/api/mes/cal/holiday'; +import { HolidayType } from '#/views/mes/utils/constants'; + +/** + * 排班日历通用 composable + * + * 封装日历组件中通用的响应式状态、假期加载、排班查询、月份切换逻辑 + */ +export function useCalendar() { + const loading = ref(false); + const currentDate = ref(dayjs()); + const calendarDayMap = ref>( + new Map(), + ); + const holidaySet = ref(new Set()); + + /** 计算当前月份的起止时间 */ + function getMonthRange() { + const startDay = currentDate.value + .startOf('month') + .format('YYYY-MM-DD 00:00:00'); + const endDay = currentDate.value + .endOf('month') + .format('YYYY-MM-DD 23:59:59'); + return { endDay, startDay }; + } + + /** + * 获取节假日列表,按当前月份范围加载 + * + * 失败(无权限 / 接口异常)时不抛出,仅清空当月假期标记, + * 避免阻断使用方的主数据初始化 + */ + async function loadHolidays() { + const { endDay, startDay } = getMonthRange(); + const days = new Set(); + try { + const list = await getHolidayList({ endDay, startDay }); + for (const item of list || []) { + const day = item.day ? dayjs(item.day).format('YYYY-MM-DD') : ''; + if (day && item.type === HolidayType.HOLIDAY) { + days.add(day); + } + } + } catch { + // 没有 mes:cal-holiday:query 权限或接口异常时,仅忽略假期标记 + } + holidaySet.value = days; + } + + /** 查询排班日历,params 由调用方提供 queryType 相关参数 */ + async function fetchCalendar(params: Record) { + loading.value = true; + try { + const { endDay, startDay } = getMonthRange(); + const list = await getCalendarList({ ...params, endDay, startDay }); + const map = new Map(); + for (const item of list || []) { + const day = item.day ? dayjs(item.day).format('YYYY-MM-DD') : ''; + if (day) { + map.set(day, { ...item, day }); + } + } + calendarDayMap.value = map; + } finally { + loading.value = false; + } + } + + /** 监听月份切换,调用回调刷新数据 */ + function watchMonth(callback: () => void) { + watch( + () => currentDate.value.format('YYYY-MM'), + () => { + void loadHolidays(); + callback(); + }, + ); + } + + return { + calendarDayMap, + currentDate, + fetchCalendar, + holidaySet, + loadHolidays, + loading, + watchMonth, + }; +} diff --git a/apps/web-ele/src/views/mes/cal/calendar/index.vue b/apps/web-ele/src/views/mes/cal/calendar/index.vue new file mode 100644 index 000000000..1330438bf --- /dev/null +++ b/apps/web-ele/src/views/mes/cal/calendar/index.vue @@ -0,0 +1,42 @@ + + + diff --git a/apps/web-ele/src/views/mes/cal/calendar/modules/team-view.vue b/apps/web-ele/src/views/mes/cal/calendar/modules/team-view.vue new file mode 100644 index 000000000..7637c755b --- /dev/null +++ b/apps/web-ele/src/views/mes/cal/calendar/modules/team-view.vue @@ -0,0 +1,84 @@ + + + diff --git a/apps/web-ele/src/views/mes/cal/calendar/modules/type-view.vue b/apps/web-ele/src/views/mes/cal/calendar/modules/type-view.vue new file mode 100644 index 000000000..2919e0755 --- /dev/null +++ b/apps/web-ele/src/views/mes/cal/calendar/modules/type-view.vue @@ -0,0 +1,85 @@ + + + diff --git a/apps/web-ele/src/views/mes/cal/calendar/modules/user-view.vue b/apps/web-ele/src/views/mes/cal/calendar/modules/user-view.vue new file mode 100644 index 000000000..556af5fe3 --- /dev/null +++ b/apps/web-ele/src/views/mes/cal/calendar/modules/user-view.vue @@ -0,0 +1,98 @@ + + +