From 04b19bc45dae76586ebad36432a5d47b45a61834 Mon Sep 17 00:00:00 2001
From: lbw_9527443 <780139497@qq.com>
Date: Fri, 29 Aug 2025 11:59:20 +0800
Subject: [PATCH] =?UTF-8?q?feat(Calendar):=20=E6=B7=BB=E5=8A=A0=E6=B3=95?=
=?UTF-8?q?=E5=AE=9A=E8=8A=82=E5=81=87=E6=97=A5=E6=98=BE=E7=A4=BA=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD=E5=B9=B6=E4=BC=98=E5=8C=96=E4=BA=A4=E4=BA=92?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新增节假日API获取及显示功能
- 将点击事件改为鼠标悬停触发
- 添加节假日样式和名称显示
- 优化事件点颜色和样式
- 移除secondTop.vue中不再使用的录音获取方法
---
.../views/secondTop/components/Calendar.vue | 158 +++++++++++++++++-
my-vue-app/src/views/secondTop/secondTop.vue | 4 +-
2 files changed, 151 insertions(+), 11 deletions(-)
diff --git a/my-vue-app/src/views/secondTop/components/Calendar.vue b/my-vue-app/src/views/secondTop/components/Calendar.vue
index 0d2e518..3524edb 100644
--- a/my-vue-app/src/views/secondTop/components/Calendar.vue
+++ b/my-vue-app/src/views/secondTop/components/Calendar.vue
@@ -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)"
>
{{ date.day }}
休
+ 休
+
+ {{ char }}
+
@@ -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;
diff --git a/my-vue-app/src/views/secondTop/secondTop.vue b/my-vue-app/src/views/secondTop/secondTop.vue
index 9df50a3..6520e50 100644
--- a/my-vue-app/src/views/secondTop/secondTop.vue
+++ b/my-vue-app/src/views/secondTop/secondTop.vue
@@ -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') // 初始化加载全部高级经理数据
// 输出缓存信息