| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | |
| | | <!-- ç鿡件 --> |
| | | <div class="filter-section"> |
| | | <el-select v-model="deviceFilter" placeholder="设å¤ç¶æçé" clearable style="width: 200px; margin-right: 10px;"> |
| | | <el-option label="å
¨é¨" value="all" /> |
| | | <el-option label="è¿è¡ä¸" value="start" /> |
| | | <el-option label="忢è¿è¡" value="stop" /> |
| | | </el-select> |
| | | </div> |
| | | |
| | | <!-- 设å¤å¯åè®°å½è¡¨æ ¼ --> |
| | | <el-card class="table-card"> |
| | | <template #header> |
| | | <span>设å¤è¿è¡è®°å½</span> |
| | | </template> |
| | | <el-table |
| | | :data="filteredDeviceRecords" |
| | | style="width: 100%" |
| | | :header-cell-style="{ background: '#F0F1F5', color: '#333333' }" |
| | | :row-class-name="getRowClassName" |
| | | v-loading="loading" |
| | | > |
| | | <el-table-column |
| | | align="center" |
| | | label="åºå·" |
| | | type="index" |
| | | width="60" |
| | | /> |
| | | <el-table-column |
| | | label="设å¤åç§°" |
| | | prop="deviceName" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="è§æ ¼åå·" |
| | | prop="deviceModel" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="设å¤ç¶æ" |
| | | prop="status" |
| | | width="150" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | <!-- è¶
æ¶æªå¯å¨æ¶æ¾ç¤ºè¦å --> |
| | | <el-tag |
| | | v-if="isOverdue(scope.row)" |
| | | type="warning" |
| | | size="small" |
| | | effect="dark" |
| | | > |
| | | <el-icon><Warning /></el-icon> |
| | | è¶
æ¶æªå¯å¨ |
| | | </el-tag> |
| | | <!-- æ£å¸¸ç¶ææ¶æ¾ç¤ºè®¾å¤ç¶æ --> |
| | | <el-tag |
| | | v-else |
| | | :type="getDeviceStatusType(scope.row.status)" |
| | | size="small" |
| | | > |
| | | <el-icon v-if="scope.row.status === 'è¿è¡ä¸'"><VideoPlay /></el-icon> |
| | | <el-icon v-else><VideoPause /></el-icon> |
| | | {{ scope.row.status || 'æªç¥' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="计åè¿è¡æ¶é´" |
| | | prop="planRuntimeTime" |
| | | width="150" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | {{ scope.row.planRuntimeTime || '-' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="å¼å§è¿è¡æ¶é´" |
| | | prop="startRuntimeTime" |
| | | width="180" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | {{ scope.row.startRuntimeTime || '-' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="ç»æè¿è¡æ¶é´" |
| | | prop="endRuntimeTime" |
| | | width="180" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | {{ scope.row.endRuntimeTime || '-' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="è¿è¡æ¶é¿" |
| | | prop="runtimeDuration" |
| | | width="120" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | {{ scope.row.runtimeDuration || '-' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æä½" |
| | | width="120" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | <!-- è¶
æ¶æªå¯å¨æ¶æ¾ç¤ºå¯å¨æé® --> |
| | | <el-button |
| | | v-if="isOverdue(scope.row)" |
| | | type="warning" |
| | | size="small" |
| | | @click="changeDeviceStatus(scope.row, 'å¯å¨è¿è¡')" |
| | | > |
| | | <el-icon><VideoPlay /></el-icon> |
| | | ç«å³å¯å¨ |
| | | </el-button> |
| | | <!-- æ£å¸¸ç¶ææ¶æ¾ç¤ºå¯¹åºçæä½æé® --> |
| | | <template v-else> |
| | | <el-button |
| | | v-if="scope.row.status === 'è¿è¡ä¸'" |
| | | type="danger" |
| | | size="small" |
| | | @click="changeDeviceStatus(scope.row, '忢è¿è¡')" |
| | | > |
| | | <el-icon><VideoPause /></el-icon> |
| | | 忢è¿è¡ |
| | | </el-button> |
| | | <el-button |
| | | v-else |
| | | type="success" |
| | | size="small" |
| | | @click="changeDeviceStatus(scope.row, 'å¯å¨è¿è¡')" |
| | | > |
| | | <el-icon><VideoPlay /></el-icon> |
| | | å¯å¨è¿è¡ |
| | | </el-button> |
| | | </template> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, computed } from 'vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import { |
| | | VideoPlay, |
| | | VideoPause, |
| | | Warning |
| | | } from '@element-plus/icons-vue' |
| | | import {editLedger, getLedgerPage} from "@/api/equipmentManagement/ledger.js"; |
| | | |
| | | // ååºå¼æ°æ® |
| | | const deviceFilter = ref('all') |
| | | const loading = ref(false) |
| | | const total = ref(0) |
| | | const queryParams = ref({ |
| | | current: -1, |
| | | size: -1 |
| | | }) |
| | | |
| | | // ç§»é¤æ¦è§æ°æ®ï¼å 为ç°å¨ä½¿ç¨è¡¨æ ¼å±ç¤º |
| | | |
| | | // 设å¤å¯åè®°å½æ°æ® |
| | | const deviceRecords = ref([]) |
| | | const allDeviceRecords = ref([]) // å卿æåå§æ°æ® |
| | | |
| | | // æ ¹æ®çéæ¡ä»¶è¿æ»¤æ°æ® |
| | | const filteredDeviceRecords = computed(() => { |
| | | let filtered = allDeviceRecords.value |
| | | |
| | | // æ ¹æ®è®¾å¤ç¶æçé |
| | | if (deviceFilter.value !== 'all') { |
| | | if (deviceFilter.value === 'start') { |
| | | filtered = filtered.filter(device => device.status === 'è¿è¡ä¸') |
| | | } else if (deviceFilter.value === 'stop') { |
| | | filtered = filtered.filter(device => device.status === '忢è¿è¡') |
| | | } |
| | | } |
| | | |
| | | return filtered |
| | | }) |
| | | |
| | | // æ£æ¥è®¾å¤æ¯å¦è¶
æ¶æªå¯å¨ |
| | | const isOverdue = (device) => { |
| | | if (!device.planRuntimeTime || device.status === 'è¿è¡ä¸' || device.startRuntimeTime) { |
| | | return false |
| | | } |
| | | |
| | | const planTime = new Date(device.planRuntimeTime) |
| | | const currentTime = new Date() |
| | | |
| | | return currentTime > planTime |
| | | } |
| | | |
| | | // æ¹æ³ |
| | | const getList = async () => { |
| | | loading.value = true |
| | | try { |
| | | const response = await getLedgerPage(queryParams.value) |
| | | if (response.code === 200) { |
| | | allDeviceRecords.value = response.data.records || [] |
| | | total.value = response.data.total || 0 |
| | | } |
| | | } catch (error) { |
| | | console.error('è·å设å¤å表失败:', error) |
| | | ElMessage.error('è·å设å¤å表失败') |
| | | } finally { |
| | | loading.value = false |
| | | } |
| | | } |
| | | |
| | | const changeDeviceStatus = async (device, status) => { |
| | | try { |
| | | const currentTime = new Date().toLocaleString('zh-CN', { |
| | | year: 'numeric', |
| | | month: '2-digit', |
| | | day: '2-digit', |
| | | hour: '2-digit', |
| | | minute: '2-digit', |
| | | second: '2-digit', |
| | | hour12: false |
| | | }).replace(/\//g, '-') |
| | | |
| | | // æ´æ°è®¾å¤ç¶æåç¸å
³æ¶é´å段 |
| | | if (status === 'å¯å¨è¿è¡') { |
| | | device.status = 'è¿è¡ä¸' |
| | | device.startRuntimeTime = currentTime |
| | | device.endRuntimeTime = null // æ¸
ç©ºç»ææ¶é´ |
| | | device.runtimeDuration = null // æ¸
空è¿è¡æ¶é¿ |
| | | } else { |
| | | device.status = '忢è¿è¡' |
| | | device.endRuntimeTime = currentTime |
| | | // 计ç®è¿è¡æ¶é¿ |
| | | if (device.startRuntimeTime) { |
| | | const startTime = new Date(device.startRuntimeTime) |
| | | const endTime = new Date(currentTime) |
| | | const duration = endTime - startTime |
| | | const hours = Math.floor(duration / (1000 * 60 * 60)) |
| | | const minutes = Math.floor((duration % (1000 * 60 * 60)) / (1000 * 60)) |
| | | device.runtimeDuration = `${hours}å°æ¶${minutes}åé` |
| | | } |
| | | } |
| | | const params = { |
| | | id: device.id, |
| | | status: device.status, |
| | | planRuntimeTime: device.planRuntimeTime, |
| | | startRuntimeTime: device.startRuntimeTime, |
| | | endRuntimeTime: device.endRuntimeTime, |
| | | runtimeDuration: device.runtimeDuration, |
| | | } |
| | | // è°ç¨APIæ´æ°è®¾å¤ç¶æ |
| | | const response = await editLedger(params) |
| | | if (response.code === 200) { |
| | | ElMessage.success(`${device.deviceName} ${status}æå`) |
| | | // å·æ°å表 |
| | | await getList() |
| | | } else { |
| | | ElMessage.error(response.msg || 'æä½å¤±è´¥') |
| | | } |
| | | } catch (error) { |
| | | console.error('æ´æ°è®¾å¤ç¶æå¤±è´¥:', error) |
| | | ElMessage.error('æä½å¤±è´¥') |
| | | } |
| | | } |
| | | |
| | | const getDeviceStatusType = (status) => { |
| | | if (status === 'è¿è¡ä¸') { |
| | | return 'success' |
| | | } else if (status === '忢è¿è¡') { |
| | | return 'danger' |
| | | } else { |
| | | return 'info' |
| | | } |
| | | } |
| | | |
| | | // è·åè¡¨æ ¼è¡çç±»å |
| | | const getRowClassName = ({ row }) => { |
| | | if (isOverdue(row)) { |
| | | return 'overdue-row' |
| | | } |
| | | return '' |
| | | } |
| | | |
| | | |
| | | |
| | | // ç»ä»¶æè½½æ¶åå§åæ°æ® |
| | | onMounted(() => { |
| | | getList() |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .app-container { |
| | | padding: 20px; |
| | | background: #f5f7fa; |
| | | min-height: 100vh; |
| | | } |
| | | |
| | | |
| | | .filter-section { |
| | | margin-bottom: 20px; |
| | | padding: 15px; |
| | | background: #fff; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
| | | display: flex; |
| | | justify-content: flex-start; |
| | | } |
| | | |
| | | .table-card { |
| | | margin-bottom: 20px; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | :deep(.el-card__header) { |
| | | background: #f8f9fa; |
| | | border-bottom: 1px solid #e9ecef; |
| | | font-weight: 500; |
| | | font-size: 16px; |
| | | } |
| | | |
| | | :deep(.el-table .el-table__header-wrapper th) { |
| | | background-color: #F0F1F5 !important; |
| | | color: #333333; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | :deep(.el-table .el-table__body-wrapper td) { |
| | | padding: 12px 0; |
| | | } |
| | | |
| | | :deep(.el-select) { |
| | | width: 100%; |
| | | } |
| | | |
| | | :deep(.el-tag) { |
| | | display: inline-flex; |
| | | align-items: center; |
| | | gap: 4px; |
| | | } |
| | | |
| | | /* è¶
æ¶æªå¯å¨è¡çæ ·å¼ */ |
| | | :deep(.overdue-row) { |
| | | background-color: #fef0f0 !important; |
| | | border-left: 4px solid #f56c6c; |
| | | } |
| | | |
| | | :deep(.overdue-row:hover) { |
| | | background-color: #fde2e2 !important; |
| | | } |
| | | |
| | | :deep(.overdue-row td) { |
| | | background-color: transparent !important; |
| | | } |
| | | </style> |