| | |
| | | <div |
| | | class="cell content-cell" |
| | | :class="[cell.type, `status-${cell.meeting?.status || '0'}`]" |
| | | :style="{ flex: cell.span-0.2 }" |
| | | :style="{ flex: cell.span }" |
| | | @click="viewMeetingDetails(cell)" |
| | | > |
| | | <div v-if="cell.type === 'meeting'" class="meeting-content"> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref, reactive, onMounted} from 'vue' |
| | | import {ref, reactive, onMounted, onActivated} from 'vue' |
| | | import {ElMessage} from 'element-plus' |
| | | import {getMeetingUseList} from "@/api/collaborativeApproval/meeting.js" |
| | | import dayjs from "dayjs"; |
| | |
| | | // 是否显示详情对话框 |
| | | const detailDialogVisible = ref(false) |
| | | |
| | | // 初始化时间槽(以半小时为间隔,从8:00到18:00) |
| | | // 初始化时间槽(以半小时为间隔,从8:00到19:00) |
| | | const initTimeSlots = () => { |
| | | const slots = [] |
| | | for (let hour = 8; hour < 18; hour++) { |
| | | for (let hour = 8; hour < 19; hour++) { |
| | | // 每个小时添加两个时间段:整点和半点 |
| | | slots.push({ |
| | | label: `${hour.toString().padStart(2, '0')}:00`, |
| | | value: `${hour.toString().padStart(2, '0')}:00` |
| | | }) |
| | | |
| | | if (hour < 18) { // 到17:30为止 |
| | | if (hour < 19) { // 到18:30为止 |
| | | slots.push({ |
| | | label: `${hour.toString().padStart(2, '0')}:30`, |
| | | value: `${hour.toString().padStart(2, '0')}:30` |
| | |
| | | timeSlots.value = slots |
| | | } |
| | | |
| | | const toMinutes = (time) => { |
| | | if (!time) return 0 |
| | | const [h, m] = time.split(':').map(Number) |
| | | return h * 60 + m |
| | | } |
| | | |
| | | // 生成会议室的时间单元格 |
| | | const generateMeetingCells = (room) => { |
| | | const cells = [] |
| | | const meetings = room.meetings || [] |
| | | const occupiedSlots = new Set() |
| | | |
| | | // 处理每个会议 |
| | | for (const meeting of meetings) { |
| | | const startMin = toMinutes(meeting.startTime) |
| | | const endMin = toMinutes(meeting.endTime) |
| | | |
| | | const startIdx = timeSlots.value.findIndex(slot => slot.value === meeting.startTime) |
| | | let endIdx = timeSlots.value.findIndex(slot => slot.value === meeting.endTime) |
| | | if (endIdx === -1) { |
| | | endIdx = timeSlots.value.length |
| | | } |
| | | console.log('endIdx111', endIdx) |
| | | if (startIdx !== -1 && endIdx !== -1) { |
| | | // 标记被占用的时间段 |
| | | // 找到第一个时间 > startMin 的槽位,再往前退一格 |
| | | let startIdx = timeSlots.value.findIndex(slot => toMinutes(slot.value) > startMin) |
| | | if (startIdx === -1) startIdx = timeSlots.value.length |
| | | startIdx = Math.max(0, startIdx - 1) |
| | | |
| | | // 找到第一个时间 >= endMin 的槽位,没找到则延伸到末尾 |
| | | let endIdx = timeSlots.value.findIndex(slot => toMinutes(slot.value) >= endMin) |
| | | if (endIdx === -1) endIdx = timeSlots.value.length |
| | | |
| | | if (startIdx < endIdx) { |
| | | for (let i = startIdx; i < endIdx; i++) { |
| | | occupiedSlots.add(timeSlots.value[i].value) |
| | | } |
| | | |
| | | // 创建会议单元格 |
| | | cells.push({ |
| | | type: 'meeting', |
| | | meeting: meeting, |
| | |
| | | } |
| | | } |
| | | |
| | | // 处理空闲时间段 |
| | | for (let i = 0; i < timeSlots.value.length; i++) { |
| | | const slot = timeSlots.value[i] |
| | | if (!occupiedSlots.has(slot.value)) { |
| | | // 查找连续的空闲时间段 |
| | | let span = 1 |
| | | while (i + span < timeSlots.value.length && |
| | | !occupiedSlots.has(timeSlots.value[i + span].value)) { |
| | |
| | | } |
| | | } |
| | | |
| | | // 按时间排序 |
| | | cells.sort((a, b) => { |
| | | const timeA = a.startTime || a.time |
| | | const timeB = b.startTime || b.time |
| | | return timeSlots.value.findIndex(s => s.value === timeA) - |
| | | timeSlots.value.findIndex(s => s.value === timeB) |
| | | return toMinutes(timeA) - toMinutes(timeB) |
| | | }) |
| | | console.log('cells', cells) |
| | | return cells |
| | | } |
| | | |
| | |
| | | |
| | | // 页面加载时获取数据 |
| | | onMounted(() => { |
| | | // 初始化时间槽 |
| | | initTimeSlots() |
| | | }) |
| | | |
| | | // 默认查询今天的数据 |
| | | const today = new Date() |
| | | queryForm.date = today.toISOString().split('T')[0] |
| | | onActivated(() => { |
| | | handleSearch() |
| | | }) |
| | | </script> |