import Week from "./func/week"; import { Logger, Slide, GetDate, initialTasks } from "./func/utils"; import initCalendar, { jump, getCurrentYM, whenChangeDate, renderCalendar, whenMulitSelect, whenSingleSelect, whenChooseArea, getCalendarDates, } from "./main.js"; import { getPatientOnlineRecord, addPatientOnlineRecord, } from "../../pages/home/request"; import tickleBehavior, { getTickleContext, } from "../../core/behavior/tickle.behavior"; const slide = new Slide(); const logger = new Logger(); const getDate = new GetDate(); // 获取上个月 function getPrevMonth(year, month) { if (month === 1) { return { year: year - 1, month: 12 }; } return { year, month: month - 1 }; } // 获取下个月 function getNextMonth(year, month) { if (month === 12) { return { year: year + 1, month: 1 }; } return { year, month: month + 1 }; } function pad(num) { return num < 10 ? "0" + num : "" + num; } Component({ options: { styleIsolation: "apply-shared", multipleSlots: true, // 在组件定义时的选项中启用多slot支持 }, properties: { calendarConfig: { type: Object, value: {}, }, }, behaviors: [tickleBehavior], data: { noClockIn: [], clockIn: [], id: "", handleMap: { prev_year: "chooseYear", prev_month: "chooseMonth", next_month: "chooseMonth", next_year: "chooseYear", }, currentMonth: null, currentYear: null, firstDate: null, lastDate: null, dateArrType: 1, days: [], dayData: "", isFutureDate: false, }, observers: { "calendar.days": function (newVal: any) { // 简化条件判断,只检查 newVal if ( newVal && newVal.length > 0 && newVal[0] && newVal[0].year && newVal[0].month ) { this.setData({ currentMonth: newVal[0].month, currentYear: newVal[0].year, }); let firstDate = null; const empytGrids = this.data.calendar.empytGrids || []; const days = newVal || []; let prevData = null; if (empytGrids.length > 0) { // 有上月补齐格子,第一个就是上月的 prevData = { year: getPrevMonth(days[0].year, days[0].month).year, month: getPrevMonth(days[0].year, days[0].month).month, day: empytGrids[0].day, }; } else if (days.length > 0) { // 没有上月补齐格子,第一个就是本月1号 prevData = { year: days[0].year, month: days[0].month, day: days[0].day, }; } let lastDate = null; let nextData = null; const lastEmptyGrids = this.data.calendar.lastEmptyGrids || []; if (lastEmptyGrids.length > 0) { nextData = { year: getNextMonth(days[0].year, days[0].month).year, month: getNextMonth(days[0].year, days[0].month).month, day: lastEmptyGrids[lastEmptyGrids.length - 1].day, }; } else if (days.length > 0) { nextData = { year: days[days.length - 1].year, month: days[days.length - 1].month, day: days[days.length - 1].day, }; } lastDate = nextData.year + "-" + pad(nextData.month) + "-" + pad(nextData.day); firstDate = prevData.year + "-" + pad(prevData.month) + "-" + pad(prevData.day); this.setData({ firstDate, lastDate, }); this.setData({ id: wx.getStorageSync("recordId") || "", }); if (this.data.id) { this.getCaRecord(this.data.id, firstDate, lastDate); } else { setTimeout(() => { this.getCaRecord(this.data.id, firstDate, lastDate); }, 2000); } } }, }, lifetimes: { attached: async function () { this.initComp(); }, detached: function () { initialTasks.flag = "finished"; initialTasks.tasks.length = 0; }, }, methods: { // 补卡 async onPatchCard(e: any) { try { const cardId = e.currentTarget.dataset.id; await addPatientOnlineRecord(cardId); wx.showToast({ title: "补卡成功", icon: "success", duration: 1500, }); await this.getCaRecord( this.data.id, this.data.firstDate, this.data.lastDate ); } catch (error: any) { getTickleContext.call(this).showWarnMessage(error.errMsg); } }, async getCaRecord(id: string | number, startDate: string, endDate: string) { try { const res = await getPatientOnlineRecord(id, startDate, endDate); const { currentYear, currentMonth } = this.data; if (res && res.length > 0) { // 1. 先筛选出本月的数据 const monthData = (res || []).filter( (item: any) => item.arrangeYear == currentYear && item.arrangeMon == currentMonth ); // 2. 遍历本月 days,赋值 (this.data.calendar.days || []).forEach((dayItem: any) => { // 只处理本月的格子 if (dayItem.year == currentYear && dayItem.month == currentMonth) { // 只给当前日期及之前的日期赋值 const currentDate = new Date(); const itemDate = new Date( dayItem.year, dayItem.month - 1, dayItem.day ); // 如果日期是今天或之前,才进行赋值 if (itemDate <= currentDate) { const match = monthData.find( (d: any) => d.arrangeDay == dayItem.day ); if (match) { dayItem.clockIn = [...match.clockIn]; dayItem.noClockIn = [...match.noClockIn]; dayItem.type = match.type; } } else { // 未来日期设置空的打卡数据,确保不显示打卡和补卡功能 dayItem.clockIn = []; dayItem.noClockIn = []; dayItem.type = null; } } }); const matchData = monthData.filter( (d: any) => d.arrangeDay == this.data.dayData ); if (matchData.length > 0) { this.setData({ noClockIn: matchData[0].noClockIn, clockIn: matchData[0].clockIn, }); } this.setData({ days: this.data.calendar.days, }); if (this.data.dateArrType == 1) { const currentDay = this.data.days.find( (item: any) => item.lunar.isToday ); if (currentDay) { // 检查当前日期是否为未来日期 const currentDate = new Date(); const itemDate = new Date( currentDay.year, currentDay.month - 1, currentDay.day ); const isCurrentDayFuture = itemDate > currentDate; if (!isCurrentDayFuture) { this.setData({ noClockIn: currentDay.noClockIn, clockIn: currentDay.clockIn, isFutureDate: false, }); } else { this.setData({ noClockIn: [], clockIn: [], isFutureDate: true, }); } } } } } catch (error) { getTickleContext.call(this).showWarnMessage(error.errMsg); } }, initComp() { const calendarConfig = this.setDefaultDisableDate(); this.setConfig(calendarConfig); }, setDefaultDisableDate() { const calendarConfig = this.properties.calendarConfig || {}; if (calendarConfig.disableMode && !calendarConfig.disableMode.date) { calendarConfig.disableMode.date = getDate.toTimeStr( getDate.todayDate() ); } return calendarConfig; }, setConfig(config) { if (config.markToday && typeof config.markToday === "string") { config.highlightToday = true; } config.theme = config.theme || "default"; this.weekMode = config.weekMode; this.setData( { calendarConfig: config, }, () => { initCalendar(this, config); } ); }, chooseDate(e) { const { type } = e.currentTarget.dataset; if (!type) return; const methodName = this.data.handleMap[type]; this[methodName](type); }, chooseYear(type) { const { curYear, curMonth } = this.data.calendar; if (!curYear || !curMonth) return logger.warn("异常:未获取到当前年月"); if (this.weekMode) { return console.warn("周视图下不支持点击切换年月"); } let newYear = +curYear; let newMonth = +curMonth; if (type === "prev_year") { newYear -= 1; } else if (type === "next_year") { newYear += 1; } this.render(curYear, curMonth, newYear, newMonth); }, chooseMonth(type) { const { curYear, curMonth } = this.data.calendar; if (!curYear || !curMonth) return logger.warn("异常:未获取到当前年月"); if (this.weekMode) return console.warn("周视图下不支持点击切换年月"); let newYear = +curYear; let newMonth = +curMonth; if (type === "prev_month") { newMonth = newMonth - 1; if (newMonth < 1) { newYear -= 1; newMonth = 12; } } else if (type === "next_month") { newMonth += 1; if (newMonth > 12) { newYear += 1; newMonth = 1; } } this.render(curYear, curMonth, newYear, newMonth); }, render(curYear, curMonth, newYear, newMonth) { whenChangeDate.call(this, { curYear, curMonth, newYear, newMonth, }); this.setData({ "calendar.curYear": newYear, "calendar.curMonth": newMonth, }); renderCalendar.call(this, newYear, newMonth); }, /** * 日期点击事件 * @param {!object} e 事件对象 */ tapDayItem(e) { this.setData({ dateArrType: 2, }); const { idx, date = {} } = e.currentTarget.dataset; const selectedDate = `${date.year} ${date.month}.${date.day}`; this.triggerEvent("onSelect", { selectedDate, }); const { day, disable, clockIn, noClockIn, type } = date; // 检查是否为未来日期 const currentDate = new Date(); const itemDate = new Date(date.year, date.month - 1, date.day); const isFutureDate = itemDate > currentDate; // 如果是未来日期,设置空的打卡数据,但仍然可以点击 if (isFutureDate) { this.setData({ noClockIn: [], clockIn: [], dayData: day, isFutureDate: true, }); } else { this.setData({ noClockIn: noClockIn || [], clockIn: clockIn || [], dayData: day, isFutureDate: false, }); } if (disable || !day) return; const config = this.data.calendarConfig || this.config || {}; const { multi, chooseAreaMode } = config; if (multi) { whenMulitSelect.call(this, idx); } else if (chooseAreaMode) { whenChooseArea.call(this, idx); } else { whenSingleSelect.call(this, idx); } this.setData({ "calendar.noDefault": false, }); }, doubleClickToToday() { if (this.config.multi || this.weekMode) return; if (this.count === undefined) { this.count = 1; } else { this.count += 1; } if (this.lastClick) { const difference = new Date().getTime() - this.lastClick; if (difference < 500 && this.count >= 2) { jump.call(this); } this.count = undefined; this.lastClick = undefined; } else { this.lastClick = new Date().getTime(); } }, /** * 日历滑动开始 * @param {object} e */ calendarTouchstart(e) { const t = e.touches[0]; const startX = t.clientX; const startY = t.clientY; this.slideLock = true; // 滑动事件加锁 this.setData({ "gesture.startX": startX, "gesture.startY": startY, }); }, /** * 日历滑动中 * @param {object} e */ calendarTouchmove(e) { const { gesture } = this.data; const { preventSwipe } = this.properties.calendarConfig; if (!this.slideLock || preventSwipe) return; if (slide.isLeft(gesture, e.touches[0])) { this.handleSwipe("left"); this.slideLock = false; } if (slide.isRight(gesture, e.touches[0])) { this.handleSwipe("right"); this.slideLock = false; } }, calendarTouchend(e) { this.setData({ "calendar.leftSwipe": 0, "calendar.rightSwipe": 0, }); }, handleSwipe(direction) { let swipeKey = "calendar.leftSwipe"; let swipeCalendarType = "next_month"; let weekChangeType = "next_week"; if (direction === "right") { swipeKey = "calendar.rightSwipe"; swipeCalendarType = "prev_month"; weekChangeType = "prev_week"; } this.setData({ [swipeKey]: 1, }); this.currentYM = getCurrentYM(); if (this.weekMode) { this.slideLock = false; this.currentDates = getCalendarDates(); if (weekChangeType === "prev_week") { Week(this).calculatePrevWeekDays(); } else if (weekChangeType === "next_week") { Week(this).calculateNextWeekDays(); } this.onSwipeCalendar(weekChangeType); this.onWeekChange(weekChangeType); return; } this.chooseMonth(swipeCalendarType); this.onSwipeCalendar(swipeCalendarType); }, onSwipeCalendar(direction) { this.triggerEvent("onSwipe", { directionType: direction, currentYM: this.currentYM, }); }, onWeekChange(direction) { this.triggerEvent("whenChangeWeek", { current: { currentYM: this.currentYM, dates: [...this.currentDates], }, next: { currentYM: getCurrentYM(), dates: getCalendarDates(), }, directionType: direction, }); this.currentDates = null; this.currentYM = null; }, }, });