import { ref, watchEffect, nextTick } from 'vue'; import { GetMyTaskDailyDistribution, GetMyTaskMonthDistribution } from '@/api/user'; import { useRoute } from 'vue-router/composables'; import dayjs from 'dayjs'; export const weekList = [ { name: '日', label: 'Sun' }, { name: '一', label: 'Mon' }, { name: '二', label: 'Tue' }, { name: '三', label: 'Wed' }, { name: '四', label: 'Thu' }, { name: '五', label: 'Fri' }, { name: '六', label: 'Sat' } ]; export const monthList = ref([ { name: '01月', label: 'Jan', month: '01' }, { name: '02月', label: 'Feb', month: '02' }, { name: '03月', label: 'Mar', month: '03' }, { name: '04月', label: 'Apr', month: '04' }, { name: '05月', label: 'May', month: '05' }, { name: '06月', label: 'Jun', month: '06' }, { name: '07月', label: 'Jul', month: '07' }, { name: '08月', label: 'Aug', month: '08' }, { name: '09月', label: 'Sep', month: '09' }, { name: '10月', label: 'Oct', month: '10' }, { name: '11月', label: 'Nov', month: '11' }, { name: '12月', label: 'Dec', month: '12' } ]); // 日历显示模式 export const modeList = [ { type: 'DAY', name: 'Key311' }, { type: 'MONTH', name: 'Key310' } ]; /** * 日历方法 * @param {Emits} emits */ export function useMonthlyCalendar(emits) { const route = useRoute(); const dateSta = route.query.dateStamp; let dateStamp = dateSta ? new Date(dateSta) : new Date(); let focusDate = ref(dateStamp.getDate()); // 选中的当前日期 let focusMonth = ref(0); // 选中的当前月份 let curYear = ref(dateStamp.getFullYear()); // 当前年份 let curMonth = ref(dateStamp.getMonth() + 1); // 当前月份 const DAY = modeList[0].type; const MONTH = modeList[1].type; let calendar = ref([]); // 日历数组 let taskMonthDistribution = ref({}); // 任务每月分布 watchEffect(() => { GetMyTaskMonthDistribution({ year_stamp: curYear.value }).then(({ status, ...data }) => { if (status !== 1) return; const taskMonthArr = {}; for (const [key, value] of Object.entries(data)) { taskMonthArr[key.slice(5)] = value; } taskMonthDistribution.value = taskMonthArr; }); }); // 得到当前日历任务每日分布 let date = ref(`${dateStamp.getFullYear()}-${dateStamp.getMonth() + 1}`); let taskDailyDistribution = ref({}); // 任务每日分布 watchEffect(() => { curYear.value = dayjs(date.value).year(); curMonth.value = dayjs(date.value).month() + 1; focusMonth.value = dayjs(date.value).month(); GetMyTaskDailyDistribution({ month_stamp: date.value }).then(({ status, ...data }) => { if (status !== 1) return; const taskDailyArr = {}; for (const [key, value] of Object.entries(data)) { taskDailyArr[key.slice(5)] = value; } taskDailyDistribution.value = taskDailyArr; }); }); const taskDailyClass = new Map([ [0, ''], [1, 'has-task'], [2, 'task-completed'] ]); // 得到日历每日样式 function getTaskDailyClass(month, day) { const date = `${month < 10 ? '0' : ''}${month}-${day < 10 ? '0' : ''}${day}`; return date in taskDailyDistribution.value ? taskDailyClass.get(taskDailyDistribution.value[date]) : ''; } // 得到日历每月样式 function getTaskMonthClass(month) { return month in taskMonthDistribution.value ? taskDailyClass.get(taskMonthDistribution.value[month]) : ''; } // 得到日历所需数组 function getDateArr() { const daysInMonth = dayjs(date.value).daysInMonth(); const dayOfWeek = dayjs(`${date.value}-1`).day(); const curMonth = dayjs(date.value).month(); const curYear = dayjs(date.value).year(); const lastDays = dayjs(curMonth === 0 ? `${curYear - 1}-12` : `${curYear}-${curMonth}`).daysInMonth(); const cDate = new Date(); const curDate = cDate.getDate(); const isThisMonth = curMonth === cDate.getMonth() && curYear === cDate.getFullYear(); let arr = []; // 是否有上个月 for (let i = 0; i < dayOfWeek; i++) { arr[i] = { key: `last-${i}`, month: (curMonth === 0 ? 11 : curMonth - 1) + 1, day: lastDays - dayOfWeek + i + 1, isCurMonth: false, isToday: false }; } // 本月 for (let j = 1; j <= daysInMonth; j++) { arr[j + dayOfWeek - 1] = { key: `cur-${j}`, month: curMonth + 1, day: j, isCurMonth: true, isToday: j === curDate && isThisMonth }; } if (arr.length === 35) return (calendar.value = arr); // 下月 let next = (arr.length < 35 ? 35 : 42) - dayOfWeek - daysInMonth; for (let k = 1; k <= next; k++) { arr.push({ key: `next-${k}`, month: (curMonth === 11 ? 1 : curMonth + 1) + 1, day: k, isCurMonth: false, isToday: false }); } calendar.value = arr; } getDateArr(); // 返回今天 function backToday() { const curDate = new Date(); date.value = `${curDate.getFullYear()}-${curDate.getMonth() + 1}`; focusDate.value = curDate.getDate(); focusMonth.value = curDate.getMonth(); emits('changeDate'); getDateArr(); } /** * 日历模式切换 */ let time_unit = ref(modeList[0].type); // 当前日历模式 let calendarStyle = ref(''); // 日历样式 // 根据日历模式切换样式 watchEffect(() => { if (time_unit.value === DAY) { return (calendarStyle.value = `40px repeat(${calendar.value.length > 35 ? 6 : 5}, 1fr) / repeat(7, 1fr)`); } if (time_unit.value === MONTH) return (calendarStyle.value = `repeat(4, 1fr) / repeat(3, 1fr)`); }); // 月份向前或向后 function changeMonth(type) { const curMonth = dayjs(date.value).month(); const curYear = dayjs(date.value).year(); if (type === 'pre' && time_unit.value === DAY) { date.value = curMonth === 0 ? `${curYear - 1}-12` : `${curYear}-${curMonth}`; } if (type === 'pre' && time_unit.value === MONTH) { date.value = `${curYear - 1}-${curMonth + 1}`; } if (type === 'next' && time_unit.value === DAY) { date.value = curMonth === 11 ? `${curYear + 1}-1` : `${curYear}-${curMonth + 2}`; } if (type === 'next' && time_unit.value === MONTH) { date.value = `${curYear + 1}-${curMonth + 1}`; } nextTick(() => { emits('changeDate'); }); getDateArr(); } /** * 改变显示方式 日/月 */ function changeMenu(type) { time_unit.value = type; emits('changeTimeUnit'); } // 日模式 -> 选择日期 function selectDate(number, isCurMonth) { if (time_unit.value === DAY) { focusDate.value = number; } if (!isCurMonth) { return changeMonth(number < 7 ? 'next' : 'pre'); } emits('changeDate'); } // 月模式 -> 选择月份 function selectMonth(number) { date.value = `${curYear.value}-${number + 1}`; focusMonth.value = number; nextTick(() => { emits('changeDate'); }); getDateArr(); } return { DAY, MONTH, time_unit, curYear, curMonth, focusDate, calendarStyle, calendar, taskDailyDistribution, taskMonthDistribution, focusMonth, getTaskDailyClass, getTaskMonthClass, backToday, changeMonth, changeMenu, selectDate, selectMonth }; }