|
|
@@ -2,8 +2,13 @@
|
|
|
<div class="app-container">
|
|
|
<!-- 顶部搜索区 -->
|
|
|
<el-form :model="searchKey" :inline="true" class="search-form">
|
|
|
- <el-form-item label="管线编号">
|
|
|
- <el-input v-model="searchKey.pipeNo" placeholder="请输入管线编号" clearable style="width: 220px" />
|
|
|
+ <el-form-item label="管网名称">
|
|
|
+ <el-input v-model="searchKey.name" placeholder="请输入管网名称" clearable style="width: 220px" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="管网类型">
|
|
|
+ <el-select v-model="searchKey.networkType" placeholder="请选择" clearable style="width: 140px">
|
|
|
+ <el-option v-for="item in networkTypeOptions" :key="item" :label="item" :value="item" />
|
|
|
+ </el-select>
|
|
|
</el-form-item>
|
|
|
<el-form-item>
|
|
|
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
|
|
@@ -11,18 +16,23 @@
|
|
|
</el-form>
|
|
|
|
|
|
<div class="main-layout">
|
|
|
- <!-- 左侧管线列表 -->
|
|
|
+ <!-- 左侧管网列表 -->
|
|
|
<div class="left-panel">
|
|
|
- <div class="panel-title">管线列表</div>
|
|
|
- <div class="pipe-list">
|
|
|
- <div v-for="item in filteredList" :key="item.pipeNo" class="pipe-item"
|
|
|
- :class="{ active: currentPipe?.pipeNo === item.pipeNo }" @click="selectPipe(item)">
|
|
|
- <div class="pipe-item-no">{{ item.pipeNo }}</div>
|
|
|
- <div class="pipe-item-name">{{ item.pipeName }}</div>
|
|
|
- <el-tag size="small" :color="riskLevelColor(item.riskLevel)" effect="dark" style="border:none">{{
|
|
|
- riskLevelText(item.riskLevel) }}</el-tag>
|
|
|
+ <div class="panel-title">管网列表</div>
|
|
|
+ <div class="pipe-list" v-loading="listLoading">
|
|
|
+ <div v-for="item in pipeList" :key="item.id" class="pipe-item"
|
|
|
+ :class="{ active: currentPipe?.id === item.id }" @click="selectPipe(item)">
|
|
|
+ <div class="pipe-item-name">{{ item.name }}</div>
|
|
|
+ <div class="pipe-item-meta">
|
|
|
+ <el-tag size="small" :type="networkTypeTagType(item.networkType)" effect="light">{{ item.networkType }}</el-tag>
|
|
|
+ <span class="pipe-item-area">{{ item.area }}</span>
|
|
|
+ </div>
|
|
|
+ <div v-if="item._alarmCount > 0" class="pipe-item-alarm">
|
|
|
+ <el-icon color="#F56C6C"><Warning /></el-icon>
|
|
|
+ <span>{{ item._alarmCount }} 条报警</span>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <el-empty v-if="filteredList.length === 0" description="暂无数据" :image-size="60" />
|
|
|
+ <el-empty v-if="pipeList.length === 0 && !listLoading" description="暂无数据" :image-size="60" />
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
@@ -33,145 +43,88 @@
|
|
|
<!-- Tab 1: 基本信息 -->
|
|
|
<el-tab-pane label="基本信息" name="basic">
|
|
|
<el-descriptions :column="2" border>
|
|
|
- <el-descriptions-item label="管线编号">{{ currentPipe.pipeNo }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="管线名称">{{ currentPipe.pipeName }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="管线类别">
|
|
|
- <el-tag :type="pipeTypeTagType(currentPipe.pipeType)" effect="light">{{ currentPipe.pipeType }}</el-tag>
|
|
|
- </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="管网名称">{{ currentPipe.name }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="所属区域">{{ currentPipe.area }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="所在道路">{{ currentPipe.road }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="起点坐标">{{ currentPipe.startCoord }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="终点坐标">{{ currentPipe.endCoord }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="建设年份">{{ currentPipe.buildYear }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="使用年限">{{ currentPipe.serviceLife }} 年</el-descriptions-item>
|
|
|
- <el-descriptions-item label="管理单位">{{ currentPipe.manageUnit }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="负责人">{{ currentPipe.manager }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="联系电话">{{ currentPipe.phone }}</el-descriptions-item>
|
|
|
- </el-descriptions>
|
|
|
- </el-tab-pane>
|
|
|
-
|
|
|
- <!-- Tab 2: 管线信息 -->
|
|
|
- <el-tab-pane label="管线信息" name="pipeInfo">
|
|
|
- <el-descriptions :column="2" border>
|
|
|
- <el-descriptions-item label="管径(mm)">{{ currentPipe.diameter }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="管线长度(m)">{{ currentPipe.length }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="埋深(m)">{{ currentPipe.depth }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="管材类型">{{ currentPipe.material }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="坡度">{{ currentPipe.slope }}‰</el-descriptions-item>
|
|
|
- <el-descriptions-item label="流向">{{ currentPipe.flowDir }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="接口形式">{{ currentPipe.jointType }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="连接方式">{{ currentPipe.connectType }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="上游节点">{{ currentPipe.upstreamNode }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="下游节点">{{ currentPipe.downstreamNode }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="周边环境描述" :span="2">{{ currentPipe.surroundEnv }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="管网类型">
|
|
|
+ <el-tag :type="networkTypeTagType(currentPipe.networkType)" effect="light">{{ currentPipe.networkType }}</el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="关联设备">
|
|
|
+ <span v-if="currentPipe.equipmentId">已关联 (ID: {{ currentPipe.equipmentId }})</span>
|
|
|
+ <span v-else style="color:#909399">未关联</span>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="坐标信息" :span="2">{{ formatPoints(currentPipe.points) }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="创建时间">{{ currentPipe.createTime }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="更新时间">{{ currentPipe.updateTime }}</el-descriptions-item>
|
|
|
</el-descriptions>
|
|
|
</el-tab-pane>
|
|
|
|
|
|
- <!-- Tab 3: 评估详情 -->
|
|
|
- <el-tab-pane label="评估详情" name="assessDetail">
|
|
|
- <!-- 评估结果卡片 -->
|
|
|
- <div class="assess-result-card">
|
|
|
- <div class="assess-level" :style="{ background: riskLevelColor(currentPipe.riskLevel) }">
|
|
|
- <div class="assess-level-text">{{ riskLevelText(currentPipe.riskLevel) }}</div>
|
|
|
- <div class="assess-level-score">{{ currentPipe.riskScore }} 分</div>
|
|
|
- </div>
|
|
|
- <div class="assess-result-info">
|
|
|
- <div class="assess-result-row">
|
|
|
- <span class="label">评估时间:</span>
|
|
|
- <span>{{ currentPipe.assessTime }}</span>
|
|
|
+ <!-- Tab 2: 报警统计 -->
|
|
|
+ <el-tab-pane label="报警统计" name="alarm">
|
|
|
+ <div v-if="currentPipe.equipmentId" v-loading="alarmLoading">
|
|
|
+ <!-- 报警统计概览 -->
|
|
|
+ <div class="alarm-stats-bar">
|
|
|
+ <div class="alarm-stat-item">
|
|
|
+ <span class="alarm-stat-value">{{ alarmTotal }}</span>
|
|
|
+ <span class="alarm-stat-label">总报警数</span>
|
|
|
</div>
|
|
|
- <div class="assess-result-row">
|
|
|
- <span class="label">评估机构:</span>
|
|
|
- <span>{{ currentPipe.assessOrg }}</span>
|
|
|
+ <div class="alarm-stat-item">
|
|
|
+ <span class="alarm-stat-value" style="color:#F56C6C">{{ alarmUnhandled }}</span>
|
|
|
+ <span class="alarm-stat-label">未处理</span>
|
|
|
</div>
|
|
|
- <div class="assess-result-row">
|
|
|
- <span class="label">下次评估:</span>
|
|
|
- <span>{{ currentPipe.nextAssessTime }}</span>
|
|
|
+ <div class="alarm-stat-item">
|
|
|
+ <span class="alarm-stat-value" style="color:#E6A23C">{{ alarmHandling }}</span>
|
|
|
+ <span class="alarm-stat-label">处理中</span>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 评估指标表格 -->
|
|
|
- <el-table :data="currentPipe.indicators" border style="width: 100%; margin-top: 20px;">
|
|
|
- <el-table-column label="指标名称" prop="name" min-width="160" />
|
|
|
- <el-table-column label="权重" prop="weight" min-width="80" align="center">
|
|
|
- <template #default="{ row }">{{ (row.weight * 100).toFixed(0) }}%</template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="评分" prop="score" min-width="80" align="center">
|
|
|
- <template #default="{ row }">
|
|
|
- <span :style="{ color: scoreColor(row.score), fontWeight: 700 }">{{ row.score }}</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="等级" prop="level" min-width="100" align="center">
|
|
|
- <template #default="{ row }">
|
|
|
- <el-tag :color="indicatorLevelColor(row.level)" effect="dark" size="small" style="border:none">{{
|
|
|
- row.level }}</el-tag>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
- </el-tab-pane>
|
|
|
-
|
|
|
- <!-- Tab 4: 评估分析 -->
|
|
|
- <!-- <el-tab-pane label="评估分析" name="assessAnalysis">
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="12">
|
|
|
- <el-card shadow="hover">
|
|
|
- <template #header><span style="font-weight:600">风险维度雷达图</span></template>
|
|
|
- <div ref="radarChartRef" style="height: 350px;"></div>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- <el-col :span="12">
|
|
|
- <el-card shadow="hover">
|
|
|
- <template #header><span style="font-weight:600">风险趋势折线图</span></template>
|
|
|
- <div ref="lineChartRef" style="height: 350px;"></div>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- </el-row> -->
|
|
|
-
|
|
|
- <!-- 评估建议 -->
|
|
|
- <!-- <el-card shadow="hover" style="margin-top: 20px;">
|
|
|
- <template #header><span style="font-weight:600">评估建议</span></template>
|
|
|
- <div class="suggest-section">
|
|
|
- <div class="suggest-row">
|
|
|
- <span class="suggest-label">当前风险等级:</span>
|
|
|
- <el-tag :color="riskLevelColor(currentPipe.riskLevel)" effect="dark" style="border:none">{{
|
|
|
- riskLevelText(currentPipe.riskLevel) }}</el-tag>
|
|
|
- </div>
|
|
|
- <div class="suggest-row">
|
|
|
- <span class="suggest-label">风险说明:</span>
|
|
|
- <span>{{ currentPipe.riskDesc }}</span>
|
|
|
- </div>
|
|
|
- <div class="suggest-row">
|
|
|
- <span class="suggest-label">建议措施:</span>
|
|
|
- <span>{{ currentPipe.suggestion }}</span>
|
|
|
+ <div class="alarm-stat-item">
|
|
|
+ <span class="alarm-stat-value" style="color:#67C23A">{{ alarmHandled }}</span>
|
|
|
+ <span class="alarm-stat-label">已处理</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
- </el-card> -->
|
|
|
-
|
|
|
- <!-- 历史评估记录 -->
|
|
|
- <!-- <el-card shadow="hover" style="margin-top: 20px;">
|
|
|
- <template #header><span style="font-weight:600">历史评估记录</span></template>
|
|
|
- <el-table :data="currentPipe.historyRecords" border style="width: 100%">
|
|
|
- <el-table-column label="评估时间" prop="time" min-width="120" align="center" />
|
|
|
- <el-table-column label="风险评分" prop="score" min-width="100" align="center">
|
|
|
- <template #default="{ row }">
|
|
|
- <span :style="{ color: scoreColor(row.score), fontWeight: 700 }">{{ row.score }}</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="风险级别" prop="level" min-width="100" align="center">
|
|
|
+
|
|
|
+ <!-- 报警列表 -->
|
|
|
+ <el-table :data="alarmList" border style="width: 100%; margin-top: 16px;" v-if="alarmList.length > 0">
|
|
|
+ <el-table-column label="序号" type="index" width="60" align="center" />
|
|
|
+ <el-table-column prop="alarmTime" label="报警时间" min-width="160" />
|
|
|
+ <el-table-column prop="alarmType" label="报警类型" min-width="100" />
|
|
|
+ <el-table-column prop="alarmContent" label="报警内容" min-width="220" />
|
|
|
+ <el-table-column prop="status" label="状态" min-width="90" align="center">
|
|
|
<template #default="{ row }">
|
|
|
- <el-tag :color="riskLevelColor(row.riskLevel)" effect="dark" size="small" style="border:none">{{
|
|
|
- riskLevelText(row.riskLevel) }}</el-tag>
|
|
|
+ <el-tag :type="row.status === 0 ? 'warning' : row.status === 1 ? 'primary' : 'success'" size="small">
|
|
|
+ {{ row.status === 0 ? '未处理' : row.status === 1 ? '处理中' : '已处理' }}
|
|
|
+ </el-tag>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="评估机构" prop="org" min-width="160" />
|
|
|
- <el-table-column label="备注" prop="remark" min-width="200" />
|
|
|
</el-table>
|
|
|
- </el-card>
|
|
|
- </el-tab-pane> -->
|
|
|
+ <el-empty v-else description="暂无报警数据" :image-size="60" />
|
|
|
+
|
|
|
+ <!-- 报警分页 -->
|
|
|
+ <div v-if="alarmTotal > 0" class="alarm-pagination">
|
|
|
+ <el-pagination
|
|
|
+ v-model:current-page="alarmPageNum"
|
|
|
+ v-model:page-size="alarmPageSize"
|
|
|
+ :page-sizes="[10, 20, 50]"
|
|
|
+ :total="alarmTotal"
|
|
|
+ layout="total, sizes, prev, pager, next"
|
|
|
+ small
|
|
|
+ background
|
|
|
+ @size-change="loadAlarmData"
|
|
|
+ @current-change="loadAlarmData"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <el-empty v-else description="该管网未关联设备,无报警数据" :image-size="80" />
|
|
|
+ </el-tab-pane>
|
|
|
+
|
|
|
+ <!-- Tab 3: 报警趋势 -->
|
|
|
+ <el-tab-pane label="报警趋势" name="trend">
|
|
|
+ <div v-if="currentPipe.equipmentId && alarmTrendData.length > 0">
|
|
|
+ <div ref="trendChartRef" style="height: 350px;"></div>
|
|
|
+ </div>
|
|
|
+ <el-empty v-else description="暂无报警趋势数据" :image-size="80" />
|
|
|
+ </el-tab-pane>
|
|
|
</el-tabs>
|
|
|
</template>
|
|
|
- <el-empty v-else description="请选择左侧管线查看详情" :image-size="120" />
|
|
|
+ <el-empty v-else description="请选择左侧管网查看详情" :image-size="120" />
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -180,287 +133,204 @@
|
|
|
<script setup name="Zhfxxqfx">
|
|
|
import { ref, computed, watch, nextTick, onMounted } from 'vue'
|
|
|
import { useRoute } from 'vue-router'
|
|
|
+import { Warning } from '@element-plus/icons-vue'
|
|
|
import * as echarts from 'echarts'
|
|
|
+import { getPipeNetworkPage, getAlarmDataPage } from '@/api/drainage'
|
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
|
-// ==================== 搜索 ====================
|
|
|
-const searchKey = ref({ pipeNo: '' })
|
|
|
-const handleSearch = () => {
|
|
|
- // 搜索时自动选中第一个匹配项
|
|
|
- const list = filteredList.value
|
|
|
- if (list.length > 0 && (!currentPipe.value || !list.find(i => i.pipeNo === currentPipe.value.pipeNo))) {
|
|
|
- selectPipe(list[0])
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// ==================== 模拟数据 ====================
|
|
|
-const pipeDataList = ref([
|
|
|
- {
|
|
|
- pipeNo: 'GX-2024-001', pipeName: '沅陵大道雨水主干线', pipeType: '雨水管', area: '沅陵大道', road: '沅陵大道',
|
|
|
- startCoord: '110.3968, 28.4521', endCoord: '110.4085, 28.4589',
|
|
|
- buildYear: 2008, serviceLife: 17, manageUnit: '沅陵县排水管理中心', manager: '张建国', phone: '13874452103',
|
|
|
- diameter: 800, length: 1250, depth: 2.5, material: '钢筋混凝土', slope: 2.5, flowDir: '自西向东',
|
|
|
- jointType: '承插式', connectType: '柔性连接', upstreamNode: 'J-001', downstreamNode: 'J-025',
|
|
|
- surroundEnv: '两侧为商业建筑,人流密集,地下管线交错,靠近沅水河岸',
|
|
|
- riskScore: 87, riskLevel: 'high', assessTime: '2025-11-15',
|
|
|
- assessOrg: '湖南省管网检测中心', nextAssessTime: '2026-05-15',
|
|
|
- riskDesc: '该管线使用年限较长,结构性缺陷较多,部分区域存在塌陷风险,需重点关注。',
|
|
|
- suggestion: '建议3个月内进行全面检修,更换受损管段;加强日常监测频率至每日1次;雨季前完成清淤疏浚。',
|
|
|
- indicators: [
|
|
|
- { name: '结构性缺陷评分', weight: 0.3, score: 92, level: '高风险' },
|
|
|
- { name: '功能性缺陷评分', weight: 0.25, score: 85, level: '高风险' },
|
|
|
- { name: '环境影响评分', weight: 0.2, score: 78, level: '中风险' },
|
|
|
- { name: '运行状态评分', weight: 0.15, score: 88, level: '高风险' },
|
|
|
- { name: '历史事故评分', weight: 0.1, score: 95, level: '高风险' },
|
|
|
- { name: '综合评分', weight: 1.0, score: 87, level: '高风险' }
|
|
|
- ],
|
|
|
- historyRecords: [
|
|
|
- { time: '2025-11-15', score: 87, riskLevel: 'high', org: '湖南省管网检测中心', remark: '结构性缺陷加剧' },
|
|
|
- { time: '2025-08-20', score: 82, riskLevel: 'high', org: '沅陵县排水管理中心', remark: '雨季检测发现新增裂缝' },
|
|
|
- { time: '2025-05-10', score: 75, riskLevel: 'medium', org: '湖南省管网检测中心', remark: '常规评估' },
|
|
|
- { time: '2025-01-15', score: 70, riskLevel: 'medium', org: '沅陵县排水管理中心', remark: '年度评估' }
|
|
|
- ]
|
|
|
- },
|
|
|
- {
|
|
|
- pipeNo: 'GX-2024-002', pipeName: '城北路段污水管线', pipeType: '污水管', area: '城北路段', road: '城北路',
|
|
|
- startCoord: '110.3912, 28.4567', endCoord: '110.3998, 28.4601',
|
|
|
- buildYear: 2012, serviceLife: 13, manageUnit: '沅陵县排水管理中心', manager: '李明辉', phone: '13974438921',
|
|
|
- diameter: 600, length: 980, depth: 3.1, material: 'PE', slope: 3.0, flowDir: '自北向南',
|
|
|
- jointType: '热熔连接', connectType: '刚性连接', upstreamNode: 'J-030', downstreamNode: 'J-048',
|
|
|
- surroundEnv: '居民区密集,沿线有学校和医院,交通量较大',
|
|
|
- riskScore: 72, riskLevel: 'medium', assessTime: '2025-11-10',
|
|
|
- assessOrg: '湖南省管网检测中心', nextAssessTime: '2026-05-10',
|
|
|
- riskDesc: '该管线存在功能性缺陷,部分管段渗漏较严重,需加强维护。',
|
|
|
- suggestion: '建议6个月内进行渗漏点修复;增加CCTV检测频率至每季度1次;关注周边施工影响。',
|
|
|
- indicators: [
|
|
|
- { name: '结构性缺陷评分', weight: 0.3, score: 68, level: '中风险' },
|
|
|
- { name: '功能性缺陷评分', weight: 0.25, score: 80, level: '中风险' },
|
|
|
- { name: '环境影响评分', weight: 0.2, score: 65, level: '低风险' },
|
|
|
- { name: '运行状态评分', weight: 0.15, score: 75, level: '中风险' },
|
|
|
- { name: '历史事故评分', weight: 0.1, score: 70, level: '中风险' },
|
|
|
- { name: '综合评分', weight: 1.0, score: 72, level: '中风险' }
|
|
|
- ],
|
|
|
- historyRecords: [
|
|
|
- { time: '2025-11-10', score: 72, riskLevel: 'medium', org: '湖南省管网检测中心', remark: '渗漏加剧' },
|
|
|
- { time: '2025-07-15', score: 65, riskLevel: 'medium', org: '沅陵县排水管理中心', remark: '常规评估' },
|
|
|
- { time: '2025-03-20', score: 58, riskLevel: 'medium', org: '湖南省管网检测中心', remark: '发现渗漏点' }
|
|
|
- ]
|
|
|
- },
|
|
|
- {
|
|
|
- pipeNo: 'GX-2024-003', pipeName: '河西片区合流管线', pipeType: '合流管', area: '河西片区', road: '河西大道',
|
|
|
- startCoord: '110.3856, 28.4489', endCoord: '110.3978, 28.4534',
|
|
|
- buildYear: 2015, serviceLife: 10, manageUnit: '沅陵县排水管理中心', manager: '王志强', phone: '13787456210',
|
|
|
- diameter: 1000, length: 1560, depth: 2.8, material: 'PVC', slope: 2.0, flowDir: '自南向北',
|
|
|
- jointType: '胶圈承插', connectType: '柔性连接', upstreamNode: 'J-050', downstreamNode: 'J-075',
|
|
|
- surroundEnv: '新开发区,建筑密度中等,绿化带较多',
|
|
|
- riskScore: 45, riskLevel: 'low', assessTime: '2025-11-08',
|
|
|
- assessOrg: '湖南省管网检测中心', nextAssessTime: '2026-11-08',
|
|
|
- riskDesc: '管线整体状况良好,个别节点存在轻微功能性问题,风险可控。',
|
|
|
- suggestion: '建议12个月内进行常规检修维护;保持现有监测频率;重点关注雨季排水情况。',
|
|
|
- indicators: [
|
|
|
- { name: '结构性缺陷评分', weight: 0.3, score: 40, level: '低风险' },
|
|
|
- { name: '功能性缺陷评分', weight: 0.25, score: 48, level: '低风险' },
|
|
|
- { name: '环境影响评分', weight: 0.2, score: 42, level: '低风险' },
|
|
|
- { name: '运行状态评分', weight: 0.15, score: 50, level: '低风险' },
|
|
|
- { name: '历史事故评分', weight: 0.1, score: 45, level: '低风险' },
|
|
|
- { name: '综合评分', weight: 1.0, score: 45, level: '低风险' }
|
|
|
- ],
|
|
|
- historyRecords: [
|
|
|
- { time: '2025-11-08', score: 45, riskLevel: 'low', org: '湖南省管网检测中心', remark: '年度评估' },
|
|
|
- { time: '2025-05-12', score: 42, riskLevel: 'low', org: '沅陵县排水管理中心', remark: '常规评估' }
|
|
|
- ]
|
|
|
- },
|
|
|
- {
|
|
|
- pipeNo: 'GX-2024-004', pipeName: '人民路雨水管线', pipeType: '雨水管', area: '人民路', road: '人民路',
|
|
|
- startCoord: '110.4001, 28.4502', endCoord: '110.4076, 28.4556',
|
|
|
- buildYear: 2005, serviceLife: 20, manageUnit: '沅陵县排水管理中心', manager: '陈伟华', phone: '13687451230',
|
|
|
- diameter: 500, length: 870, depth: 2.2, material: '铸铁', slope: 3.5, flowDir: '自东向西',
|
|
|
- jointType: '法兰连接', connectType: '刚性连接', upstreamNode: 'J-080', downstreamNode: 'J-095',
|
|
|
- surroundEnv: '老城区,道路狭窄,两侧建筑老旧,地下管线复杂',
|
|
|
- riskScore: 91, riskLevel: 'high', assessTime: '2025-11-05',
|
|
|
- assessOrg: '湖南省管网检测中心', nextAssessTime: '2026-02-05',
|
|
|
- riskDesc: '该管线使用年限长,管材老化严重,多处存在腐蚀穿孔风险,需紧急处理。',
|
|
|
- suggestion: '建议1个月内启动应急检修;制定管线更换方案;加密监测至每4小时1次;对高风险段实施临时加固。',
|
|
|
- indicators: [
|
|
|
- { name: '结构性缺陷评分', weight: 0.3, score: 95, level: '高风险' },
|
|
|
- { name: '功能性缺陷评分', weight: 0.25, score: 90, level: '高风险' },
|
|
|
- { name: '环境影响评分', weight: 0.2, score: 85, level: '高风险' },
|
|
|
- { name: '运行状态评分', weight: 0.15, score: 92, level: '高风险' },
|
|
|
- { name: '历史事故评分', weight: 0.1, score: 98, level: '高风险' },
|
|
|
- { name: '综合评分', weight: 1.0, score: 91, level: '高风险' }
|
|
|
- ],
|
|
|
- historyRecords: [
|
|
|
- { time: '2025-11-05', score: 91, riskLevel: 'high', org: '湖南省管网检测中心', remark: '管材腐蚀严重' },
|
|
|
- { time: '2025-09-10', score: 85, riskLevel: 'high', org: '沅陵县排水管理中心', remark: '发现渗漏隐患' },
|
|
|
- { time: '2025-06-18', score: 78, riskLevel: 'high', org: '湖南省管网检测中心', remark: '老化评估' },
|
|
|
- { time: '2025-03-05', score: 72, riskLevel: 'medium', org: '沅陵县排水管理中心', remark: '常规评估' }
|
|
|
- ]
|
|
|
- },
|
|
|
- {
|
|
|
- pipeNo: 'GX-2024-005', pipeName: '南环路污水支线', pipeType: '污水管', area: '南环路', road: '南环路',
|
|
|
- startCoord: '110.3945, 28.4432', endCoord: '110.4012, 28.4478',
|
|
|
- buildYear: 2020, serviceLife: 5, manageUnit: '沅陵县排水管理中心', manager: '刘志远', phone: '13587412306',
|
|
|
- diameter: 400, length: 640, depth: 1.9, material: 'PE', slope: 4.0, flowDir: '自南向北',
|
|
|
- jointType: '热熔连接', connectType: '刚性连接', upstreamNode: 'J-100', downstreamNode: 'J-112',
|
|
|
- surroundEnv: '新建住宅区,配套设施完善,绿化良好',
|
|
|
- riskScore: 38, riskLevel: 'veryLow', assessTime: '2025-11-02',
|
|
|
- assessOrg: '湖南省管网检测中心', nextAssessTime: '2026-11-02',
|
|
|
- riskDesc: '管线状况优良,运行稳定,各项指标均在安全范围内。',
|
|
|
- suggestion: '维持现有监测频率;定期进行常规巡检;做好预防性维护即可。',
|
|
|
- indicators: [
|
|
|
- { name: '结构性缺陷评分', weight: 0.3, score: 30, level: '极低风险' },
|
|
|
- { name: '功能性缺陷评分', weight: 0.25, score: 35, level: '极低风险' },
|
|
|
- { name: '环境影响评分', weight: 0.2, score: 40, level: '低风险' },
|
|
|
- { name: '运行状态评分', weight: 0.15, score: 42, level: '低风险' },
|
|
|
- { name: '历史事故评分', weight: 0.1, score: 45, level: '低风险' },
|
|
|
- { name: '综合评分', weight: 1.0, score: 38, level: '极低风险' }
|
|
|
- ],
|
|
|
- historyRecords: [
|
|
|
- { time: '2025-11-02', score: 38, riskLevel: 'veryLow', org: '湖南省管网检测中心', remark: '年度评估' },
|
|
|
- { time: '2025-05-20', score: 35, riskLevel: 'veryLow', org: '沅陵县排水管理中心', remark: '常规评估' }
|
|
|
- ]
|
|
|
- }
|
|
|
-])
|
|
|
+// ==================== 选项 ====================
|
|
|
+const networkTypeOptions = ['管线', '管点', '排口']
|
|
|
|
|
|
-// ==================== 过滤与选中 ====================
|
|
|
-const filteredList = computed(() => {
|
|
|
- if (!searchKey.value.pipeNo) return pipeDataList.value
|
|
|
- return pipeDataList.value.filter(i => i.pipeNo.includes(searchKey.value.pipeNo))
|
|
|
-})
|
|
|
+// ==================== 搜索 ====================
|
|
|
+const searchKey = ref({ name: '', networkType: '管线' })
|
|
|
+const handleSearch = () => { loadPipeList() }
|
|
|
|
|
|
+// ==================== 管网列表 ====================
|
|
|
+const pipeList = ref([])
|
|
|
+const listLoading = ref(false)
|
|
|
const currentPipe = ref(null)
|
|
|
const activeTab = ref('basic')
|
|
|
|
|
|
+const loadPipeList = async () => {
|
|
|
+ listLoading.value = true
|
|
|
+ try {
|
|
|
+ const params = {}
|
|
|
+ if (searchKey.value.name) params.name = searchKey.value.name
|
|
|
+ if (searchKey.value.networkType) params.networkType = searchKey.value.networkType
|
|
|
+
|
|
|
+ // 加载较多数据用于左侧列表
|
|
|
+ const res = await getPipeNetworkPage(1, 200, params)
|
|
|
+ const pageData = res.code !== undefined ? res.data : res
|
|
|
+ const rows = pageData.records || pageData.rows || []
|
|
|
+
|
|
|
+ // 批量查询报警数
|
|
|
+ const withAlarms = await Promise.all(
|
|
|
+ rows.map(async (item) => {
|
|
|
+ let alarmCount = 0
|
|
|
+ if (item.equipmentId) {
|
|
|
+ try {
|
|
|
+ const alarmRes = await getAlarmDataPage(1, 1, { equipmentId: item.equipmentId, equipmentType: 'drainage' })
|
|
|
+ const alarmPageData = alarmRes.code !== undefined ? alarmRes.data : alarmRes
|
|
|
+ alarmCount = alarmPageData.total ?? 0
|
|
|
+ } catch (e) { /* ignore */ }
|
|
|
+ }
|
|
|
+ return { ...item, _alarmCount: alarmCount }
|
|
|
+ })
|
|
|
+ )
|
|
|
+ pipeList.value = withAlarms
|
|
|
+
|
|
|
+ // 如果有路由参数指定ID,自动选中
|
|
|
+ const queryId = route.query.id
|
|
|
+ if (queryId) {
|
|
|
+ const found = withAlarms.find(i => String(i.id) === String(queryId))
|
|
|
+ if (found) selectPipe(found)
|
|
|
+ } else if (withAlarms.length > 0 && !currentPipe.value) {
|
|
|
+ selectPipe(withAlarms[0])
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('加载管网列表失败', e)
|
|
|
+ pipeList.value = []
|
|
|
+ } finally {
|
|
|
+ listLoading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
const selectPipe = (item) => {
|
|
|
currentPipe.value = item
|
|
|
activeTab.value = 'basic'
|
|
|
+ // 重置报警数据
|
|
|
+ alarmList.value = []
|
|
|
+ alarmTotal.value = 0
|
|
|
+ alarmPageNum.value = 1
|
|
|
+ alarmTrendData.value = []
|
|
|
}
|
|
|
|
|
|
-// ==================== 工具函数 ====================
|
|
|
-const pipeTypeTagType = (type) => {
|
|
|
- const map = { '雨水管': '', '污水管': 'warning', '合流管': 'success', '燃气管': 'danger' }
|
|
|
- return map[type] || ''
|
|
|
-}
|
|
|
-
|
|
|
-const riskLevelColor = (level) => {
|
|
|
- const map = { high: '#F56C6C', medium: '#E6A23C', low: '#409EFF', veryLow: '#67C23A' }
|
|
|
- return map[level] || '#909399'
|
|
|
-}
|
|
|
-
|
|
|
-const riskLevelText = (level) => {
|
|
|
- const map = { high: '高风险', medium: '中风险', low: '低风险', veryLow: '极低风险' }
|
|
|
- return map[level] || '未知'
|
|
|
-}
|
|
|
-
|
|
|
-const scoreColor = (score) => {
|
|
|
- if (score >= 80) return '#F56C6C'
|
|
|
- if (score >= 60) return '#E6A23C'
|
|
|
- if (score >= 40) return '#409EFF'
|
|
|
- return '#67C23A'
|
|
|
-}
|
|
|
-
|
|
|
-const indicatorLevelColor = (level) => {
|
|
|
- const map = { '高风险': '#F56C6C', '中风险': '#E6A23C', '低风险': '#409EFF', '极低风险': '#67C23A' }
|
|
|
- return map[level] || '#909399'
|
|
|
+// ==================== 报警数据 ====================
|
|
|
+const alarmLoading = ref(false)
|
|
|
+const alarmList = ref([])
|
|
|
+const alarmTotal = ref(0)
|
|
|
+const alarmPageNum = ref(1)
|
|
|
+const alarmPageSize = ref(10)
|
|
|
+
|
|
|
+const alarmUnhandled = computed(() => alarmList.value.filter(i => i.status === 0).length)
|
|
|
+const alarmHandling = computed(() => alarmList.value.filter(i => i.status === 1).length)
|
|
|
+const alarmHandled = computed(() => alarmList.value.filter(i => i.status === 2).length)
|
|
|
+
|
|
|
+const loadAlarmData = async () => {
|
|
|
+ if (!currentPipe.value?.equipmentId) return
|
|
|
+ alarmLoading.value = true
|
|
|
+ try {
|
|
|
+ const res = await getAlarmDataPage(alarmPageNum.value, alarmPageSize.value, {
|
|
|
+ equipmentId: currentPipe.value.equipmentId,
|
|
|
+ equipmentType: 'drainage'
|
|
|
+ })
|
|
|
+ const pageData = res.code !== undefined ? res.data : res
|
|
|
+ alarmList.value = pageData.records || pageData.rows || []
|
|
|
+ alarmTotal.value = pageData.total ?? 0
|
|
|
+ } catch (e) {
|
|
|
+ alarmList.value = []
|
|
|
+ alarmTotal.value = 0
|
|
|
+ } finally {
|
|
|
+ alarmLoading.value = false
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-// ==================== ECharts ====================
|
|
|
-const radarChartRef = ref(null)
|
|
|
-const lineChartRef = ref(null)
|
|
|
-let radarChart = null
|
|
|
-let lineChart = null
|
|
|
-
|
|
|
-const initRadarChart = () => {
|
|
|
- if (!radarChartRef.value || !currentPipe.value) return
|
|
|
- radarChart = echarts.init(radarChartRef.value)
|
|
|
- const indicators = currentPipe.value.indicators.slice(0, 5).map(i => ({
|
|
|
- name: i.name.replace('评分', ''),
|
|
|
- max: 100
|
|
|
- }))
|
|
|
- radarChart.setOption({
|
|
|
- tooltip: { trigger: 'item' },
|
|
|
- radar: {
|
|
|
- indicator: indicators,
|
|
|
- shape: 'polygon',
|
|
|
- splitNumber: 5,
|
|
|
- axisName: { color: '#606266', fontSize: 12 },
|
|
|
- splitArea: { areaStyle: { color: ['rgba(64,158,255,0.05)', 'rgba(64,158,255,0.1)'] } }
|
|
|
- },
|
|
|
- series: [{
|
|
|
- type: 'radar',
|
|
|
- data: [{
|
|
|
- value: currentPipe.value.indicators.slice(0, 5).map(i => i.score),
|
|
|
- name: '风险评分',
|
|
|
- areaStyle: { color: 'rgba(245,108,108,0.2)' },
|
|
|
- lineStyle: { color: '#F56C6C', width: 2 },
|
|
|
- itemStyle: { color: '#F56C6C' }
|
|
|
- }]
|
|
|
- }]
|
|
|
- })
|
|
|
+// ==================== 报警趋势 ====================
|
|
|
+const alarmTrendData = ref([])
|
|
|
+const trendChartRef = ref(null)
|
|
|
+let trendChart = null
|
|
|
+
|
|
|
+const loadAlarmTrend = async () => {
|
|
|
+ if (!currentPipe.value?.equipmentId) return
|
|
|
+ try {
|
|
|
+ // 加载较多报警数据用于趋势分析
|
|
|
+ const res = await getAlarmDataPage(1, 500, {
|
|
|
+ equipmentId: currentPipe.value.equipmentId,
|
|
|
+ equipmentType: 'drainage'
|
|
|
+ })
|
|
|
+ const trendPageData = res.code !== undefined ? res.data : res
|
|
|
+ const rows = trendPageData.records || trendPageData.rows || []
|
|
|
+ // 按日期聚合报警数
|
|
|
+ const dateMap = {}
|
|
|
+ rows.forEach(item => {
|
|
|
+ const date = (item.alarmTime || '').substring(0, 10)
|
|
|
+ if (date) {
|
|
|
+ dateMap[date] = (dateMap[date] || 0) + 1
|
|
|
+ }
|
|
|
+ })
|
|
|
+ alarmTrendData.value = Object.entries(dateMap)
|
|
|
+ .sort((a, b) => a[0].localeCompare(b[0]))
|
|
|
+ .map(([date, count]) => ({ date, count }))
|
|
|
+ } catch (e) {
|
|
|
+ alarmTrendData.value = []
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-const initLineChart = () => {
|
|
|
- if (!lineChartRef.value || !currentPipe.value) return
|
|
|
- lineChart = echarts.init(lineChartRef.value)
|
|
|
- const records = [...currentPipe.value.historyRecords].reverse()
|
|
|
- lineChart.setOption({
|
|
|
+const initTrendChart = () => {
|
|
|
+ if (!trendChartRef.value || alarmTrendData.value.length === 0) return
|
|
|
+ if (trendChart) { trendChart.dispose(); trendChart = null }
|
|
|
+ trendChart = echarts.init(trendChartRef.value)
|
|
|
+ trendChart.setOption({
|
|
|
tooltip: { trigger: 'axis' },
|
|
|
grid: { left: 50, right: 30, top: 30, bottom: 30 },
|
|
|
xAxis: {
|
|
|
type: 'category',
|
|
|
- data: records.map(r => r.time),
|
|
|
- axisLabel: { fontSize: 11, color: '#909399' }
|
|
|
+ data: alarmTrendData.value.map(d => d.date),
|
|
|
+ axisLabel: { fontSize: 11, color: '#909399', rotate: 30 }
|
|
|
},
|
|
|
yAxis: {
|
|
|
type: 'value',
|
|
|
- min: 0, max: 100,
|
|
|
+ minInterval: 1,
|
|
|
axisLabel: { color: '#909399' },
|
|
|
splitLine: { lineStyle: { type: 'dashed' } }
|
|
|
},
|
|
|
series: [{
|
|
|
- type: 'line',
|
|
|
- data: records.map(r => r.score),
|
|
|
- smooth: true,
|
|
|
- symbol: 'circle',
|
|
|
- symbolSize: 8,
|
|
|
- lineStyle: { color: '#E6A23C', width: 2 },
|
|
|
- itemStyle: { color: '#E6A23C' },
|
|
|
- areaStyle: { color: { type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [{ offset: 0, color: 'rgba(230,162,60,0.3)' }, { offset: 1, color: 'rgba(230,162,60,0.02)' }] } },
|
|
|
- markLine: {
|
|
|
- silent: true,
|
|
|
- lineStyle: { type: 'dashed', color: '#F56C6C' },
|
|
|
- data: [{ yAxis: 80, label: { formatter: '高风险线', color: '#F56C6C', fontSize: 11 } }]
|
|
|
- }
|
|
|
+ type: 'bar',
|
|
|
+ data: alarmTrendData.value.map(d => d.count),
|
|
|
+ itemStyle: { color: '#E6A23C', borderRadius: [4, 4, 0, 0] },
|
|
|
+ barMaxWidth: 30
|
|
|
}]
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-// 监听Tab切换到评估分析时初始化图表
|
|
|
+// ==================== 监听Tab切换 ====================
|
|
|
watch(activeTab, (val) => {
|
|
|
- if (val === 'assessAnalysis' && currentPipe.value) {
|
|
|
- nextTick(() => {
|
|
|
- initRadarChart()
|
|
|
- initLineChart()
|
|
|
- })
|
|
|
+ if (val === 'alarm' && currentPipe.value?.equipmentId) {
|
|
|
+ loadAlarmData()
|
|
|
+ }
|
|
|
+ if (val === 'trend' && currentPipe.value?.equipmentId) {
|
|
|
+ loadAlarmTrend().then(() => nextTick(() => initTrendChart()))
|
|
|
}
|
|
|
})
|
|
|
|
|
|
-// 监听选中管线变化时销毁旧图表
|
|
|
+// 监听选中管网变化时销毁图表
|
|
|
watch(currentPipe, () => {
|
|
|
- if (radarChart) { radarChart.dispose(); radarChart = null }
|
|
|
- if (lineChart) { lineChart.dispose(); lineChart = null }
|
|
|
+ if (trendChart) { trendChart.dispose(); trendChart = null }
|
|
|
})
|
|
|
|
|
|
-// 从路由参数中获取管线编号
|
|
|
-onMounted(() => {
|
|
|
- const pipeNo = route.query.pipeNo
|
|
|
- if (pipeNo) {
|
|
|
- const found = pipeDataList.value.find(i => i.pipeNo === pipeNo)
|
|
|
- if (found) selectPipe(found)
|
|
|
- } else if (pipeDataList.value.length > 0) {
|
|
|
- selectPipe(pipeDataList.value[0])
|
|
|
+// ==================== 工具函数 ====================
|
|
|
+const networkTypeTagType = (type) => {
|
|
|
+ const map = { '管线': '', '管点': 'warning', '排口': 'success' }
|
|
|
+ return map[type] || ''
|
|
|
+}
|
|
|
+
|
|
|
+const formatPoints = (points) => {
|
|
|
+ if (!points) return '暂无坐标'
|
|
|
+ try {
|
|
|
+ const parsed = typeof points === 'string' ? JSON.parse(points) : points
|
|
|
+ if (Array.isArray(parsed)) {
|
|
|
+ return parsed.map(p => `${p.lng || p[0]}, ${p.lat || p[1]}`).join(' → ')
|
|
|
+ }
|
|
|
+ return String(points)
|
|
|
+ } catch {
|
|
|
+ return String(points)
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+// ==================== 初始化 ====================
|
|
|
+onMounted(() => {
|
|
|
+ loadPipeList()
|
|
|
})
|
|
|
</script>
|
|
|
|
|
|
@@ -524,12 +394,6 @@ onMounted(() => {
|
|
|
border-color: #409EFF;
|
|
|
}
|
|
|
|
|
|
-.pipe-item-no {
|
|
|
- font-size: 13px;
|
|
|
- color: #909399;
|
|
|
- margin-bottom: 2px;
|
|
|
-}
|
|
|
-
|
|
|
.pipe-item-name {
|
|
|
font-size: 14px;
|
|
|
color: #303133;
|
|
|
@@ -537,75 +401,64 @@ onMounted(() => {
|
|
|
margin-bottom: 6px;
|
|
|
}
|
|
|
|
|
|
+.pipe-item-meta {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+ margin-bottom: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.pipe-item-area {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #909399;
|
|
|
+}
|
|
|
+
|
|
|
+.pipe-item-alarm {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 4px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #F56C6C;
|
|
|
+ margin-top: 4px;
|
|
|
+}
|
|
|
+
|
|
|
/* 右侧面板 */
|
|
|
.right-panel {
|
|
|
flex: 1;
|
|
|
min-width: 0;
|
|
|
}
|
|
|
|
|
|
-/* 评估结果卡片 */
|
|
|
-.assess-result-card {
|
|
|
+/* 报警统计栏 */
|
|
|
+.alarm-stats-bar {
|
|
|
display: flex;
|
|
|
- align-items: center;
|
|
|
gap: 24px;
|
|
|
- padding: 20px;
|
|
|
+ padding: 16px 20px;
|
|
|
background: #f5f7fa;
|
|
|
border-radius: 8px;
|
|
|
}
|
|
|
|
|
|
-.assess-level {
|
|
|
- width: 120px;
|
|
|
- height: 90px;
|
|
|
- border-radius: 8px;
|
|
|
+.alarm-stat-item {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
|
- justify-content: center;
|
|
|
- color: #fff;
|
|
|
- flex-shrink: 0;
|
|
|
}
|
|
|
|
|
|
-.assess-level-text {
|
|
|
- font-size: 16px;
|
|
|
- font-weight: 600;
|
|
|
-}
|
|
|
-
|
|
|
-.assess-level-score {
|
|
|
+.alarm-stat-value {
|
|
|
font-size: 24px;
|
|
|
font-weight: 700;
|
|
|
- margin-top: 4px;
|
|
|
-}
|
|
|
-
|
|
|
-.assess-result-info {
|
|
|
- flex: 1;
|
|
|
-}
|
|
|
-
|
|
|
-.assess-result-row {
|
|
|
- font-size: 14px;
|
|
|
- color: #606266;
|
|
|
- margin-bottom: 8px;
|
|
|
+ color: #303133;
|
|
|
}
|
|
|
|
|
|
-.assess-result-row .label {
|
|
|
+.alarm-stat-label {
|
|
|
+ font-size: 13px;
|
|
|
color: #909399;
|
|
|
- margin-right: 8px;
|
|
|
-}
|
|
|
-
|
|
|
-/* 评估建议 */
|
|
|
-.suggest-section {
|
|
|
- padding: 4px 0;
|
|
|
-}
|
|
|
-
|
|
|
-.suggest-row {
|
|
|
- font-size: 14px;
|
|
|
- color: #606266;
|
|
|
- margin-bottom: 12px;
|
|
|
- line-height: 1.6;
|
|
|
+ margin-top: 4px;
|
|
|
}
|
|
|
|
|
|
-.suggest-label {
|
|
|
- color: #909399;
|
|
|
- margin-right: 8px;
|
|
|
- white-space: nowrap;
|
|
|
+/* 报警分页 */
|
|
|
+.alarm-pagination {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ margin-top: 12px;
|
|
|
}
|
|
|
</style>
|