econtrol-tools-calendar 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +368 -0
- package/dist/calendar.js +1599 -0
- package/dist/calendar.js.map +1 -0
- package/dist/calendar.umd.cjs +1595 -0
- package/dist/calendar.umd.cjs.map +1 -0
- package/dist/components/FullCalendarDemo.vue.d.ts +2 -0
- package/dist/index.d.ts +7 -0
- package/dist/style.css +926 -0
- package/dist/utils/holidays.d.ts +25 -0
- package/dist/vite.svg +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.js","sources":["../node_modules/.pnpm/@fullcalendar+core@6.1.20/node_modules/@fullcalendar/core/locales/zh-cn.js","../src/components/FullCalendarDemo.vue","../src/utils/holidays.ts","../src/index.ts"],"sourcesContent":["var l77 = {\n code: 'zh-cn',\n week: {\n // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效\n dow: 1,\n doy: 4, // The week that contains Jan 4th is the first week of the year.\n },\n buttonText: {\n prev: '上月',\n next: '下月',\n today: '今天',\n year: '年',\n month: '月',\n week: '周',\n day: '日',\n list: '日程',\n },\n weekText: '周',\n allDayText: '全天',\n moreLinkText(n) {\n return '另外 ' + n + ' 个';\n },\n noEventsText: '没有事件显示',\n};\n\nexport { l77 as default };\n","<template>\n <div class=\"fullcalendar-demo\">\n <div class=\"demo-header\">\n <div class=\"device-info\" v-if=\"props.deviceId\">\n <span class=\"device-label\">设备ID:</span>\n <span class=\"device-id\" @click=\"handleDeviceClick\">{{\n props.deviceId\n }}</span>\n </div>\n <div>\n <el-button\n type=\"primary\"\n size=\"small\"\n @click=\"handleAddEvent\"\n :disabled=\"isOccupied\"\n >\n 添加预约\n </el-button>\n <el-button\n v-if=\"props.quickAddTimeRange\"\n type=\"success\"\n size=\"small\"\n @click=\"handleQuickAdd\"\n :disabled=\"isOccupied\"\n >\n 快速添加\n </el-button>\n </div>\n </div>\n\n <FullCalendar :options=\"calendarOptions\" class=\"calendar\">\n <template #eventContent=\"arg\">\n <el-tooltip\n placement=\"right\"\n :width=\"350\"\n effect=\"light\"\n popper-class=\"event-detail-tooltip\"\n :show-after=\"200\"\n >\n <template #content>\n <div class=\"event-detail\">\n <div class=\"detail-header\">\n <span class=\"detail-title\">{{ arg.event.title }}</span>\n </div>\n <div class=\"detail-body\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">\n <el-icon class=\"detail-icon\"><Clock /></el-icon>\n 时间范围:\n </span>\n <span class=\"detail-value\">{{ arg.timeText }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">\n <el-icon class=\"detail-icon\"><Calendar /></el-icon>\n 开始时间:\n </span>\n <span class=\"detail-value\">{{\n formatEventDateTime(arg.event.start)\n }}</span>\n </div>\n <div class=\"detail-item\" v-if=\"arg.event.end\">\n <span class=\"detail-label\">\n <el-icon class=\"detail-icon\"><Calendar /></el-icon>\n 结束时间:\n </span>\n <span class=\"detail-value\">{{\n formatEventDateTime(arg.event.end)\n }}</span>\n </div>\n <div\n class=\"detail-item\"\n v-if=\"arg.event.extendedProps?.organizer\"\n >\n <span class=\"detail-label\">\n <el-icon class=\"detail-icon\"><User /></el-icon>\n 预定人:\n </span>\n <span class=\"detail-value\">{{\n arg.event.extendedProps.organizer\n }}</span>\n </div>\n <div\n class=\"detail-item\"\n v-if=\"arg.event.extendedProps?.deviceId\"\n >\n <span class=\"detail-label\">\n <el-icon class=\"detail-icon\"><Monitor /></el-icon>\n 设备ID:\n </span>\n <span class=\"detail-value\">{{\n arg.event.extendedProps.deviceId\n }}</span>\n </div>\n <div\n class=\"detail-item\"\n v-if=\"arg.event.extendedProps?.description\"\n >\n <span class=\"detail-label\">\n <el-icon class=\"detail-icon\"><Document /></el-icon>\n 描述:\n </span>\n <span class=\"detail-value description-text\">{{\n arg.event.extendedProps.description\n }}</span>\n </div>\n </div>\n </div>\n </template>\n <div class=\"event-content\">\n <!-- 如果是自己的事件,显示用户图标 -->\n <el-icon v-if=\"isMyEvent(arg.event)\" class=\"my-event-marker\">\n <User />\n </el-icon>\n <span class=\"event-time\">{{ arg.timeText }}</span>\n <span class=\"event-title\">{{\n truncateTitle(arg.event.title, 10)\n }}</span>\n </div>\n </el-tooltip>\n </template>\n </FullCalendar>\n\n <!-- 添加/编辑事件对话框 -->\n <el-dialog\n v-model=\"dialogVisible\"\n :title=\"editingEvent ? '编辑预约' : '添加预约'\"\n width=\"520px\"\n class=\"event-dialog\"\n :close-on-click-modal=\"false\"\n >\n <el-form :model=\"formData\" label-width=\"80px\">\n <el-form-item label=\"预定人\">\n <el-input v-model=\"currentUser\" disabled placeholder=\"当前登录人\" />\n </el-form-item>\n <el-form-item label=\"标题\" required>\n <el-input v-model=\"formData.title\" placeholder=\"请输入事件标题\" />\n </el-form-item>\n <el-form-item label=\"开始时间\">\n <el-date-picker\n v-model=\"formData.start\"\n type=\"datetime\"\n placeholder=\"选择开始时间\"\n format=\"YYYY-MM-DD HH:mm\"\n value-format=\"YYYY-MM-DD HH:mm:ss\"\n :disabled-date=\"disabledPastDate\"\n :key=\"`start-${formData.start || 'empty'}`\"\n style=\"width: 100%\"\n />\n </el-form-item>\n <el-form-item label=\"结束时间\">\n <el-date-picker\n v-model=\"formData.end\"\n type=\"datetime\"\n placeholder=\"选择结束时间\"\n format=\"YYYY-MM-DD HH:mm\"\n value-format=\"YYYY-MM-DD HH:mm:ss\"\n :disabled-date=\"disabledPastDate\"\n :key=\"`end-${formData.end || 'empty'}`\"\n style=\"width: 100%\"\n />\n </el-form-item>\n <el-form-item label=\"描述\">\n <el-input\n v-model=\"formData.description\"\n type=\"textarea\"\n :rows=\"3\"\n placeholder=\"请输入描述(可选)\"\n />\n </el-form-item>\n </el-form>\n <template #footer>\n <el-button @click=\"dialogVisible = false\">取消</el-button>\n <el-button v-if=\"editingEvent\" type=\"danger\" @click=\"handleDelete\"\n >删除</el-button\n >\n <el-button type=\"primary\" @click=\"handleSave\">保存</el-button>\n </template>\n </el-dialog>\n\n <!-- 设备详情对话框 -->\n <el-dialog\n v-model=\"deviceDialogVisible\"\n title=\"设备详情\"\n width=\"600px\"\n class=\"device-dialog\"\n :close-on-click-modal=\"true\"\n >\n <div class=\"device-detail-content\" v-if=\"deviceInfo\">\n <el-descriptions :column=\"1\" border>\n <el-descriptions-item label=\"设备ID\">\n {{ deviceInfo.id }}\n </el-descriptions-item>\n <el-descriptions-item label=\"设备名称\">\n {{ deviceInfo.name }}\n </el-descriptions-item>\n <el-descriptions-item label=\"设备状态\" v-if=\"deviceInfo.status\">\n <el-tag :type=\"deviceInfo.status === '在线' ? 'success' : 'danger'\">\n {{ deviceInfo.status }}\n </el-tag>\n </el-descriptions-item>\n <el-descriptions-item label=\"设备类型\" v-if=\"deviceInfo.type\">\n {{ deviceInfo.type }}\n </el-descriptions-item>\n <el-descriptions-item label=\"设备位置\" v-if=\"deviceInfo.location\">\n {{ deviceInfo.location }}\n </el-descriptions-item>\n <el-descriptions-item label=\"设备描述\" v-if=\"deviceInfo.description\">\n {{ deviceInfo.description }}\n </el-descriptions-item>\n </el-descriptions>\n </div>\n <div v-else class=\"device-detail-loading\">\n <el-empty description=\"暂无设备信息\" />\n </div>\n <template #footer>\n <el-button type=\"primary\" @click=\"deviceDialogVisible = false\"\n >关闭</el-button\n >\n </template>\n </el-dialog>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, reactive, computed, nextTick, watch } from \"vue\";\nimport FullCalendar from \"@fullcalendar/vue3\";\n\n// 定义 emit 事件\nconst emit = defineEmits<{\n quickAddSaved: [event: EventInput];\n eventAdded: [event: EventInput];\n eventUpdated: [event: EventInput];\n eventDeleted: [eventId: string];\n eventsChange: [events: EventInput[]];\n}>();\nimport dayGridPlugin from \"@fullcalendar/daygrid\";\nimport timeGridPlugin from \"@fullcalendar/timegrid\";\nimport listPlugin from \"@fullcalendar/list\";\nimport interactionPlugin from \"@fullcalendar/interaction\";\nimport zhCnLocale from \"@fullcalendar/core/locales/zh-cn\";\nimport type {\n EventInput,\n EventApi,\n DateSelectArg,\n EventClickArg,\n DateSpanApi,\n} from \"@fullcalendar/core\";\nimport { ElMessage } from \"element-plus\";\nimport {\n Clock,\n User,\n Monitor,\n Document,\n Calendar,\n} from \"@element-plus/icons-vue\";\nimport type {\n DayCellContentArg,\n DayCellMountArg,\n EventMountArg,\n} from \"@fullcalendar/core\";\n\n// Props 定义\ninterface DeviceInfo {\n id: string;\n name: string;\n status?: string;\n type?: string;\n location?: string;\n description?: string;\n}\n\n// 节假日数据接口:格式 { \"YYYY-MM-DD\": \"节假日名称\" }\ninterface HolidayData {\n [date: string]: string;\n}\n\ninterface Props {\n isOccupied?: boolean; // 占用状态,为 true 时不能新增事件\n allowOverlap?: boolean; // 是否允许时间冲突,为 false 时不允许事件时间重合\n userid?: string; // 当前用户ID,只有匹配的事件才能被修改\n deviceId?: string; // 设备ID,用于标识事件所属的设备\n deviceInfo?: DeviceInfo | null; // 设备详细信息\n taskid?: string; // 当前任务ID,匹配的事件显示红色\n quickAddTimeRange?: { start: string; end: string } | null; // 快速添加的时间段(ISO格式)\n quickAddTaskName?: string; // 快速添加的任务名称\n holidays?: HolidayData | null; // 节假日数据对象,格式: { \"YYYY-MM-DD\": \"节假日名称\" }\n events?: EventInput[]; // 事件列表,从外部传入\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n isOccupied: false,\n allowOverlap: true, // 默认允许时间冲突\n userid: \"\",\n deviceId: \"\",\n deviceInfo: null,\n taskid: \"\",\n quickAddTimeRange: null,\n quickAddTaskName: \"\",\n holidays: null, // 默认不提供节假日数据\n events: () => [], // 默认空数组\n});\n\ninterface CalendarEvent {\n id?: string;\n title: string;\n start: string;\n end?: string;\n allDay?: boolean;\n description?: string;\n organizer?: string;\n backgroundColor?: string;\n borderColor?: string;\n taskid?: string;\n deviceId?: string;\n userid?: string;\n}\n\nconst dialogVisible = ref(false);\nconst editingEvent = ref<EventApi | null>(null);\nconst deviceDialogVisible = ref(false);\nconst deviceInfo = computed(() => {\n // 如果提供了 deviceInfo prop,直接使用\n if (props.deviceInfo) {\n return props.deviceInfo;\n }\n // 否则根据 deviceId 构造基本信息\n if (props.deviceId) {\n return {\n id: props.deviceId,\n name: props.deviceId,\n };\n }\n return null;\n});\n\n// 当前登录用户(可以从登录状态获取)\nconst currentUser = ref(\"张三\");\n\n// 黑色颜色,用于没有传 taskid 的情况\nconst myEventColor = { bg: \"#000000\", border: \"#000000\", name: \"黑色\" };\n// 纯红色,用于当前任务(匹配 taskid)\nconst taskColor = { bg: \"#FF0000\", border: \"#FF0000\", name: \"红色\" };\n\n// 中等亮度颜色数组(用于其他任务,避开黑色、红色、白色)\n// 使用中等亮度的颜色,确保文字清晰可读,同时避开黑色和红色\nconst eventColors = [\n { bg: \"#4A90E2\", border: \"#4A90E2\", name: \"蓝色\" }, // 中等蓝色\n { bg: \"#50C878\", border: \"#50C878\", name: \"绿色\" }, // 中等绿色\n { bg: \"#FFA500\", border: \"#FFA500\", name: \"橙色\" }, // 中等橙色\n { bg: \"#9370DB\", border: \"#9370DB\", name: \"紫色\" }, // 中等紫色\n { bg: \"#20B2AA\", border: \"#20B2AA\", name: \"青色\" }, // 中等青色\n { bg: \"#FF69B4\", border: \"#FF69B4\", name: \"粉色\" }, // 中等粉色\n { bg: \"#4169E1\", border: \"#4169E1\", name: \"靛蓝\" }, // 中等靛蓝色\n { bg: \"#00CED1\", border: \"#00CED1\", name: \"青绿\" }, // 中等青绿色\n { bg: \"#FF8C00\", border: \"#FF8C00\", name: \"深橙\" }, // 中等深橙色\n { bg: \"#FFD700\", border: \"#FFD700\", name: \"金色\" }, // 中等金色\n { bg: \"#DA70D6\", border: \"#DA70D6\", name: \"粉紫\" }, // 中等粉紫色\n { bg: \"#8A2BE2\", border: \"#8A2BE2\", name: \"蓝紫\" }, // 中等蓝紫色\n { bg: \"#00FA9A\", border: \"#00FA9A\", name: \"春绿\" }, // 中等春绿色\n { bg: \"#FF7F50\", border: \"#FF7F50\", name: \"珊瑚\" }, // 中等珊瑚色\n { bg: \"#40E0D0\", border: \"#40E0D0\", name: \"青蓝\" }, // 中等青蓝色\n { bg: \"#FFD700\", border: \"#FFD700\", name: \"黄色\" }, // 中等黄色\n { bg: \"#1E90FF\", border: \"#1E90FF\", name: \"天蓝\" }, // 中等天蓝色\n { bg: \"#32CD32\", border: \"#32CD32\", name: \"草绿\" }, // 中等草绿色\n { bg: \"#BA55D3\", border: \"#BA55D3\", name: \"中紫\" }, // 中等紫色\n { bg: \"#00CED1\", border: \"#00CED1\", name: \"青绿2\" }, // 中等青绿色\n { bg: \"#87CEFA\", border: \"#87CEFA\", name: \"浅蓝\" }, // 中等浅蓝色\n { bg: \"#FFA07A\", border: \"#FFA07A\", name: \"浅橙\" }, // 中等浅橙色\n { bg: \"#48D1CC\", border: \"#48D1CC\", name: \"中青\" }, // 中等青色\n { bg: \"#7B68EE\", border: \"#7B68EE\", name: \"中蓝紫\" }, // 中等蓝紫色\n { bg: \"#00CED1\", border: \"#00CED1\", name: \"青绿3\" }, // 中等青绿色\n { bg: \"#6495ED\", border: \"#6495ED\", name: \"矢车菊\" }, // 中等矢车菊蓝\n { bg: \"#FF6347\", border: \"#FF6347\", name: \"番茄\" }, // 中等番茄色(避开红色)\n { bg: \"#4682B4\", border: \"#4682B4\", name: \"钢蓝\" }, // 中等钢蓝色\n { bg: \"#9ACD32\", border: \"#9ACD32\", name: \"黄绿\" }, // 中等黄绿色\n { bg: \"#5F9EA0\", border: \"#5F9EA0\", name: \"青灰\" }, // 中等青灰色\n];\n\n// 检查事件是否属于当前用户\nfunction isEventEditable(event: any): boolean {\n if (!props.userid) {\n return true; // 如果没有设置 userid,允许所有操作\n }\n const eventOrganizer = event.extendedProps?.organizer || \"\";\n return eventOrganizer === props.userid;\n}\n\n// 事件数据 - 从 props 接收,使用内部 ref 管理以便响应式更新\nconst events = ref<EventInput[]>([...props.events]);\n\n// 监听 props.events 的变化,同步到内部 events\nwatch(\n () => props.events,\n (newEvents) => {\n events.value = [...(newEvents || [])];\n },\n { deep: true, immediate: true }\n);\n\n// 根据 userid 动态更新事件的 editable 属性和颜色\nconst editableEvents = computed(() => {\n return events.value.map((event) => {\n const eventOrganizer = (event.extendedProps as any)?.organizer || \"\";\n let editable = !props.userid || eventOrganizer === props.userid;\n\n // 检查事件开始时间是否在今天之前\n let eventStart = \"\";\n if (typeof event.start === \"string\") {\n eventStart = event.start;\n } else if (event.start instanceof Date) {\n eventStart = event.start.toISOString();\n } else if (event.start) {\n eventStart = new Date(event.start as any).toISOString();\n }\n\n // 如果事件在今天之前,则不可编辑\n if (eventStart && isPastDateTime(eventStart)) {\n editable = false;\n }\n\n // 根据任务ID设置颜色:匹配 taskid 的任务使用红色,其他任务根据任务ID分配颜色(避开红色和黑色)\n // 如果没有传 taskid,使用黑色\n let backgroundColor = event.backgroundColor;\n let borderColor = event.borderColor;\n\n if (!props.taskid) {\n // 如果没有传 taskid,使用黑色\n backgroundColor = myEventColor.bg;\n borderColor = myEventColor.border;\n } else if (event.id === props.taskid) {\n // 当前任务使用红色\n backgroundColor = taskColor.bg;\n borderColor = taskColor.border;\n } else {\n // 其他任务根据任务ID分配颜色(确保同一任务使用相同颜色,避开红色和黑色)\n const colorIndex = getTaskColorIndex(event.id);\n backgroundColor = eventColors[colorIndex].bg;\n borderColor = eventColors[colorIndex].border;\n }\n\n return {\n ...event,\n editable,\n backgroundColor,\n borderColor,\n };\n });\n});\n\n// 表单数据\nconst formData = reactive<CalendarEvent>({\n title: \"\",\n start: \"\",\n end: \"\",\n allDay: false,\n description: \"\",\n organizer: \"\",\n taskid: \"\",\n deviceId: \"\",\n userid: \"\",\n});\n\n// 检查日期时间是否在今天0点之前\nfunction isPastDateTime(dateStr: string): boolean {\n if (!dateStr) return false;\n const selectedDate = new Date(dateStr);\n const today = new Date();\n // 设置为今天0点0分0秒\n today.setHours(0, 0, 0, 0);\n // 将选择的日期也设置为0点0分0秒进行比较\n const selectedDateStart = new Date(selectedDate);\n selectedDateStart.setHours(0, 0, 0, 0);\n // 如果选择的日期在今天0点之前,则返回true\n return selectedDateStart < today;\n}\n\n// 禁用今天之前的日期(用于 el-date-picker)\nfunction disabledPastDate(time: Date) {\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n return time.getTime() < today.getTime();\n}\n\n// 日期选择处理\nfunction handleDateSelect(selectInfo: DateSelectArg) {\n if (props.isOccupied) {\n ElMessage.warning(\"当前处于占用状态,无法新增事件\");\n return;\n }\n\n // 检查选择的开始时间是否在今天之前\n if (isPastDateTime(selectInfo.startStr)) {\n ElMessage.warning(\"不能选择今天之前的时间进行预约\");\n return;\n }\n\n // 确保时间数据正确转换\n // 优先使用 startStr/endStr,如果不存在则使用 start/end Date 对象\n let startStr = selectInfo.startStr;\n let endStr = selectInfo.endStr;\n\n // 如果没有 startStr,从 Date 对象转换\n if (!startStr && selectInfo.start) {\n startStr = selectInfo.start.toISOString();\n }\n\n // 如果没有 endStr,从 Date 对象转换\n if (!endStr && selectInfo.end) {\n endStr = selectInfo.end.toISOString();\n }\n\n // 转换时间格式并填充表单\n // 确保格式为 YYYY-MM-DD HH:mm:ss,如果只有日期则自动添加 00:00:00\n let formattedStart = \"\";\n let formattedEnd = \"\";\n\n // 处理开始时间 - 转换为中国北京时间(UTC+8),默认补全为 00:00:00\n if (selectInfo.start) {\n const startDate =\n selectInfo.start instanceof Date\n ? selectInfo.start\n : new Date(selectInfo.start);\n if (!isNaN(startDate.getTime())) {\n // 转换为 ISO 字符串,然后使用 formatFromISO 转换为北京时间\n const isoStr = startDate.toISOString();\n formattedStart = formatFromISO(isoStr, true); // 传入 true 表示转换为北京时间\n // 提取日期部分,补全为 00:00:00\n const dateMatch = formattedStart.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (dateMatch) {\n formattedStart = dateMatch[1] + \" 00:00:00\";\n }\n } else if (startStr) {\n formattedStart = formatFromISO(startStr, true); // 传入 true 表示转换为北京时间\n // 确保格式完整,默认补全为 00:00:00\n if (formattedStart && formattedStart.match(/^\\d{4}-\\d{2}-\\d{2}$/)) {\n formattedStart = formattedStart + \" 00:00:00\";\n } else if (\n formattedStart &&\n formattedStart.match(/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$/)\n ) {\n formattedStart = formattedStart + \":00\";\n } else if (\n formattedStart &&\n !formattedStart.match(/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/)\n ) {\n // 如果格式不完整,提取日期部分并补全为 00:00:00\n const dateMatch = formattedStart.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (dateMatch) {\n formattedStart = dateMatch[1] + \" 00:00:00\";\n }\n }\n }\n } else if (startStr) {\n formattedStart = formatFromISO(startStr, true); // 传入 true 表示转换为北京时间\n // 确保格式完整,默认补全为 00:00:00\n if (formattedStart && formattedStart.match(/^\\d{4}-\\d{2}-\\d{2}$/)) {\n formattedStart = formattedStart + \" 00:00:00\";\n } else if (\n formattedStart &&\n formattedStart.match(/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$/)\n ) {\n formattedStart = formattedStart + \":00\";\n } else if (\n formattedStart &&\n !formattedStart.match(/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/)\n ) {\n // 如果格式不完整,提取日期部分并补全为 00:00:00\n const dateMatch = formattedStart.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (dateMatch) {\n formattedStart = dateMatch[1] + \" 00:00:00\";\n }\n }\n }\n\n // 处理结束时间 - 转换为中国北京时间(UTC+8),默认补全为 00:00:00\n if (selectInfo.end) {\n const endDate =\n selectInfo.end instanceof Date\n ? selectInfo.end\n : new Date(selectInfo.end);\n if (!isNaN(endDate.getTime())) {\n // 转换为 ISO 字符串,然后使用 formatFromISO 转换为北京时间\n const isoStr = endDate.toISOString();\n formattedEnd = formatFromISO(isoStr, true); // 传入 true 表示转换为北京时间\n // 提取日期部分,补全为 00:00:00\n const dateMatch = formattedEnd.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (dateMatch) {\n formattedEnd = dateMatch[1] + \" 00:00:00\";\n }\n } else if (endStr) {\n formattedEnd = formatFromISO(endStr, true); // 传入 true 表示转换为北京时间\n // 确保格式完整,默认补全为 00:00:00\n if (formattedEnd && formattedEnd.match(/^\\d{4}-\\d{2}-\\d{2}$/)) {\n formattedEnd = formattedEnd + \" 00:00:00\";\n } else if (\n formattedEnd &&\n formattedEnd.match(/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$/)\n ) {\n formattedEnd = formattedEnd + \":00\";\n } else if (\n formattedEnd &&\n !formattedEnd.match(/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/)\n ) {\n // 如果格式不完整,提取日期部分并补全为 00:00:00\n const dateMatch = formattedEnd.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (dateMatch) {\n formattedEnd = dateMatch[1] + \" 00:00:00\";\n }\n }\n }\n } else if (endStr) {\n formattedEnd = formatFromISO(endStr, true); // 传入 true 表示转换为北京时间\n // 确保格式完整,默认补全为 00:00:00\n if (formattedEnd && formattedEnd.match(/^\\d{4}-\\d{2}-\\d{2}$/)) {\n formattedEnd = formattedEnd + \" 00:00:00\";\n } else if (\n formattedEnd &&\n formattedEnd.match(/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$/)\n ) {\n formattedEnd = formattedEnd + \":00\";\n } else if (\n formattedEnd &&\n !formattedEnd.match(/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/)\n ) {\n // 如果格式不完整,提取日期部分并补全为 00:00:00\n const dateMatch = formattedEnd.match(/^(\\d{4}-\\d{2}-\\d{2})/);\n if (dateMatch) {\n formattedEnd = dateMatch[1] + \" 00:00:00\";\n }\n }\n }\n\n // 先重置表单,确保清除旧数据\n formData.title = \"\";\n formData.description = \"\";\n formData.allDay = false;\n formData.organizer = currentUser.value;\n // 如果存在 taskid,设置到表单数据中\n if (props.taskid) {\n formData.taskid = props.taskid;\n } else {\n formData.taskid = \"\";\n }\n // 设置 deviceId 和 userid\n formData.deviceId = props.deviceId || \"\";\n formData.userid = props.userid || \"\";\n\n // 然后设置时间,确保响应式更新\n formData.start = formattedStart;\n formData.end = formattedEnd;\n\n editingEvent.value = null;\n\n // 直接打开弹窗,Vue 的响应式系统会自动更新\n dialogVisible.value = true;\n\n // 使用 nextTick 确保 DOM 更新后再次设置值(如果需要)\n nextTick(() => {\n // 再次确认数据并强制更新\n if (formattedStart && !formData.start) {\n formData.start = formattedStart;\n }\n if (formattedEnd && !formData.end) {\n formData.end = formattedEnd;\n }\n });\n}\n\n// 事件点击处理\nfunction handleEventClick(clickInfo: EventClickArg) {\n // 检查权限:只有事件的所有者才能编辑\n if (!isEventEditable(clickInfo.event)) {\n ElMessage.warning(\"您没有权限编辑此事件\");\n return;\n }\n\n // 检查事件开始时间是否在今天之前\n const eventStartStr = clickInfo.event.start?.toISOString() || \"\";\n if (isPastDateTime(eventStartStr)) {\n ElMessage.warning(\"今天之前的事件不能修改\");\n return;\n }\n\n editingEvent.value = clickInfo.event;\n const eventProps = clickInfo.event.extendedProps;\n\n formData.title = clickInfo.event.title;\n formData.start = formatFromISO(eventStartStr);\n formData.end = formatFromISO(clickInfo.event.end?.toISOString() || \"\");\n formData.allDay = false;\n formData.description = (eventProps.description as string) || \"\";\n formData.organizer = (eventProps.organizer as string) || currentUser.value;\n // 如果存在 taskid,设置到表单数据中\n if (props.taskid) {\n formData.taskid = props.taskid;\n } else {\n formData.taskid = \"\";\n }\n // 设置 deviceId 和 userid\n formData.deviceId = props.deviceId || \"\";\n formData.userid = props.userid || \"\";\n\n dialogVisible.value = true;\n}\n\n// 事件拖拽处理\nfunction handleEventDrop(dropInfo: any) {\n // 检查权限:只有事件的所有者才能拖拽\n if (!isEventEditable(dropInfo.event)) {\n dropInfo.revert();\n ElMessage.warning(\"您没有权限修改此事件\");\n return;\n }\n\n // 获取拖拽后的新时间\n const newStart = dropInfo.event.start\n ? dropInfo.event.start instanceof Date\n ? dropInfo.event.start.toISOString()\n : typeof dropInfo.event.start === \"string\"\n ? dropInfo.event.start\n : \"\"\n : \"\";\n const newEnd = dropInfo.event.end\n ? dropInfo.event.end instanceof Date\n ? dropInfo.event.end.toISOString()\n : typeof dropInfo.event.end === \"string\"\n ? dropInfo.event.end\n : undefined\n : undefined;\n const eventId = dropInfo.event.id;\n\n // 检查拖拽后的开始时间是否在今天之前\n if (isPastDateTime(newStart)) {\n dropInfo.revert();\n ElMessage.warning(\"不能将事件移动到今天之前的时间\");\n return;\n }\n\n // 如果不允许时间冲突,检查拖拽后的时间是否与其他事件冲突\n if (!props.allowOverlap) {\n if (checkTimeConflict(newStart, newEnd, eventId)) {\n // 恢复原位置\n dropInfo.revert();\n ElMessage.error(\"该时间段与其他事件冲突,无法移动到此位置\");\n return;\n }\n }\n\n // 打开弹窗并填充表单数据\n editingEvent.value = dropInfo.event;\n const eventProps = dropInfo.event.extendedProps;\n\n // 确保时间数据正确转换\n formData.title = dropInfo.event.title || \"\";\n\n // 转换开始时间:确保格式正确\n if (newStart) {\n formData.start = formatFromISO(newStart);\n } else {\n formData.start = \"\";\n }\n\n // 转换结束时间:如果存在则转换,否则设置为空字符串\n if (newEnd) {\n formData.end = formatFromISO(newEnd);\n } else {\n formData.end = \"\";\n }\n\n formData.allDay = false;\n formData.description = (eventProps?.description as string) || \"\";\n formData.organizer = (eventProps?.organizer as string) || currentUser.value;\n // 如果存在 taskid,设置到表单数据中\n if (props.taskid) {\n formData.taskid = props.taskid;\n } else {\n formData.taskid = \"\";\n }\n // 设置 deviceId 和 userid\n formData.deviceId = props.deviceId || \"\";\n formData.userid = props.userid || \"\";\n\n // 直接打开弹窗,Vue 的响应式系统会自动更新\n dialogVisible.value = true;\n}\n\n// 截取标题,如果超过指定长度则截取并添加省略号\nfunction truncateTitle(title: string, maxLength: number): string {\n if (!title) return \"\";\n if (title.length <= maxLength) return title;\n return title.substring(0, maxLength) + \"...\";\n}\n\n// 判断事件是否是自己的\nfunction isMyEvent(event: any): boolean {\n // 判断是否是自己的事件(根据 userid)\n const eventOrganizer = event.extendedProps?.organizer || \"\";\n return !props.userid || eventOrganizer === props.userid;\n}\n\n// 根据任务ID生成颜色索引(用于确保同一任务使用相同颜色)\nfunction getTaskColorIndex(taskId: string | undefined): number {\n if (!taskId) return 0;\n // 使用简单的哈希算法,确保同一任务ID总是得到相同的颜色索引\n let hash = 0;\n for (let i = 0; i < taskId.length; i++) {\n hash = (hash << 5) - hash + taskId.charCodeAt(i);\n hash = hash & hash; // Convert to 32bit integer\n }\n return Math.abs(hash) % eventColors.length;\n}\n\n// 格式化事件日期时间用于 tooltip 显示\nfunction formatEventDateTime(date: Date | string | null | undefined): string {\n if (!date) return \"-\";\n let dateObj: Date;\n if (date instanceof Date) {\n dateObj = date;\n } else if (typeof date === \"string\") {\n dateObj = new Date(date);\n } else {\n dateObj = new Date(date as any);\n }\n\n // 使用本地时间格式化\n const year = dateObj.getFullYear();\n const month = String(dateObj.getMonth() + 1).padStart(2, \"0\");\n const day = String(dateObj.getDate()).padStart(2, \"0\");\n const hours = String(dateObj.getHours()).padStart(2, \"0\");\n const minutes = String(dateObj.getMinutes()).padStart(2, \"0\");\n const seconds = String(dateObj.getSeconds()).padStart(2, \"0\");\n\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n}\n\n// 事件调整大小处理\nfunction handleEventResize(resizeInfo: any) {\n // 检查权限:只有事件的所有者才能调整大小\n if (!isEventEditable(resizeInfo.event)) {\n resizeInfo.revert();\n ElMessage.warning(\"您没有权限修改此事件\");\n return;\n }\n\n const newStart = resizeInfo.event.start?.toISOString() || \"\";\n const newEnd = resizeInfo.event.end?.toISOString() || undefined;\n const eventId = resizeInfo.event.id;\n\n // 检查调整后的开始时间是否在今天之前\n if (isPastDateTime(newStart)) {\n resizeInfo.revert();\n ElMessage.warning(\"不能将事件调整到今天之前的时间\");\n return;\n }\n\n // 如果不允许时间冲突,检查调整后的时间是否与其他事件冲突\n if (!props.allowOverlap) {\n if (checkTimeConflict(newStart, newEnd, eventId)) {\n // 恢复原大小\n resizeInfo.revert();\n ElMessage.error(\"该时间段与其他事件冲突,无法调整到此时间\");\n return;\n }\n }\n\n // 重新分配颜色(同一时间段需要不同颜色)\n const eventOrganizer =\n (resizeInfo.event.extendedProps as any)?.organizer || currentUser.value;\n // 获取事件的 taskid\n const eventTaskId = (resizeInfo.event.extendedProps as any)?.taskid;\n const colorInfo = assignEventColor(\n formatFromISO(newStart),\n newEnd ? formatFromISO(newEnd) : undefined,\n eventId,\n eventOrganizer,\n eventId, // 传入事件ID用于颜色分配\n eventTaskId // 传入 taskid 用于颜色分配\n );\n\n // 查找要更新的事件\n const eventIndex = events.value.findIndex((e) => e.id === eventId);\n if (eventIndex !== -1) {\n const originalEvent = events.value[eventIndex];\n const eventOrganizer =\n (originalEvent.extendedProps as any)?.organizer || \"\";\n const editable = !props.userid || eventOrganizer === props.userid;\n const updatedEvent: EventInput = {\n ...originalEvent,\n start: newStart,\n end: newEnd,\n backgroundColor: colorInfo.bg,\n borderColor: colorInfo.border,\n editable: editable, // 根据 userid 设置可编辑性\n extendedProps: {\n ...originalEvent.extendedProps,\n colorIndex: colorInfo.index,\n deviceId: props.deviceId || \"\", // 保存设备ID\n },\n };\n emit(\"eventUpdated\", updatedEvent);\n // 计算更新后的事件列表(不修改原数组)\n const updatedEventsList = events.value.map((e) =>\n e.id === eventId ? updatedEvent : e\n );\n emit(\"eventsChange\", updatedEventsList);\n }\n}\n\n// 格式化日期为 YYYY-MM-DD 格式\nfunction formatDate(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n}\n\n// 获取节假日名称:接收 Date 对象,返回节假日名称或 null\nfunction getHolidayName(date: Date): string | null {\n if (!props.holidays) {\n return null;\n }\n const dateStr = formatDate(date);\n return props.holidays[dateStr] || null;\n}\n\n// 自定义日期单元格内容,显示节假日\nfunction dayCellContent(arg: DayCellContentArg) {\n // 如果提供了节假日数据,使用它来获取节假日名称\n const holidayName = getHolidayName(arg.date);\n\n if (holidayName) {\n // 创建包含日期和节假日标记的 HTML\n const wrapper = document.createElement(\"div\");\n wrapper.style.cssText =\n \"display: flex; flex-direction: column; align-items: flex-start; width: 100%; padding: 2px;\";\n\n const dateEl = document.createElement(\"div\");\n dateEl.textContent = String(arg.dayNumberText);\n dateEl.style.cssText = \"font-weight: 600; color: #f56c6c;\";\n wrapper.appendChild(dateEl);\n\n const holidayEl = document.createElement(\"div\");\n holidayEl.textContent = holidayName;\n holidayEl.className = \"holiday-label\";\n holidayEl.style.cssText =\n \"font-size: 9px; color: #f56c6c; font-weight: 500; margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; line-height: 1.2;\";\n wrapper.appendChild(holidayEl);\n\n return { domNodes: [wrapper] };\n }\n\n // 非节假日或未提供节假日数据,返回默认内容\n return { html: arg.dayNumberText };\n}\n\n// 日期单元格挂载后,为节假日添加 CSS 类\nfunction dayCellDidMount(arg: DayCellMountArg) {\n // 如果提供了节假日数据,使用它来检查是否为节假日\n const holidayName = getHolidayName(arg.date);\n\n if (holidayName) {\n // 为节假日日期添加 CSS 类\n arg.el.classList.add(\"holiday-day\");\n }\n}\n\n// 根据事件ID获取统一的背景色(确保同一事件的所有实例使用相同颜色)\nfunction getEventBackgroundColor(eventId: string | undefined): string {\n if (!eventId) {\n // 如果没有传 taskid,返回黑色;否则返回默认颜色\n return props.taskid ? \"#409eff\" : myEventColor.bg;\n }\n\n // 如果匹配当前任务ID,显示红色\n if (props.taskid && eventId === props.taskid) {\n return taskColor.bg;\n }\n\n // 如果没有传 taskid,显示黑色\n if (!props.taskid) {\n return myEventColor.bg;\n }\n\n // 检查事件列表中是否有相同 taskid 的事件(通过 extendedProps.taskid)\n if (props.taskid && eventId) {\n const existingEvent = events.value.find((e) => {\n const eventTaskId = (e.extendedProps as any)?.taskid;\n return eventTaskId === props.taskid;\n });\n if (existingEvent) {\n return taskColor.bg; // 返回红色\n }\n }\n\n // 从事件列表中查找原始事件,获取其背景色\n const originalEvent = events.value.find((e) => e.id === eventId);\n if (originalEvent) {\n // 检查原始事件的 taskid\n const eventTaskId = (originalEvent.extendedProps as any)?.taskid;\n if (eventTaskId === props.taskid) {\n return taskColor.bg; // 返回红色\n }\n // 根据任务ID分配颜色(确保同一任务使用相同颜色,避开红色和黑色)\n const colorIndex = getTaskColorIndex(eventId);\n return eventColors[colorIndex].bg;\n }\n\n // 如果找不到原始事件,从editableEvents中查找\n const editableEvent = editableEvents.value.find((e) => e.id === eventId);\n if (editableEvent && editableEvent.backgroundColor) {\n return editableEvent.backgroundColor;\n }\n\n // 根据任务ID分配默认颜色(避开红色和黑色)\n const colorIndex = getTaskColorIndex(eventId);\n return eventColors[colorIndex].bg;\n}\n\n// 事件挂载后,确保背景色正确显示\nfunction eventDidMount(arg: EventMountArg) {\n // 确保事件在月视图中显示为10px横线\n if (arg.view.type === \"dayGridMonth\") {\n const eventEl = arg.el;\n const event = arg.event;\n\n // 根据事件ID获取统一的背景色,确保同一事件的所有实例使用相同颜色\n const eventId = event.id;\n const backgroundColor = getEventBackgroundColor(eventId);\n const borderColor = backgroundColor;\n\n // 同时更新事件对象本身的backgroundColor属性,确保FullCalendar使用统一颜色\n // 这对于跨天事件特别重要,确保所有实例都使用相同颜色\n if (event.setProp) {\n event.setProp(\"backgroundColor\", backgroundColor);\n event.setProp(\"borderColor\", borderColor);\n }\n\n // 强制设置背景色和样式(内联样式优先级最高)\n eventEl.style.backgroundColor = backgroundColor;\n eventEl.style.borderColor = borderColor;\n eventEl.style.height = \"10px\";\n eventEl.style.minHeight = \"10px\";\n eventEl.style.maxHeight = \"10px\";\n eventEl.style.display = \"block\";\n eventEl.style.visibility = \"visible\";\n eventEl.style.opacity = \"1\";\n eventEl.style.width = \"100%\";\n eventEl.style.border = \"none\";\n eventEl.style.borderRadius = \"0\";\n eventEl.style.padding = \"0\";\n eventEl.style.margin = \"1px 0\";\n eventEl.style.cursor = \"pointer\"; // 确保可以hover\n\n // 确保事件框架也使用相同的背景色\n const eventFrame = eventEl.querySelector(\".fc-daygrid-event-frame\");\n if (eventFrame) {\n (eventFrame as HTMLElement).style.backgroundColor = backgroundColor;\n (eventFrame as HTMLElement).style.height = \"10px\";\n (eventFrame as HTMLElement).style.minHeight = \"10px\";\n (eventFrame as HTMLElement).style.maxHeight = \"10px\";\n (eventFrame as HTMLElement).style.cursor = \"pointer\";\n }\n\n // 确保tooltip触发器可以正常工作 - 让整个事件元素作为tooltip触发器\n const tooltipTrigger =\n eventEl.querySelector(\".el-tooltip__trigger\") || eventEl;\n if (tooltipTrigger) {\n (tooltipTrigger as HTMLElement).style.display = \"block\";\n (tooltipTrigger as HTMLElement).style.width = \"100%\";\n (tooltipTrigger as HTMLElement).style.height = \"100%\";\n (tooltipTrigger as HTMLElement).style.cursor = \"pointer\";\n (tooltipTrigger as HTMLElement).style.position = \"relative\";\n }\n\n // 确保事件框架也设置cursor\n if (eventFrame) {\n (eventFrame as HTMLElement).style.cursor = \"pointer\";\n }\n\n // 确保所有子元素也使用相同的背景色(但保持tooltip可交互)\n const allChildren = eventEl.querySelectorAll(\"*\");\n allChildren.forEach((child) => {\n const childEl = child as HTMLElement;\n // 如果是tooltip相关元素,不设置背景色,但确保可以交互\n if (\n childEl.classList.contains(\"el-tooltip__trigger\") ||\n childEl.closest(\".el-tooltip\")\n ) {\n childEl.style.cursor = \"pointer\";\n childEl.style.pointerEvents = \"auto\";\n // 确保tooltip触发器覆盖整个事件区域\n childEl.style.width = \"100%\";\n childEl.style.height = \"100%\";\n childEl.style.position = \"absolute\";\n childEl.style.top = \"0\";\n childEl.style.left = \"0\";\n childEl.style.zIndex = \"10\";\n } else {\n // 其他子元素设置背景色\n childEl.style.backgroundColor = backgroundColor;\n }\n });\n\n // 确保事件元素本身可以触发tooltip\n eventEl.style.position = \"relative\";\n eventEl.style.pointerEvents = \"auto\";\n\n // 检查是否是自己创建的事件,如果是,添加一个小图标\n const eventOrganizer = (event.extendedProps as any)?.organizer || \"\";\n const isMyEvent = !props.userid || eventOrganizer === props.userid;\n\n if (isMyEvent) {\n // 检查是否已经添加过图标\n const existingIcon = eventEl.querySelector(\n \".my-event-icon\"\n ) as HTMLElement | null;\n\n if (!existingIcon) {\n // 创建图标元素\n const iconEl = document.createElement(\"span\");\n iconEl.className = \"my-event-icon\";\n iconEl.innerHTML = \"★\"; // 使用星号作为图标\n iconEl.style.cssText = `\n position: absolute;\n left: 2px;\n top: 50%;\n transform: translateY(-50%);\n font-size: 8px;\n color: #fff;\n line-height: 1;\n z-index: 20;\n pointer-events: none;\n font-weight: bold;\n `;\n\n // 将图标添加到事件元素中\n eventEl.appendChild(iconEl);\n }\n }\n }\n}\n\n// 日历配置\nconst calendarOptions = computed(() => ({\n plugins: [dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin],\n locale: zhCnLocale,\n timeZone: \"Asia/Shanghai\",\n initialView: \"dayGridMonth\",\n allDaySlot: false, // 禁用全天事件槽\n headerToolbar: {\n left: \"prev,next\",\n center: \"title\",\n right: \"dayGridMonth,listWeek,timeGridDay\",\n },\n buttonText: {\n today: \"今天\",\n month: \"月\",\n day: \"日\",\n list: \"周\",\n prev: \"<\",\n next: \">\",\n },\n height: 480, // 限制日历高度为480px\n slotDuration: \"01:00:00\", // 时间轴间隔为1小时\n views: {\n dayGridMonth: {\n height: 480, // 限制月视图高度为480px\n dayCellContent: dayCellContent, // 自定义日期单元格内容\n dayCellDidMount: dayCellDidMount, // 日期单元格挂载后添加样式类\n dayMaxEvents: false, // 不显示\"more\"链接,超出的事件不显示\n moreLinkClick: \"popover\", // 如果显示more链接,点击时显示弹窗\n eventDidMount: eventDidMount, // 事件挂载后确保背景色显示\n },\n },\n events: editableEvents.value, // 使用动态计算的可编辑事件\n editable: true,\n selectable: !props.isOccupied, // 占用状态时禁用日期选择\n selectMirror: true,\n selectAllow: (span: DateSpanApi) => {\n // 不允许选择今天之前的日期\n const startStr = span.start?.toISOString() || \"\";\n return !isPastDateTime(startStr);\n },\n dayMaxEvents: false, // 不显示\"more\"链接,超出的事件不显示\n weekends: true,\n select: handleDateSelect,\n eventClick: handleEventClick,\n eventDrop: handleEventDrop,\n eventResize: handleEventResize,\n eventDidMount: eventDidMount, // 事件挂载后确保背景色显示\n}));\n\n// 点击设备名称,打开设备详情弹窗\nfunction handleDeviceClick() {\n if (!props.deviceId) {\n return;\n }\n deviceDialogVisible.value = true;\n}\n\n// 添加事件\nfunction handleAddEvent() {\n if (props.isOccupied) {\n ElMessage.warning(\"当前处于占用状态,无法新增事件\");\n return;\n }\n const now = new Date();\n // 格式化为 YYYY-MM-DD HH:mm:ss 格式,与 el-date-picker 的 value-format 匹配\n const formatDateTime = (date: Date) => {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n const hours = String(date.getHours()).padStart(2, \"0\");\n const minutes = String(date.getMinutes()).padStart(2, \"0\");\n const seconds = String(date.getSeconds()).padStart(2, \"0\");\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n };\n\n formData.start = formatDateTime(now);\n formData.end = formatDateTime(new Date(now.getTime() + 60 * 60 * 1000));\n formData.allDay = false;\n formData.title = \"\";\n formData.description = \"\";\n formData.organizer = currentUser.value;\n editingEvent.value = null;\n dialogVisible.value = true;\n}\n\n// 快速添加事件(直接保存,不打开弹窗)\nfunction handleQuickAdd() {\n if (props.isOccupied) {\n ElMessage.warning(\"当前处于占用状态,无法新增事件\");\n return;\n }\n if (!props.quickAddTimeRange) {\n ElMessage.warning(\"未提供快速添加的时间段\");\n return;\n }\n if (!props.quickAddTaskName || !props.quickAddTaskName.trim()) {\n ElMessage.warning(\"未提供快速添加的任务名称\");\n return;\n }\n\n // 将 ISO 格式的时间段转换为表单需要的格式(YYYY-MM-DD HH:mm:ss)\n const startStr = formatFromISO(props.quickAddTimeRange.start);\n const endStr = formatFromISO(props.quickAddTimeRange.end);\n\n // 检查开始时间是否在今天之前\n if (isPastDateTime(startStr)) {\n ElMessage.warning(\"不能选择今天之前的时间进行预约\");\n return;\n }\n\n // 检查时间冲突\n if (checkTimeConflict(startStr, endStr)) {\n ElMessage.error(\"该时间段与其他事件冲突,请选择其他时间\");\n return;\n }\n\n // 生成事件ID\n const eventId = `event-${Date.now()}-${Math.random()\n .toString(36)\n .substr(2, 9)}`;\n\n // 分配颜色(快速添加时,使用 formData.taskid 或 props.taskid)\n const taskId = formData.taskid || props.taskid || \"\";\n const colorInfo = assignEventColor(\n startStr,\n endStr,\n undefined,\n currentUser.value,\n eventId, // 传入事件ID用于颜色分配\n taskId // 传入 taskid 用于颜色分配\n );\n\n // 添加新事件\n const startISO = formatToISO(startStr);\n const endISO = endStr ? formatToISO(endStr) : undefined;\n\n const eventOrganizer = currentUser.value;\n const editable = !props.userid || eventOrganizer === props.userid;\n const newEvent: EventInput = {\n id: eventId,\n title: props.quickAddTaskName,\n start: startISO,\n end: endISO,\n allDay: false,\n backgroundColor: colorInfo.bg,\n borderColor: colorInfo.border,\n editable: editable,\n extendedProps: {\n description: \"\",\n organizer: eventOrganizer,\n colorIndex: colorInfo.index,\n deviceId: props.deviceId || \"\",\n taskid: props.taskid || \"\", // 如果存在 taskid,保存到事件数据中\n },\n };\n\n // 抛出保存事件,通知父组件\n emit(\"quickAddSaved\", newEvent);\n emit(\"eventAdded\", newEvent);\n // 计算新的事件列表(不修改原数组)\n const newEventsList = [...events.value, newEvent];\n emit(\"eventsChange\", newEventsList);\n}\n\n// 将 ISO 格式转换为 YYYY-MM-DD HH:mm:ss 格式(用于 el-date-picker)\n// 将 ISO 格式转换为 YYYY-MM-DD HH:mm:ss 格式\n// useBeijingTime: 如果为 true,转换为中国北京时间(UTC+8),否则使用本地时间\nfunction formatFromISO(\n isoStr: string,\n useBeijingTime: boolean = false\n): string {\n if (!isoStr) return \"\";\n // 如果已经是 YYYY-MM-DD HH:mm:ss 格式,直接返回\n if (!isoStr.includes(\"T\")) return isoStr;\n\n try {\n // 解析 ISO 字符串为 Date 对象\n const date = new Date(isoStr);\n if (isNaN(date.getTime())) {\n // 如果解析失败,尝试手动处理\n let cleaned = isoStr;\n if (cleaned.endsWith(\"Z\")) {\n cleaned = cleaned.slice(0, -1);\n }\n cleaned = cleaned.replace(/[+-]\\d{2}:\\d{2}$/, \"\");\n return cleaned.replace(\"T\", \" \").split(\".\")[0];\n }\n\n let year: number,\n month: number,\n day: number,\n hours: number,\n minutes: number,\n seconds: number;\n\n if (useBeijingTime) {\n // 转换为中国北京时间(UTC+8)\n // 使用 toLocaleString 获取北京时间\n const beijingStr = date.toLocaleString(\"en-US\", {\n timeZone: \"Asia/Shanghai\",\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false,\n });\n // 格式: \"MM/DD/YYYY, HH:mm:ss\"\n const parts = beijingStr.split(\", \");\n const datePart = parts[0].split(\"/\");\n const timePart = parts[1].split(\":\");\n year = parseInt(datePart[2]);\n month = parseInt(datePart[0]);\n day = parseInt(datePart[1]);\n hours = parseInt(timePart[0]);\n minutes = parseInt(timePart[1]);\n seconds = parseInt(timePart[2]);\n } else {\n // 使用本地时间\n year = date.getFullYear();\n month = date.getMonth() + 1;\n day = date.getDate();\n hours = date.getHours();\n minutes = date.getMinutes();\n seconds = date.getSeconds();\n }\n\n return `${year}-${String(month).padStart(2, \"0\")}-${String(day).padStart(\n 2,\n \"0\"\n )} ${String(hours).padStart(2, \"0\")}:${String(minutes).padStart(\n 2,\n \"0\"\n )}:${String(seconds).padStart(2, \"0\")}`;\n } catch (e) {\n // 如果出错,使用原来的方法\n let cleaned = isoStr;\n if (cleaned.endsWith(\"Z\")) {\n cleaned = cleaned.slice(0, -1);\n }\n cleaned = cleaned.replace(/[+-]\\d{2}:\\d{2}$/, \"\");\n return cleaned.replace(\"T\", \" \").split(\".\")[0];\n }\n}\n\n// 将 YYYY-MM-DD HH:mm:ss 格式转换为 ISO 格式(用于 FullCalendar)\nfunction formatToISO(dateStr: string): string {\n if (!dateStr) return \"\";\n // 如果已经是 ISO 格式,直接返回\n if (dateStr.includes(\"T\")) return dateStr;\n // 将 YYYY-MM-DD HH:mm:ss 转换为 ISO 格式\n return dateStr.replace(\" \", \"T\");\n}\n\n// 检查两个时间段是否有重叠\nfunction hasTimeOverlap(\n start1: string,\n end1: string | undefined,\n start2: string,\n end2: string | undefined\n): boolean {\n // 正常时间比较\n const startTime1 = new Date(start1).getTime();\n const endTime1 = end1\n ? new Date(end1).getTime()\n : startTime1 + 60 * 60 * 1000; // 如果没有结束时间,默认1小时\n const startTime2 = new Date(start2).getTime();\n const endTime2 = end2\n ? new Date(end2).getTime()\n : startTime2 + 60 * 60 * 1000; // 如果没有结束时间,默认1小时\n\n // 检查是否有重叠:两个时间段有交集\n return startTime1 < endTime2 && endTime1 > startTime2;\n}\n\n// 检查事件是否与其他事件有时间冲突\nfunction checkTimeConflict(\n start: string,\n end: string | undefined,\n excludeEventId?: string\n): boolean {\n if (props.allowOverlap) {\n return false; // 允许冲突,不检查\n }\n\n const startISO = formatToISO(start);\n const endISO = end ? formatToISO(end) : undefined;\n\n // 检查所有事件\n for (const event of events.value) {\n // 排除当前编辑的事件\n if (excludeEventId && event.id === excludeEventId) {\n continue;\n }\n\n // 处理事件开始时间\n let eventStart = \"\";\n if (typeof event.start === \"string\") {\n eventStart = event.start;\n } else if (event.start instanceof Date) {\n eventStart = event.start.toISOString();\n } else if (event.start) {\n eventStart = new Date(event.start as any).toISOString();\n }\n\n // 处理事件结束时间\n let eventEnd: string | undefined = undefined;\n if (event.end) {\n if (typeof event.end === \"string\") {\n eventEnd = event.end;\n } else if (event.end instanceof Date) {\n eventEnd = event.end.toISOString();\n } else {\n eventEnd = new Date(event.end as any).toISOString();\n }\n }\n\n if (!eventStart) continue;\n\n // 检查是否有时间重叠\n if (hasTimeOverlap(startISO, endISO, eventStart, eventEnd)) {\n return true; // 发现冲突\n }\n }\n\n return false; // 没有冲突\n}\n\n// 为事件分配颜色\n// 根据任务ID分配颜色:匹配 taskid 的任务使用红色,其他任务根据任务ID分配颜色(避开红色和黑色)\n// 如果没有传 taskid,使用黑色\nfunction assignEventColor(\n _start: string,\n _end: string | undefined,\n _excludeEventId?: string,\n _organizer?: string,\n eventId?: string,\n eventTaskId?: string // 新增参数:事件的 taskid\n): { bg: string; border: string; index: number } {\n // 如果没有传 taskid,返回黑色\n if (!props.taskid) {\n return {\n ...myEventColor,\n index: -1, // 使用 -1 表示黑色\n };\n }\n\n // 如果提供了事件ID且匹配当前任务ID,返回红色\n if (eventId && eventId === props.taskid) {\n return {\n ...taskColor,\n index: -2, // 使用 -2 表示红色(当前任务)\n };\n }\n\n // 如果事件的 taskid 匹配 props.taskid,返回红色\n if (eventTaskId && eventTaskId === props.taskid) {\n return {\n ...taskColor,\n index: -2, // 使用 -2 表示红色(当前任务)\n };\n }\n\n // 检查事件列表中是否有相同 taskid 的事件(通过 extendedProps.taskid)\n if (props.taskid && eventId) {\n const existingEvent = events.value.find((e) => {\n const eventTaskId = (e.extendedProps as any)?.taskid;\n return eventTaskId === props.taskid;\n });\n if (existingEvent) {\n return {\n ...taskColor,\n index: -2, // 使用 -2 表示红色(当前任务)\n };\n }\n }\n\n // 根据任务ID分配颜色(确保同一任务使用相同颜色,避开红色和黑色)\n const taskIdForColor = eventId || `temp-${Date.now()}-${Math.random()}`;\n const colorIndex = getTaskColorIndex(taskIdForColor);\n\n return {\n ...eventColors[colorIndex],\n index: colorIndex,\n };\n}\n\n// 保存事件\nfunction handleSave() {\n // 占用状态时,只能编辑已有事件,不能新增\n if (props.isOccupied && !editingEvent.value) {\n ElMessage.warning(\"当前处于占用状态,无法新增事件\");\n return;\n }\n\n if (!formData.title.trim()) {\n ElMessage.warning(\"请输入事件标题\");\n return;\n }\n\n if (!formData.start) {\n ElMessage.warning(\"请选择开始时间\");\n return;\n }\n\n // 检查开始时间是否在今天之前\n if (isPastDateTime(formData.start)) {\n ElMessage.warning(\"不能选择今天之前的时间进行预约\");\n return;\n }\n\n // 检查时间冲突\n const excludeEventId = editingEvent.value?.id;\n if (checkTimeConflict(formData.start, formData.end, excludeEventId)) {\n ElMessage.error(\"该时间段与其他事件冲突,请选择其他时间\");\n return;\n }\n // 分配颜色(无论是否允许竞态,同一时间段都显示不同颜色)\n // 如果存在 taskid 且等于 props.taskid,使用 taskid 作为事件ID,确保颜色正确\n let eventId = editingEvent.value?.id;\n if (!eventId) {\n // 新增事件时,如果 formData.taskid 存在且等于 props.taskid,使用 taskid 作为事件ID\n if (\n formData.taskid &&\n formData.taskid.trim() &&\n formData.taskid === props.taskid\n ) {\n eventId = formData.taskid;\n } else {\n eventId = `event-${Date.now()}-${Math.random()\n .toString(36)\n .substr(2, 9)}`;\n }\n }\n const colorInfo = assignEventColor(\n formData.start,\n formData.end,\n editingEvent.value?.id,\n formData.organizer || currentUser.value,\n eventId, // 传入事件ID用于颜色分配\n formData.taskid // 传入 taskid 用于颜色分配\n );\n\n if (editingEvent.value) {\n // 更新事件\n const startISO = formatToISO(formData.start);\n const endISO = formData.end ? formatToISO(formData.end) : null;\n\n editingEvent.value.setProp(\"title\", formData.title);\n editingEvent.value.setStart(startISO);\n if (endISO) {\n editingEvent.value.setEnd(endISO);\n } else {\n editingEvent.value.setEnd(startISO);\n }\n editingEvent.value.setAllDay(false);\n editingEvent.value.setExtendedProp(\"description\", formData.description);\n editingEvent.value.setExtendedProp(\n \"organizer\",\n formData.organizer || currentUser.value\n );\n editingEvent.value.setExtendedProp(\"colorIndex\", colorInfo.index);\n // 保存设备ID\n if (props.deviceId) {\n editingEvent.value.setExtendedProp(\"deviceId\", props.deviceId);\n }\n // 保存 taskid(如果存在)\n if (props.taskid) {\n editingEvent.value.setExtendedProp(\"taskid\", props.taskid);\n }\n editingEvent.value.setProp(\"backgroundColor\", colorInfo.bg);\n editingEvent.value.setProp(\"borderColor\", colorInfo.border);\n\n // 构建更新后的事件对象用于emit\n const updatedEvent: EventInput = {\n id: editingEvent.value.id,\n title: formData.title,\n start: startISO,\n end: endISO || startISO,\n allDay: false,\n backgroundColor: colorInfo.bg,\n borderColor: colorInfo.border,\n editable:\n !props.userid ||\n (formData.organizer || currentUser.value) === props.userid,\n extendedProps: {\n description: formData.description,\n organizer: formData.organizer || currentUser.value,\n colorIndex: colorInfo.index,\n deviceId: props.deviceId || \"\",\n taskid: props.taskid || \"\",\n },\n };\n\n emit(\"eventUpdated\", updatedEvent);\n // 计算更新后的事件列表(不修改原数组)\n const updatedEventsList = events.value.map((e) =>\n e.id === updatedEvent.id ? updatedEvent : e\n );\n emit(\"eventsChange\", updatedEventsList);\n } else {\n // 添加新事件\n const startISO = formatToISO(formData.start);\n const endISO = formData.end ? formatToISO(formData.end) : undefined;\n\n const eventOrganizer = formData.organizer || currentUser.value;\n const editable = !props.userid || eventOrganizer === props.userid;\n const newEvent: EventInput = {\n id: eventId, // 使用之前生成的事件ID\n title: formData.title,\n start: startISO,\n end: endISO,\n allDay: false,\n backgroundColor: colorInfo.bg,\n borderColor: colorInfo.border,\n editable: editable, // 根据 userid 设置可编辑性\n extendedProps: {\n description: formData.description,\n organizer: eventOrganizer,\n colorIndex: colorInfo.index,\n deviceId: props.deviceId || \"\", // 保存设备ID\n taskid: props.taskid || \"\", // 保存 taskid(如果存在)\n },\n };\n emit(\"eventAdded\", newEvent);\n // 计算新的事件列表(不修改原数组)\n const newEventsList = [...events.value, newEvent];\n emit(\"eventsChange\", newEventsList);\n }\n\n dialogVisible.value = false;\n resetForm();\n}\n\n// 删除事件\nfunction handleDelete() {\n if (editingEvent.value) {\n const eventId = editingEvent.value.id;\n editingEvent.value.remove();\n dialogVisible.value = false;\n resetForm();\n emit(\"eventDeleted\", eventId || \"\");\n // 计算删除后的事件列表(不修改原数组)\n const newEventsList = events.value.filter((e) => e.id !== eventId);\n emit(\"eventsChange\", newEventsList);\n }\n}\n\n// 重置表单\nfunction resetForm() {\n formData.title = \"\";\n formData.start = \"\";\n formData.end = \"\";\n formData.allDay = false;\n formData.description = \"\";\n formData.organizer = currentUser.value;\n formData.taskid = \"\";\n formData.deviceId = \"\";\n formData.userid = \"\";\n editingEvent.value = null;\n}\n</script>\n\n<style scoped>\nbutton:focus-visible {\n outline: none;\n}\n:deep(.fc .fc-button:focus) {\n box-shadow: none !important;\n}\n.fullcalendar-demo {\n padding: 4px; /* 压缩容器内边距 */\n background-color: #fff;\n border-radius: 4px;\n box-shadow: 0 0 8px rgba(0, 0, 0, 0.08);\n}\n\n.demo-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px; /* 压缩底部间距 */\n padding-bottom: 4px; /* 压缩底部内边距 */\n border-bottom: 1px solid #dcdfe6;\n}\n\n.device-info {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.device-label {\n font-size: 12px;\n color: #606266;\n font-weight: 500;\n}\n\n.device-id {\n font-size: 12px;\n color: #409eff;\n font-weight: 600;\n cursor: pointer;\n text-decoration: underline;\n transition: color 0.2s;\n}\n\n.device-id:hover {\n color: #66b1ff;\n}\n\n.demo-header h2 {\n margin: 0;\n color: #303133;\n font-size: 18px;\n font-weight: 500;\n}\n\n.calendar {\n margin-top: 0;\n background: #fff;\n border-radius: 4px;\n height: 480px; /* 限制日历容器高度为480px */\n max-height: 480px; /* 确保最大高度不超过480px */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n:deep(.fc) {\n height: 100%;\n max-height: 480px; /* 限制FullCalendar最大高度为480px */\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n:deep(.fc-view-harness) {\n flex: 1;\n min-height: 0;\n max-height: 480px; /* 限制视图容器最大高度为480px */\n overflow: hidden;\n}\n\n.event-content {\n display: flex;\n align-items: center;\n gap: 2px; /* 压缩时间和标题之间的间距 */\n font-size: 10px;\n line-height: 1.2;\n flex-direction: row; /* 改为横向排列 */\n justify-content: flex-start;\n cursor: pointer;\n width: 100%;\n height: 100%;\n white-space: nowrap;\n overflow: hidden;\n}\n\n/* 自己的事件标记图标样式 */\n.my-event-marker {\n font-size: 10px;\n color: #409eff;\n flex-shrink: 0;\n margin-right: 2px;\n}\n\n.event-content i {\n font-size: 11px;\n opacity: 0.9;\n margin-top: 0;\n}\n\n.event-time {\n white-space: nowrap;\n opacity: 0.8;\n font-size: 9px;\n flex-shrink: 0; /* 时间不收缩 */\n}\n\n.event-info {\n flex: 1;\n display: flex;\n min-width: 0;\n}\n\n.event-title {\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 10px;\n flex: 1;\n min-width: 0;\n}\n\n.event-user {\n font-size: 9px;\n color: rgba(255, 255, 255, 0.75);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* 日历整体样式优化 */\n:deep(.fc) {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto,\n \"Helvetica Neue\", Arial, sans-serif;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n:deep(.fc-view-harness) {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n:deep(.fc-header-toolbar) {\n margin-bottom: 5px !important; /* 压缩工具栏底部间距 */\n padding: 0;\n gap: 2px; /* 压缩工具栏内按钮间距 */\n}\n\n:deep(.fc-toolbar-chunk) {\n gap: 2px; /* 压缩工具栏块内间距 */\n}\n\n:deep(.fc-toolbar-title) {\n font-size: 14px;\n font-weight: 500;\n color: #303133;\n text-transform: capitalize;\n}\n\n/* 按钮样式优化 - Element Plus 风格 */\n:deep(.fc-button) {\n background-color: #409eff;\n border-color: #409eff;\n border-radius: 3px;\n padding: 2px 6px; /* 压缩按钮内边距 */\n font-size: 10px; /* 压缩按钮字号 */\n font-weight: 500;\n color: #fff;\n transition: all 0.1s;\n border: 1px solid;\n cursor: pointer;\n box-shadow: none;\n outline: none;\n min-height: 22px; /* 设置最小高度 */\n line-height: 1.2;\n}\n\n:deep(.fc-button:hover) {\n background-color: #66b1ff;\n border-color: #66b1ff;\n color: #fff;\n box-shadow: none;\n}\n\n:deep(.fc-button:active) {\n background-color: #a5846a;\n border-color: #6a86a5;\n color: #fff;\n box-shadow: none;\n}\n\n:deep(.fc-button:focus-visible) {\n outline: 2px solid #409eff;\n outline-offset: 1px;\n}\n\n:deep(.fc-button-active),\n:deep(.fc-button-primary:not(:disabled):active),\n:deep(.fc-button-primary:not(:disabled).fc-button-active) {\n background-color: var(--el-color-success);\n border-color: var(--el-color-success);\n color: #fff;\n box-shadow: none;\n}\n\n:deep(.fc-today-button) {\n background-color: #409eff;\n border-color: #409eff;\n color: #fff;\n box-shadow: none;\n}\n\n:deep(.fc-today-button:hover) {\n background-color: #66b1ff;\n border-color: #66b1ff;\n color: #fff;\n box-shadow: none;\n}\n\n:deep(.fc-button:disabled) {\n background-color: #fff;\n border-color: #e4e7ed;\n color: #c0c4cc;\n cursor: not-allowed;\n opacity: 1;\n box-shadow: none;\n}\n\n:deep(.fc-button:disabled:hover) {\n background-color: #fff;\n border-color: #e4e7ed;\n color: #c0c4cc;\n box-shadow: none;\n}\n\n/* 日历表格样式优化 - Element Plus 风格 */\n:deep(.fc-scrollgrid) {\n border: 1px solid #dcdfe6;\n border-radius: 4px;\n overflow: hidden;\n}\n\n:deep(.fc-col-header-cell) {\n background-color: #f5f7fa;\n padding: 3px 2px; /* 压缩表头单元格内边距 */\n font-weight: 500;\n color: #606266;\n border-color: #dcdfe6;\n font-size: 12px;\n}\n\n:deep(.fc-daygrid-day) {\n border-color: #dcdfe6;\n transition: background-color 0.2s;\n min-height: 65px; /* 统一单元格最小高度 */\n height: 65px; /* 统一单元格高度 */\n}\n\n:deep(.fc-daygrid-day:hover) {\n background-color: #f5f7fa;\n}\n\n/* 统一单元格框架高度 */\n:deep(.fc-daygrid-day-frame) {\n min-height: 65px;\n height: 65px;\n}\n\n:deep(.fc-day-today) {\n background-color: #ecf5ff !important;\n}\n\n:deep(.fc-day-today .fc-daygrid-day-number) {\n color: #409eff;\n font-weight: 500;\n}\n\n:deep(.fc-daygrid-day-number) {\n padding: 2px; /* 压缩日期数字内边距 */\n font-size: 12px;\n color: #606266;\n transition: color 0.2s;\n}\n\n:deep(.fc-daygrid-day-number:hover) {\n color: #409eff;\n}\n\n/* 节假日日期单元格样式 */\n:deep(.fc-daygrid-day.holiday-day) {\n background-color: #fef0f0 !important;\n}\n\n:deep(.fc-daygrid-day.holiday-day:hover) {\n background-color: #fde2e2 !important;\n}\n\n:deep(.fc-daygrid-day.holiday-day .fc-daygrid-day-number) {\n color: #f56c6c;\n font-weight: 600;\n}\n\n/* 节假日标签样式 */\n.holiday-label {\n font-size: 9px !important;\n color: #f56c6c !important;\n font-weight: 500 !important;\n margin-top: 2px !important;\n white-space: nowrap !important;\n overflow: hidden !important;\n text-overflow: ellipsis !important;\n max-width: 100% !important;\n line-height: 1.2 !important;\n}\n\n/* 隐藏\"more\"链接,不显示额外事件数量 */\n:deep(.fc-more-link) {\n display: none !important;\n}\n\n/* 月视图事件样式 - 显示为10px高度的横线,不显示文字,保留背景颜色 */\n:deep(.fc-daygrid-event) {\n margin: 1px 0 !important; /* 确保事件之间有间距 */\n border-radius: 0 !important;\n display: block !important;\n width: 100% !important;\n height: 10px !important; /* 固定高度10px */\n min-height: 10px !important;\n max-height: 10px !important;\n padding: 0 !important;\n overflow: visible !important; /* 改为visible确保可见 */\n line-height: 10px !important;\n /* 确保背景颜色显示,不覆盖原有颜色 */\n border: none !important;\n visibility: visible !important;\n opacity: 1 !important;\n /* 强制显示背景色 - 从内联样式获取 */\n /* background-color: inherit !important; */\n background-image: none !important;\n}\n\n/* 确保事件的所有子元素也正确显示 */\n:deep(.fc-daygrid-event *) {\n /* 子元素默认透明,但tooltip触发器需要特殊处理 */\n background-color: transparent !important;\n}\n\n/* 确保tooltip触发器不覆盖背景色 */\n:deep(.fc-daygrid-event .el-tooltip__trigger) {\n background-color: transparent !important;\n background: transparent !important;\n}\n\n/* 确保事件容器可见 */\n:deep(.fc-daygrid-day-events) {\n margin-top: 2px !important;\n min-height: 0 !important;\n}\n\n/* 确保事件框架可见并显示背景色 */\n:deep(.fc-daygrid-event-frame) {\n height: 10px !important;\n min-height: 10px !important;\n max-height: 10px !important;\n overflow: visible !important;\n /* background-color: inherit !important; */\n display: block !important;\n width: 100% !important;\n}\n\n/* 隐藏月视图事件文字内容 - 只针对月视图 */\n:deep(.fc-daygrid-event .fc-event-main) {\n display: none !important;\n}\n\n:deep(.fc-daygrid-event .fc-event-title) {\n display: none !important;\n}\n\n:deep(.fc-daygrid-event .fc-event-time) {\n display: none !important;\n}\n\n/* 隐藏月视图事件内容区域的所有文字 - 只针对月视图 */\n:deep(.fc-daygrid-event .event-content),\n:deep(.fc-daygrid-event .event-time),\n:deep(.fc-daygrid-event .event-info),\n:deep(.fc-daygrid-event .event-title),\n:deep(.fc-daygrid-event .my-event-marker) {\n display: none !important;\n visibility: hidden !important;\n opacity: 0 !important;\n height: 0 !important;\n width: 0 !important;\n padding: 0 !important;\n margin: 0 !important;\n font-size: 0 !important;\n line-height: 0 !important;\n}\n\n/* 月视图下自己创建事件的图标样式 */\n:deep(.fc-daygrid-event .my-event-icon) {\n display: block !important;\n position: absolute !important;\n left: 2px !important;\n top: 50% !important;\n transform: translateY(-50%) !important;\n font-size: 8px !important;\n color: #fff !important;\n line-height: 1 !important;\n z-index: 20 !important;\n pointer-events: none !important;\n font-weight: bold !important;\n}\n\n/* 确保月视图事件元素可以hover并显示tooltip */\n:deep(.fc-daygrid-event) {\n cursor: pointer !important;\n position: relative !important;\n pointer-events: auto !important;\n}\n\n/* 确保tooltip在月视图中可以正常显示 */\n:deep(.fc-daygrid-event .el-tooltip__trigger) {\n display: block !important;\n width: 100% !important;\n height: 100% !important;\n cursor: pointer !important;\n pointer-events: auto !important;\n position: absolute !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 10 !important;\n background: transparent !important;\n visibility: visible !important;\n opacity: 1 !important;\n}\n\n/* 确保事件框架也可以触发tooltip */\n:deep(.fc-daygrid-event-frame) {\n cursor: pointer !important;\n pointer-events: auto !important;\n}\n\n/* 确保tooltip内容区域在月视图中可见(虽然事件内容被隐藏,但tooltip应该显示) */\n:deep(.fc-daygrid-event:hover) {\n opacity: 0.9 !important;\n z-index: 100 !important;\n}\n\n/* 确保tooltip弹窗可以正常显示 */\n:deep(.el-popper.is-light) {\n z-index: 9999 !important;\n pointer-events: auto !important;\n}\n\n:deep(.event-detail-tooltip) {\n z-index: 9999 !important;\n pointer-events: auto !important;\n}\n\n/* 确保日视图和列表视图显示文字内容 - 覆盖月视图的隐藏规则 */\n:deep(.fc-timegrid-event .event-content),\n:deep(.fc-list-event .event-content) {\n display: flex !important;\n flex-direction: row !important; /* 一行显示 */\n align-items: center !important;\n gap: 2px !important; /* 压缩时间和标题之间的间距 */\n visibility: visible !important;\n opacity: 1 !important;\n height: auto !important;\n width: auto !important;\n margin: 0 !important;\n font-size: 11px !important;\n line-height: 1.2 !important;\n white-space: nowrap !important;\n overflow: hidden !important;\n}\n\n/* 标记图标在日视图和列表视图中的样式 */\n:deep(.fc-timegrid-event .my-event-marker),\n:deep(.fc-list-event .my-event-marker) {\n display: inline-flex !important;\n font-size: 10px !important;\n color: #409eff !important;\n flex-shrink: 0 !important;\n margin-right: 2px !important;\n}\n\n:deep(.fc-timegrid-event .event-time),\n:deep(.fc-list-event .event-time) {\n display: inline-block !important;\n visibility: visible !important;\n opacity: 0.8 !important;\n font-size: 9px !important;\n flex-shrink: 0 !important;\n white-space: nowrap !important;\n}\n\n:deep(.fc-timegrid-event .event-title),\n:deep(.fc-list-event .event-title) {\n display: inline-block !important;\n visibility: visible !important;\n opacity: 1 !important;\n font-size: 10px !important;\n font-weight: 500 !important;\n overflow: hidden !important;\n text-overflow: ellipsis !important;\n white-space: nowrap !important;\n flex: 1 !important;\n min-width: 0 !important;\n}\n\n:deep(.fc-timegrid-event .event-info),\n:deep(.fc-list-event .event-info) {\n display: none !important; /* 隐藏 event-info,因为标题已经直接显示 */\n}\n\n/* 事件样式优化 - Element Plus 风格(用于其他视图) */\n:deep(.fc-event) {\n cursor: pointer;\n border-radius: 3px;\n padding: 2px 4px;\n border: none;\n transition: opacity 0.2s;\n font-weight: 400;\n font-size: 11px;\n}\n\n:deep(.fc-event:hover) {\n opacity: 0.9;\n}\n\n/* 日视图和列表视图的事件主内容区域 - 确保显示 */\n:deep(.fc-timegrid-event .fc-event-main),\n:deep(.fc-list-event .fc-event-main) {\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n}\n\n/* 日视图和列表视图的事件样式 - 显示文字内容 */\n:deep(.fc-timegrid-event .fc-event-main),\n:deep(.fc-list-event .fc-event-main) {\n display: block !important;\n}\n\n/* 确保日视图和列表视图的事件文字可见 */\n:deep(.fc-timegrid-event .fc-event-title),\n:deep(.fc-timegrid-event .fc-event-time),\n:deep(.fc-list-event .fc-event-title),\n:deep(.fc-list-event .fc-event-time) {\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n}\n\n/* 列表视图中自己的事件(黑色背景)的所有文字元素使用 #409eff 颜色 */\n:deep(\n .fc-list-event[style*=\"background-color: rgb(0, 0, 0)\"] .fc-event-title,\n .fc-list-event[style*=\"background-color:#000\"] .fc-event-title,\n .fc-list-event[style*=\"background-color: #000\"] .fc-event-title,\n .fc-list-event[style*=\"background-color:rgb(0, 0, 0)\"] .fc-event-title,\n .fc-list-event[style*=\"background-color:#000000\"] .fc-event-title,\n .fc-list-event[style*=\"background-color: rgb(0, 0, 0)\"] .fc-event-time,\n .fc-list-event[style*=\"background-color:#000\"] .fc-event-time,\n .fc-list-event[style*=\"background-color: #000\"] .fc-event-time,\n .fc-list-event[style*=\"background-color:rgb(0, 0, 0)\"] .fc-event-time,\n .fc-list-event[style*=\"background-color:#000000\"] .fc-event-time\n ) {\n color: #409eff !important;\n}\n\n/* 确保自己的事件(黑色)在月视图中正确显示为10px黑色横线 */\n:deep(\n .fc-daygrid-event[style*=\"background-color: rgb(0, 0, 0)\"],\n .fc-daygrid-event[style*=\"background-color:#000\"],\n .fc-daygrid-event[style*=\"background-color: #000\"],\n .fc-daygrid-event[style*=\"background-color:rgb(0, 0, 0)\"],\n .fc-daygrid-event[style*=\"background-color:#000000\"],\n .fc-daygrid-event[style*=\"background-color: rgb(0,0,0)\"],\n .fc-daygrid-event[style*=\"background-color:rgb(0,0,0)\"]\n ) {\n background-color: #000000 !important;\n border-color: #000000 !important;\n height: 10px !important;\n min-height: 10px !important;\n max-height: 10px !important;\n /* 确保黑色横线可见 */\n border: none !important;\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n width: 100% !important;\n background-image: none !important;\n}\n\n/* 确保事件框架也显示黑色 */\n:deep(\n .fc-daygrid-event[style*=\"background-color: rgb(0, 0, 0)\"]\n .fc-daygrid-event-frame,\n .fc-daygrid-event[style*=\"background-color:#000\"] .fc-daygrid-event-frame,\n .fc-daygrid-event[style*=\"background-color: #000\"] .fc-daygrid-event-frame,\n .fc-daygrid-event[style*=\"background-color:rgb(0, 0, 0)\"]\n .fc-daygrid-event-frame,\n .fc-daygrid-event[style*=\"background-color:#000000\"] .fc-daygrid-event-frame\n ) {\n background-color: #000000 !important;\n}\n\n/* 自己的事件(黑色背景)在日视图和列表视图中使用 #409eff 颜色的文字 */\n:deep(\n .fc-timegrid-event[style*=\"background-color: rgb(0, 0, 0)\"],\n .fc-timegrid-event[style*=\"background-color:#000\"],\n .fc-timegrid-event[style*=\"background-color: #000\"],\n .fc-timegrid-event[style*=\"background-color:rgb(0, 0, 0)\"],\n .fc-timegrid-event[style*=\"background-color:#000000\"],\n .fc-list-event[style*=\"background-color: rgb(0, 0, 0)\"],\n .fc-list-event[style*=\"background-color:#000\"],\n .fc-list-event[style*=\"background-color: #000\"],\n .fc-list-event[style*=\"background-color:rgb(0, 0, 0)\"],\n .fc-list-event[style*=\"background-color:#000000\"]\n ) {\n background-color: #000000 !important;\n border-color: #000000 !important;\n color: #409eff !important; /* 文字颜色使用 #409eff */\n}\n\n/* 自己的事件文字内容使用 #409eff 颜色 */\n:deep(\n .fc-timegrid-event[style*=\"background-color: rgb(0, 0, 0)\"] .event-content,\n .fc-timegrid-event[style*=\"background-color:#000\"] .event-content,\n .fc-timegrid-event[style*=\"background-color: #000\"] .event-content,\n .fc-timegrid-event[style*=\"background-color:rgb(0, 0, 0)\"] .event-content,\n .fc-timegrid-event[style*=\"background-color:#000000\"] .event-content,\n .fc-list-event[style*=\"background-color: rgb(0, 0, 0)\"] .event-content,\n .fc-list-event[style*=\"background-color:#000\"] .event-content,\n .fc-list-event[style*=\"background-color: #000\"] .event-content,\n .fc-list-event[style*=\"background-color:rgb(0, 0, 0)\"] .event-content,\n .fc-list-event[style*=\"background-color:#000000\"] .event-content\n ) {\n color: #409eff !important;\n}\n\n:deep(\n .fc-timegrid-event[style*=\"background-color: rgb(0, 0, 0)\"] .event-time,\n .fc-timegrid-event[style*=\"background-color:#000\"] .event-time,\n .fc-timegrid-event[style*=\"background-color: #000\"] .event-time,\n .fc-timegrid-event[style*=\"background-color:rgb(0, 0, 0)\"] .event-time,\n .fc-timegrid-event[style*=\"background-color:#000000\"] .event-time,\n .fc-list-event[style*=\"background-color: rgb(0, 0, 0)\"] .event-time,\n .fc-list-event[style*=\"background-color:#000\"] .event-time,\n .fc-list-event[style*=\"background-color: #000\"] .event-time,\n .fc-list-event[style*=\"background-color:rgb(0, 0, 0)\"] .event-time,\n .fc-list-event[style*=\"background-color:#000000\"] .event-time\n ) {\n color: #409eff !important;\n}\n\n:deep(\n .fc-timegrid-event[style*=\"background-color: rgb(0, 0, 0)\"] .event-title,\n .fc-timegrid-event[style*=\"background-color:#000\"] .event-title,\n .fc-timegrid-event[style*=\"background-color: #000\"] .event-title,\n .fc-timegrid-event[style*=\"background-color:rgb(0, 0, 0)\"] .event-title,\n .fc-timegrid-event[style*=\"background-color:#000000\"] .event-title,\n .fc-list-event[style*=\"background-color: rgb(0, 0, 0)\"] .event-title,\n .fc-list-event[style*=\"background-color:#000\"] .event-title,\n .fc-list-event[style*=\"background-color: #000\"] .event-title,\n .fc-list-event[style*=\"background-color:rgb(0, 0, 0)\"] .event-title,\n .fc-list-event[style*=\"background-color:#000000\"] .event-title\n ) {\n color: #409eff !important;\n}\n\n/* 列表视图中自己的事件(黑色背景)所有文字元素都使用 #409eff 颜色 */\n:deep(\n .fc-list-event[style*=\"background-color: rgb(0, 0, 0)\"] *,\n .fc-list-event[style*=\"background-color:#000\"] *,\n .fc-list-event[style*=\"background-color: #000\"] *,\n .fc-list-event[style*=\"background-color:rgb(0, 0, 0)\"] *,\n .fc-list-event[style*=\"background-color:#000000\"] *\n ) {\n color: #409eff !important;\n}\n\n/* 确保所有事件横线都显示背景颜色 - 使用更通用的选择器 */\n:deep(.fc-daygrid-event) {\n /* 确保高度和显示 */\n height: 10px !important;\n min-height: 10px !important;\n max-height: 10px !important;\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n width: 100% !important;\n /* 确保背景色显示 - 从内联样式继承 */\n /* background-color: inherit !important; */\n background-image: none !important;\n /* 确保背景色不被覆盖 */\n}\n\n/* 针对有内联样式背景色的事件 - 确保显示 */\n:deep(.fc-daygrid-event[style*=\"background\"]) {\n /* 保留事件原有的背景颜色 */\n height: 10px !important;\n min-height: 10px !important;\n max-height: 10px !important;\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n width: 100% !important;\n /* 确保内联样式背景色显示 - 使用!important强制应用 */\n /* background-color: inherit !important; */\n}\n\n/* 确保事件框架和所有子元素都显示背景色 */\n:deep(.fc-daygrid-event-frame),\n:deep(.fc-daygrid-event .fc-event-main-frame),\n:deep(.fc-daygrid-event .fc-event-main) {\n /* background-color: inherit !important; */\n height: 10px !important;\n display: block !important;\n width: 100% !important;\n}\n\n/* 确保事件容器中的事件正确显示 */\n:deep(.fc-daygrid-day .fc-daygrid-day-events .fc-daygrid-event) {\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n height: 10px !important;\n min-height: 10px !important;\n max-height: 10px !important;\n width: 100% !important;\n /* 确保背景色显示 - 从内联样式或CSS变量获取 */\n /* background-color: inherit !important; */\n}\n\n/* 确保事件框架和主容器也显示背景色 */\n:deep(.fc-daygrid-event-frame),\n:deep(.fc-daygrid-event .fc-event-main-frame) {\n /* background-color: inherit !important; */\n height: 10px !important;\n display: block !important;\n width: 100% !important;\n}\n\n/* 确保事件框架也显示背景色 */\n:deep(.fc-daygrid-event-frame) {\n /* background-color: inherit !important; */\n height: 10px !important;\n min-height: 10px !important;\n max-height: 10px !important;\n display: block !important;\n}\n\n/* 确保事件主容器显示背景色 */\n:deep(.fc-daygrid-event .fc-event-main-frame) {\n /* background-color: inherit !important; */\n height: 20px !important;\n}\n\n/* 确保事件容器可见并正确显示 */\n:deep(.fc-daygrid-day-events) {\n margin-top: 2px !important;\n margin-bottom: 2px !important;\n min-height: 0 !important;\n display: block !important;\n visibility: visible !important;\n}\n\n/* 确保事件在单元格中可见 */\n:deep(.fc-daygrid-day .fc-daygrid-day-events .fc-daygrid-event) {\n display: block !important;\n visibility: visible !important;\n opacity: 1 !important;\n height: 10px !important;\n min-height: 10px !important;\n max-height: 10px !important;\n}\n\n:deep(.fc-timegrid-event) {\n border-radius: 2px;\n border-left-width: 2px;\n}\n\n:deep(.fc-timegrid-event-short) {\n min-height: 16px;\n}\n\n:deep(.fc-event-time) {\n font-weight: 400;\n opacity: 0.9;\n}\n\n/* 选择区域样式 - Element Plus 风格 */\n:deep(.fc-highlight) {\n background: rgba(64, 158, 255, 0.15) !important;\n border: 2px dashed #409eff !important;\n border-radius: 4px;\n}\n\n:deep(.fc-select-marker) {\n background-color: rgba(64, 158, 255, 0.2);\n border: 2px dashed #409eff;\n border-radius: 4px;\n opacity: 0.8;\n}\n\n/* 拖拽新增时的镜像事件样式 - 更明显的区别 */\n:deep(.fc-event-mirror) {\n opacity: 0.7 !important;\n border: 2px dashed #67c23a !important;\n background-color: rgba(103, 194, 58, 0.2) !important;\n box-shadow: 0 2px 8px rgba(103, 194, 58, 0.4) !important;\n transform: scale(1.02);\n}\n\n/* 拖拽选择时的临时事件条 */\n:deep(.fc-timegrid-event.fc-event-mirror),\n:deep(.fc-daygrid-event.fc-event-mirror) {\n border: 2px dashed #67c23a !important;\n background-color: rgba(103, 194, 58, 0.25) !important;\n box-shadow: 0 2px 8px rgba(103, 194, 58, 0.5) !important;\n opacity: 0.8 !important;\n}\n\n/* 日视图单元格样式 - 添加 padding */\n:deep(.fc-timegrid-col) {\n padding-right: 10px;\n}\n\n:deep(.fc-timegrid-col-frame) {\n padding: 2px;\n}\n\n/* 时间网格样式 - Element Plus 风格 */\n:deep(.fc-timegrid-slot) {\n border-color: #ebeef5;\n height: 32px;\n}\n\n:deep(.fc-timegrid-slot-label) {\n border-color: #dcdfe6;\n color: #909399;\n font-size: 11px;\n}\n\n:deep(.fc-timegrid-now-indicator-line) {\n border-color: #f56c6c;\n border-width: 2px;\n}\n\n:deep(.fc-timegrid-now-indicator-arrow) {\n border-left-color: #f56c6c;\n}\n\n/* 滚动条样式 - Element Plus 风格 */\n:deep(.fc-scroller::-webkit-scrollbar) {\n width: 6px;\n height: 6px;\n}\n\n:deep(.fc-scroller::-webkit-scrollbar-track) {\n background: #f5f7fa;\n border-radius: 3px;\n}\n\n:deep(.fc-scroller::-webkit-scrollbar-thumb) {\n background: #c0c4cc;\n border-radius: 3px;\n}\n\n:deep(.fc-scroller::-webkit-scrollbar-thumb:hover) {\n background: #a4a9ae;\n}\n\n/* 列表视图滚动优化 */\n:deep(.fc-list-view) {\n height: 350px !important;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n:deep(.fc-list-view .fc-view-harness) {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n height: 100% !important;\n}\n\n:deep(.fc-list-view .fc-scroller) {\n overflow-y: auto !important;\n overflow-x: hidden !important;\n height: 100% !important;\n max-height: 100% !important;\n flex: 1;\n min-height: 0;\n}\n\n:deep(.fc-list-view .fc-scroller-liquid-absolute) {\n position: relative !important;\n height: auto !important;\n min-height: 100%;\n}\n\n:deep(.fc-list-view .fc-list) {\n height: auto !important;\n min-height: 100%;\n}\n\n:deep(.fc-list-view .fc-list-table) {\n height: auto !important;\n}\n\n:deep(.fc-list-view .fc-list-day-cushion) {\n position: sticky;\n top: 0;\n z-index: 1;\n}\n\n/* 对话框样式优化 - 使用 Element Plus 默认样式 */\n:deep(.event-dialog) {\n border-radius: 4px;\n}\n\n:deep(.event-dialog .el-dialog__header) {\n padding: 20px 20px 10px;\n border-bottom: 1px solid #ebeef5;\n}\n\n:deep(.event-dialog .el-dialog__title) {\n font-size: 18px;\n font-weight: 500;\n color: #303133;\n line-height: 24px;\n}\n\n:deep(.event-dialog .el-dialog__body) {\n padding: 20px;\n}\n\n:deep(.event-dialog .el-dialog__footer) {\n padding: 10px 20px 20px;\n border-top: 1px solid #ebeef5;\n}\n\n:deep(.event-dialog .el-form-item__label) {\n font-weight: 400;\n color: #606266;\n font-size: 14px;\n}\n\n/* 响应式优化 */\n@media (max-width: 768px) {\n .fullcalendar-demo {\n padding: 16px;\n }\n\n .demo-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 16px;\n }\n\n .demo-header h2 {\n font-size: 24px;\n }\n\n :deep(.fc-header-toolbar) {\n flex-direction: column;\n gap: 12px;\n }\n\n :deep(.fc-toolbar-chunk) {\n width: 100%;\n display: flex;\n justify-content: center;\n }\n\n :deep(.fc-button) {\n padding: 6px 12px;\n font-size: 13px;\n }\n}\n\n/* 事件详情 Tooltip 样式 */\n:deep(.event-detail-tooltip) {\n padding: 0 !important;\n max-width: 350px;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n}\n\n.event-detail {\n display: flex;\n flex-direction: column;\n background: #fff;\n overflow: hidden;\n}\n\n.detail-header {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n padding: 12px 16px;\n border-bottom: none;\n}\n\n.detail-title {\n color: #fff;\n font-size: 16px;\n font-weight: 600;\n line-height: 1.5;\n display: block;\n word-break: break-word;\n}\n\n.detail-body {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n background: #fff;\n}\n\n.detail-item {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n font-size: 13px;\n line-height: 1.6;\n padding: 4px 0;\n}\n\n.detail-item:not(:last-child) {\n border-bottom: 1px solid #f0f0f0;\n padding-bottom: 12px;\n}\n\n.detail-label {\n color: #606266;\n font-weight: 500;\n white-space: nowrap;\n min-width: 80px;\n display: flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.detail-icon {\n font-size: 14px;\n color: #909399;\n margin-right: 2px;\n}\n\n.detail-value {\n color: #303133;\n flex: 1;\n word-break: break-word;\n line-height: 1.6;\n}\n\n.detail-value.description-text {\n color: #606266;\n font-size: 12px;\n line-height: 1.6;\n white-space: pre-wrap;\n max-height: 100px;\n overflow-y: auto;\n padding: 8px 12px;\n background: #f5f7fa;\n border-radius: 4px;\n border: 1px solid #e4e7ed;\n}\n\n/* Tooltip 箭头样式优化 */\n:deep(.el-popper.is-light .el-popper__arrow::before) {\n border: 1px solid #e4e7ed;\n background: #fff;\n}\n</style>\n","/**\n * 中国法定节假日数据\n * 格式: { \"YYYY-MM-DD\": \"节假日名称\" }\n */\n\nexport interface HolidayData {\n [date: string]: string;\n}\n\n/**\n * 获取指定年份的节假日数据\n * @param year 年份,如 2024\n * @returns 节假日数据对象\n */\nexport function getHolidays(year: number): HolidayData {\n const holidays: HolidayData = {};\n // 2026年节假日\n if (year === 2026) {\n // 元旦\n holidays[\"2026-01-01\"] = \"元旦\";\n holidays[\"2026-01-02\"] = \"元旦\";\n holidays[\"2026-01-03\"] = \"元旦\";\n\n // 春节\n holidays[\"2026-02-16\"] = \"春节\";\n holidays[\"2026-02-17\"] = \"春节\";\n holidays[\"2026-02-18\"] = \"春节\";\n holidays[\"2026-02-19\"] = \"春节\";\n holidays[\"2026-02-20\"] = \"春节\";\n holidays[\"2026-02-21\"] = \"春节\";\n holidays[\"2026-02-22\"] = \"春节\";\n\n // 清明节\n holidays[\"2026-04-04\"] = \"清明节\";\n holidays[\"2026-04-05\"] = \"清明节\";\n holidays[\"2026-04-06\"] = \"清明节\";\n\n // 劳动节\n holidays[\"2026-05-01\"] = \"劳动节\";\n holidays[\"2026-05-02\"] = \"劳动节\";\n holidays[\"2026-05-03\"] = \"劳动节\";\n holidays[\"2026-05-04\"] = \"劳动节\";\n holidays[\"2026-05-05\"] = \"劳动节\";\n\n // 端午节\n holidays[\"2026-06-19\"] = \"端午节\";\n holidays[\"2026-06-20\"] = \"端午节\";\n holidays[\"2026-06-21\"] = \"端午节\";\n\n // 中秋节\n holidays[\"2026-09-25\"] = \"中秋节\";\n holidays[\"2026-09-26\"] = \"中秋节\";\n holidays[\"2026-09-27\"] = \"中秋节\";\n\n // 国庆节\n holidays[\"2026-10-01\"] = \"国庆节\";\n holidays[\"2026-10-02\"] = \"国庆节\";\n holidays[\"2026-10-03\"] = \"国庆节\";\n holidays[\"2026-10-04\"] = \"国庆节\";\n holidays[\"2026-10-05\"] = \"国庆节\";\n holidays[\"2026-10-06\"] = \"国庆节\";\n holidays[\"2026-10-07\"] = \"国庆节\";\n holidays[\"2026-10-08\"] = \"国庆节\";\n }\n\n return holidays;\n}\n\n/**\n * 检查指定日期是否为节假日\n * @param date 日期字符串,格式: YYYY-MM-DD\n * @returns 如果是节假日返回节假日名称,否则返回 null\n */\nexport function isHoliday(date: string): string | null {\n const dateObj = new Date(date);\n const year = dateObj.getFullYear();\n const holidays = getHolidays(year);\n return holidays[date] || null;\n}\n\n/**\n * 格式化日期为 YYYY-MM-DD 格式\n * @param date Date 对象\n * @returns 格式化后的日期字符串\n */\nexport function formatDate(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n}\n","import FullCalendarDemo from './components/FullCalendarDemo.vue'\nimport type { App } from 'vue'\n\n// 导出组件\nexport { FullCalendarDemo }\n\n// 导出工具函数和类型\nexport * from './utils/holidays'\n\n// 安装函数,用于全局注册组件\nexport function install(app: App) {\n app.component('FullCalendarDemo', FullCalendarDemo)\n}\n\n// 默认导出组件(用于兼容性)\nexport default FullCalendarDemo\n"],"names":["eventOrganizer","formatDate","_a","colorIndex","isMyEvent","zhCnLocale","eventTaskId","_openBlock","_createElementBlock","_createElementVNode","_toDisplayString","_createVNode","_createBlock","_unref","_withCtx","_createTextVNode"],"mappings":";;;;;;;;AAAA,IAAI,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA;AAAA,IAEF,KAAK;AAAA,IACL,KAAK;AAAA;AAAA,EACb;AAAA,EACI,YAAY;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,KAAK;AAAA,IACL,MAAM;AAAA,EACd;AAAA,EACI,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,aAAa,GAAG;AACZ,WAAO,QAAQ,IAAI;AAAA,EACvB;AAAA,EACA,cAAc;AAClB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC8MA,UAAM,OAAO;AA6Db,UAAM,QAAQ;AA4Bd,UAAM,gBAAgB,IAAI,KAAK;AAC/B,UAAM,eAAe,IAAqB,IAAI;AAC9C,UAAM,sBAAsB,IAAI,KAAK;AACrC,UAAM,aAAa,SAAS,MAAM;AAEhC,UAAI,MAAM,YAAY;AACpB,eAAO,MAAM;AAAA,MACf;AAEA,UAAI,MAAM,UAAU;AAClB,eAAO;AAAA,UACL,IAAI,MAAM;AAAA,UACV,MAAM,MAAM;AAAA,QAAA;AAAA,MAEhB;AACA,aAAO;AAAA,IACT,CAAC;AAGD,UAAM,cAAc,IAAI,IAAI;AAG5B,UAAM,eAAe,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAE/D,UAAM,YAAY,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAI5D,UAAM,cAAc;AAAA,MAClB,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,MAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,MAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,MAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,MAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,MAC1C,EAAE,IAAI,WAAW,QAAQ,WAAW,MAAM,KAAA;AAAA;AAAA,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","x_google_ignoreList":[0]}
|