From 4c06067dd44bb003d3fe6ceebe02017ffd43334c Mon Sep 17 00:00:00 2001 From: lbw_9527443 <780139497@qq.com> Date: Sat, 30 Aug 2025 14:20:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(Calendar):=20=E6=B7=BB=E5=8A=A0=E6=9C=AA?= =?UTF-8?q?=E6=9D=A5=E8=90=A5=E6=9C=9F=E6=98=BE=E7=A4=BA=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增未来3个营期的预期安排显示功能 - 为未来营期事件添加新的类型和样式 - 优化现有营期事件的样式和显示逻辑 - 修复用户名称动态获取的问题 --- .../views/secondTop/components/Calendar.vue | 235 ++++++++++++++++-- 1 file changed, 213 insertions(+), 22 deletions(-) diff --git a/my-vue-app/src/views/secondTop/components/Calendar.vue b/my-vue-app/src/views/secondTop/components/Calendar.vue index ddf2960..80bb91d 100644 --- a/my-vue-app/src/views/secondTop/components/Calendar.vue +++ b/my-vue-app/src/views/secondTop/components/Calendar.vue @@ -584,8 +584,8 @@ const returnToCurrentPeriod = async () => { try { // 调用取消切换历史营期API await cancelSwitchHistoryCampPeriod({ - "user_name": "潘加俊", - "user_level": "4" + user_level: "4", + user_name: userStore.userInfo.username }); selectedHistoryPeriod.value = null; @@ -633,7 +633,7 @@ const saveCampSettings = async () => { receipt_data_time: campDays.value.toString(), rest_time: restDays.value.toString(), user_level: "4", - user_name: params.user_name || "潘加俊" + user_name: params.user_name || userStore.userInfo.username }); if (result && result.data) { @@ -677,6 +677,12 @@ const getEventTypeClass = (dateStr) => { return 'event-course'; case 'rest': return 'event-rest'; + case 'future-data': + return 'event-future-data'; + case 'future-course': + return 'event-future-course'; + case 'future-rest': + return 'event-future-rest'; default: return ''; } @@ -684,7 +690,7 @@ const getEventTypeClass = (dateStr) => { // 方法:判断是否为休息日 const isRestDay = (dateStr) => { - const dayEvents = events.value.filter(event => event.date === dateStr && event.isCampEvent && event.type === 'rest'); + const dayEvents = events.value.filter(event => event.date === dateStr && event.isCampEvent && (event.type === 'rest' || event.type === 'future-rest')); return dayEvents.length > 0; }; @@ -852,7 +858,7 @@ async function CenterCampPeriodAdmin(data = {}) { // 方法:将营期时间安排映射到日历 const mapCampPeriodToCalendar = (campPeriod) => { - // 清除之前的营期相关事件 + // 清除之前的营期相关事件(包括未来营期) events.value = events.value.filter(event => !event.isCampEvent); let eventId = events.value.length + 1; @@ -917,6 +923,70 @@ const mapCampPeriodToCalendar = (campPeriod) => { isCampEvent: true, type: 'rest' }); + + // 只在非历史模式下生成未来3个营期的预期安排 + if (!isViewingHistory.value) { + generateFutureCampPeriods(restDate, eventId); + } + } +}; + +// 生成未来营期的函数 +const generateFutureCampPeriods = (currentCampEndDate, startEventId) => { + let eventId = startEventId; + let nextStartDate = new Date(currentCampEndDate); + nextStartDate.setDate(nextStartDate.getDate() + 1); // 从当前营期结束后的第二天开始 + + // 生成3个未来营期 + for (let periodIndex = 1; periodIndex <= 3; periodIndex++) { + let currentDate = new Date(nextStartDate); + + // 1. 接数据阶段(2天) + for (let day = 0; day < 2; day++) { + const dateStr = formatDateToString(currentDate); + events.value.push({ + id: eventId++, + date: dateStr, + title: '接数据', + description: `预期第${periodIndex + 1}期营期数据接收阶段`, + isCampEvent: true, + type: 'future-data', + futurePeriod: periodIndex + }); + currentDate.setDate(currentDate.getDate() + 1); + } + + // 2. 课程阶段(4天连续) + const courses = ['课1', '课2', '课3', '课4']; + courses.forEach((courseTitle, index) => { + const dateStr = formatDateToString(currentDate); + events.value.push({ + id: eventId++, + date: dateStr, + title: courseTitle, + description: `预期第${periodIndex + 1}期营期${courseTitle}阶段`, + isCampEvent: true, + type: 'future-course', + futurePeriod: periodIndex + }); + currentDate.setDate(currentDate.getDate() + 1); + }); + + // 3. 休息阶段(1天) + const restDateStr = formatDateToString(currentDate); + events.value.push({ + id: eventId++, + date: restDateStr, + title: '休息', + description: `预期第${periodIndex + 1}期营期休息日`, + isCampEvent: true, + type: 'future-rest', + futurePeriod: periodIndex + }); + + // 为下一个营期设置开始日期(休息日后的第二天) + nextStartDate = new Date(currentDate); + nextStartDate.setDate(nextStartDate.getDate() + 1); } }; @@ -932,7 +1002,12 @@ const parseDateRange = (dateRangeStr) => { // 方法:将历史营期数据映射到日历 const mapHistoryPeriodToCalendar = (historyPeriod) => { - // 清除之前的营期相关事件 + // 清除当前营期和未来营期事件,保留其他历史营期事件 + events.value = events.value.filter(event => + !event.isCampEvent || + (event.type && event.type.startsWith('future-')) + ); + // 然后清除所有营期事件,重新加载历史营期 events.value = events.value.filter(event => !event.isCampEvent); let eventId = events.value.length + 1; @@ -1015,26 +1090,106 @@ onMounted(async () => { // 如果没有获取到营期数据,添加一些测试数据以便测试结束营期功能 if (!result || !result.data || !result.data.camp_period) { // 添加一些测试营期事件 - events.value.push({ - id: 999, - date: formatDateToString(new Date()), - title: '测试营期', - description: '测试营期数据', - isCampEvent: true, - type: 'data' + const today = new Date(); + let eventId = 1000; + + // 接数据阶段(2天) + for (let i = 0; i < 2; i++) { + const testDate = new Date(today); + testDate.setDate(today.getDate() + i); + events.value.push({ + id: eventId++, + date: formatDateToString(testDate), + title: '接数据', + description: '测试营期数据接收阶段', + isCampEvent: true, + type: 'data' + }); + } + + // 课程阶段(4天) + const courses = ['课1', '课2', '课3', '课4']; + courses.forEach((courseTitle, index) => { + const testDate = new Date(today); + testDate.setDate(today.getDate() + 2 + index); + events.value.push({ + id: eventId++, + date: formatDateToString(testDate), + title: courseTitle, + description: `测试营期${courseTitle}阶段`, + isCampEvent: true, + type: 'course' + }); }); + + // 休息日 + const restDate = new Date(today); + restDate.setDate(today.getDate() + 6); + events.value.push({ + id: eventId++, + date: formatDateToString(restDate), + title: '休息', + description: '测试营期休息日', + isCampEvent: true, + type: 'rest' + }); + + // 生成未来3个营期的预期安排 + if (!isViewingHistory.value) { + generateFutureCampPeriods(restDate, eventId); + } } } catch (error) { console.error('获取营期数据失败:', error); // 即使API失败,也添加测试数据 - events.value.push({ - id: 999, - date: formatDateToString(new Date()), - title: '测试营期', - description: '测试营期数据', - isCampEvent: true, - type: 'data' + const today = new Date(); + let eventId = 1000; + + // 接数据阶段(2天) + for (let i = 0; i < 2; i++) { + const testDate = new Date(today); + testDate.setDate(today.getDate() + i); + events.value.push({ + id: eventId++, + date: formatDateToString(testDate), + title: '接数据', + description: '测试营期数据接收阶段', + isCampEvent: true, + type: 'data' + }); + } + + // 课程阶段(4天) + const courses = ['课1', '课2', '课3', '课4']; + courses.forEach((courseTitle, index) => { + const testDate = new Date(today); + testDate.setDate(today.getDate() + 2 + index); + events.value.push({ + id: eventId++, + date: formatDateToString(testDate), + title: courseTitle, + description: `测试营期${courseTitle}阶段`, + isCampEvent: true, + type: 'course' + }); }); + + // 休息日 + const restDate = new Date(today); + restDate.setDate(today.getDate() + 6); + events.value.push({ + id: eventId++, + date: formatDateToString(restDate), + title: '休息', + description: '测试营期休息日', + isCampEvent: true, + type: 'rest' + }); + + // 生成未来3个营期的预期安排 + if (!isViewingHistory.value) { + generateFutureCampPeriods(restDate, eventId); + } } }); @@ -1172,6 +1327,26 @@ onMounted(async () => { background: #ff4757 !important; } +.date-cell.has-event .event-dot.event-course { + background: #fd7e14 !important; +} + +.date-cell.has-event .event-dot.event-rest { + background: #28a745 !important; +} + +.date-cell.has-event .event-dot.event-future-data { + background: #74b9ff !important; +} + +.date-cell.has-event .event-dot.event-future-course { + background: #0984e3 !important; +} + +.date-cell.has-event .event-dot.event-future-rest { + background: #00b894 !important; +} + .date-tooltip { position: fixed; z-index: 1000; @@ -1454,12 +1629,12 @@ onMounted(async () => { } .event-dot.event-course { - background: linear-gradient(135deg, #fd7e14, #e55a00); + background: #fd7e14; box-shadow: 0 2px 4px rgba(253, 126, 20, 0.3); } .event-dot.event-rest { - background: linear-gradient(135deg, #28a745, #1e7e34); + background: #28a745; box-shadow: 0 2px 4px rgba(40, 167, 69, 0.3); } @@ -1485,6 +1660,22 @@ onMounted(async () => { box-shadow: 0 2px 4px rgba(108, 117, 125, 0.3); } +/* 未来营期事件点样式 - 蓝色系区分 */ +.event-dot.event-future-data { + background: #74b9ff; + box-shadow: 0 2px 4px rgba(116, 185, 255, 0.3); +} + +.event-dot.event-future-course { + background: #0984e3; + box-shadow: 0 2px 4px rgba(9, 132, 227, 0.3); +} + +.event-dot.event-future-rest { + background: #00b894; + box-shadow: 0 2px 4px rgba(0, 184, 148, 0.3); +} + /* 休息日文字样式 */ .rest-text { position: absolute;