|
@@ -1,2 +1,1312 @@
|
|
|
-<template>LEAF</template>
|
|
|
|
|
-<script setup lang="ts"></script>
|
|
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="dashboard-container">
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 主体内容 -->
|
|
|
|
|
+ <div class="main-content">
|
|
|
|
|
+ <!-- 内容区域 -->
|
|
|
|
|
+ <div class="content-area">
|
|
|
|
|
+ <!-- 顶部信息卡片 -->
|
|
|
|
|
+ <div class="top-info">
|
|
|
|
|
+ <div class="info-card">
|
|
|
|
|
+ <div class="card-title">
|
|
|
|
|
+ <div class="info-details">
|
|
|
|
|
+ <div class="label">{{ basicInfo.mineName }}</div>
|
|
|
|
|
+ <!-- <div class="value">西川煤矿分公司</div> -->
|
|
|
|
|
+ <div class="tag" :style="{ backgroundColor: getAlarmColor(basicInfo.alarmLevel), color: '#fff' }">{{ getRiskText(basicInfo.alarmLevel) }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <a-button type="primary" @click="handleGoToPageQuery('/warningAnalysis/connectAnalysis')">数据看板</a-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="info-border">
|
|
|
|
|
+ <div class="info-border-icon"></div>
|
|
|
|
|
+ <div class="info-border-line"></div>
|
|
|
|
|
+ <div class="info-border-icon"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="card-details">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="item in basicInfoColumns"
|
|
|
|
|
+ :key="item.key"
|
|
|
|
|
+ class="info-card-item"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="card-label">{{ item.label }}</div>
|
|
|
|
|
+ <div class="card-value-wrapper">
|
|
|
|
|
+ <span
|
|
|
|
|
+ v-if="['accessStatus', 'status', 'gasLevelName', 'alarmLevel', 'gjMineStatus'].includes(item.key)"
|
|
|
|
|
+ class="status-dot"
|
|
|
|
|
+ :style="{ backgroundColor: getBasicInfoColor(item.key),boxShadow: `0 0 10px ${getBasicInfoColor(item.key)}` }"
|
|
|
|
|
+ ></span>
|
|
|
|
|
+
|
|
|
|
|
+ <span
|
|
|
|
|
+ class="card-value-text"
|
|
|
|
|
+ :style="{ color: getBasicInfoColor(item.key) }"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ getBasicInfoValue(item.key) }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="card-border">
|
|
|
|
|
+ <div class="card-border-icon"></div>
|
|
|
|
|
+ <div class="card-border-line"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 预警统计 -->
|
|
|
|
|
+ <div class="warning-statistics">
|
|
|
|
|
+ <div class="statistics-header">
|
|
|
|
|
+ <div class="title">预警统计</div>
|
|
|
|
|
+ <div class="btn-group">
|
|
|
|
|
+ <!-- <button class="btn">预警级别</button> -->
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="statistics-content">
|
|
|
|
|
+ <div class="stat-item high-risk">
|
|
|
|
|
+ <div class="icon">
|
|
|
|
|
+ <div class="icon-top"></div>
|
|
|
|
|
+ <div class="icon-bottom"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="text">高风险<span class="text-sub">(需立即处理)</span></div>
|
|
|
|
|
+ <div class="count">{{ alarmStatistics.alarm4 }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="stat-item medium-risk">
|
|
|
|
|
+ <div class="icon">
|
|
|
|
|
+ <div class="icon-top"></div>
|
|
|
|
|
+ <div class="icon-bottom"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="text">较高风险<span class="text-sub">(需立即处理)</span></div>
|
|
|
|
|
+ <div class="count">{{ alarmStatistics.alarm3 }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="stat-item normal-risk">
|
|
|
|
|
+ <div class="icon">
|
|
|
|
|
+ <div class="icon-top"></div>
|
|
|
|
|
+ <div class="icon-bottom"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="text">一般风险<span class="text-sub">(需立即处理)</span></div>
|
|
|
|
|
+ <div class="count">{{ alarmStatistics.alarm2 }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="stat-item low-risk">
|
|
|
|
|
+ <div class="icon">
|
|
|
|
|
+ <div class="icon-top"></div>
|
|
|
|
|
+ <div class="icon-bottom"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="text">低风险<span class="text-sub">(需立即处理)</span></div>
|
|
|
|
|
+ <div class="count">{{ alarmStatistics.alarm1 }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 预警数据详情 -->
|
|
|
|
|
+ <div class="warning-details">
|
|
|
|
|
+ <div class="details-header">
|
|
|
|
|
+ <div class="title">预警数据详情</div>
|
|
|
|
|
+ <div class="btn-group">
|
|
|
|
|
+ <button class="btn" @click="collapseAll">收起所有分组</button>
|
|
|
|
|
+ <button class="btn" @click="expandAll">展开详情</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="details-content">
|
|
|
|
|
+ <!-- 第一个预警项 -->
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="(item, index) in goafMonitorData"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ class="warning-item"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="item-header">
|
|
|
|
|
+ <div class="header-left">
|
|
|
|
|
+ <div class="icon"></div>
|
|
|
|
|
+ <div class="name">老空区密闭名称: {{ item.devicePos }}</div>
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="risk-level"
|
|
|
|
|
+ :style="{ backgroundColor: getAlarmColor(item.alarmLevel), color: '#fff' }"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ getRiskText(item.alarmLevel) }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <a-button
|
|
|
|
|
+ class="expand-btn"
|
|
|
|
|
+ @click="toggleExpand(index)"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ isExpanded(index) ? '收起' : '展开' }}
|
|
|
|
|
+ <div class="arrow-icon-wrapper">
|
|
|
|
|
+ <div class="arrow-icon" :class="{ 'rotate': isExpanded(index) }"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </a-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="item-body">
|
|
|
|
|
+ <div class="data-row">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="(col, colIndex) in dataColumns"
|
|
|
|
|
+ :key="colIndex"
|
|
|
|
|
+ class="data-col"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="col-title">{{ col.label }}</div>
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="col-value"
|
|
|
|
|
+ :style="{ color: getColValueColor(col, item) }"
|
|
|
|
|
+ >
|
|
|
|
|
+
|
|
|
|
|
+ <span
|
|
|
|
|
+ v-if="col.type !== 'text'"
|
|
|
|
|
+ class="status-dot"
|
|
|
|
|
+ :style="{
|
|
|
|
|
+ backgroundColor: getColValueColor(col, item),
|
|
|
|
|
+ boxShadow: `0 0 10px ${getColValueColor(col, item)}`
|
|
|
|
|
+ }"
|
|
|
|
|
+ ></span>
|
|
|
|
|
+ {{ getColDisplayText(col, item) }}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="col-icon"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="monitoring-indicators" v-show="isExpanded(index)">
|
|
|
|
|
+ <div class="indicator-group">
|
|
|
|
|
+ <div class="group-title">
|
|
|
|
|
+ <div class="title-icon-top"></div>
|
|
|
|
|
+ <div class="title-icon-bottom"></div>
|
|
|
|
|
+ <div class="title-content">
|
|
|
|
|
+ 密闭墙内<br />
|
|
|
|
|
+ 监测指标
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="indicator-area">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="(ind, indIndex) in indicatorColumns"
|
|
|
|
|
+ :key="'inner-' + indIndex"
|
|
|
|
|
+ class="indicator-item"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="label">{{ ind.label }}:</div>
|
|
|
|
|
+ <!-- 墙内数据直接取 item[key],例如 item.coVal -->
|
|
|
|
|
+ <div class="value">{{ getDataValue(item, ind.key) }} {{ ind.unit }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="indicator-group">
|
|
|
|
|
+ <div class="group-title">
|
|
|
|
|
+ <div class="title-icon-top icon-outer"></div>
|
|
|
|
|
+ <div class="title-icon-bottom"></div>
|
|
|
|
|
+ <div class="title-content">
|
|
|
|
|
+ 密闭墙外<br />
|
|
|
|
|
+ 监测指标
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="indicator-area">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="(ind, indIndex) in indicatorColumns"
|
|
|
|
|
+ :key="'outer-' + indIndex"
|
|
|
|
|
+ class="indicator-item"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="label">{{ ind.label }}:</div>
|
|
|
|
|
+ <!-- 墙外数据+ Out item[key],例如 item.coValOut -->
|
|
|
|
|
+ <div class="value">{{ getDataValue(item, ind.key + 'Out') }} {{ ind.unit }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="indicator-group">
|
|
|
|
|
+ <div class="group-title">
|
|
|
|
|
+ <div class="title-icon-top icon-result"></div>
|
|
|
|
|
+ <div class="title-icon-bottom"></div>
|
|
|
|
|
+ <div class="title-content">
|
|
|
|
|
+ 预警结果
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="indicator-area indicator-result">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="(res, resIndex) in resultColumns"
|
|
|
|
|
+ :key="'result-' + resIndex"
|
|
|
|
|
+ class="indicator-item"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="label">{{ res.label }}:</div>
|
|
|
|
|
+ <div class="value">{{ res.value }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <!-- 需要占位符以保持网格对齐,保留一个空的 placeholder -->
|
|
|
|
|
+ <div class="indicator-item placeholder-item"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 异常超限报警 -->
|
|
|
|
|
+ <div class="abnormal-alarm">
|
|
|
|
|
+ <div class="alarm-header">
|
|
|
|
|
+ <div class="title">异常超限报警</div>
|
|
|
|
|
+ <div class="btn-group">
|
|
|
|
|
+ <!-- <button class="btn">收起图表</button> -->
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="alarm-content">
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-for="(alarm, index) in alarmColumns"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ class="alarm-item"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="alarm-name">{{ alarm.label }}</div>
|
|
|
|
|
+ <div class="alarm-count">{{ mineAlarmData[alarm.key] ?? '-' }}</div>
|
|
|
|
|
+ <div class="alarm-border">
|
|
|
|
|
+ <div class="alarm-border-icon"></div>
|
|
|
|
|
+ <div class="alarm-border-line"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="alarm-border-bottom"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 历史数据折线图 -->
|
|
|
|
|
+ <div class="historical-data">
|
|
|
|
|
+ <div class="chart-header">
|
|
|
|
|
+ <div class="title">历史数据分析图表</div>
|
|
|
|
|
+ <div class="btn-group">
|
|
|
|
|
+ <button class="btn" @click="toggleChartVisibility">
|
|
|
|
|
+ {{ isChartVisible ? '收起图表' : '展开图表' }}
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="chart-content" v-show="isChartVisible">
|
|
|
|
|
+ <ConnectAnalysis ref="connectAnalysisRef"/>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+ import { useRouter, useRoute } from 'vue-router';
|
|
|
|
|
+ import { useAppStore } from '/@/store/modules/app';
|
|
|
|
|
+ import { computed, ref, watch, onMounted, nextTick } from 'vue';
|
|
|
|
|
+ import { useMineDepartmentStore } from '/@/store/modules/mine';
|
|
|
|
|
+ import { getGoafAlarmNum, getGoafData, getMineData, getProvinceAlarm } from '../overhaul.api';
|
|
|
|
|
+ import { StatusColorEnum } from '/@/enums/jeecgEnum';
|
|
|
|
|
+ import ConnectAnalysis from '/@/views/analysis/warningAnalysis/connectAnalysis/index.vue';
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ const appStore = useAppStore();
|
|
|
|
|
+ const mineStore = useMineDepartmentStore();
|
|
|
|
|
+
|
|
|
|
|
+ // 路由实例
|
|
|
|
|
+ const router = useRouter();
|
|
|
|
|
+ const route = useRoute();
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 定义数据类型接口
|
|
|
|
|
+ interface GoafMonitorItem {
|
|
|
|
|
+ devicePos?: string;
|
|
|
|
|
+ [key: string]: any; // 允许其他动态属性
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 风险等级映射配置
|
|
|
|
|
+ */
|
|
|
|
|
+ const RISK_LEVEL_MAP: Record<string, { text: string; color: string }> = {
|
|
|
|
|
+ '4': { text: '高风险', color: StatusColorEnum.red },
|
|
|
|
|
+ '3': { text: '较高风险', color: StatusColorEnum.gold },
|
|
|
|
|
+ '2': { text: '一般风险', color: StatusColorEnum.yellow },
|
|
|
|
|
+ '1': { text: '低风险', color: StatusColorEnum.blue },
|
|
|
|
|
+ '0': { text: '无风险', color: '#333' }, // 假设 0 为无风险或默认
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 顶部的基础信息部分
|
|
|
|
|
+ const basicInfoColumns = [
|
|
|
|
|
+ { label: '组织机构', key: 'parentArea' },
|
|
|
|
|
+ { label: '瓦斯等级', key: 'gasLevelName' },
|
|
|
|
|
+ { label: '煤层自燃倾向性', key: 'coalSeamLevel' },
|
|
|
|
|
+ { label: '生产状态', key: 'gjMineStatus' },
|
|
|
|
|
+ { label: '预警结果', key: 'alarmLevel' },
|
|
|
|
|
+ { label: '预警时间', key: 'createTime' },
|
|
|
|
|
+ { label: '持续时间', key: 'chixuTime' },
|
|
|
|
|
+ { label: '接入状态', key: 'accessStatus' },
|
|
|
|
|
+ { label: '数据联网状态', key: 'status' },
|
|
|
|
|
+ { label: '设备数量', key: 'accessGoafNum' },
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 预警数据详情 - 顶部指标列配置
|
|
|
|
|
+ const dataColumns = [
|
|
|
|
|
+ { label: '闭内自燃发火隐患', key: 'fireAlarm.alarmName', colorKey: 'fireAlarm.alarmLevel', type: 'alarm' },
|
|
|
|
|
+ { label: '闭外自燃发火隐患', key: 'fireAlarmOut.alarmName', colorKey: 'fireAlarmOut.alarmLevel', type: 'alarm' },
|
|
|
|
|
+ { label: '爆炸三角', key: 'explosionAlarm.alarmName', colorKey: 'explosionAlarm.alarmLevel', type: 'alarm' },
|
|
|
|
|
+ { label: '压差预警', key: 'sourcePressureAlarm.alarmName', colorKey: 'sourcePressureAlarm.alarmLevel', type: 'alarm' },
|
|
|
|
|
+ { label: '漏风状态判定', key: 'leakageAlarm.alarmName', colorKey: 'leakageAlarm.alarmLevel', type: 'alarm' },
|
|
|
|
|
+ { label: '设备状态', key: 'linkStatus', type: 'status' },
|
|
|
|
|
+ { label: '检查时间', key: 'readTime',type: 'text' },
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 监测指标通用配置 (用于墙内和墙外)
|
|
|
|
|
+ const indicatorColumns = [
|
|
|
|
|
+ { label: 'CO', key: 'coVal', unit: 'ppm' },
|
|
|
|
|
+ { label: 'CO2', key: 'co2Val', unit: '%' },
|
|
|
|
|
+ { label: 'CH4', key: 'ch4Val', unit: '%' },
|
|
|
|
|
+ { label: 'O2', key: 'o2Val', unit: '%' },
|
|
|
|
|
+ { label: 'C2H2', key: 'c2h2Val', unit: 'ppm' },
|
|
|
|
|
+ { label: 'C2H4', key: 'c2h4Val', unit: 'ppm' },
|
|
|
|
|
+ { label: '温度', key: 'temperature', unit: '°C' },
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 预警结果配置
|
|
|
|
|
+ const resultColumns = [
|
|
|
|
|
+ { label: '数据来源', value: '最近2天' }, // 静态数据可以直接写死在配置里,或者从 item 取
|
|
|
|
|
+ { label: '预警结果', value: '异常' }, // 这里假设是静态展示,如果是动态可改为 key: 'resultStatus'
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 异常超限报警配置
|
|
|
|
|
+ const alarmColumns = [
|
|
|
|
|
+ { label: '甲烷超限', key: 'ch4Val' },
|
|
|
|
|
+ { label: '氧气超限', key: 'o2Val' },
|
|
|
|
|
+ { label: '一氧化碳超限', key: 'coVal' },
|
|
|
|
|
+ { label: '二氧化碳超限', key: 'co2Val' },
|
|
|
|
|
+ { label: '乙烯超限', key: 'c2h4Val' },
|
|
|
|
|
+ { label: '乙炔超限', key: 'c2h2Val' },
|
|
|
|
|
+ { label: '压差超限', key: 'sourcePressure' },
|
|
|
|
|
+ { label: '温度超限', key: 'temperature' },
|
|
|
|
|
+ ];
|
|
|
|
|
+ const basicInfo = ref<any>({}); //煤矿基础信息数据
|
|
|
|
|
+ const alarmStatistics = ref<any>({}); //预警统计数据
|
|
|
|
|
+ const goafMonitorData = ref<GoafMonitorItem[]>([]); //密闭监测详情数据
|
|
|
|
|
+ const mineAlarmData = ref<any>({}); // 煤矿预警数据
|
|
|
|
|
+
|
|
|
|
|
+ const connectAnalysisRef = ref<any>(null); // 连接分析组件实例
|
|
|
|
|
+ const isChartVisible = ref(true); // 控制图表显示/隐藏的状态
|
|
|
|
|
+
|
|
|
|
|
+ // 1. 用于存储展开状态的索引集合 (key: index, value: boolean)
|
|
|
|
|
+ const expandedIndices = ref<Record<number, boolean>>({});
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 切换展开/收起状态的方法
|
|
|
|
|
+ const toggleExpand = (index: number) => {
|
|
|
|
|
+ expandedIndices.value[index] = !expandedIndices.value[index];
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 判断是否展开
|
|
|
|
|
+ const isExpanded = (index: number) => {
|
|
|
|
|
+ return !!expandedIndices.value[index];
|
|
|
|
|
+ };
|
|
|
|
|
+ // 4. 展开所有详情
|
|
|
|
|
+ const expandAll = () => {
|
|
|
|
|
+ goafMonitorData.value.forEach((_, index) => {
|
|
|
|
|
+ expandedIndices.value[index] = true;
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 收起所有分组
|
|
|
|
|
+ const collapseAll = () => {
|
|
|
|
|
+ // 清空对象即可,或者遍历设为 false
|
|
|
|
|
+ expandedIndices.value = {};
|
|
|
|
|
+ };
|
|
|
|
|
+ // 切换图表显示状态
|
|
|
|
|
+ const toggleChartVisibility = () => {
|
|
|
|
|
+ isChartVisible.value = !isChartVisible.value;
|
|
|
|
|
+ };
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取设备状态信息 (文本和颜色)
|
|
|
|
|
+ * @param status 0: 断开, 1: 正常
|
|
|
|
|
+ */
|
|
|
|
|
+ const getlinkStatusInfo = (status?: number | string) => {
|
|
|
|
|
+ if (status === 1 || status === '1') {
|
|
|
|
|
+ return { text: '正常', color: '#52c41a' }; // 绿色
|
|
|
|
|
+ }
|
|
|
|
|
+ return { text: '断开', color: '#ff4d4f' }; // 红色
|
|
|
|
|
+ };
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取列显示的文本
|
|
|
|
|
+ */
|
|
|
|
|
+ const getColDisplayText = (col: any, item: any) => {
|
|
|
|
|
+ const rawValue = getDataValue(item, col.key);
|
|
|
|
|
+
|
|
|
|
|
+ if (col.type === 'status') {
|
|
|
|
|
+ return getlinkStatusInfo(rawValue).text;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 默认直接返回原始值或经过 getDataValue 处理后的值
|
|
|
|
|
+ return rawValue;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取列显示的颜色
|
|
|
|
|
+ */
|
|
|
|
|
+ const getColValueColor = (col: any, item: any) => {
|
|
|
|
|
+ // 如果是报警类型,使用原有的报警颜色逻辑
|
|
|
|
|
+ if (col.type === 'alarm' && col.colorKey) {
|
|
|
|
|
+ return getAlarmColor(getDataValue(item, col.colorKey));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果是设备状态类型,使用状态颜色逻辑
|
|
|
|
|
+ if (col.type === 'status') {
|
|
|
|
|
+ return getlinkStatusInfo(getDataValue(item, col.key)).color;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 默认黑色
|
|
|
|
|
+ return '#333';
|
|
|
|
|
+ };
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取风险等级对应的文本
|
|
|
|
|
+ * @param level 报警级别 '1', '2', '3', '4'
|
|
|
|
|
+ */
|
|
|
|
|
+ const getRiskText = (level?: string | number) => {
|
|
|
|
|
+ if (!level && level !== 0) return '-';
|
|
|
|
|
+ return RISK_LEVEL_MAP[String(level)]?.text || '未知';
|
|
|
|
|
+ };
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据点分字符串路径获取对象值 (例如: 'fireAlarm.alarmName')
|
|
|
|
|
+ * @param item 数据对象
|
|
|
|
|
+ * @param path 路径字符串
|
|
|
|
|
+ * @param defaultValue 默认值
|
|
|
|
|
+ */
|
|
|
|
|
+ const getDataValue = (item: any, path: string, defaultValue: string = '-') => {
|
|
|
|
|
+ if (!item || !path) return defaultValue;
|
|
|
|
|
+ const val = path.split('.').reduce((acc, part) => acc && acc[part], item);
|
|
|
|
|
+ return val ?? defaultValue;
|
|
|
|
|
+ };
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取报警颜色
|
|
|
|
|
+ * @param level 报警级别 '1', '2', '3', '4'
|
|
|
|
|
+ */
|
|
|
|
|
+ const getAlarmColor = (level?: string | number) => {
|
|
|
|
|
+ if (!level && level !== 0) return '#333'; // 默认颜色
|
|
|
|
|
+ return RISK_LEVEL_MAP[String(level)]?.color;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取基础信息的显示内容(包含文本和颜色)
|
|
|
|
|
+ */
|
|
|
|
|
+ const getBasicInfoDisplay = (key: string) => {
|
|
|
|
|
+ const value = basicInfo.value[key];
|
|
|
|
|
+
|
|
|
|
|
+ // 默认返回黑色文本
|
|
|
|
|
+ const defaultResult = { text: value ?? '-', color: '#333' };
|
|
|
|
|
+
|
|
|
|
|
+ if (key === 'accessStatus') {
|
|
|
|
|
+ // 1: 已接入 (绿色), 其他: 未接入 (红色)
|
|
|
|
|
+ return value === 1
|
|
|
|
|
+ ? { text: '已接入', color: '#52c41a' }
|
|
|
|
|
+ : { text: '未接入', color: StatusColorEnum.red };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (key === 'status') {
|
|
|
|
|
+ // 1: 在线 (绿色), 其他: 离线 (红色)
|
|
|
|
|
+ return value === 1
|
|
|
|
|
+ ? { text: '在线', color: '#52c41a' }
|
|
|
|
|
+ : { text: '离线', color: StatusColorEnum.red };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (key === 'alarmLevel') {
|
|
|
|
|
+ // 根据风险等级获取颜色
|
|
|
|
|
+ const levelStr = String(value);
|
|
|
|
|
+ const riskInfo = RISK_LEVEL_MAP[levelStr];
|
|
|
|
|
+ if (riskInfo) {
|
|
|
|
|
+ return { text: riskInfo.text, color: riskInfo.color };
|
|
|
|
|
+ }
|
|
|
|
|
+ return { text: '未知', color: '#333' };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (key === 'gasLevelName') {
|
|
|
|
|
+ // 瓦斯等级特殊处理
|
|
|
|
|
+ const val = String(value);
|
|
|
|
|
+ if (val.includes('低瓦斯')) {
|
|
|
|
|
+ return { text: val, color: StatusColorEnum.blue }; // 蓝色
|
|
|
|
|
+ } else if (val.includes('高瓦斯')) {
|
|
|
|
|
+ return { text: val, color: StatusColorEnum.gold }; // 橙色/金色
|
|
|
|
|
+ } else if (val.includes('突出')) {
|
|
|
|
|
+ return { text: val, color: StatusColorEnum.red }; // 红色
|
|
|
|
|
+ }
|
|
|
|
|
+ return { text: val, color: '#333' };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (key === 'gjMineStatus') {
|
|
|
|
|
+ // 生产状态特殊处理
|
|
|
|
|
+ const val = String(value);
|
|
|
|
|
+ if (val.includes('正常生产')) {
|
|
|
|
|
+ return { text: val, color: '#52c41a' }; // 绿色
|
|
|
|
|
+ } else if (val.includes('拟建')) {
|
|
|
|
|
+ return { text: val, color: StatusColorEnum.blue }; // 蓝色
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 其余状态均显示绿色
|
|
|
|
|
+ return { text: val, color: StatusColorEnum.red };
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ return defaultResult;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取基础信息值的文本(兼容旧逻辑,如果只需要文本)
|
|
|
|
|
+ */
|
|
|
|
|
+ const getBasicInfoValue = (key: string) => {
|
|
|
|
|
+ return getBasicInfoDisplay(key).text;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取基础信息值的颜色
|
|
|
|
|
+ */
|
|
|
|
|
+ const getBasicInfoColor = (key: string) => {
|
|
|
|
|
+ return getBasicInfoDisplay(key).color;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 通用页面跳转方法
|
|
|
|
|
+ * @param record 当前行数据
|
|
|
|
|
+ * @param path 目标路径
|
|
|
|
|
+ */
|
|
|
|
|
+ function handleGoToPageQuery(path: string) {
|
|
|
|
|
+
|
|
|
|
|
+ router.push({
|
|
|
|
|
+ path,
|
|
|
|
|
+ }).catch(err => {
|
|
|
|
|
+ console.error('跳转失败:', err);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async function fetchLeafData() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 异步获取所有接口数据(并行请求提升性能)
|
|
|
|
|
+ const [goafAlarmNum, goafData, mineData, alarmData ] = await Promise.all([
|
|
|
|
|
+ getGoafAlarmNum(appStore.simpleMapParams), // 预警统计
|
|
|
|
|
+ getGoafData(appStore.simpleMapParams), // 密闭监测数据
|
|
|
|
|
+ getMineData(appStore.simpleMapParams), // 煤矿基础信息数据
|
|
|
|
|
+ getProvinceAlarm(appStore.simpleMapParams), // 预警信息列表
|
|
|
|
|
+ ]);
|
|
|
|
|
+ alarmStatistics.value = goafAlarmNum[0];
|
|
|
|
|
+ goafMonitorData.value = goafData.records;
|
|
|
|
|
+ basicInfo.value = mineData.records[0];
|
|
|
|
|
+ mineAlarmData.value = alarmData.records[0];
|
|
|
|
|
+
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ if (connectAnalysisRef.value && typeof connectAnalysisRef.value.generateChart === 'function') {
|
|
|
|
|
+ connectAnalysisRef.value.generateChart();
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('数据获取/配置更新失败:', error);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ onMounted(() => {
|
|
|
|
|
+ fetchLeafData();
|
|
|
|
|
+ console.log('当前页面的参数:', mineStore.getRoot);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+// 页面逻辑代码
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+.dashboard-container {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ overflow: scroll;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ padding: 16px 24px;
|
|
|
|
|
+ background-color: #1a3d72;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ font-size: 18px;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.user-info {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.sidebar {
|
|
|
|
|
+ width: 200px;
|
|
|
|
|
+ background-color: #1a3d72;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ padding: 20px 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.menu-item {
|
|
|
|
|
+ padding: 12px 20px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ transition: background-color 0.3s;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.menu-item:hover {
|
|
|
|
|
+ background-color: rgba(255, 255, 255, 0.1);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.menu-item.active {
|
|
|
|
|
+ background-color: rgba(255, 255, 255, 0.2);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.content-area {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ padding: 20px;
|
|
|
|
|
+ background-color: #f0f8ff;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.top-info {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 200px;
|
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.info-card {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: row;
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/info-card-bg.png');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100%;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ padding: 20px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.card-title {
|
|
|
|
|
+ width: 20%;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ padding: 8px 10px 8px 50px;
|
|
|
|
|
+}
|
|
|
|
|
+.info-border {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 20px;
|
|
|
|
|
+ left: 20px;
|
|
|
|
|
+ .info-border-icon {
|
|
|
|
|
+ width: 16px;
|
|
|
|
|
+ height: 16px;
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/info-card-icon1.svg');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100%;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ .info-border-line {
|
|
|
|
|
+ width: 1px;
|
|
|
|
|
+ height: 95px;
|
|
|
|
|
+ border-left: 2px dotted #397af3;
|
|
|
|
|
+ margin-left: 7px;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+.info-details {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ padding: 8px 0;
|
|
|
|
|
+
|
|
|
|
|
+ .label {
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ color: #000;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .value {
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ color: #000;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .tag {
|
|
|
|
|
+ width: fit-content;
|
|
|
|
|
+ height: 24px;
|
|
|
|
|
+ padding: 2px 8px;
|
|
|
|
|
+ border-radius: 15px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ background-color: #ff6b6b;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.card-details {
|
|
|
|
|
+ width: 80%;
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: repeat(5, 1fr);
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+.info-card-item {
|
|
|
|
|
+ max-width: 245px;
|
|
|
|
|
+ height: 70px;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ padding: 8px 10px 8px 40px;;
|
|
|
|
|
+ background-color: #f1f7ff;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ text-align: left;
|
|
|
|
|
+}
|
|
|
|
|
+.card-border {
|
|
|
|
|
+ width: 20px;
|
|
|
|
|
+ height: 50px;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 14px;
|
|
|
|
|
+ left: 15px;
|
|
|
|
|
+
|
|
|
|
|
+ .card-border-icon{
|
|
|
|
|
+ width: 16px;
|
|
|
|
|
+ height: 16px;
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/info-card-icon.svg');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100%;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ .card-border-line{
|
|
|
|
|
+ width: 1px;
|
|
|
|
|
+ height: 30px;
|
|
|
|
|
+ border-left: 2px dotted #397af3;
|
|
|
|
|
+ margin-left: 7px;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.card-label {
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ color: #000;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.card-value-wrapper {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 6px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.status-dot {
|
|
|
|
|
+ width: 8px;
|
|
|
|
|
+ height: 8px;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ display: inline-block;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.card-value-text {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+.warning-statistics {
|
|
|
|
|
+ background-color: #ffffff;
|
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.statistics-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.title {
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.btn-group {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.btn {
|
|
|
|
|
+ color: #2b6ff0;
|
|
|
|
|
+ padding: 6px 12px;
|
|
|
|
|
+ border: 1px solid #2b6ff0;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ background-color: #E9F0FE;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.btn:hover {
|
|
|
|
|
+ background-color: #f5f5f5;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.statistics-content {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 50px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.stat-item {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ padding: 16px 50px 10px 90px;
|
|
|
|
|
+ text-align: left;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/high-risk-bg.png');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100%;
|
|
|
|
|
+
|
|
|
|
|
+ .icon {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 15px;
|
|
|
|
|
+ left: 20px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .text {
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ color: #000;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ .text-sub {
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ color: #989587;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .count {
|
|
|
|
|
+ font-size: 24px;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .icon-top{
|
|
|
|
|
+ width: 40px;
|
|
|
|
|
+ height: 40px;
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/high-risk-icon1.svg');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100%;;
|
|
|
|
|
+ }
|
|
|
|
|
+ .icon-bottom{
|
|
|
|
|
+ width: 40px;
|
|
|
|
|
+ height: 20px;
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/high-risk-icon2.png');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100%;
|
|
|
|
|
+ margin-top: -5px;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.stat-item.high-risk {
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/high-risk-bg.png');
|
|
|
|
|
+ .icon-top {
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/high-risk-icon1.svg');
|
|
|
|
|
+ }
|
|
|
|
|
+ .icon-bottom {
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/high-risk-icon2.png');
|
|
|
|
|
+ }
|
|
|
|
|
+ .count {
|
|
|
|
|
+ color: #FF0000;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.stat-item.medium-risk {
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/medium-risk-bg.png');
|
|
|
|
|
+ .icon-top {
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/medium-risk-icon1.svg');
|
|
|
|
|
+ }
|
|
|
|
|
+ .icon-bottom {
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/medium-risk-icon2.png');
|
|
|
|
|
+ }
|
|
|
|
|
+ .count {
|
|
|
|
|
+ color: #FF7700;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.stat-item.normal-risk {
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/normal-risk-bg.png');
|
|
|
|
|
+ .icon-top {
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/normal-risk-icon1.svg');
|
|
|
|
|
+ }
|
|
|
|
|
+ .icon-bottom {
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/normal-risk-icon2.png');
|
|
|
|
|
+ }
|
|
|
|
|
+ .count {
|
|
|
|
|
+ color: #D5C702;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.stat-item.low-risk {
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/low-risk-bg.png');
|
|
|
|
|
+ .icon-top {
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/low-risk-icon1.svg');
|
|
|
|
|
+ }
|
|
|
|
|
+ .icon-bottom {
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/low-risk-icon2.png');
|
|
|
|
|
+ }
|
|
|
|
|
+ .count {
|
|
|
|
|
+ color: #0070FF;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.warning-details {
|
|
|
|
|
+ background-color: #ffffff;
|
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.details-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.warning-item {
|
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
|
+ background-color: rgba(218, 234, 251, 0.5);
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ padding: 16px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.item-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ padding-bottom: 10px;
|
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
|
+ border-bottom: 1px solid rgba(43, 111, 240, 0.2);
|
|
|
|
|
+
|
|
|
|
|
+ .icon {
|
|
|
|
|
+ width: 16px;
|
|
|
|
|
+ height: 16px;
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/info-card-icon1.svg');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+ .name {
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ margin: 0 15px 0px 5px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .risk-level {
|
|
|
|
|
+ width: fit-content;
|
|
|
|
|
+ height: 24px;
|
|
|
|
|
+ padding: 2px 8px;
|
|
|
|
|
+ border-radius: 15px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ background-color: #ff6b6b;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ .header-left {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .expand-btn {
|
|
|
|
|
+ color: #2b6ff0;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 4px;
|
|
|
|
|
+ padding: 6px 12px;
|
|
|
|
|
+ border: 1px solid #2b6ff0;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ background-color: #E9F0FE;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .expand-btn:hover {
|
|
|
|
|
+ color: #1a5cc8;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .arrow-icon-wrapper {
|
|
|
|
|
+ width: 16px;
|
|
|
|
|
+ height: 16px;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ display: inline-block;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .arrow-icon {
|
|
|
|
|
+ width: 16px;
|
|
|
|
|
+ height: 16px;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 50%;
|
|
|
|
|
+ left: 50%;
|
|
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/icon-down.png');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100% 100%;
|
|
|
|
|
+ transition: transform 0.3s ease;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .arrow-icon.rotate {
|
|
|
|
|
+ transform: translate(-50%, -50%) rotate(180deg);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.data-row {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: repeat(7, 1fr);
|
|
|
|
|
+ gap: 12px;
|
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.data-col {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 80px;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: start;
|
|
|
|
|
+ justify-content: center ;
|
|
|
|
|
+ padding: 0 16px 0 30px;
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/warning-item-bg.png');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100% 100%;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+
|
|
|
|
|
+ .col-title {
|
|
|
|
|
+ color: #000;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ margin-bottom: 5px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .col-value {
|
|
|
|
|
+ color: #000;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+
|
|
|
|
|
+ .status-dot {
|
|
|
|
|
+ width: 8px;
|
|
|
|
|
+ height: 8px;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ display: inline-block;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .col-icon {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 10px;
|
|
|
|
|
+ left: 10px;
|
|
|
|
|
+ width: 18px;
|
|
|
|
|
+ height: 18px;
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/info-card-icon.svg');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.monitoring-indicators {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 20px;
|
|
|
|
|
+ margin-top: 20px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.indicator-group {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ background-color: white;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
|
|
|
+ min-width: 0;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.indicator-group:nth-child(1) {
|
|
|
|
|
+ flex: 4;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.indicator-group:nth-child(2) {
|
|
|
|
|
+ flex: 4;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.indicator-group:nth-child(3) {
|
|
|
|
|
+ flex: 2;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.group-title {
|
|
|
|
|
+ width: 120px;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ color: #000;
|
|
|
|
|
+ background-color: rgba(192, 222, 255, 0.6);
|
|
|
|
|
+
|
|
|
|
|
+ .title-icon-top {
|
|
|
|
|
+ width: 30px;
|
|
|
|
|
+ height: 30px;
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/icon-top1.svg');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100%;
|
|
|
|
|
+ margin-bottom: -5px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .icon-outer{
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/icon-top2.svg');
|
|
|
|
|
+ }
|
|
|
|
|
+ .icon-result{
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/icon-top3.svg');
|
|
|
|
|
+ }
|
|
|
|
|
+ .title-icon-bottom{
|
|
|
|
|
+ width: 50px;
|
|
|
|
|
+ height: 23px;
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/icon-bottom.png');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.indicator-area {
|
|
|
|
|
+ width: calc(100% - 120px);
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: repeat(3, 1fr);
|
|
|
|
|
+ gap: 10px;
|
|
|
|
|
+ padding: 10px 16px;
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+.indicator-result {
|
|
|
|
|
+ grid-template-columns: repeat(1, 1fr);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.indicator-item {
|
|
|
|
|
+ height: 30px;
|
|
|
|
|
+ line-height: 30px;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ background: linear-gradient(90deg, rgba(192, 222, 255, 0.5) 0%, rgba(192, 222, 255, 0.2) 100%);
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
|
+ padding: 0 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 预警结果只有两行,用来占位的 item */
|
|
|
|
|
+.placeholder-item {
|
|
|
|
|
+ visibility: hidden;
|
|
|
|
|
+ height: 30px;
|
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
|
+ background: transparent;
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.indicator-result .indicator-item:last-of-type {
|
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.indicator-item:last-child {
|
|
|
|
|
+ border-bottom: none;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+.abnormal-alarm {
|
|
|
|
|
+ background-color: #fff;
|
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.alarm-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.alarm-content {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+ gap: 16px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.alarm-item {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ min-width: 120px;
|
|
|
|
|
+ height: 70px;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ padding: 8px 10px 8px 40px;;
|
|
|
|
|
+ background-color: rgba(215, 233, 253, 0.9);
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ text-align: left;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.alarm-name {
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ color: #000;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.alarm-count {
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+}
|
|
|
|
|
+.alarm-border {
|
|
|
|
|
+ width: 20px;
|
|
|
|
|
+ height: 50px;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 14px;
|
|
|
|
|
+ left: 15px;
|
|
|
|
|
+
|
|
|
|
|
+ .alarm-border-icon{
|
|
|
|
|
+ width: 16px;
|
|
|
|
|
+ height: 16px;
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/info-card-icon.svg');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100%;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ .alarm-border-line{
|
|
|
|
|
+ width: 1px;
|
|
|
|
|
+ height: 30px;
|
|
|
|
|
+ border-left: 2px dotted #397af3;
|
|
|
|
|
+ margin-left: 7px;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+.alarm-border-bottom{
|
|
|
|
|
+ width: 30px;
|
|
|
|
|
+ height: 30px;
|
|
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafgPage/alarm-card-icon.png');
|
|
|
|
|
+ background-repeat: no-repeat;
|
|
|
|
|
+ background-size: 100%;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.historical-data {
|
|
|
|
|
+ background-color: #fff;
|
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.chart-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.chart-content {
|
|
|
|
|
+ padding: 0;
|
|
|
|
|
+ height: 600px;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 深度选择器:重置 ConnectAnalysis 的样式以适配嵌入环境 */
|
|
|
|
|
+:deep(.connectAnalysis) {
|
|
|
|
|
+ margin: 0 !important;
|
|
|
|
|
+ width: 100% !important;
|
|
|
|
|
+ height: 100% !important;
|
|
|
|
|
+ border: none !important;
|
|
|
|
|
+ box-shadow: none !important;
|
|
|
|
|
+ padding: 0 !important;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.filter-area) {
|
|
|
|
|
+ display: none;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.echart-box) {
|
|
|
|
|
+ /* 让图表区域占据剩余所有高度 */
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ height: auto !important;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ padding: 10px;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.echart-content) {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ height: auto !important;
|
|
|
|
|
+ min-height: 300px;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|