|
@@ -0,0 +1,571 @@
|
|
|
+<template>
|
|
|
+ <div class="app-container">
|
|
|
+ <el-form :model="queryParams" ref="queryRef" :inline="true" label-width="80px">
|
|
|
+ <el-form-item label="告警级别" prop="alarmLevel">
|
|
|
+ <el-select v-model="queryParams.alarmLevel" placeholder="请选择告警级别" clearable style="width: 150px">
|
|
|
+ <el-option label="低" :value="1" />
|
|
|
+ <el-option label="中" :value="2" />
|
|
|
+ <el-option label="高" :value="3" />
|
|
|
+ <el-option label="紧急" :value="4" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="设备类型" prop="deviceType">
|
|
|
+ <el-select v-model="queryParams.deviceType" placeholder="请选择设备类型" clearable style="width: 150px">
|
|
|
+ <el-option label="空调" value="空调" />
|
|
|
+ <el-option label="新风" value="新风" />
|
|
|
+ <el-option label="电梯" value="电梯" />
|
|
|
+ <el-option label="配电" value="配电" />
|
|
|
+ <el-option label="照明" value="照明" />
|
|
|
+ <el-option label="水泵" value="水泵" />
|
|
|
+ <el-option label="冷源" value="冷源" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="空间位置" prop="spaceLocation">
|
|
|
+ <el-cascader
|
|
|
+ v-model="queryParams.spaceLocation"
|
|
|
+ :options="spaceOptions"
|
|
|
+ :props="{ expandTrigger: 'hover', value: 'label', label: 'label' }"
|
|
|
+ placeholder="请选择空间位置"
|
|
|
+ clearable
|
|
|
+ style="width: 200px"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="复位状态" prop="isReset">
|
|
|
+ <el-select v-model="queryParams.isReset" placeholder="请选择复位状态" clearable style="width: 150px">
|
|
|
+ <el-option label="未复位" :value="0" />
|
|
|
+ <el-option label="已复位" :value="1" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="告警时间" prop="timeRange">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="queryParams.timeRange"
|
|
|
+ type="datetimerange"
|
|
|
+ range-separator="至"
|
|
|
+ start-placeholder="开始时间"
|
|
|
+ end-placeholder="结束时间"
|
|
|
+ format="YYYY-MM-DD HH:mm:ss"
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button type="primary" icon="Search" @click="getList">搜索</el-button>
|
|
|
+ <el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+<!-- <el-row :gutter="10" class="mb8">-->
|
|
|
+<!-- <el-col :span="1.5">-->
|
|
|
+<!-- <el-button-->
|
|
|
+<!-- type="warning"-->
|
|
|
+<!-- plain-->
|
|
|
+<!-- icon="Download"-->
|
|
|
+<!-- @click="handleExport"-->
|
|
|
+<!-- v-hasPermi="['device:alarm:export']"-->
|
|
|
+<!-- >导出</el-button>-->
|
|
|
+<!-- </el-col>-->
|
|
|
+<!-- </el-row>-->
|
|
|
+
|
|
|
+ <!-- 告警统计卡片 -->
|
|
|
+ <el-row :gutter="20" class="mb20">
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-card class="stat-card">
|
|
|
+ <div class="stat-item">
|
|
|
+ <div class="stat-title">总告警数</div>
|
|
|
+ <div class="stat-value total">{{ alarmStats.total }}</div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-card class="stat-card">
|
|
|
+ <div class="stat-item">
|
|
|
+ <div class="stat-title">未复位</div>
|
|
|
+ <div class="stat-value unreset">{{ alarmStats.unreset }}</div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-card class="stat-card">
|
|
|
+ <div class="stat-item">
|
|
|
+ <div class="stat-title">高级别告警</div>
|
|
|
+ <div class="stat-value high">{{ alarmStats.highLevel }}</div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-card class="stat-card">
|
|
|
+ <div class="stat-item">
|
|
|
+ <div class="stat-title">今日新增</div>
|
|
|
+ <div class="stat-value today">{{ alarmStats.today }}</div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-table v-loading="loading" :data="alarmList" stripe border @selection-change="handleSelectionChange">
|
|
|
+ <el-table-column type="selection" width="55" align="center" />
|
|
|
+ <el-table-column label="告警编码" prop="alarmCode" width="150" />
|
|
|
+ <el-table-column label="设备信息" width="200">
|
|
|
+ <template #default="scope">
|
|
|
+ <div>{{ scope.row.deviceName }}</div>
|
|
|
+ <div class="text-small">{{ scope.row.deviceCode }}</div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="告警级别" prop="alarmLevel" width="100" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-tag :type="alarmLevelType(scope.row.alarmLevel)" effect="dark">
|
|
|
+ {{ alarmLevelText(scope.row.alarmLevel) }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="告警类型" prop="alarmType" width="120" />
|
|
|
+ <el-table-column label="告警描述" prop="alarmDesc" min-width="200" show-overflow-tooltip />
|
|
|
+ <el-table-column label="空间位置" prop="spaceLocation" width="180" show-overflow-tooltip />
|
|
|
+ <el-table-column label="告警时间" prop="alarmTime" width="160">
|
|
|
+ <template #default="scope">
|
|
|
+ <span>{{ parseTime(scope.row.alarmTime) }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="复位状态" prop="isReset" width="100" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-tag :type="scope.row.isReset === 1 ? 'success' : 'danger'">
|
|
|
+ {{ scope.row.isReset === 1 ? '已复位' : '未复位' }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="处理状态" prop="handleStatus" width="100" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-tag :type="handleStatusType(scope.row.handleStatus)">
|
|
|
+ {{ handleStatusText(scope.row.handleStatus) }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="200" fixed="right">
|
|
|
+ <template #default="scope">
|
|
|
+ <el-button
|
|
|
+ v-if="scope.row.isReset === 0"
|
|
|
+ link
|
|
|
+ type="primary"
|
|
|
+ icon="Refresh"
|
|
|
+ @click="handleReset(scope.row)"
|
|
|
+ v-hasPermi="['device:alarm:reset']"
|
|
|
+ >复位</el-button>
|
|
|
+ <el-button
|
|
|
+ v-if="!scope.row.serviceOrderNo"
|
|
|
+ link
|
|
|
+ type="primary"
|
|
|
+ icon="Document"
|
|
|
+ @click="handleCreateOrder(scope.row)"
|
|
|
+ v-hasPermi="['device:alarm:createOrder']"
|
|
|
+ >创建服务单</el-button>
|
|
|
+ <el-button link type="primary" icon="View" @click="handleDetail(scope.row)">详情</el-button>
|
|
|
+ </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"
|
|
|
+ />
|
|
|
+
|
|
|
+ <!-- 告警详情抽屉 -->
|
|
|
+ <el-drawer
|
|
|
+ v-model="detailVisible"
|
|
|
+ title="告警详情"
|
|
|
+ direction="rtl"
|
|
|
+ size="45%"
|
|
|
+ >
|
|
|
+ <el-descriptions :column="2" border>
|
|
|
+ <el-descriptions-item label="告警编码">{{ currentAlarm.alarmCode }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="告警级别">
|
|
|
+ <el-tag :type="alarmLevelType(currentAlarm.alarmLevel)" effect="dark">
|
|
|
+ {{ alarmLevelText(currentAlarm.alarmLevel) }}
|
|
|
+ </el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="设备编码">{{ currentAlarm.deviceCode }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="设备名称">{{ currentAlarm.deviceName }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="设备类型">{{ currentAlarm.deviceType }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="子系统类型">{{ currentAlarm.subsystemType }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="告警类型">{{ currentAlarm.alarmType }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="空间位置">{{ currentAlarm.spaceLocation }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="告警描述" :span="2">{{ currentAlarm.alarmDesc }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="告警时间">{{ parseTime(currentAlarm.alarmTime) }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="复位状态">
|
|
|
+ <el-tag :type="currentAlarm.isReset === 1 ? 'success' : 'danger'">
|
|
|
+ {{ currentAlarm.isReset === 1 ? '已复位' : '未复位' }}
|
|
|
+ </el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="复位时间" v-if="currentAlarm.isReset === 1">
|
|
|
+ {{ parseTime(currentAlarm.resetTime) }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="复位人" v-if="currentAlarm.isReset === 1">
|
|
|
+ {{ currentAlarm.resetBy }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="服务单号" v-if="currentAlarm.serviceOrderNo">
|
|
|
+ {{ currentAlarm.serviceOrderNo }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="处理状态">
|
|
|
+ <el-tag :type="handleStatusType(currentAlarm.handleStatus)">
|
|
|
+ {{ handleStatusText(currentAlarm.handleStatus) }}
|
|
|
+ </el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+
|
|
|
+ <!-- 告警处理记录时间线 -->
|
|
|
+ <div class="timeline-container" v-if="alarmLogs && alarmLogs.length > 0">
|
|
|
+ <h4>处理记录</h4>
|
|
|
+ <el-timeline>
|
|
|
+ <el-timeline-item
|
|
|
+ v-for="(log, index) in alarmLogs"
|
|
|
+ :key="index"
|
|
|
+ :timestamp="parseTime(log.createTime)"
|
|
|
+ placement="top"
|
|
|
+ >
|
|
|
+ <el-card>
|
|
|
+ <p>{{ log.content }}</p>
|
|
|
+ <p class="text-small">操作人:{{ log.operator }}</p>
|
|
|
+ </el-card>
|
|
|
+ </el-timeline-item>
|
|
|
+ </el-timeline>
|
|
|
+ </div>
|
|
|
+ </el-drawer>
|
|
|
+
|
|
|
+ <!-- 创建服务单对话框 -->
|
|
|
+ <el-dialog v-model="orderDialogVisible" title="创建服务单" width="600px" append-to-body>
|
|
|
+ <el-form ref="orderFormRef" :model="orderForm" :rules="orderRules" label-width="100px">
|
|
|
+ <el-form-item label="告警编码">
|
|
|
+ <el-input v-model="orderForm.alarmCode" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="设备名称">
|
|
|
+ <el-input v-model="orderForm.deviceName" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="服务类型" prop="serviceType">
|
|
|
+ <el-select v-model="orderForm.serviceType" placeholder="请选择服务类型">
|
|
|
+ <el-option label="维修" value="维修" />
|
|
|
+ <el-option label="保养" value="保养" />
|
|
|
+ <el-option label="巡检" value="巡检" />
|
|
|
+ <el-option label="更换" value="更换" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="紧急程度" prop="urgency">
|
|
|
+ <el-radio-group v-model="orderForm.urgency">
|
|
|
+ <el-radio :label="1">一般</el-radio>
|
|
|
+ <el-radio :label="2">紧急</el-radio>
|
|
|
+ <el-radio :label="3">特急</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="问题描述" prop="description">
|
|
|
+ <el-input
|
|
|
+ v-model="orderForm.description"
|
|
|
+ type="textarea"
|
|
|
+ :rows="4"
|
|
|
+ placeholder="请输入问题描述"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <span class="dialog-footer">
|
|
|
+ <el-button @click="orderDialogVisible = false">取 消</el-button>
|
|
|
+ <el-button type="primary" @click="submitOrder">确 定</el-button>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, reactive } from 'vue'
|
|
|
+import { listDeviceAlarm, exportDeviceAlarm, resetAlarm, createServiceOrder, getAlarmDetail } from '@/api/device/alarm'
|
|
|
+
|
|
|
+const { proxy } = getCurrentInstance()
|
|
|
+
|
|
|
+// 查询参数
|
|
|
+const queryParams = reactive({
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ alarmLevel: null,
|
|
|
+ deviceType: null,
|
|
|
+ spaceLocation: [],
|
|
|
+ isReset: null,
|
|
|
+ timeRange: []
|
|
|
+})
|
|
|
+
|
|
|
+// 空间位置级联选择器选项
|
|
|
+const spaceOptions = ref([
|
|
|
+ {
|
|
|
+ label: 'A栋',
|
|
|
+ children: [
|
|
|
+ { label: '1F' },
|
|
|
+ { label: '2F' },
|
|
|
+ { label: '3F' },
|
|
|
+ { label: '4F' },
|
|
|
+ { label: '5F' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: 'B栋',
|
|
|
+ children: [
|
|
|
+ { label: '1F' },
|
|
|
+ { label: '2F' },
|
|
|
+ { label: '3F' },
|
|
|
+ { label: '4F' },
|
|
|
+ { label: '5F' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: 'C栋',
|
|
|
+ children: [
|
|
|
+ { label: '1F' },
|
|
|
+ { label: '2F' },
|
|
|
+ { label: '3F' },
|
|
|
+ { label: '4F' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: 'D栋',
|
|
|
+ children: [
|
|
|
+ { label: '1F' },
|
|
|
+ { label: '2F' },
|
|
|
+ { label: '3F' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: 'E栋',
|
|
|
+ children: [
|
|
|
+ { label: 'B1F' },
|
|
|
+ { label: '1F' },
|
|
|
+ { label: '2F' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+])
|
|
|
+
|
|
|
+// 数据列表
|
|
|
+const alarmList = ref([])
|
|
|
+const total = ref(0)
|
|
|
+const loading = ref(false)
|
|
|
+const ids = ref([])
|
|
|
+
|
|
|
+// 告警统计
|
|
|
+const alarmStats = ref({
|
|
|
+ total: 0,
|
|
|
+ unreset: 0,
|
|
|
+ highLevel: 0,
|
|
|
+ today: 0
|
|
|
+})
|
|
|
+
|
|
|
+// 详情相关
|
|
|
+const detailVisible = ref(false)
|
|
|
+const currentAlarm = ref({})
|
|
|
+const alarmLogs = ref([])
|
|
|
+
|
|
|
+// 创建服务单相关
|
|
|
+const orderDialogVisible = ref(false)
|
|
|
+const orderForm = ref({
|
|
|
+ alarmId: null,
|
|
|
+ alarmCode: '',
|
|
|
+ deviceName: '',
|
|
|
+ serviceType: '',
|
|
|
+ urgency: 1,
|
|
|
+ description: ''
|
|
|
+})
|
|
|
+
|
|
|
+const orderRules = {
|
|
|
+ serviceType: [
|
|
|
+ { required: true, message: '请选择服务类型', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ description: [
|
|
|
+ { required: true, message: '请输入问题描述', trigger: 'blur' }
|
|
|
+ ]
|
|
|
+}
|
|
|
+
|
|
|
+// 告警级别配置
|
|
|
+const alarmLevelType = (level) => {
|
|
|
+ const types = ['', 'info', 'warning', 'danger', 'danger']
|
|
|
+ return types[level] || 'info'
|
|
|
+}
|
|
|
+
|
|
|
+const alarmLevelText = (level) => {
|
|
|
+ const texts = ['', '低', '中', '高', '紧急']
|
|
|
+ return texts[level] || '未知'
|
|
|
+}
|
|
|
+
|
|
|
+// 处理状态配置
|
|
|
+const handleStatusType = (status) => {
|
|
|
+ const types = ['warning', 'primary', 'success']
|
|
|
+ return types[status] || 'info'
|
|
|
+}
|
|
|
+
|
|
|
+const handleStatusText = (status) => {
|
|
|
+ const texts = ['待处理', '处理中', '已处理']
|
|
|
+ return texts[status] || '未知'
|
|
|
+}
|
|
|
+
|
|
|
+// 查询告警列表
|
|
|
+function getList() {
|
|
|
+ loading.value = true
|
|
|
+ const params = {
|
|
|
+ ...queryParams,
|
|
|
+ pageNum: queryParams.pageNum,
|
|
|
+ pageSize: queryParams.pageSize
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理空间位置参数
|
|
|
+ if (queryParams.spaceLocation && queryParams.spaceLocation.length > 0) {
|
|
|
+ params.buildingName = queryParams.spaceLocation[0]
|
|
|
+ params.floorName = queryParams.spaceLocation[1]
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理时间范围参数
|
|
|
+ if (queryParams.timeRange && queryParams.timeRange.length === 2) {
|
|
|
+ params.beginTime = queryParams.timeRange[0]
|
|
|
+ params.endTime = queryParams.timeRange[1]
|
|
|
+ }
|
|
|
+
|
|
|
+ listDeviceAlarm(params).then(response => {
|
|
|
+ alarmList.value = response.rows
|
|
|
+ total.value = response.total
|
|
|
+ // 更新统计数据
|
|
|
+ if (response.extData.stats) {
|
|
|
+ alarmStats.value = response.extData.stats
|
|
|
+ }
|
|
|
+ loading.value = false
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 重置查询
|
|
|
+function resetQuery() {
|
|
|
+ proxy.resetForm('queryRef')
|
|
|
+ queryParams.pageNum = 1
|
|
|
+ queryParams.spaceLocation = []
|
|
|
+ getList()
|
|
|
+}
|
|
|
+
|
|
|
+// 多选框选中数据
|
|
|
+function handleSelectionChange(selection) {
|
|
|
+ ids.value = selection.map(item => item.id)
|
|
|
+}
|
|
|
+
|
|
|
+// 导出
|
|
|
+function handleExport() {
|
|
|
+ const params = {
|
|
|
+ ...queryParams,
|
|
|
+ pageNum: undefined,
|
|
|
+ pageSize: undefined
|
|
|
+ }
|
|
|
+ if (queryParams.timeRange && queryParams.timeRange.length === 2) {
|
|
|
+ params.beginTime = queryParams.timeRange[0]
|
|
|
+ params.endTime = queryParams.timeRange[1]
|
|
|
+ }
|
|
|
+ proxy.$modal.confirm('确认导出设备告警记录吗?').then(() => {
|
|
|
+ exportDeviceAlarm(params).then(response => {
|
|
|
+ proxy.download(response.msg)
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 手动复位
|
|
|
+function handleReset(row) {
|
|
|
+ proxy.$modal.confirm(`确认复位告警"${row.alarmCode}"吗?`).then(() => {
|
|
|
+ return resetAlarm({ id: row.id })
|
|
|
+ }).then(() => {
|
|
|
+ proxy.$modal.msgSuccess('复位成功')
|
|
|
+ getList()
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 创建服务单
|
|
|
+function handleCreateOrder(row) {
|
|
|
+ orderForm.value = {
|
|
|
+ alarmId: row.id,
|
|
|
+ alarmCode: row.alarmCode,
|
|
|
+ deviceName: row.deviceName,
|
|
|
+ serviceType: '',
|
|
|
+ urgency: row.alarmLevel >= 3 ? 2 : 1,
|
|
|
+ description: row.alarmDesc
|
|
|
+ }
|
|
|
+ orderDialogVisible.value = true
|
|
|
+}
|
|
|
+
|
|
|
+// 提交服务单
|
|
|
+function submitOrder() {
|
|
|
+ proxy.$refs.orderFormRef.validate(valid => {
|
|
|
+ if (valid) {
|
|
|
+ createServiceOrder(orderForm.value).then(response => {
|
|
|
+ proxy.$modal.msgSuccess('服务单创建成功')
|
|
|
+ orderDialogVisible.value = false
|
|
|
+ getList()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 查看详情
|
|
|
+function handleDetail(row) {
|
|
|
+ getAlarmDetail(row.id).then(response => {
|
|
|
+ currentAlarm.value = response.data
|
|
|
+ alarmLogs.value = response.logs || []
|
|
|
+ detailVisible.value = true
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 初始化
|
|
|
+getList()
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.stat-card {
|
|
|
+ height: 100px;
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-item {
|
|
|
+ text-align: center;
|
|
|
+ padding: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-title {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #909399;
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-value {
|
|
|
+ font-size: 28px;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-value.total {
|
|
|
+ color: #409EFF;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-value.unreset {
|
|
|
+ color: #F56C6C;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-value.high {
|
|
|
+ color: #E6A23C;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-value.today {
|
|
|
+ color: #67C23A;
|
|
|
+}
|
|
|
+
|
|
|
+.text-small {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #909399;
|
|
|
+}
|
|
|
+
|
|
|
+.timeline-container {
|
|
|
+ margin: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.timeline-container h4 {
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.mb20 {
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+</style>
|