| 
					
				 | 
			
			
				@@ -1,6 +1,5 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   <div class="app-container"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <!-- 搜索栏 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       <el-form-item label="状态" prop="status"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         <el-radio-group v-model="queryParams.status"> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -46,320 +45,219 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       </el-form-item> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     </el-form> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <!-- 状态筛选 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <div class="status-filter"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <el-tag type="success" size="small">可用</el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <el-tag type="warning" size="small">占用</el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <el-tag type="info" size="small">禁用</el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <!-- 会议室列表 --> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    <div class="meeting-list"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      <div v-for="meeting in waringList" :key="meeting.id" class="meeting-card"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <div class="card-header"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <img :src="getImageUrl(meeting.images)" alt="会议室图片" class="meeting-image"/> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <div class="meeting-info"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <h3>{{ meeting.name }}</h3> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              {{ meeting.seats === 0 ? '无限制' : meeting.seats }}人 | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              {{ meeting.room_type_name[0] }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <div v-if="meeting.device_name_arr.length > 0"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <el-tag v-for="device in meeting.device_name_arr" :key="device" size="small">{{ device }}</el-tag> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <div v-else>暂无设备信息</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <p></p> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <div v-if="meeting.usage && meeting.usage.appointTime && meeting.usage.appointTime.length > 0"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              已预订时间段: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <span v-for="(appointment, index) in [...meeting.usage.appointTime].reverse()"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  {{ appointment.start_time }} - {{ appointment.end_time }}<span v-if="index < meeting.usage.appointTime.length - 1"> | </span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              </span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <div v-else> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              <span>暂无预订时间段</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <!--          <el-button type="primary" size="small" @click="handleReserve(meeting)">预定</el-button>--> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        <div class="time-slots"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          <div class="slot-container"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            <div v-for="(slot, index) in timeSlots" :key="index" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 :class="['slot', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  current: isCurrent(slot), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  booked: isBookedBetween(meeting, slot, timeSlots[index+1]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                }]"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              {{ slot }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    <el-row :gutter="10" class="mb8"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    </el-row> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    <el-table v-loading="loading" :data="waringList" @selection-change="handleSelectionChange"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <el-table-column label="会议名称" align="center" prop="name" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <el-table-column label="会议类型" align="center" prop="room_type_name" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <el-table-column label="容纳人数" align="center" prop="seats"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <span>{{ scope.row.seats === 0 ? '无限制' : scope.row.seats }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <el-table-column label="预定时间段" align="center"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <div v-if="scope.row.usage.appointTime.length > 0"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <span v-for="(time, index) in scope.row.usage.appointTime" :key="index"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          {{ time.start_time }} - {{ time.end_time }} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <br v-if="index < scope.row.usage.appointTime.length - 1" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <span v-else>无预定</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <el-table-column label="设备" align="center" prop="device_names" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      <el-table-column label="创建时间" align="center" prop="created_at" width="180"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        <template #default="scope"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          <span>{{ parseTime(scope.row.created_at, '{y}-{m}-{d} {h}:{i}') }}</span> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      </el-table-column> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    </el-table> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    <pagination 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        v-show="total>0" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        :total="total" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        v-model:page="queryParams.pageNum" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        v-model:limit="queryParams.pageSize" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        @pagination="getList" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   </div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 </template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <script setup name="Waring"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import {listMeeting} from "@/api/meeting/meeting"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import {ElMessage} from "element-plus"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import {ref, reactive, toRefs, onMounted, nextTick} from 'vue'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { listMeeting } from "@/api/meeting/meeting"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { ElMessage } from "element-plus"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const { proxy } = getCurrentInstance(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const {alarm_level} = proxy.useDict('alarm_level'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const waringList = ref([]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const open = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const loading = ref(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const showSearch = ref(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const ids = ref([]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const single = ref(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const multiple = ref(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const total = ref(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const url_str = ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const title = ref(""); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 获取当前时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const currentTime = getCurrentHour(); // 当前整点时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const data = reactive({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   form: {}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   queryParams: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     pageNum: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pageSize: 10000, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pageSize: 10, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     status: '', // 默认选中"全部" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     date: new Date().toISOString().split('T')[0], // 格式化为YYYY-MM-DD 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     appoint_time: "", // 重置为空 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     start_time: "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     end_time: "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    interfaceName:"会议", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    interfaceName:"会议预订", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     search: '' // 搜索文本默认为空 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  timeSlots: generateTimeSlots(), // 动态生成时间轴 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-const {queryParams, timeSlots} = toRefs(data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 动态生成时间轴,从 00:00 到 23:00 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function generateTimeSlots() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const slots = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (let i = 0; i <= 23; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    slots.push(`${i.toString().padStart(2, '0')}:00`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const { queryParams, form, rules } = toRefs(data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+watch(() => queryParams.value.status, (newStatus) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if(newStatus === "1") { // 当前可用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    queryParams.value.appoint_time = getCurrentTimeRange(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else if(newStatus === "2") { // 一小时后可用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    queryParams.value.appoint_time = getCurrentTimeRange(1, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    queryParams.value.appoint_time = ""; // 选择"全部"时清空 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return slots; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 获取当前整点时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function getCurrentHour() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const now = new Date(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const hour = now.getHours(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return `${hour.toString().padStart(2, '0')}:00`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 获取会议室列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function getList() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  loading.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  listMeeting(queryParams.value).then(response => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    console.log(response); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    waringList.value = response.data.list; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    total.value = response.data.total; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    loading.value = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 更新预约时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function updateAppointTime() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (queryParams.value.start_time && queryParams.value.end_time) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if(queryParams.value.start_time && queryParams.value.end_time) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     queryParams.value.appoint_time = `${queryParams.value.start_time}~${queryParams.value.end_time}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 查询设备告警列表 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const getList = async () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    loading.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    listMeeting(queryParams.value).then(response => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      waringList.value = response.data.list; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      total.value = response.data.total; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      loading.value = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    console.error('获取数据失败:', error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    loading.value = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 判断某个时间段区间是否被预订 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function isBookedBetween(meeting, startTime, endTime) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (!endTime) endTime = '24:00'; // 处理最后一个时间段 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const appointments = meeting.usage?.appointTime || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return appointments.some(appointment => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        (appointment.start_time < endTime) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        (appointment.end_time > startTime) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 表单重置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function reset() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  form.value = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    status: '', // 默认选中"全部" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    date: new Date(), // 默认当天 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    appoint_time: '', // 时间默认为空 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    search: '' // 搜索文本默认为空 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  proxy.resetForm("waringRef"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function getCurrentTimeRange(hoursLater = 0, fullHour = false) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const now = new Date(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  now.setHours(now.getHours() + hoursLater); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const startHours = now.getHours().toString().padStart(2, '0'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const startMinutes = now.getMinutes().toString().padStart(2, '0'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  let endHours, endMinutes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if(fullHour) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 计算一小时后的时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const endTime = new Date(now.getTime() + 60 * 60 * 1000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    endHours = endTime.getHours().toString().padStart(2, '0'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    endMinutes = endTime.getMinutes().toString().padStart(2, '0'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 只增加一分钟 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    endHours = startHours; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    endMinutes = (now.getMinutes() + 1).toString().padStart(2, '0'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 搜索按钮操作 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return `${startHours}:${startMinutes}~${endHours}:${endMinutes}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 搜索按钮操作 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function handleQuery() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   queryParams.value.pageNum = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 重置按钮操作 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 重置按钮操作 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 function resetQuery() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  queryParams.value = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pageNum: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pageSize: 10000, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    status: '', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    date: new Date().toISOString().split('T')[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    appoint_time: "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    interfaceName:"会议", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    start_time: "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    end_time: "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    search: '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  proxy.resetForm("queryRef"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   handleQuery(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 判断某个时间段是否被预订 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function isBooked(meeting, timeSlot) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const appointments = meeting.usage?.appointTime || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return appointments.some(appointment => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return appointment.start_time <= timeSlot && appointment.end_time >= timeSlot; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 多选框选中数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function handleSelectionChange(selection) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ids.value = selection.map(item => item.id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  single.value = selection.length != 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  multiple.value = !selection.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 判断是否是当前时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function isCurrent(timeSlot) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return timeSlot === currentTime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 新增按钮操作 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function handleAdd() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  reset(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  open.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  title.value = "添加设备告警"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 预定按钮操作 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function handleReserve(meeting) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  proxy.$modal.confirm('是否确认预定会议室 "' + meeting.name + '"?').then(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 这里可以添加预定逻辑 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ElMessage.success('预定成功'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }).catch(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 修改按钮操作 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function handleUpdate(row) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  reset(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const _id = row.id || ids.value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  getWaring(_id).then(response => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    form.value = response.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    open.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    title.value = "修改设备告警"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 处理图片URL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function getImageUrl(url) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (!url || url.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return 'http://183.129.224.253:9998/assets/defRoomIng.3e28e55b.png'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return `http://183.129.224.253:9998${url}`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-onMounted(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const checkReady = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (waringList.value.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // 添加双重延迟确保DOM完全渲染 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      setTimeout(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        scrollToCurrentTime(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 二次检查确保滚动执行 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        //setTimeout(scrollToCurrentTime, 300); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      }, 100); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      setTimeout(checkReady, 200); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  checkReady(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 滚动到当前时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function scrollToCurrentTime() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  const currentSlots = document.querySelectorAll('.slot.current'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  currentSlots.forEach(slot => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const container = slot.closest('.time-slots'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (container) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const slotRect = slot.getBoundingClientRect(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const containerRect = container.getBoundingClientRect(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      container.scrollLeft = slotRect.left - containerRect.left;// - (container.clientWidth) + (slotRect.width); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 提交按钮 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function submitForm() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  proxy.$refs["waringRef"].validate(valid => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (valid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (form.value.id != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        updateWaring(form.value).then(response => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          proxy.$modal.msgSuccess("修改成功"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          open.value = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        addWaring(form.value).then(response => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          proxy.$modal.msgSuccess("新增成功"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          open.value = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-</script> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-<style scoped> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.time-slots { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  overflow-x: auto; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  width: 100%; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  max-width: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-top: 10px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.slot-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  display: inline-flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /* min-width: calc(64px * 24 + 4px * 23);  24个时间槽+间隙 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  padding: 5px 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gap: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.app-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  padding: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.status-filter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-bottom: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.meeting-list { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  display: grid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grid-template-columns: repeat(auto-fill, minmax(500px, 1fr)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gap: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-@media (max-width: 768px) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  .meeting-list { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    grid-template-columns: 1fr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.meeting-card { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  border-radius: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  padding: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.card-header { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  justify-content: space-between; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  align-items: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-bottom: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 删除按钮操作 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function handleDelete(row) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const _ids = row.id || ids.value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  proxy.$modal.confirm('是否确认删除设备告警编号为"' + _ids + '"的数据项?').then(function() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return delWaring(_ids); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }).then(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    proxy.$modal.msgSuccess("删除成功"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }).catch(() => {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.meeting-image { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  width: 100px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  height: 100px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  object-fit: cover; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  border-radius: 8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 导出按钮操作 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function handleExport() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  proxy.download('waring/waring/export', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ...queryParams.value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }, `waring_${new Date().getTime()}.xlsx`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.meeting-info { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  flex: 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-left: 16px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.time-slots { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  overflow-x: auto; /* 添加水平滚动条 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  white-space: nowrap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  margin-top: 10px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  @media (max-width: 768px) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    max-width: 300px; /* 小屏幕宽度 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  @media (min-width: 769px) and (max-width: 1024px) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    max-width: 400px; /* 中等屏幕宽度 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  @media (min-width: 1025px) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    max-width: 900px; /* 大屏幕宽度 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.slot-container { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  display: inline-flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gap: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.slot { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  width: 60px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  height: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #f0f0f0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  text-align: center; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  line-height: 20px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  border-radius: 4px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  cursor: pointer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.slot.current { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #409EFF; /* 当前时间高亮 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  color: #fff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-.slot.booked { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  background-color: #ff9900; /* 占用状态 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-</style> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+getList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+</script> 
			 |