admin-vben/apps/web-antd/src/views/mes/cal/calendar/components/use-calendar.ts

100 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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>(dayjs());
const calendarDayMap = ref<Map<string, MesCalCalendarApi.CalendarDay>>(
new Map(),
);
const holidaySet = ref(new Set<string>());
/** 计算当前月份的起止时间 */
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<string>();
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<string, any>) {
loading.value = true;
try {
const { endDay, startDay } = getMonthRange();
const list = await getCalendarList({ ...params, endDay, startDay });
const map = new Map<string, MesCalCalendarApi.CalendarDay>();
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,
};
}