feat(Calendar): 添加未来营期显示功能并优化样式

- 新增未来3个营期的预期安排显示功能
- 为未来营期事件添加新的类型和样式
- 优化现有营期事件的样式和显示逻辑
- 修复用户名称动态获取的问题
This commit is contained in:
2025-08-30 14:20:09 +08:00
parent f87c6b8252
commit 4c06067dd4

View File

@@ -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,27 +1090,107 @@ onMounted(async () => {
// 如果没有获取到营期数据,添加一些测试数据以便测试结束营期功能
if (!result || !result.data || !result.data.camp_period) {
// 添加一些测试营期事件
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: 999,
date: formatDateToString(new Date()),
title: '测试营期',
description: '测试营期数据',
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失败也添加测试数据
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: 999,
date: formatDateToString(new Date()),
title: '测试营期',
description: '测试营期数据',
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);
}
}
});
</script>
@@ -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;