import { ref, computed, watch } from 'vue'; import { getPlanStudyRecord } from '@/api/modules/study'; // @ts-ignore import CalendarUtil from '@/uni_modules/uni-calendar/components/uni-calendar/util.js'; export interface PracticeStatistics { list: PracticeData[], rate: number, studyDays: number, total: number, } export interface PracticeData { date: string; info: number; questionNum: number; } export function useCalendar() { const calendarUtil = new CalendarUtil(); const globalStudentId = ref(0); const selected = ref([]); const statistics = ref({ list: [], rate: 0, studyDays: 0, total: 0 }); const currentWeekNumber = ref(1); // 用于外部数据计算 const calendarWeekNumber = ref(1); // 专门用于日历组件显示 const currentDate = ref(new Date()); const displayMode = ref<'year' | 'month'>('year'); const loading = ref(false); // 计算当前周范围 const currentWeekRange = computed(() => { return calendarUtil.getCurrentWeekRange(currentDate.value, currentWeekNumber.value); }); // 计算当前月份范围 const currentMonthRange = computed(() => { return calendarUtil.getCurrentMonthRange(currentDate.value); }); // 计算是否可以切换到上一周/月/年 const canGoPrev = computed(() => { const today = new Date(); const current = currentDate.value; if (displayMode.value === 'year') { return current.getFullYear() > EARLIEST_YEAR.value; } else { // 月份模式:支持跨年,只要不是最早年份1月就可以往前切换 return !(current.getFullYear() === EARLIEST_YEAR.value && current.getMonth() === 0); } }); // 计算是否可以切换到下一周/月/年(不能超过当前日期) const canGoNext = computed(() => { const today = new Date(); const current = currentDate.value; if (displayMode.value === 'year') { return current.getFullYear() < today.getFullYear(); } else { // 月份模式,不能超过当前月份 return current.getFullYear() < today.getFullYear() || (current.getFullYear() === today.getFullYear() && current.getMonth() < today.getMonth()); } }); // 3. 确保返回的数据格式符合 PracticeData[] 接口 // 4. 统计数据会从返回的练习数据中自动计算,无需额外处理 // ======================================================== const fetchPracticeData = async (year: number, month: number): Promise => { console.log('请求数据', year, month, globalStudentId.value) let practiceData: PracticeStatistics = { list: [], rate: 0, studyDays: 0, total: 0 }; const { data } = await getPlanStudyRecord({ year, month }); practiceData.list = data.list.map(item => ({ date: item.date, info: item.rate ? Number(item.rate) : 0, questionNum: item.study ? Number(item.study) : 0 })).sort((a, b) => a.date.localeCompare(b.date)); practiceData.rate = data.rate ? Number(data.rate) : 0; practiceData.studyDays = data.studyDays ? Number(data.studyDays) : 0; practiceData.total = data.total ? Number(data.total) : 0; console.log('response', practiceData) return practiceData; }; // 更新日历数据 - 统一的数据更新方法 const updateCalendarData = async (year: number, month: number) => { if (month !== 0) { displayMode.value = 'month'; currentDate.value = new Date(year, month - 1, 1); } else { displayMode.value = 'year'; currentDate.value = new Date(year, month, 1); } console.log(year, month) console.log('currentDate', currentDate.value) loading.value = true; try { // 请求数据 const practiceData = await fetchPracticeData(year, month); // 更新状态 selected.value = practiceData.list statistics.value = practiceData; } finally { loading.value = false; } }; // 切换到上一个月 const goToPrevMonth = async () => { if (!canGoPrev.value) return; const currentMonth = currentDate.value.getMonth(); const targetMonth = currentMonth === 0 ? 12 : currentMonth; // 如果当前是1月,目标月份是12月 const targetYear = currentMonth === 0 ? currentDate.value.getFullYear() - 1 : currentDate.value.getFullYear(); const prevDate = new Date(targetYear, targetMonth - 1, 1); currentDate.value = prevDate; await updateCalendarData(targetYear, targetMonth); }; // 切换到下一个月 const goToNextMonth = async () => { if (!canGoNext.value) return; const currentMonth = currentDate.value.getMonth(); const targetMonth = currentMonth === 11 ? 1 : currentMonth + 2; // 如果当前是12月,目标月份是1月 const targetYear = currentMonth === 11 ? currentDate.value.getFullYear() + 1 : currentDate.value.getFullYear(); const nextDate = new Date(targetYear, targetMonth - 1, 1); currentDate.value = nextDate; await updateCalendarData(targetYear, targetMonth); }; // 根据年份跳转 const goToYear = async (year: number) => { await updateCalendarData(year, 0); }; // 根据年份和月份跳转 const goToYearMonth = async (year: number, month: number) => { await updateCalendarData(year, month); }; // 生成可以选择的年份列表,默认去年+今年 const yearList = computed(() => { const today = new Date(); const currentYear = today.getFullYear(); return [ { label: currentYear - 1, value: currentYear - 1 }, { label: currentYear, value: currentYear } ]; }) // 配置变量:最早可访问的年份 const EARLIEST_YEAR = computed(() => { return yearList.value[0].value; }); // 获取当前年份 const currentYear = computed(() => currentDate.value.getFullYear()); // 获取当前月份 const currentMonth = computed(() => currentDate.value.getMonth() + 1); // 初始化下拉菜单数据 const initializeFormData = () => { const today = new Date(); const currentYearToday = today.getFullYear(); return { year: currentYearToday.toString(), month: '', // 默认不选择月份 }; }; // 初始化数据 - 默认按年份模式初始化 const init = async (studentId: number) => { const today = new Date(); globalStudentId.value = studentId; await updateCalendarData(today.getFullYear(), 0); }; return { // 数据 calendarUtil, selected, statistics, currentWeekNumber, calendarWeekNumber, currentDate, displayMode, currentWeekRange, currentMonthRange, // 状态 canGoPrev, canGoNext, loading, // 计算属性 currentYear, currentMonth, // 配置 EARLIEST_YEAR, yearList, // 方法 updateCalendarData, goToPrevMonth, goToNextMonth, goToYear, goToYearMonth, initializeFormData, init }; }