feat(Calendar): 添加法定节假日显示功能并优化交互

- 新增节假日API获取及显示功能
- 将点击事件改为鼠标悬停触发
- 添加节假日样式和名称显示
- 优化事件点颜色和样式
- 移除secondTop.vue中不再使用的录音获取方法
This commit is contained in:
2025-08-29 11:59:20 +08:00
parent 2827d70f65
commit 04b19bc45d
2 changed files with 151 additions and 11 deletions

View File

@@ -53,14 +53,19 @@
'other-month': !date.isCurrentMonth,
'today': date.isToday,
'selected': date.isSelected,
'has-event': date.hasEvent
'has-event': date.hasEvent,
'legal-holiday': date.isHoliday
}
]"
@click="selectDate(date, $event)"
@mouseenter="selectDate(date, $event)"
>
<span class="date-number">{{ date.day }}</span>
<div v-if="date.hasEvent && !isRestDay(date.dateStr)" class="event-dot" :class="getEventTypeClass(date.dateStr)"></div>
<span v-if="isRestDay(date.dateStr)" class="rest-text"></span>
<span v-if="date.isHoliday" class="holiday-text"></span>
<div v-if="isHolidayStart(date.dateStr)" class="holiday-name">
<span v-for="(char, index) in getHolidayName(date.dateStr)" :key="index" class="holiday-char">{{ char }}</span>
</div>
</div>
</div>
@@ -298,6 +303,63 @@ const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
// 示例事件数据
const events = ref([]);
// 节假日数据
const holidays = ref([]);
// 获取节假日数据
const fetchHolidays = async (year) => {
try {
const response = await fetch(`https://timor.tech/api/holiday/year/${year}/`);
const data = await response.json();
if (data && data.holiday) {
const holidayList = [];
Object.keys(data.holiday).forEach(key => {
const holiday = data.holiday[key];
holidayList.push({
date: holiday.date,
name: holiday.name,
isHoliday: !holiday.target // 如果没有target字段说明是法定节假日而不是调休
});
});
holidays.value = holidayList;
}
} catch (error) {
console.error('获取节假日数据失败:', error);
holidays.value = [];
}
};
// 判断是否为法定节假日
const isLegalHoliday = (dateStr) => {
return holidays.value.some(holiday => holiday.date === dateStr && holiday.isHoliday);
};
// 获取节假日名称
const getHolidayName = (dateStr) => {
const holiday = holidays.value.find(holiday => holiday.date === dateStr && holiday.isHoliday);
return holiday ? holiday.name : '';
};
// 判断是否为节假日的开始日期
const isHolidayStart = (dateStr) => {
if (!isLegalHoliday(dateStr)) return false;
const currentHoliday = holidays.value.find(holiday => holiday.date === dateStr && holiday.isHoliday);
if (!currentHoliday) return false;
// 检查前一天是否也是同一个节假日
const currentDate = new Date(dateStr);
const previousDate = new Date(currentDate);
previousDate.setDate(previousDate.getDate() - 1);
const previousDateStr = `${previousDate.getFullYear()}-${String(previousDate.getMonth() + 1).padStart(2, '0')}-${String(previousDate.getDate()).padStart(2, '0')}`;
const previousHoliday = holidays.value.find(holiday => holiday.date === previousDateStr && holiday.isHoliday);
// 如果前一天不是节假日,或者前一天是不同名称的节假日,则当前日期是节假日的开始
return !previousHoliday || previousHoliday.name !== currentHoliday.name;
};
// 计算属性:当前月份的日期数组
const calendarDates = computed(() => {
const dates = [];
@@ -317,6 +379,7 @@ const calendarDates = computed(() => {
const isCurrentMonth = date.getMonth() === currentMonth.value;
const isToday = dateStr === todayString;
const hasEvent = events.value.some(event => event.date === dateStr);
const isHoliday = isLegalHoliday(dateStr);
dates.push({
key: `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`,
@@ -326,7 +389,9 @@ const calendarDates = computed(() => {
isCurrentMonth: isCurrentMonth,
isToday: isToday,
isSelected: selectedDate.value && selectedDate.value.dateStr === dateStr,
hasEvent: hasEvent
hasEvent: hasEvent,
isHoliday: isHoliday,
holidayName: isHoliday ? getHolidayName(dateStr) : ''
});
}
@@ -347,29 +412,43 @@ const selectedDateEvents = computed(() => {
});
// 方法:上一月
const previousMonth = () => {
const previousMonth = async () => {
const oldYear = currentYear.value;
if (currentMonth.value === 0) {
currentMonth.value = 11;
currentYear.value--;
} else {
currentMonth.value--;
}
// 如果年份发生变化,重新获取节假日数据
if (oldYear !== currentYear.value) {
await fetchHolidays(currentYear.value);
}
};
// 方法:下一月
const nextMonth = () => {
const nextMonth = async () => {
const oldYear = currentYear.value;
if (currentMonth.value === 11) {
currentMonth.value = 0;
currentYear.value++;
} else {
currentMonth.value++;
}
// 如果年份发生变化,重新获取节假日数据
if (oldYear !== currentYear.value) {
await fetchHolidays(currentYear.value);
}
};
// 方法:选择日期
const selectDate = (date, event) => {
selectedDate.value = date;
if (event) {
// 只有当日期有事件时才显示悬浮框
if (event && date.hasEvent) {
tooltipPosition.value = {
x: event.clientX + 10,
y: event.clientY - 10
@@ -760,6 +839,9 @@ onMounted(async () => {
selectedDate.value = todayDate;
}
// 获取当前年份的节假日数据
await fetchHolidays(currentYear.value);
// 获取现有的营期数据
try {
const result = await CenterCampPeriodAdmin();
@@ -911,7 +993,7 @@ onMounted(async () => {
width: 6px;
height: 6px;
border-radius: 50%;
background: #ff6b6b;
background:rgb(146, 107, 107);
position: absolute;
bottom: 8px;
}
@@ -920,6 +1002,10 @@ onMounted(async () => {
background: #4ecdc4;
}
.date-cell.has-event .event-dot.event-data {
background: #ff4757 !important;
}
.date-tooltip {
position: fixed;
z-index: 1000;
@@ -1197,8 +1283,8 @@ onMounted(async () => {
/* 营期事件类型样式 */
.event-dot.event-data {
background: linear-gradient(135deg, #9c27b0, #7b1fa2);
box-shadow: 0 2px 4px rgba(156, 39, 176, 0.3);
background: #ff4757;
box-shadow: 0 2px 4px rgba(255, 71, 87, 0.3);
}
.event-dot.event-course {
@@ -1225,6 +1311,60 @@ onMounted(async () => {
line-height: 1;
}
/* 法定节假日样式 */
.date-cell.legal-holiday {
background: linear-gradient(135deg, #fff3e0, #ffcc80);
color: #d84315;
}
.date-cell.legal-holiday .date-number {
color: #d84315;
font-weight: 600;
}
.holiday-text {
position: absolute;
bottom: 2px;
right: 2px;
font-size: 10px;
color: white;
font-weight: bold;
background: rgba(255, 255, 255, 0.2);
padding: 1px 3px;
border-radius: 2px;
line-height: 1;
}
/* 节假日名称样式 */
.holiday-name {
position: absolute;
top: 2px;
left: 2px;
display: flex;
flex-direction: column;
align-items: center;
z-index: 2;
}
.holiday-char {
font-size: 8px;
color: #d63031;
font-weight: bold;
line-height: 1;
margin-bottom: 1px;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
background: rgba(255, 255, 255, 0.9);
border-radius: 2px;
padding: 1px 2px;
min-width: 10px;
text-align: center;
}
.date-cell.legal-holiday .holiday-char {
color: #d63031;
background: rgba(255, 255, 255, 0.9);
}
/* 确认弹框样式 */
.confirm-modal {
max-width: 420px;

View File

@@ -893,7 +893,7 @@ const excellentRecord = ref({});
await CenterUrgentNeedToAddress()
await CenterConversionRateVsAverage()
await CenterSeniorManagerList()
await CentergetGoodRecord()
// await CentergetGoodRecord()
await CenterGroupList('all')
console.log('[强制刷新] 所有数据已重新加载')
@@ -929,7 +929,7 @@ const excellentRecord = ref({});
await CenterConversionRateVsAverage()
await CenterSeniorManagerList()
// 获取优秀录音
await CentergetGoodRecord()
// await CentergetGoodRecord()
await CenterGroupList('all') // 初始化加载全部高级经理数据
// 输出缓存信息