| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- <template>
- <el-drawer v-model="visible" title="报警详情" size="min(680px, 100vw)" append-to-body destroy-on-close class="alarm-detail">
- <div v-loading="loading">
- <el-alert v-if="error" :title="error" type="error" :closable="false" show-icon />
- <template v-if="alarm">
- <AlarmSummary :alarm="alarm" :level-tone="levelTone(alarm.alarmLevel)" />
- <dl class="alarm-state-grid">
- <div class="alarm-state-item"><dt>监测状态</dt><dd><el-tag size="small" effect="light" :type="monitorStatusTone(alarm.alarmStatus)">{{ alarm.monitorStatusName || '未知' }}</el-tag></dd></div>
- <div class="alarm-state-item"><dt>核实结果</dt><dd><el-tag size="small" effect="light" :type="auditStatusTone(alarm.auditStatus)">{{ alarmAuditText(alarm) }}</el-tag></dd></div>
- <div class="alarm-state-item"><dt>处置状态</dt><dd><el-tag size="small" effect="light" :type="alarm.workOrderId != null && alarm.orderStatus != null ? orderStatusType(alarm.orderStatus) : 'info'">{{ alarm.orderStatusName || '未转工单' }}</el-tag></dd></div>
- </dl>
- <el-descriptions :column="2" border><el-descriptions-item label="关联工单">{{ alarm.orderNo || '—' }}</el-descriptions-item><el-descriptions-item label="责任人">{{ alarm.receiveUserName || '未分配' }}</el-descriptions-item><el-descriptions-item label="完成期限" :span="2">{{ alarm.planFinishTime || '—' }}</el-descriptions-item></el-descriptions>
- <AlarmHistory :records="timeline" :loading="loading" :error="error" :base-url="baseUrl" />
- </template>
- </div>
- <template #footer><el-button v-if="alarm && hasActualValue(alarm) && menu('drainageAlarmAnalysis')" @click="navigate('drainageAlarmAnalysis', { alarmId: alarm.id })">进入研判</el-button><el-button v-if="alarm?.alarmStatus === 0 && alarm?.auditStatus === 0 && menu('alarmAudit')" type="primary" @click="navigate('alarmAudit', { alarmId: alarm.id })">前往核实</el-button><el-button v-if="waterShortcuts && alarm?.workOrderId" type="primary" @click="goWaterWorkOrder">前往设备维修派单</el-button><el-button @click="visible = false">关闭</el-button></template>
- </el-drawer>
- </template>
- <script setup>
- import { ref, watch, onBeforeUnmount } from 'vue'
- import { useRouter } from 'vue-router'
- import { ElMessage } from 'element-plus'
- import { getAlarm, getAlarmTimeline } from '@/api/alarm'
- import { alarmAuditText } from '@/utils/alarmLabels'
- import AlarmSummary from './AlarmSummary.vue'
- import AlarmHistory from './AlarmHistory.vue'
- import { auditStatusTone, levelTone, monitorStatusTone } from './common/js/alarmOperationsModel'
- import { orderStatusType } from '../pipeNetwork/ops/workOrder/js/workOrderDict'
- import { hasActualValue } from './common/js/alarmReviewModel'
- import { useAlarmScope } from './common/js/useAlarmScope'
- const { scope, scopeKey, menu, navigate } = useAlarmScope()
- const { waterShortcuts = false } = defineProps({ waterShortcuts: Boolean })
- const router = useRouter()
- const emit = defineEmits(['visible-change'])
- const visible = ref(false), loading = ref(false), alarm = ref(null), timeline = ref([]), error = ref('')
- const baseUrl = import.meta.env.VITE_APP_BASE_API
- let generation = 0
- function goWaterWorkOrder() {
- if (!alarm.value?.orderNo) return ElMessage.warning('关联工单编号未返回')
- const target = router.getRoutes().find(route => route.path.endsWith('/device/maintain') && route.path.includes('/waterSupply/'))
- if (!target) return ElMessage.warning('当前账号未配置设备维修派单菜单')
- return router.push({ path: target.path, query: { keyword: alarm.value.orderNo || '' } })
- }
- async function open(id) {
- const token = ++generation
- visible.value = true; loading.value = true; error.value = ''; alarm.value = null; timeline.value = []
- try {
- const [detail, logs] = await Promise.all([getAlarm(id, { ...scope.value }), getAlarmTimeline(id, { ...scope.value })])
- if (token !== generation) return
- alarm.value = detail.data; timeline.value = logs.data || []
- } catch (e) { if (token === generation) error.value = e.message || '详情加载失败' }
- finally { if (token === generation) loading.value = false }
- }
- watch(scopeKey, () => { ++generation; visible.value = false })
- watch(visible, value => { emit('visible-change', value); if (!value) ++generation })
- onBeforeUnmount(() => { ++generation })
- defineExpose({ open })
- </script>
- <style scoped>
- .alarm-state-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 20px; margin: 0 0 20px; }
- .alarm-state-item { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; min-width: 0; }
- .alarm-state-item dt { margin: 0; color: #606266; font-size: 13px; font-weight: 400; line-height: 22px; white-space: nowrap; }
- .alarm-state-item dd { margin: 0; min-width: 0; font-weight: 400; }
- .alarm-state-item :deep(.el-tag) { height: 22px; padding: 0 7px; border: 0; border-radius: 3px; font-size: 12px; font-weight: 400; }
- @media (max-width: 560px) { .alarm-state-grid { grid-template-columns: 1fr; } }
- </style>
|