| | |
| | | <template> |
| | | <div class="calenBox"> |
| | | <el-calendar ref="calendar" v-model="leftValue"> |
| | | <el-calendar ref="calendar" v-model="currentMonth"> |
| | | <template #header="{ date }"> |
| | | <div> |
| | | <img :src="caleft" alt="" @click="selectDate('prev-month')" /> |
| | | <span>{{ date }}</span> |
| | | <el-date-picker |
| | | v-model="currentMonth" |
| | | type="month" |
| | | :clearable="false" |
| | | :prefix-icon="''" |
| | | @change="handleMonthChange" |
| | | /> |
| | | <img :src="caright" alt="" @click="selectDate('next-month')" /> |
| | | </div> |
| | | </template> |
| | |
| | | |
| | | <script setup> |
| | | import dayjs from 'dayjs'; |
| | | import { jobEventBar, getCalen } from '@/api/home/index'; |
| | | import { ref, watch, onMounted, nextTick } from 'vue'; |
| | | import { getCalen } from '@/api/home/index'; |
| | | import { useRouter } from 'vue-router'; |
| | | import ev1 from '@/assets/images/workbench/ev1.svg'; |
| | | import ev2 from '@/assets/images/workbench/ev2.svg'; |
| | | import caleft from '@/assets/images/workbench/caleft.png'; |
| | | import caright from '@/assets/images/workbench/caright.png'; |
| | | import { ElMessage } from 'element-plus'; |
| | | const calendar = ref(); |
| | | |
| | | const router = useRouter(); |
| | | const calendar = ref(); |
| | | const events = ref({}); |
| | | const currentMonth = ref(new Date()); // 控制当前显示的月份 |
| | | const selectedDate = ref(null); // 控制选中的日期 |
| | | const params = ref({ |
| | | end_date: undefined, |
| | | start_date: undefined, |
| | | }); |
| | | const isCurrentMonth = (date) => { |
| | | return dayjs(date).isSame(dayjs(), 'month'); |
| | | }; |
| | | const leftValue = ref(null); |
| | | |
| | | const eventIcons = ref({ |
| | | 'work-order': ev1, |
| | | task: ev2, |
| | | }); |
| | | const getEventIcon = type => { |
| | | return eventIcons.value[type] || eventIcons.value.default; |
| | | // 检查日期是否是当前月份 |
| | | const isCurrentMonth = date => { |
| | | return dayjs(date).isSame(dayjs(), 'month'); |
| | | }; |
| | | function getCurrentMonthRange() { |
| | | return { |
| | | start_date: dayjs().startOf('month').format('YYYY-MM-DD HH:mm:ss'), |
| | | end_date: dayjs().endOf('month').format('YYYY-MM-DD HH:mm:ss'), |
| | | }; |
| | | } |
| | | const selectDate = val => { |
| | | if (!calendar.value) return; |
| | | calendar.value.selectDate(val); |
| | | // 处理月份选择器变化 |
| | | const handleMonthChange = val => { |
| | | const selectedDate = new Date(val); |
| | | const now = new Date(); |
| | | |
| | | // 如果是当前月份,则选中当天;否则不选中 |
| | | if ( |
| | | selectedDate.getFullYear() === now.getFullYear() && |
| | | selectedDate.getMonth() === now.getMonth() |
| | | ) { |
| | | currentMonth.value = selectedDate; |
| | | } else { |
| | | currentMonth.value = selectedDate; |
| | | // 清除选中状态 |
| | | nextTick(() => { |
| | | const selectedCells = document.querySelectorAll('.el-calendar-table td.is-selected'); |
| | | selectedCells.forEach(cell => { |
| | | cell.classList.remove('is-selected'); |
| | | }); |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | // watch( |
| | | // () => leftValue.value, |
| | | // (newV, oldV) => { |
| | | // if (newV && oldV) { |
| | | // const newDate = dayjs(newV); |
| | | // params.value = { |
| | | // start_date: newDate.startOf('month').format('YYYY-MM-DD HH:mm:ss'), |
| | | // end_date: newDate.endOf('month').format('YYYY-MM-DD HH:mm:ss'), |
| | | // }; |
| | | // getJobEventBar(); |
| | | // } |
| | | // }, |
| | | // { deep: true, immediate: true } |
| | | // ); |
| | | watch( |
| | | () => leftValue.value, |
| | | (newV, oldV) => { |
| | | if (newV) { |
| | | const newDate = dayjs(newV); |
| | | params.value = { |
| | | start_date: newDate.startOf('month').format('YYYY-MM-DD HH:mm:ss'), |
| | | end_date: newDate.endOf('month').format('YYYY-MM-DD HH:mm:ss'), |
| | | }; |
| | | |
| | | // 新增:如果是当前月份,自动选中当天 |
| | | if (isCurrentMonth(newV)) { |
| | | nextTick(() => { |
| | | if (calendar.value) { |
| | | calendar.value.selectDate(new Date()); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | getJobEventBar(); |
| | | } |
| | | }, |
| | | { deep: true, immediate: true } |
| | | ); |
| | | // 获取日期数字 |
| | | const getDate = date => { |
| | | return date.getDate(); |
| | | }; |
| | | |
| | | // 获取对应日期的事件 |
| | | const getEvents = dateString => { |
| | | return events.value[dateString] || []; |
| | | }; |
| | | const monthRange = getCurrentMonthRange(); |
| | | params.value = monthRange; |
| | | |
| | | // 获取日历数据 |
| | | const getJobEventBar = () => { |
| | | getCalen(params.value).then(res => { |
| | | if (res.data.code !== 0) return; |
| | |
| | | filteredData[date] = a[date].filter(item => item.type !== 'work-order'); |
| | | } |
| | | events.value = filteredData; |
| | | // events.value = res.data.data |
| | | }); |
| | | }; |
| | | |
| | | // 获取事件图标 |
| | | const getEventIcon = type => { |
| | | return eventIcons.value[type] || eventIcons.value.default; |
| | | }; |
| | | |
| | | // 获取当前月份范围 |
| | | function getCurrentMonthRange() { |
| | | return { |
| | | start_date: dayjs().startOf('month').format('YYYY-MM-DD HH:mm:ss'), |
| | | end_date: dayjs().endOf('month').format('YYYY-MM-DD HH:mm:ss'), |
| | | }; |
| | | } |
| | | |
| | | // 月份切换处理 |
| | | const selectDate = async val => { |
| | | if (!calendar.value) return; |
| | | |
| | | if (val === 'prev-month') { |
| | | currentMonth.value = dayjs(currentMonth.value).subtract(1, 'month').toDate(); |
| | | } else if (val === 'next-month') { |
| | | currentMonth.value = dayjs(currentMonth.value).add(1, 'month').toDate(); |
| | | } |
| | | |
| | | // 等待DOM更新 |
| | | await nextTick(); |
| | | |
| | | // 强制清除所有选中状态 |
| | | const selectedCells = document.querySelectorAll('.el-calendar-table td.is-selected'); |
| | | selectedCells.forEach(cell => { |
| | | cell.classList.remove('is-selected'); |
| | | }); |
| | | |
| | | // 如果是当前月份才设置选中 |
| | | if (isCurrentMonth(currentMonth.value)) { |
| | | selectedDate.value = new Date(); |
| | | } |
| | | }; |
| | | |
| | | // 监听当前月份变化 |
| | | watch( |
| | | () => currentMonth.value, |
| | | newMonth => { |
| | | const newDate = dayjs(newMonth); |
| | | params.value = { |
| | | start_date: newDate.startOf('month').format('YYYY-MM-DD HH:mm:ss'), |
| | | end_date: newDate.endOf('month').format('YYYY-MM-DD HH:mm:ss'), |
| | | }; |
| | | |
| | | // 如果是当前月份,则选中当天;否则清除选中 |
| | | if (isCurrentMonth(newMonth)) { |
| | | selectedDate.value = new Date(); |
| | | } else { |
| | | selectedDate.value = null; |
| | | } |
| | | |
| | | getJobEventBar(); |
| | | }, |
| | | { deep: true, immediate: true } |
| | | ); |
| | | |
| | | // 获取日期数字 |
| | | const getDate = date => { |
| | | return date.getDate(); |
| | | }; |
| | | |
| | | // 获取对应日期的事件 |
| | | const getEvents = dateString => { |
| | | return events.value[dateString] || []; |
| | | }; |
| | | |
| | | // 初始化月份范围 |
| | | const monthRange = getCurrentMonthRange(); |
| | | params.value = monthRange; |
| | | |
| | | const jumpcalendar = (event, day) => { |
| | | if (event.name === '工单') { |
| | | router.push({ |
| | |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | // 新增:挂载时如果是当前月份,设置默认选中 |
| | | if (isCurrentMonth(leftValue.value)) { |
| | | leftValue.value = new Date(); |
| | | // 初始化时如果是当前月份,选中当天;否则不选中 |
| | | if (isCurrentMonth(currentMonth.value)) { |
| | | selectedDate.value = new Date(); |
| | | } else { |
| | | selectedDate.value = null; |
| | | } |
| | | getJobEventBar(); |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .calenBox { |
| | | height: pxToVh(660); |
| | |
| | | } |
| | | .el-calendar__header { |
| | | justify-content: center; |
| | | margin-top: 18px; |
| | | margin-top: 10px; |
| | | padding-bottom: 0; |
| | | border-bottom: transparent; |
| | | div { |
| | |
| | | } |
| | | .el-calendar-table .el-calendar-day { |
| | | box-sizing: border-box; |
| | | |
| | | padding: 0.8rem; |
| | | background: #f5f7fa; |
| | | border-radius: 6px 6px 6px 6px; |
| | |
| | | margin-right: 5px; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | // 非选中日期的样式 |
| | | .el-calendar-table td:not(.is-selected) { |
| | | .el-calendar-day { |
| | | background: #f5f7fa; |
| | | border: 1px solid #efefef; |
| | | |
| | | .date-number { |
| | | font-weight: normal; |
| | | color: inherit; |
| | | } |
| | | } |
| | | } |
| | | .el-input__prefix-inner { |
| | | display: none !important; |
| | | } |
| | | .el-input__suffix { |
| | | width: 0 !important; |
| | | } |
| | | .el-input__wrapper { |
| | | align-items: center !important; |
| | | cursor: text; |
| | | box-shadow: none !important; |
| | | display: inline-flex !important; |
| | | flex-grow: 1; |
| | | justify-content: center; |
| | | } |
| | | .el-input__inner { |
| | | font-weight: bold; |
| | | font-size: 14px; |
| | | color: #363636; |
| | | } |
| | | .el-date-editor.el-input, |
| | | .el-date-editor.el-input__wrapper { |
| | | height: var(--el-input-height, var(--el-component-size)); |
| | | |
| | | width: 150px !important; |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | <style lang="scss" scoped> |
| | | .calenBox { |
| | | margin-top: 10px; |
| | | // height: 630px; |
| | | height: pxToVh(622); |
| | | border-radius: 10px; |
| | | overflow: hidden; |
| | | background-color: #fff; |
| | | |
| | | :deep(.el-date-picker .el-input__prefix-inner) { |
| | | display: none !important; |
| | | } |
| | | ::v-deep(.el-calendar) { |
| | | // 标题样式 |
| | | .el-calendar__title { |
| | |
| | | color: #363636; |
| | | } |
| | | .el-calendar-table .el-calendar-day { |
| | | height: pxToVh(88) !important; |
| | | height: pxToVh(85) !important; |
| | | } |
| | | |
| | | // 选中日期样式 |
| | | .el-calendar-table td.is-selected { |
| | | .el-calendar-day { |
| | | outline: 2px solid #409eff; |
| | | outline-offset: -2px; |
| | | border: none !important; |
| | | .date-number { |
| | | font-weight: bold; |
| | | color: #409eff; |
| | | .el-calendar-day { |
| | | outline: 2px solid #409eff; |
| | | outline-offset: -2px; |
| | | border: none !important; |
| | | .date-number { |
| | | font-weight: bold; |
| | | color: #409eff; |
| | | } |
| | | } |
| | | }} |
| | | } |
| | | .el-calendar-table td.is-selected { |
| | | background-color: transparent; |
| | | } |
| | | |
| | | } |
| | | |
| | | .event-item { |
| | |
| | | text-align: center; |
| | | border-radius: 3px; |
| | | white-space: nowrap; |
| | | position: relative; |
| | | z-index: 2; |
| | | |
| | | &.work-order { |
| | | font-weight: 400; |