|
|
@@ -1,58 +1,309 @@
|
|
|
<template>
|
|
|
<div class="dashboard-container">
|
|
|
- <div class="info-card">
|
|
|
- <div class="card-title">
|
|
|
- <div class="info-details">
|
|
|
- <div class="label">{{ mineStore.getRoot }}</div>
|
|
|
- <!-- <div class="value">西川煤矿分公司</div> -->
|
|
|
- <!-- <div class="tag" :style="{ backgroundColor: getAlarmColor(basicInfo.alarmLevel), color: '#fff' }">
|
|
|
- {{ getRiskText(basicInfo.alarmLevel) }}
|
|
|
- </div> -->
|
|
|
+ <div class="content-area" v-if="isDataLoaded">
|
|
|
+ <!-- 顶部信息卡片 -->
|
|
|
+ <div class="top-info">
|
|
|
+ <!-- {{ mineStore.getRoot }} -->
|
|
|
+ <div class="info-card">
|
|
|
+ <div class="card-title">
|
|
|
+ <div class="info-details">
|
|
|
+ <div class="label">{{ mineStore.getRoot?.departName }}</div>
|
|
|
+ <!-- <div class="tag" :style="{ backgroundColor: getAlarmColor(mineStore.alarmLevel), color: '#fff' }">{{ getRiskText(mineStore.alarmLevel) }}</div> -->
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <a-button class="btn" @click="handleGoToPageQuery('/basicinfo/access-statistics')">接入详情</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="value in accessStatics" :key="value.id" class="card-item">
|
|
|
+ <div class="item-cont">
|
|
|
+ 组织机构:{{ value.name }}
|
|
|
+ </div>
|
|
|
+ <div class="item-cont">
|
|
|
+ 应接入:{{ value.yjNum }}
|
|
|
+ </div>
|
|
|
+ <div class="item-cont">
|
|
|
+ 在线:{{ value.yjNum }}
|
|
|
+ </div>
|
|
|
+ <div class="item-cont">
|
|
|
+ 中断:{{ value.yjNum }}
|
|
|
+ </div>
|
|
|
+ <div class="item-cont">
|
|
|
+ 未接入:{{ value.yjNum }}
|
|
|
+ </div>
|
|
|
+ <div class="item-cont">
|
|
|
+ 接入密闭数:{{ value.yjNum }}
|
|
|
+ </div>
|
|
|
+ <div class="bg-line">
|
|
|
+ </div>
|
|
|
+ <div class="bg-icon"></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">超限异常报警</div>
|
|
|
+ <div class="count">{{ realtimeWarning.overLimitCount }}</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">预测预警</div>
|
|
|
+ <div class="count">{{ realtimeWarning.alarmInfoCount }}</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">数据中断</div>
|
|
|
+ <div class="count">{{ realtimeWarning.dataBreakCount }}</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">数据质量</div>
|
|
|
+ <div class="count">{{ realtimeWarning.dataQualityCount }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 预警数据详情 -->
|
|
|
+ <div class="warning-details">
|
|
|
+ <div class="details-header">
|
|
|
+ <div class="title">预警数据详情</div>
|
|
|
+ <div class="btn-group">
|
|
|
+ <button class="btn" @click="handleShowDetail({deptId:mineStore.getRootId})">展开详情</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="details-content">
|
|
|
+ <div
|
|
|
+ v-for="(item, index) in mineData?.records"
|
|
|
+ :key="index"
|
|
|
+ class="warning-item"
|
|
|
+ >
|
|
|
+ <div class="item-header">
|
|
|
+ <div class="header-left">
|
|
|
+ <div class="icon"></div>
|
|
|
+ <div class="name">煤矿名称: {{ item.mineName }}</div>
|
|
|
+ <div
|
|
|
+ class="risk-level"
|
|
|
+ :style="{ backgroundColor: getAlarmColor(item.alarmLevel), color: '#fff' }"
|
|
|
+ >
|
|
|
+ {{ getRiskText(item.alarmLevel) }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <a-button
|
|
|
+ class="expand-btn"
|
|
|
+ @click="handleShowDetail(item)"
|
|
|
+ >
|
|
|
+ 详情
|
|
|
+ </a-button>
|
|
|
+ </div>
|
|
|
+ <div class="item-body">
|
|
|
+ <div class="data-row">
|
|
|
+ <div
|
|
|
+ v-for="(col, colIndex) in dataColumns"
|
|
|
+ :key="colIndex"
|
|
|
+ class="data-col"
|
|
|
+ :class="{
|
|
|
+ 'col-first-row': colIndex < 5,
|
|
|
+ 'col-second-row': colIndex >= 5,
|
|
|
+ 'col-span-3': colIndex === 5
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <div class="col-icon">
|
|
|
+ <div class="icon-item" :class="`alarm-icon-${(colIndex % 8) + 1}`"></div>
|
|
|
+ </div>
|
|
|
+ <div class="col-cont">
|
|
|
+ <div class="col-title">{{ col.label }}</div>
|
|
|
+ <div
|
|
|
+ class="col-value"
|
|
|
+ :style="{ color: getColValueColor(col, item) }"
|
|
|
+ >
|
|
|
+ <span
|
|
|
+ v-if="col.showPoint"
|
|
|
+ class="status-dot"
|
|
|
+ :style="{
|
|
|
+ backgroundColor: getColValueColor(col, item),
|
|
|
+ boxShadow: `0 0 10px ${getColValueColor(col, item)}`
|
|
|
+ }"
|
|
|
+ ></span>
|
|
|
+ {{ getColDisplayText(col, item) }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 近半年报警统计 -->
|
|
|
+ <div class="half-year-statistics">
|
|
|
+ <div class="statistics-header">
|
|
|
+ <div class="title">近半年预测预报统计</div>
|
|
|
+ <div class="btn-group">
|
|
|
+ <button class="btn" @click="toggleChartVisibility">
|
|
|
+ {{ isChartVisible ? '收起图表' : '展开图表' }}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="statistics-content" v-show="isChartVisible">
|
|
|
+ <!-- 左侧饼图区域 -->
|
|
|
+ <div class="chart-item pie-chart">
|
|
|
+ <div class="chart-title">预测预报类型统计</div>
|
|
|
+ <Pie :chart-data="alarmType"></Pie>
|
|
|
+ </div>
|
|
|
+ <!-- 右侧柱状图区域 -->
|
|
|
+ <div class="chart-item bar-chart">
|
|
|
+ <div class="chart-title">重点矿井报警次数统计</div>
|
|
|
+ <Bar :chart-data="historyAlarmNum"></Bar>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <a-card>
|
|
|
- <title>{{ mineStore.getRoot?.departName }}</title>
|
|
|
- <span v-for="value in accessStatics" :key="value.id">
|
|
|
- 组织机构:{{ value.name }} 应接入:{{ value.yjNum }} 在线:{{ value.yjNum }} 中断:{{ value.yjNum }} 未接入:{{ value.yjNum }} 接入密闭数:{{
|
|
|
- value.yjNum
|
|
|
- }}
|
|
|
- </span>
|
|
|
- </a-card>
|
|
|
-
|
|
|
- <a-card title="实时预警统计">
|
|
|
- {{ realtimeWarning }}
|
|
|
- </a-card>
|
|
|
-
|
|
|
- <a-card title="预警数据详情">
|
|
|
- {{ mineData }}
|
|
|
- </a-card>
|
|
|
-
|
|
|
- <a-card title="近半年报警统计">
|
|
|
- <a-row>
|
|
|
- <a-col :span="12">
|
|
|
- {{ alarmType }}
|
|
|
- <Pie :chart-data="alarmType"></Pie>
|
|
|
- </a-col>
|
|
|
- <a-col :span="12">
|
|
|
- {{ historyAlarmNum }}
|
|
|
- <Bar :chart-data="historyAlarmNum"></Bar>
|
|
|
- </a-col>
|
|
|
- </a-row>
|
|
|
- </a-card>
|
|
|
+
|
|
|
+ <!-- 实时数据表格 -->
|
|
|
+ <BasicModal
|
|
|
+ v-model:open="isDetailModalVisible"
|
|
|
+ title="实时数据详情"
|
|
|
+ width="70%"
|
|
|
+ centered
|
|
|
+ :footer="null"
|
|
|
+ @cancel="handleModalClose"
|
|
|
+ >
|
|
|
+ <BasicTable @register="registerRealtimeTable" />
|
|
|
+
|
|
|
+ </BasicModal>
|
|
|
+
|
|
|
</div>
|
|
|
</template>
|
|
|
<script setup lang="ts">
|
|
|
+ import { useRouter, useRoute } from 'vue-router';
|
|
|
import { onMounted, ref } from 'vue';
|
|
|
- import { getAlarmType, getGoafAccessCount, getHistoryAlarmNum, getMineData, getRealAlarmNum } from '../overhaul.api';
|
|
|
+ import { getAlarmType, getGoafAccessCount, getHistoryAlarmNum, getMineData, getRealAlarmNum, getGoafData } from '../overhaul.api';
|
|
|
+ import { columns } from '../overhaul.data';
|
|
|
import { useMineDepartmentStore } from '/@/store/modules/mine';
|
|
|
+ import { useListPage } from '/@/hooks/system/useListPage';
|
|
|
import dayjs from 'dayjs';
|
|
|
import Pie from '/@/components/chart/Pie.vue';
|
|
|
import Bar from '/@/components/chart/Bar.vue';
|
|
|
+ import { StatusColorEnum } from '/@/enums/jeecgEnum';
|
|
|
+ import { BasicTable } from '/@/components/Table';
|
|
|
+ import { BasicModal } from '/@/components/Modal';
|
|
|
+ // 处理矿名选择器相关的逻辑
|
|
|
+ const isDetailModalVisible = ref(false);
|
|
|
+ const currentDeptId = ref<string | number>('');
|
|
|
|
|
|
- const mineStore = useMineDepartmentStore();
|
|
|
+ const getDynamicTableData = (params: any) => {
|
|
|
+ // 如果 currentDeptId 存在,则覆盖 params 中的 deptId
|
|
|
+ if (currentDeptId.value) {
|
|
|
+ params.deptId = currentDeptId.value;
|
|
|
+ } else {
|
|
|
+ // 默认使用 rootId,防止初始加载时无数据
|
|
|
+ params.deptId = mineStore.getRootId;
|
|
|
+ }
|
|
|
+ return getGoafData(params);
|
|
|
+ };
|
|
|
+ // 注册实时数据表格
|
|
|
+ const { tableContext: ctxRealtime, onExportXls: onExportXlsTime } = useListPage({
|
|
|
+ tableProps: {
|
|
|
+ api: getDynamicTableData,
|
|
|
+ columns,
|
|
|
+ showIndexColumn: false,
|
|
|
+ scroll: { x: 'max-content', y: 500 },
|
|
|
+ useSearchForm: false, // 隐藏搜索表单
|
|
|
+ showActionButtonGroup: false,
|
|
|
+ },
|
|
|
+
|
|
|
+ pagination: false,
|
|
|
+ exportConfig: {
|
|
|
+ url: '/ventanaly-province/province/device/exportGoafReal',
|
|
|
+ name: '老空区永久密闭监测数据',
|
|
|
+ // params: {
|
|
|
+ // goafId,
|
|
|
+ // },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const [registerRealtimeTable, realtimeTable] = ctxRealtime;
|
|
|
+
|
|
|
+ const handleShowDetail = (item: any) => {
|
|
|
+ // 设置当前选中的 deptId
|
|
|
+ currentDeptId.value = item.deptId;
|
|
|
+ // 显示弹框
|
|
|
+ isDetailModalVisible.value = true;
|
|
|
+
|
|
|
+ // 关键:手动触发表格刷新,因为 api 依赖的 ref 变化可能不会自动触发 BasicTable 的内部重载
|
|
|
+ // 使用 nextTick 确保 DOM 更新后再重载,或者直接在 modal 的 open 事件中处理
|
|
|
+ setTimeout(() => {
|
|
|
+ realtimeTable?.reload();
|
|
|
+ }, 100);
|
|
|
+ };
|
|
|
|
|
|
+ const handleModalClose = () => {
|
|
|
+ isDetailModalVisible.value = false;
|
|
|
+ currentDeptId.value = ''; // 可选:清空状态
|
|
|
+ };
|
|
|
+
|
|
|
+ // 路由实例
|
|
|
+ const router = useRouter();
|
|
|
+ const mineStore = useMineDepartmentStore();
|
|
|
+ // 数据加载状态
|
|
|
+ const isDataLoaded = ref(false);
|
|
|
const accessStatics = ref<any[]>([]);
|
|
|
+ // 控制图表显示/隐藏的状态
|
|
|
+ const isChartVisible = ref(true);
|
|
|
+
|
|
|
+ const dataColumns = [
|
|
|
+ { label: '瓦斯等级', key: 'gasLevelName', type: 'alarm', showPoint: true },
|
|
|
+ { label: '煤层自燃倾向性', key: 'coalSeamLevel', type: 'text' },
|
|
|
+ { label: '联网', key: 'status', colorKey: 'status', type: 'status',showPoint: true },
|
|
|
+ { label: '永久密闭数量', key: 'goafNum', type: 'text' },
|
|
|
+ { label: '报警数量', key: 'alarmCount', type: 'custom_count' },
|
|
|
+ { label: '报警原因', key: 'alarmReasons', type: 'custom_reasons' },
|
|
|
+ { label: '开始时间', key: 'createTime', type: 'text' },
|
|
|
+ { label: '最新监测时间', key: '-',type: 'text' },
|
|
|
+ ];
|
|
|
+ const alartTypeColumns = [
|
|
|
+ 'fireAlarm',
|
|
|
+ 'fireAlarmOut',
|
|
|
+ 'explosionAlarm',
|
|
|
+ 'sourcePressureAlarm',
|
|
|
+ 'leakageAlarm',
|
|
|
+ 'unsealAlarm',
|
|
|
+ // {key: 'fireAlarm', label: '闭内自燃发火'},
|
|
|
+ // {key: 'fireAlarmOut', label: '闭外自燃发火'},
|
|
|
+ // {key: 'explosionAlarm', label: '爆炸预警'},
|
|
|
+ // {key: 'sourcePressureAlarm', label: '压差隐患'},
|
|
|
+ // {key: 'leakageAlarm', label: '漏风'},
|
|
|
+ // {key: 'unsealAlarm', label: '密闭启封'},
|
|
|
+ ];
|
|
|
async function fetchAccessStatics() {
|
|
|
accessStatics.value = await getGoafAccessCount({ deptId: mineStore.getRootId });
|
|
|
}
|
|
|
@@ -95,12 +346,133 @@
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- onMounted(() => {
|
|
|
- fetchAccessStatics();
|
|
|
- fetchRealtimeWarning();
|
|
|
- fetchAlarmType();
|
|
|
- fetchHistoryAlarmNum();
|
|
|
- fetchMineData();
|
|
|
+ /**
|
|
|
+ * 风险等级映射配置
|
|
|
+ */
|
|
|
+ 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 为无风险或默认
|
|
|
+ };
|
|
|
+ /**
|
|
|
+ * 获取报警颜色
|
|
|
+ * @param level 报警级别 '1', '2', '3', '4'
|
|
|
+ */
|
|
|
+ const getAlarmColor = (level?: string | number) => {
|
|
|
+ if (!level && level !== 0) return '#333'; // 默认颜色
|
|
|
+ return RISK_LEVEL_MAP[String(level)]?.color;
|
|
|
+ };
|
|
|
+ /**
|
|
|
+ * 获取风险等级对应的文本
|
|
|
+ * @param level 报警级别 '1', '2', '3', '4'
|
|
|
+ */
|
|
|
+ const getRiskText = (level?: string | number) => {
|
|
|
+ if (!level && level !== 0) return '-';
|
|
|
+ return RISK_LEVEL_MAP[String(level)]?.text || '未知';
|
|
|
+ };
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通用页面跳转方法
|
|
|
+ * @param record 当前行数据
|
|
|
+ * @param path 目标路径
|
|
|
+ */
|
|
|
+ function handleGoToPageQuery(path: string) {
|
|
|
+
|
|
|
+ router.push({
|
|
|
+ path,
|
|
|
+ }).catch(err => {
|
|
|
+ console.error('跳转失败:', err);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取列显示的颜色
|
|
|
+ */
|
|
|
+ const getColValueColor = (col: any, item: any) => {
|
|
|
+
|
|
|
+ if (col.key === 'gasLevelName') {
|
|
|
+ const val = getDataValue(item, col.key);
|
|
|
+ if (!val || val === '-') return '#000';
|
|
|
+
|
|
|
+ const strVal = String(val);
|
|
|
+ if (strVal.includes('突出')) {
|
|
|
+ return StatusColorEnum.red; // 红色
|
|
|
+ } else if (strVal.includes('高瓦斯')) {
|
|
|
+ return StatusColorEnum.gold; // 橙色/金色
|
|
|
+ } else if (strVal.includes('低瓦斯')) {
|
|
|
+ return StatusColorEnum.blue; // 蓝色
|
|
|
+ }
|
|
|
+ return '#000';
|
|
|
+ }
|
|
|
+ // 如果是报警类型,使用原有的报警颜色逻辑
|
|
|
+ if (col.type === 'alarm' && col.colorKey) {
|
|
|
+ return getAlarmColor(getDataValue(item, col.colorKey));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果是设备状态类型,使用状态颜色逻辑
|
|
|
+ if (col.type === 'status') {
|
|
|
+ return getlinkStatusInfo(getDataValue(item, col.key)).color;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 默认黑色
|
|
|
+ return '#000';
|
|
|
+ };
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据点分字符串路径获取对象值 (例如: '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 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 toggleChartVisibility = () => {
|
|
|
+ isChartVisible.value = !isChartVisible.value;
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ onMounted(async() => {
|
|
|
+ console.log(mineStore.getRoot)
|
|
|
+ await Promise.all([
|
|
|
+ fetchAccessStatics(),
|
|
|
+ fetchRealtimeWarning(),
|
|
|
+ fetchAlarmType(),
|
|
|
+ fetchHistoryAlarmNum(),
|
|
|
+ fetchMineData(),
|
|
|
+ ]);
|
|
|
+ isDataLoaded.value = true;
|
|
|
});
|
|
|
</script>
|
|
|
<style lang="less" scoped>
|
|
|
@@ -110,24 +482,571 @@
|
|
|
height: 100%;
|
|
|
overflow: scroll;
|
|
|
}
|
|
|
+
|
|
|
+ .content-area {
|
|
|
+ flex: 1;
|
|
|
+ padding: 20px;
|
|
|
+ background-color: #f0f8ff;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 顶部信息总览样式
|
|
|
+ .top-info {
|
|
|
+ width: 100%;
|
|
|
+ height: 200px;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ flex-shrink: 0;
|
|
|
+ }
|
|
|
+
|
|
|
.info-card {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
display: flex;
|
|
|
flex-direction: row;
|
|
|
- background-image: url('/@/assets/images/overHaul/leafgPage/info-card-bg.png');
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/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;
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ color: #fff;
|
|
|
+ background-color: #2b6ff0;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: #397af3;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .info-border {
|
|
|
+ position: absolute;
|
|
|
+ top: 20px;
|
|
|
+ left: 20px;
|
|
|
+ .info-border-icon {
|
|
|
+ width: 16px;
|
|
|
+ height: 16px;
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/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%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ overflow-y: scroll;
|
|
|
+ gap: 15px;
|
|
|
+ }
|
|
|
+ .card-item {
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ background-color: #f1f7ff;
|
|
|
+ height: 40px;
|
|
|
+ align-items: center;
|
|
|
+ box-sizing: border-box;
|
|
|
+ flex-shrink: 0;
|
|
|
+ padding: 0 0 0 20px;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .item-cont {
|
|
|
+ color: #000;
|
|
|
+ font-weight: 500;
|
|
|
+ background-color: #f1f7ff;
|
|
|
+ z-index: 1;
|
|
|
+ padding: 0 10px;
|
|
|
+ }
|
|
|
+ .bg-line {
|
|
|
+ position: absolute;
|
|
|
+ width: 100%;
|
|
|
+ height: 1px;
|
|
|
+ border-top: 2px dotted #397af3;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ .bg-icon {
|
|
|
+ width: 15px;
|
|
|
+ height: 15px;
|
|
|
+ position: absolute;
|
|
|
+ left: 10px;
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/info-card-icon.svg');
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: 100%;
|
|
|
+ z-index: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+// 预警统计样式
|
|
|
+.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/leafPage/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;
|
|
|
+ }
|
|
|
|
|
|
- .card-title {
|
|
|
- width: 20%;
|
|
|
- position: relative;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: space-between;
|
|
|
- padding: 8px 10px 8px 50px;
|
|
|
+ .icon-top{
|
|
|
+ width: 40px;
|
|
|
+ height: 40px;
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/high-risk-icon1.svg');
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: 100%;;
|
|
|
}
|
|
|
+ .icon-bottom{
|
|
|
+ width: 40px;
|
|
|
+ height: 20px;
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/high-risk-icon2.png');
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: 100%;
|
|
|
+ margin-top: -5px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .stat-item.high-risk {
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/high-risk-bg.png');
|
|
|
+ .icon-top {
|
|
|
+ background-image: url('/@/assets/images/overHaul/rootPage/over-limit-icon.svg');
|
|
|
+ }
|
|
|
+ .icon-bottom {
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/high-risk-icon2.png');
|
|
|
+ }
|
|
|
+ .count {
|
|
|
+ color: #FF0000;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .stat-item.medium-risk {
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/medium-risk-bg.png');
|
|
|
+ .icon-top {
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/medium-risk-icon1.svg');
|
|
|
+ }
|
|
|
+ .icon-bottom {
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/medium-risk-icon2.png');
|
|
|
+ }
|
|
|
+ .count {
|
|
|
+ color: #FF7700;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .stat-item.normal-risk {
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/normal-risk-bg.png');
|
|
|
+ .icon-top {
|
|
|
+ background-image: url('/@/assets/images/overHaul/rootPage/data-break-icon.svg');
|
|
|
+ }
|
|
|
+ .icon-bottom {
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/normal-risk-icon2.png');
|
|
|
+ }
|
|
|
+ .count {
|
|
|
+ color: #D5C702;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .stat-item.low-risk {
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/low-risk-bg.png');
|
|
|
+ .icon-top {
|
|
|
+ background-image: url('/@/assets/images/overHaul/rootPage/data-quality-icon.svg');
|
|
|
+ }
|
|
|
+ .icon-bottom {
|
|
|
+ background-image: url('/@/assets/images/overHaul/leafPage/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;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn-group {
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+.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/leafPage/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/leafPage/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);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+.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;
|
|
|
+}
|
|
|
+
|
|
|
+.data-row {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(5, 1fr);
|
|
|
+ gap: 12px;
|
|
|
+ margin-bottom: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.data-col {
|
|
|
+ width: 100%;
|
|
|
+ height: 50px;
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: start;
|
|
|
+ justify-content: center ;
|
|
|
+ padding: 0 16px 0 30px;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 12px;
|
|
|
+
|
|
|
+ .col-icon {
|
|
|
+ width: 50px;
|
|
|
+ height: 50px;
|
|
|
+ background-image: url('/@/assets/images/overHaul/rootPage/alarm-icon-bg.png');
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ align-items: center;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+
|
|
|
+ .icon-item {
|
|
|
+ width: 25px;
|
|
|
+ height: 25px;
|
|
|
+ background-image: url('/@/assets/images/overHaul/rootPage/alarm-icon-1.svg');
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ z-index: 1;
|
|
|
+ }
|
|
|
+ .alarm-icon-1 {
|
|
|
+ background-image: url('@/assets/images/overHaul/rootPage/alarm-icon-1.svg');
|
|
|
+ }
|
|
|
+ .alarm-icon-2 {
|
|
|
+ background-image: url('@/assets/images/overHaul/rootPage/alarm-icon-2.svg');
|
|
|
+ }
|
|
|
+ .alarm-icon-3 {
|
|
|
+ background-image: url('@/assets/images/overHaul/rootPage/alarm-icon-3.svg');
|
|
|
+ }
|
|
|
+ .alarm-icon-4 {
|
|
|
+ background-image: url('@/assets/images/overHaul/rootPage/alarm-icon-4.svg');
|
|
|
+ }
|
|
|
+ .alarm-icon-5 {
|
|
|
+ background-image: url('@/assets/images/overHaul/rootPage/alarm-icon-5.svg');
|
|
|
+ }
|
|
|
+ .alarm-icon-6 {
|
|
|
+ background-image: url('@/assets/images/overHaul/rootPage/alarm-icon-6.svg');
|
|
|
+ }
|
|
|
+ .alarm-icon-7 {
|
|
|
+ background-image: url('@/assets/images/overHaul/rootPage/alarm-icon-7.svg');
|
|
|
+ }
|
|
|
+ .alarm-icon-8 {
|
|
|
+ background-image: url('@/assets/images/overHaul/rootPage/alarm-icon-8.svg');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .col-cont {
|
|
|
+ width: calc(100% - 50px);
|
|
|
+ height: 50px;
|
|
|
+ background-image: url('/@/assets/images/overHaul/rootPage/alarm-content-bg.png');
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ padding: 0 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .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-first-row {
|
|
|
+ grid-column: span 1;
|
|
|
+ }
|
|
|
+ .col-second-row:nth-child(6) {
|
|
|
+ grid-column: 1 / span 3; // 占据第 1 到第 3 列
|
|
|
+ }
|
|
|
+
|
|
|
+ .col-second-row:nth-child(7) {
|
|
|
+ grid-column: span 1; // 占据第 4 列
|
|
|
+ }
|
|
|
+
|
|
|
+ .col-second-row:nth-child(8) {
|
|
|
+ grid-column: span 1; // 占据第 5 列
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.half-year-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;
|
|
|
+ }
|
|
|
+
|
|
|
+ .statistics-content {
|
|
|
+ display: flex;
|
|
|
+ gap: 20px; // 图表之间的间距
|
|
|
+ }
|
|
|
+
|
|
|
+ .chart-item {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 0;
|
|
|
+ padding: 10px;
|
|
|
+ border-radius: 4px;
|
|
|
+ background-color: #ecf4fd;
|
|
|
+ align-items: center;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+
|
|
|
+ .chart-title {
|
|
|
+ min-width: 400px;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ text-align: center;
|
|
|
+ background-image: url('/@/assets/images/overHaul/rootPage/chart-title-bg.png');
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
</style>
|