فهرست منبع

Merge branch 'master' of http://39.97.59.228:8013/hrx/goaf-monitoring-system

wangkeyi 3 ماه پیش
والد
کامیت
43e15db05a

+ 6 - 2
src/components/Configurable/preset/BlastDelta.vue

@@ -6,13 +6,13 @@
         <div :style="{ width: '5px', height: `${lengY}px`, 'border-top': '1px solid #0079ff' }" v-for="item in 10" :key="item"></div>
       </div>
       <div class="coord-labelY">
-        <div :style="{ width: '20px', height: `${lengY}px`, color: '#fff' }" v-for="(ite, ind) in 10" :key="ind">{{ ind == 0 ? maxY : '' }}</div>
+        <div :style="{ width: '20px', height: `${lengY}px`, color: textColor }" v-for="(ite, ind) in 10" :key="ind">{{ ind == 0 ? maxY : '' }}</div>
       </div>
       <div class="coord-lineX">
         <div :style="{ height: '5px', width: `${lengY}px`, 'border-right': '1px solid #0079ff' }" v-for="item in 15" :key="item"></div>
       </div>
       <div class="coord-labelX">
-        <div :style="{ height: '20px', width: `${lengY}px`, color: '#fff' }" v-for="(ite, ind) in 15" :key="ind">{{ ind == 14 ? maxX : '' }}</div>
+        <div :style="{ height: '20px', width: `${lengY}px`, color: textColor }" v-for="(ite, ind) in 15" :key="ind">{{ ind == 14 ? maxX : '' }}</div>
       </div>
       <div class="line-AB" :style="{ width: 'calc(100% - 10px)', height: 'calc(100% - 10px)' }">
         <canvas id="myCanvas" :width="canvasSize.width" :height="canvasSize.height"></canvas>
@@ -74,6 +74,10 @@
       type: Object,
       default: () => ({ width: 348, height: 245 }),
     },
+    textColor: {
+      type: String,
+      default: '#fff',
+    },
   });
 
   // 响应式数据

+ 4 - 7
src/components/Configurable/types.ts

@@ -133,12 +133,7 @@ export interface CommonItem {
 
 export interface ModuleDataBoard extends ReadFrom {
   /** 展示牌预设的背景类型 */
-  type:
-    | 'A'
-    | 'B'
-    | 'C'
-    | 'D'
-    | 'E'
+  type: 'A' | 'B' | 'C' | 'D' | 'E';
   /** 展示牌布局,决定是 label 部分在上方或是 value 在上方 */
   layout: 'val-top' | 'label-top' | 'new-top' | 'new1-top' | 'new2-top' | 'new3-top';
   /** 核心配置,每个展示牌对应一项 */
@@ -255,6 +250,7 @@ export interface ModuleDataChart extends ReadFrom {
       interval?: number;
       [key: string]: any; // 允许其他 ECharts 支持的属性
     };
+    [key: string]: any; // 允许其他 ECharts 支持的属性
   }[];
   /** 图表y轴配置(若有),支持多个,注意至少一个 */
   yAxis: {
@@ -263,6 +259,7 @@ export interface ModuleDataChart extends ReadFrom {
     name: string;
     /** y轴的对齐方式 */
     position: 'left' | 'right';
+    [key: string]: any; // 允许其他 ECharts 支持的属性
   }[];
   /**
    * 核心配置
@@ -276,7 +273,7 @@ export interface ModuleDataChart extends ReadFrom {
     type?: 'pie' | 'bar' | 'line' | 'scatter';
     /** 该系列的数据说明, formatter 格式,将用于 legend 相关的内容 */
     label: string;
-    /** 设置 series 系列时的基础路径,配合上级 readFrom 使用,其应指向一个数组,该数组将作为映射系列时的基准 */
+    /** 重要!该值99%的情况下必须设置!它会设置 series 系列时的基础路径,配合上级 readFrom 使用,其应指向一个数组,该数组将作为映射系列时的基准 */
     readFrom: string;
     /** 取值 prop,注意该项不支持 formatter 格式,将用于 xAxis 相关的内容 */
     xprop: string;

+ 2 - 0
src/design/color.less

@@ -160,3 +160,5 @@ html {
 // ==============tabs===============
 // =================================
 @tabs-bg-not-active: #9e9e9e26;
+
+@card-bg-color: #f8f9fc;

+ 3 - 2
src/views/analysis/warningAnalysis/airLeakStatus/airLeakStatus.data.ts

@@ -91,6 +91,7 @@ export const historyColumns: BasicColumn[] = [
   {
     title: '区域',
     dataIndex: 'areaName',
+    width: 100,
   },
   {
     title: '煤矿名称',
@@ -114,12 +115,12 @@ export const historyColumns: BasicColumn[] = [
   },
   {
     title: '密闭内压力',
-    dataIndex: 'interPressure',
+    dataIndex: 'sourcePressure',
     width: 100,
   },
   {
     title: '密闭外压力',
-    dataIndex: 'outerPressure',
+    dataIndex: 'sourcePressure',
     width: 100,
   },
   {

+ 7 - 7
src/views/analysis/warningAnalysis/airLeakStatus/index.vue

@@ -212,13 +212,13 @@ const [registerHistoryTable] = useTable({
   useSearchForm: true,
   bordered: true,
   showIndexColumn: false,
-  actionColumn: {
-    width: 60,
-    title: '操作',
-    dataIndex: 'action',
-    slots: { customRender: 'action' },
-    fixed: undefined,
-  },
+  // actionColumn: {
+  //   width: 60,
+  //   title: '操作',
+  //   dataIndex: 'action',
+  //   slots: { customRender: 'action' },
+  //   fixed: undefined,
+  // },
 });
 
 // 弹窗引用

+ 14 - 14
src/views/analysis/warningAnalysis/autoFireAnalysis/index.vue

@@ -118,13 +118,13 @@ const [registerTable] = useTable({
   useSearchForm: true,
   bordered: true,
   showIndexColumn: false,
-  actionColumn: {
-    width: 60,
-    title: '操作',
-    dataIndex: 'action',
-    slots: { customRender: 'action' },
-    fixed: undefined,
-  },
+  // actionColumn: {
+  //   width: 60,
+  //   title: '操作',
+  //   dataIndex: 'action',
+  //   slots: { customRender: 'action' },
+  //   fixed: undefined,
+  // },
 });
 
 // 注册历史数据表格
@@ -213,13 +213,13 @@ const [registerHistoryTable] = useTable({
   useSearchForm: true,
   bordered: true,
   showIndexColumn: false,
-  actionColumn: {
-    width: 60,
-    title: '操作',
-    dataIndex: 'action',
-    slots: { customRender: 'action' },
-    fixed: undefined,
-  },
+  // actionColumn: {
+  //   width: 60,
+  //   title: '操作',
+  //   dataIndex: 'action',
+  //   slots: { customRender: 'action' },
+  //   fixed: undefined,
+  // },
 });
 
 // 弹窗引用

+ 296 - 299
src/views/analysis/warningAnalysis/connectAnalysis/index.vue

@@ -1,12 +1,12 @@
 <template>
   <div class="connectAnalysis">
     <div class="filter-area">
-      <Row style="width:100%">
+      <Row style="width: 100%">
         <Col :span="8">
           <div class="filter-section param-section">
             <span class="filter-label">煤矿名称:</span>
             <div class="param-selector">
-              <MineCascader style="width:300px"></MineCascader>
+              <MineCascader style="width: 300px"></MineCascader>
             </div>
           </div>
         </Col>
@@ -15,8 +15,7 @@
           <div class="filter-section param-section">
             <span class="filter-label">采空区选择:</span>
             <Select ref="select" v-model:value="goafId" style="width: 300px" placeholder="请选择采空区">
-              <SelectOption v-for="(item, index) in goafOption" :key="index" :value="item.value">{{ item.label }}
-              </SelectOption>
+              <SelectOption v-for="(item, index) in goafOption" :key="index" :value="item.value">{{ item.label }} </SelectOption>
             </Select>
           </div>
         </Col>
@@ -31,13 +30,19 @@
         </Col>
       </Row>
 
-      <Row style="width:100%">
+      <Row style="width: 100%">
         <Col :span="8">
           <!-- 时间选择 -->
           <div class="filter-section param-section">
             <span class="filter-label">时间选择:</span>
-            <RangePicker v-model="dateRange" format="YYYY-MM-DD HH:mm:ss" :placeholder="['开始时间', '结束时间']"
-              style="width: 300px" :show-time="{ format: 'HH:mm:ss' }" @change="changeTime" />
+            <RangePicker
+              v-model="dateRange"
+              format="YYYY-MM-DD HH:mm:ss"
+              :placeholder="['开始时间', '结束时间']"
+              style="width: 300px"
+              :show-time="{ format: 'HH:mm:ss' }"
+              @change="changeTime"
+            />
           </div>
         </Col>
         <Col :span="8">
@@ -48,8 +53,7 @@
               <Input v-model="selectedParamsText" placeholder="请选择监测参数" readonly style="width: 300px" />
               <Button type="primary" @click="showTree = !showTree">+</Button>
               <div class="tree-popup" v-if="showTree">
-                <BasicTree :treeData="treeData" :checkable="true" defaultExpandAll @check="handleTreeCheck"
-                  :checkedKeys="checkedTreeKeys" />
+                <BasicTree :treeData="treeData" :checkable="true" defaultExpandAll @check="handleTreeCheck" :checkedKeys="checkedTreeKeys" />
               </div>
             </div>
           </div>
@@ -64,11 +68,10 @@
     </div>
     <!-- 动态图表区域-->
     <div class="chart-area">
-      <div class="chart-item" style="flex: 1 1 100%;">
+      <div class="chart-item" style="flex: 1 1 100%">
         <div class="chart-placeholder">
           <template v-if="generatedChartData.length">
-            <CustomChart :chart-data="generatedChartData" :chart-config="generatedChartConfig"
-              style="height: 100%; width: 100%" />
+            <CustomChart :chart-data="generatedChartData" :chart-config="generatedChartConfig" style="height: 100%; width: 100%" />
           </template>
           <template v-else-if="isChartGenerated">
             <div class="empty-chart">暂无匹配数据,请调整筛选条件</div>
@@ -83,328 +86,322 @@
 </template>
 
 <script setup lang="ts">
-import { computed, ref, onMounted, watchEffect } from 'vue';
-import dayjs from 'dayjs';
-import { treeData, historicalMockChartData } from './connectAnalysis.data'; // 引入模拟数据
-import { Select, SelectOption, Row, Col, DatePicker, Button, message, Input, } from 'ant-design-vue';
-import { BasicTree } from '/@/components/Tree/index';
-import CustomChart from '/@/components/Configurable/detail/CustomChart.vue';
-import MineCascader from '@/components/Form/src/jeecg/components/MineCascader/MineCascader.vue'
-import { getGoafHistory, getGoafList } from './connectAnalysis.api'
-import { storeToRefs } from 'pinia';
-import { useMineStore } from '/@/store/modules/mine';
+  import { computed, ref, onMounted, watchEffect } from 'vue';
+  import dayjs from 'dayjs';
+  import { treeData, historicalMockChartData } from './connectAnalysis.data'; // 引入模拟数据
+  import { Select, SelectOption, Row, Col, DatePicker, Button, message, Input } from 'ant-design-vue';
+  import { BasicTree } from '/@/components/Tree/index';
+  import CustomChart from '/@/components/Configurable/detail/CustomChart.vue';
+  import MineCascader from '@/components/Form/src/jeecg/components/MineCascader/MineCascader.vue';
+  import { getGoafHistory, getGoafList } from './connectAnalysis.api';
+  import { storeToRefs } from 'pinia';
+  import { useMineStore } from '/@/store/modules/mine';
 
-// 组件注册
-const RangePicker = DatePicker.RangePicker;
-// 筛选相关响应式数据
-const dateRange = ref([dayjs().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')]); // 默认时间范围(近1天)
-// const dateRange = ref<any[]>([]); // 默认时间范围(近1天)
-const selectedParamsText = ref(''); // 参数选择框显示文本
-const showTree = ref(false); // 控制树形选择器显示/隐藏
-const checkedTreeKeys = ref([]); // 树形选中的key
-const selectedParams = ref([]); // 选中的参数(实际用于图表)
-const generatedChartData = ref<any[]>([]); // 生成的图表数据
-const generatedChartConfig = ref({}); // 生成的图表配置
-const isChartGenerated = ref(false); // 是否已点击生成
-const mineNameAbbr = ref('')//煤矿简称
-const goafId = ref('')//采空区id
-const goafOption = ref<any[]>([])//采空区列表
-const filteredData = ref<any[]>([])//曲线数据
-const mineStore = useMineStore();
-const { getMine, getMineCode, getMinePath, getMineTree } = storeToRefs(mineStore);
-const innerValue = computed(() => getMinePath.value.map((e) => e.fax));
+  // 组件注册
+  const RangePicker = DatePicker.RangePicker;
+  // 筛选相关响应式数据
+  const dateRange = ref([dayjs().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'), dayjs().format('YYYY-MM-DD HH:mm:ss')]); // 默认时间范围(近1天)
+  // const dateRange = ref<any[]>([]); // 默认时间范围(近1天)
+  const selectedParamsText = ref(''); // 参数选择框显示文本
+  const showTree = ref(false); // 控制树形选择器显示/隐藏
+  const checkedTreeKeys = ref([]); // 树形选中的key
+  const selectedParams = ref([]); // 选中的参数(实际用于图表)
+  const generatedChartData = ref<any[]>([]); // 生成的图表数据
+  const generatedChartConfig = ref({}); // 生成的图表配置
+  const isChartGenerated = ref(false); // 是否已点击生成
+  const mineNameAbbr = ref(''); //煤矿简称
+  const goafId = ref(''); //采空区id
+  const goafOption = ref<any[]>([]); //采空区列表
+  const filteredData = ref<any[]>([]); //曲线数据
+  const mineStore = useMineStore();
+  const { getMine, getMineCode, getMinePath, getMineTree } = storeToRefs(mineStore);
+  const innerValue = computed(() => getMinePath.value.map((e) => e.fax));
 
+  // Tree Key 与参数名映射(关键:关联树形节点和实际参数)
+  const treeKeyToParamMap = computed(() => ({
+    '0-0-0': 'coVal',
+    '0-0-1': 'ch4Val',
+    '0-0-2': 'c2h4Val',
+    '0-0-3': 'c2h2Val',
+    '0-0-4': 'co2Val',
+    '0-0-5': 'o2Val',
+    '1-1-0': 'sourcePressure',
+    // '1-1-1': 'outerPressure',
+    // '1-1-2': 'pressureDiff',
+    '2-2': 'temperature',
+  }));
+  // 参数标签映射(图表系列名称)
+  const paramLabelMap = computed(() => ({
+    coVal: 'CO浓度(ppm)',
+    ch4Val: 'CH4浓度(%)',
+    c2h4Val: 'C2H4浓度(ppm)',
+    c2h2Val: 'C2H2浓度(ppm)',
+    co2Val: 'CO2浓度(%)',
+    o2Val: 'O2浓度(%)',
+    sourcePressure: '压力(kPa)',
+    temperature: '温度(℃)',
+    // 'innerPressure': '内压力(kPa)',
+    // 'outerPressure': '外压力(kPa)',
+    // 'pressureDiff': '压差(kPa)',
+    // 'temperature': '温度(℃)',
+  }));
+  // 参数颜色映射
+  const paramColorMap = computed(() => ({
+    coVal: '#f5222d', // 红色
+    ch4Val: '#1890ff', // 蓝色
+    c2h4Val: '#faad14', // 橙色
+    c2h2Val: '#52c41a', // 绿色
+    co2Val: '#722ed1', // 紫色
+    o2Val: '#13c2c2', // 青色
+    sourcePressure: '#ff4d4f', // 浅红
+    // 'outerPressure': '#40a9ff',// 浅蓝
+    // 'pressureDiff': '#fa8c16', // 浅橙
+    temperature: '#9254de', // 浅紫
+  }));
 
-// Tree Key 与参数名映射(关键:关联树形节点和实际参数)
-const treeKeyToParamMap = computed(() => ({
-  '0-0-0': 'coVal',
-  '0-0-1': 'ch4Val',
-  '0-0-2': 'c2h4Val',
-  '0-0-3': 'c2h2Val',
-  '0-0-4': 'co2Val',
-  '0-0-5': 'o2Val',
-  '1-1-0': 'sourcePressure',
-  // '1-1-1': 'outerPressure',
-  // '1-1-2': 'pressureDiff',
-  '2-2': 'temperature',
-}));
-// 参数标签映射(图表系列名称)
-const paramLabelMap = computed(() => ({
-  'coVal': 'CO浓度(ppm)',
-  'ch4Val': 'CH4浓度(%)',
-  'c2h4Val': 'C2H4浓度(ppm)',
-  'c2h2Val': 'C2H2浓度(ppm)',
-  'co2Val': 'CO2浓度(%)',
-  'o2Val': 'O2浓度(%)',
-  'sourcePressure': '压力(kPa)',
-  'temperature': '温度(℃)',
-  // 'innerPressure': '内压力(kPa)',
-  // 'outerPressure': '外压力(kPa)',
-  // 'pressureDiff': '压差(kPa)',
-  // 'temperature': '温度(℃)',
-}));
-// 参数颜色映射
-const paramColorMap = computed(() => ({
-  'coVal': '#f5222d',    // 红色
-  'ch4Val': '#1890ff',   // 蓝色
-  'c2h4Val': '#faad14',  // 橙色
-  'c2h2Val': '#52c41a',  // 绿色
-  'co2Val': '#722ed1',   // 紫色
-  'o2Val': '#13c2c2',    // 青色
-  'sourcePressure': '#ff4d4f', // 浅红
-  // 'outerPressure': '#40a9ff',// 浅蓝
-  // 'pressureDiff': '#fa8c16', // 浅橙
-  'temperature': '#9254de',  // 浅紫
-}));
+  // 树形选择事件处理
+  const handleTreeCheck = (checkedKeys) => {
+    checkedTreeKeys.value = checkedKeys;
+    // 转换为实际参数名
+    const params = checkedKeys.map((key) => treeKeyToParamMap.value[key]).filter((param) => param); // 过滤无效参数
+    selectedParams.value = params;
 
-// 树形选择事件处理
-const handleTreeCheck = (checkedKeys) => {
-  checkedTreeKeys.value = checkedKeys;
-  // 转换为实际参数名
-  const params = checkedKeys
-    .map(key => treeKeyToParamMap.value[key])
-    .filter(param => param); // 过滤无效参数
-  selectedParams.value = params;
-
-  // 更新输入框显示文本
-  const paramLabels = params.map(param => paramLabelMap.value[param]);
-  selectedParamsText.value = paramLabels.join('、');
-};
-
-function changeTime(val) {
-  dateRange.value[0] = val[0].format('YYYY-MM-DD HH:mm:ss')
-  dateRange.value[1] = val[1].format('YYYY-MM-DD HH:mm:ss')
-
-}
+    // 更新输入框显示文本
+    const paramLabels = params.map((param) => paramLabelMap.value[param]);
+    selectedParamsText.value = paramLabels.join('、');
+  };
 
-// 生成折线图核心逻辑
-async function generateChart() {
-  // 校验筛选条件
-  if (!dateRange.value[0] || !dateRange.value[1]) {
-    message.warning('请选择完整的时间范围');
-    return;
-  }
-  if (selectedParams.value.length === 0) {
-    message.warning('请至少选择一个监测参数');
-    return;
-  }
-  if (!goafId.value) {
-    message.warning('请选择采空区');
-    return;
-  }
-  showTree.value = false
-  //获取采空区历史数据列表
-  let res = await getGoafHistory({ pageNo: 1, pageSize: 100, startTime: dateRange.value[0], endTime: dateRange.value[1], goafId: goafId.value })
-  if (res && res.records) {
-    filteredData.value = res.records
-    isChartGenerated.value = false
-  } else {
-    filteredData.value.length = 0
-    isChartGenerated.value = true;
+  function changeTime(val) {
+    dateRange.value[0] = val[0].format('YYYY-MM-DD HH:mm:ss');
+    dateRange.value[1] = val[1].format('YYYY-MM-DD HH:mm:ss');
   }
 
-  // const start = dayjs(dateRange.value[0]); // 转为 dayjs 实例
-  // const end = dayjs(dateRange.value[1]);   // 转为 dayjs 实例
-  // // 1. 筛选时间范围内的模拟数据(修复核心漏洞)
-  // const filteredData = historicalMockChartData.filter(item => {
-  //   const itemTime = dayjs(item.time); // 解析 item.time 为 dayjs 实例
-  //   return itemTime.isAfter(start) && itemTime.isBefore(end);
-  // });
+  // 生成折线图核心逻辑
+  async function generateChart() {
+    // 校验筛选条件
+    if (!dateRange.value[0] || !dateRange.value[1]) {
+      message.warning('请选择完整的时间范围');
+      return;
+    }
+    if (selectedParams.value.length === 0) {
+      message.warning('请至少选择一个监测参数');
+      return;
+    }
+    if (!goafId.value) {
+      message.warning('请选择采空区');
+      return;
+    }
+    showTree.value = false;
+    //获取采空区历史数据列表
+    let res = await getGoafHistory({ pageNo: 1, pageSize: 100, startTime: dateRange.value[0], endTime: dateRange.value[1], goafId: goafId.value });
+    if (res && res.records) {
+      filteredData.value = res.records;
+      isChartGenerated.value = false;
+    } else {
+      filteredData.value.length = 0;
+      isChartGenerated.value = true;
+    }
 
+    // const start = dayjs(dateRange.value[0]); // 转为 dayjs 实例
+    // const end = dayjs(dateRange.value[1]);   // 转为 dayjs 实例
+    // // 1. 筛选时间范围内的模拟数据(修复核心漏洞)
+    // const filteredData = historicalMockChartData.filter(item => {
+    //   const itemTime = dayjs(item.time); // 解析 item.time 为 dayjs 实例
+    //   return itemTime.isAfter(start) && itemTime.isBefore(end);
+    // });
 
-  // 2. 构建图表数据结构(适配 CustomChart 的 line 类型)
-  const timeMap = new Map();
-  // 修复变量名:filteredRawData → filteredData(之前未定义)
-  filteredData.value.forEach((item) => {
-    const timeStr = dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss');
-    if (!timeMap.has(timeStr)) {
-      timeMap.set(timeStr, { time: timeStr });
-    }
-    // 只保留选中的参数数据
-    selectedParams.value.forEach(param => {
-      if (item[param] !== undefined) {
-        timeMap.get(timeStr)[param] = item[param];
+    // 2. 构建图表数据结构(适配 CustomChart 的 line 类型)
+    const timeMap = new Map();
+    // 修复变量名:filteredRawData → filteredData(之前未定义)
+    filteredData.value.forEach((item) => {
+      const timeStr = dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss');
+      if (!timeMap.has(timeStr)) {
+        timeMap.set(timeStr, { time: timeStr });
       }
+      // 只保留选中的参数数据
+      selectedParams.value.forEach((param) => {
+        if (item[param] !== undefined) {
+          timeMap.get(timeStr)[param] = item[param];
+        }
+      });
     });
-  });
 
-  // 转换为数组并按时间排序
-  const chartData = Array.from(timeMap.values()).sort((a, b) => {
-    return dayjs(a.time).valueOf() - dayjs(b.time).valueOf();
-  });
-  generatedChartData.value = chartData;
+    // 转换为数组并按时间排序
+    const chartData = Array.from(timeMap.values()).sort((a, b) => {
+      return dayjs(a.time).valueOf() - dayjs(b.time).valueOf();
+    });
+    generatedChartData.value = chartData;
 
-  // 3. 构建图表配置(折线图类型,完善适配逻辑)
-  generatedChartConfig.value = {
-    type: 'line', // 折线图
-    clear: true, // 每次生成清空之前的图表
-    legend: { show: true, top: 10, right: 10, textStyle: { color: '#fff', fontSize: 14 } },
-    xAxis: [
-      {
-        type: 'category',
+    // 3. 构建图表配置(折线图类型,完善适配逻辑)
+    generatedChartConfig.value = {
+      type: 'line', // 折线图
+      clear: true, // 每次生成清空之前的图表
+      legend: { show: true, top: 10, right: 10, textStyle: { color: '#fff', fontSize: 14 } },
+      xAxis: [
+        {
+          type: 'category',
+          axisLabel: {
+            rotate: 30,
+            textStyle: {
+              color: '#fff',
+            },
+            formatter: (value) => dayjs(value).format('HH:mm:ss'),
+            interval: Math.max(1, Math.floor(chartData.length / 10)), // 控制x轴标签密度
+          },
+        },
+      ],
+      yAxis: selectedParams.value.map((param) => ({
+        type: 'value',
         axisLabel: {
-          rotate: 30,
           textStyle: {
             color: '#fff',
           },
-          formatter: (value) => dayjs(value).format('HH:mm:ss'),
-          interval: Math.max(1, Math.floor(chartData.length / 10)) // 控制x轴标签密度
-        }
-      }
-    ],
-    yAxis: selectedParams.value.map(param => ({
-      type: 'value',
-      axisLabel: {
-        textStyle: {
-          color: '#fff',
+        },
+        name: paramLabelMap.value[param].split('(')[1].replace(')', ''), // 显示单位
+        // nameTextStyle: { color: paramColorMap.value[param] },
+        nameTextStyle: { color: '#fff' },
+        axisLine: { lineStyle: { color: paramColorMap.value[param] } },
+        splitLine: { lineStyle: { opacity: 0.1 } },
+      })),
+      series: selectedParams.value.map((param, index) => ({
+        name: paramLabelMap.value[param],
+        type: 'line',
+        readFrom: '', // 适配 CustomChart 的 baseSeries 读取逻辑
+        label: paramLabelMap.value[param],
+        xprop: 'time', // 对应图表数据的 x 字段(时间)
+        yprop: param, // 对应图表数据的 y 字段(参数值)
+        color: paramColorMap.value[param],
+        smooth: true,
+        symbol: 'circle',
+        symbolSize: 4,
+        yAxisIndex: index,
+      })),
+      tooltip: {
+        trigger: 'axis',
+        axisPointer: { type: 'cross' },
+        formatter: (params) => {
+          let tooltipHtml = `<div>${dayjs(params[0].axisValue).format('YYYY-MM-DD HH:mm:ss')}</div>`;
+          params.forEach((param) => {
+            tooltipHtml += `<div style="color: ${param.color}">${param.seriesName}: ${param.value[1]} ${param.seriesName.split('(')[1].replace(')', '')}</div>`;
+          });
+          return tooltipHtml;
         },
       },
-      name: paramLabelMap.value[param].split('(')[1].replace(')', ''), // 显示单位
-      // nameTextStyle: { color: paramColorMap.value[param] },
-      nameTextStyle: { color: '#fff' },
-      axisLine: { lineStyle: { color: paramColorMap.value[param] } },
-      splitLine: { lineStyle: { opacity: 0.1 } }
-    })),
-    series: selectedParams.value.map((param, index) => ({
-      name: paramLabelMap.value[param],
-      type: 'line',
-      readFrom: '', // 适配 CustomChart 的 baseSeries 读取逻辑
-      label: paramLabelMap.value[param],
-      xprop: 'time', // 对应图表数据的 x 字段(时间)
-      yprop: param, // 对应图表数据的 y 字段(参数值)
-      color: paramColorMap.value[param],
-      smooth: true,
-      symbol: 'circle',
-      symbolSize: 4,
-      yAxisIndex: index,
-    })),
-    tooltip: {
-      trigger: 'axis',
-      axisPointer: { type: 'cross' },
-      formatter: (params) => {
-        let tooltipHtml = `<div>${dayjs(params[0].axisValue).format('YYYY-MM-DD HH:mm:ss')}</div>`;
-        params.forEach(param => {
-          tooltipHtml += `<div style="color: ${param.color}">${param.seriesName}: ${param.value[1]} ${param.seriesName.split('(')[1].replace(')', '')}</div>`;
-        });
-        return tooltipHtml;
-      }
-    },
-    grid: { left: 60, top: 40, right: 60, bottom: 60 }
-  };
+      grid: { left: 60, top: 40, right: 60, bottom: 60 },
+    };
 
-  // 无数据提示
-  if (chartData.length === 0) {
-    message.info('当前筛选条件下无数据');
+    // 无数据提示
+    if (chartData.length === 0) {
+      message.info('当前筛选条件下无数据');
+    }
   }
-};
-//获取采空区列表
-async function getGoafListData() {
-  let res = await getGoafList({ mineCode: innerValue.value[innerValue.value.length - 1] })
-  if (res.length) {
-    goafOption.value = res.map(el => {
-      return {
-        label: el.devicePos,
-        value: el.id,
-      }
-    })
+  //获取采空区列表
+  async function getGoafListData() {
+    let res = await getGoafList({ mineCode: innerValue.value[innerValue.value.length - 1] });
+    if (res.length) {
+      goafOption.value = res.map((el) => {
+        return {
+          label: el.devicePos,
+          value: el.id,
+        };
+      });
+    }
   }
-}
-
-watchEffect(() => {
-  innerValue.value && getGoafListData()
-})
 
+  watchEffect(() => {
+    innerValue.value && getGoafListData();
+  });
 </script>
 
 <style lang="less" scoped>
-.connectAnalysis {
-  padding: 16px;
+  .connectAnalysis {
+    padding: 16px;
 
-  .filter-area {
-    display: flex;
-    flex-wrap: wrap;
-    gap: 16px;
-    margin-bottom: 20px;
-    padding: 20px;
-    border: 1px solid #f0f0f0;
-    border-radius: 10px;
-    background: #f8f9fc;
-    align-items: center;
-  }
+    .filter-area {
+      display: flex;
+      flex-wrap: wrap;
+      gap: 16px;
+      margin-bottom: 20px;
+      padding: 20px;
+      border: 1px solid #f0f0f0;
+      border-radius: 10px;
+      background: @card-bg-color;
+      align-items: center;
+    }
 
-  .filter-section {
-    display: flex;
-    align-items: center;
-    gap: 8px;
-  }
+    .filter-section {
+      display: flex;
+      align-items: center;
+      gap: 8px;
+    }
 
-  .filter-label {
-    color: #666;
-    min-width: 80px;
-    flex-shrink: 0;
-    font-weight: 500;
-  }
+    .filter-label {
+      color: #666;
+      min-width: 80px;
+      flex-shrink: 0;
+      font-weight: 500;
+    }
 
-  .param-section {
-    flex: 1;
-    // min-width: 300px;
-  }
+    .param-section {
+      flex: 1;
+      // min-width: 300px;
+    }
 
-  .param-selector {
-    display: flex;
-    align-items: center;
-    gap: 8px;
-    position: relative;
-  }
+    .param-selector {
+      display: flex;
+      align-items: center;
+      gap: 8px;
+      position: relative;
+    }
 
-  .tree-popup {
-    position: absolute;
-    top: 100%;
-    left: 0;
-    margin-top: 8px;
-    width: 300px;
-    max-height: 300px;
-    overflow-y: auto;
-    background: #fff;
-    border: 1px solid #e8e8e8;
-    border-radius: 4px;
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
-    z-index: 100;
-    padding: 8px;
-  }
+    .tree-popup {
+      position: absolute;
+      top: 100%;
+      left: 0;
+      margin-top: 8px;
+      width: 300px;
+      max-height: 300px;
+      overflow-y: auto;
+      background: #fff;
+      border: 1px solid #e8e8e8;
+      border-radius: 4px;
+      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+      z-index: 100;
+      padding: 8px;
+    }
 
-  .chart-area {
-    display: flex;
-    flex-wrap: wrap;
-    gap: 16px;
-    padding: 20px;
-    border: 1px solid #f0f0f0;
-    border-radius: 10px;
-    background: #f8f9fc;
-  }
+    .chart-area {
+      display: flex;
+      flex-wrap: wrap;
+      gap: 16px;
+      padding: 20px;
+      border: 1px solid #f0f0f0;
+      border-radius: 10px;
+      background: @card-bg-color;
+    }
 
-  .chart-item {
-    flex: 1;
-    min-width: 200px;
-  }
+    .chart-item {
+      flex: 1;
+      min-width: 200px;
+    }
 
-  .chart-placeholder {
-    width: 100%;
-    height: 300px;
-    border-radius: 4px;
-    overflow: hidden;
-    background: #333;
-    border: 1px solid #eee;
-  }
+    .chart-placeholder {
+      width: 100%;
+      height: 300px;
+      border-radius: 4px;
+      overflow: hidden;
+      background: #333;
+      border: 1px solid #eee;
+    }
 
-  .empty-chart {
-    width: 100%;
-    height: 100%;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    color: #999;
-    font-size: 14px;
+    .empty-chart {
+      width: 100%;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      color: #999;
+      font-size: 14px;
+    }
   }
-}
 </style>

+ 1 - 6
src/views/analysis/warningAnalysis/fireAreaJudgeAnalysis/fireAreaJudgeAnalysis.data.ts

@@ -53,7 +53,7 @@ export const columns: BasicColumn[] = [
   },
   {
     title: '自燃倾向性',
-    dataIndex: 'riskLevel',
+    dataIndex: 'coalSeamLevel',
     width: 100,
   },
   {
@@ -101,11 +101,6 @@ export const columns: BasicColumn[] = [
     dataIndex: 'createTime',
     width: 100,
   },
-  {
-    title: '是否解决',
-    dataIndex: 'isResolved',
-    width: 100,
-  },
 ];
 
 export const searchFormSchema: FormSchema[] = [

+ 7 - 7
src/views/analysis/warningAnalysis/fireAreaJudgeAnalysis/index.vue

@@ -109,13 +109,13 @@ const [registerTable] = useTable({
   useSearchForm: true,
   bordered: true,
   showIndexColumn: false,
-  actionColumn: {
-    width: 120,
-    title: '详情',
-    dataIndex: 'action',
-    slots: { customRender: 'action' },
-    fixed: undefined,
-  },
+  // actionColumn: {
+  //   width: 120,
+  //   title: '详情',
+  //   dataIndex: 'action',
+  //   slots: { customRender: 'action' },
+  //   fixed: undefined,
+  // },
 });
 
 // 注册历史数据表格

+ 7 - 7
src/views/analysis/warningAnalysis/overlimitAlarm/index.vue

@@ -213,13 +213,13 @@ const [registerHistoryTable] = useTable({
   useSearchForm: true,
   bordered: true,
   showIndexColumn: false,
-  actionColumn: {
-    width: 60,
-    title: '操作',
-    dataIndex: 'action',
-    slots: { customRender: 'action' },
-    fixed: undefined,
-  },
+  // actionColumn: {
+  //   width: 60,
+  //   title: '操作',
+  //   dataIndex: 'action',
+  //   slots: { customRender: 'action' },
+  //   fixed: undefined,
+  // },
 });
 
 // 弹窗引用

+ 7 - 7
src/views/analysis/warningAnalysis/pressureDiffAnalysis/index.vue

@@ -231,13 +231,13 @@ const [registerHistoryTable] = useTable({
   useSearchForm: true,
   bordered: true,
   showIndexColumn: false,
-  actionColumn: {
-    width: 120,
-    title: '操作',
-    dataIndex: 'action',
-    slots: { customRender: 'action' },
-    fixed: undefined,
-  },
+  // actionColumn: {
+  //   width: 120,
+  //   title: '操作',
+  //   dataIndex: 'action',
+  //   slots: { customRender: 'action' },
+  //   fixed: undefined,
+  // },
 });
 
 // 弹窗引用

+ 13 - 13
src/views/analysis/warningAnalysis/sealRiskJudgeAnalysis/index.vue

@@ -120,12 +120,12 @@ const [registerTable] = useTable({
   useSearchForm: true,
   bordered: true,
   showIndexColumn: false,
-  actionColumn: {
-    width: 60,
-    title: '操作',
-    dataIndex: 'action',
-    slots: { customRender: 'action' },
-  },
+  // actionColumn: {
+  //   width: 60,
+  //   title: '操作',
+  //   dataIndex: 'action',
+  //   slots: { customRender: 'action' },
+  // },
 });
 
 // 注册历史数据表格
@@ -214,13 +214,13 @@ const [registerHistoryTable] = useTable({
   useSearchForm: true,
   bordered: true,
   showIndexColumn: false,
-  actionColumn: {
-    width: 60,
-    title: '操作',
-    dataIndex: 'action',
-    slots: { customRender: 'action' },
-    fixed: undefined,
-  },
+  // actionColumn: {
+  //   width: 60,
+  //   title: '操作',
+  //   dataIndex: 'action',
+  //   slots: { customRender: 'action' },
+  //   fixed: undefined,
+  // },
 });
 
 // 弹窗引用

+ 110 - 75
src/views/monitor/sealedMonitor/components/RealtimeDetailsModal.vue

@@ -1,12 +1,18 @@
 <template>
-  <Modal v-model:open="visible" title="密闭监测详情" width="1200px" @ok="handleOk" @cancel="handleCancel" prefixCls="custom-modal">
+  <BasicModal
+    v-bind="$attrs"
+    title="密闭监测详情"
+    width="1400px"
+    :bodyStyle="{ padding: `0 20px 0 20px` }"
+    @register="register"
+    @close="okHandler"
+    @ok="okHandler"
+  >
     <!-- 基础信息栏(修改布局:每行4列,共两行) -->
     <div class="base-info">
       <div v-for="(item, index) in modalDetailsData.basicInfo" :key="index" class="info-item">
         <span class="label">{{ item.label }}:</span>
-        <span class="value" :class="getBasicInfoTagClass(item.value)">
-          {{ dataRef[item.value] || '-' }}
-        </span>
+        <component :is="contextRender(item)"></component>
       </div>
     </div>
 
@@ -27,14 +33,14 @@
       <div class="chart-item">
         <div class="chart-title">爆炸三角形</div>
         <div class="chart-placeholder">
-          <BlastDelta :posMonitor="modalDetailsData.demoBlastData" :canvasSize="{ width: '95%', height: '95%' }" />
+          <BlastDelta :posMonitor="dataRef" :canvasSize="{ width: '95%', height: '95%' }" text-color="#000" />
         </div>
       </div>
       <div class="chart-item">
         <div class="chart-title">气体浓度曲线</div>
         <div class="chart-placeholder">
           <CustomChart
-            :chart-data="modalDetailsData.gasConcentrationData"
+            :chart-data="{ chartData: dataArray }"
             :chart-config="modalDetailsData.gasConcentrationConfig"
             :chart-option="{
               textStyle: {
@@ -49,7 +55,7 @@
         <div class="chart-title">内外压力及压差曲线</div>
         <div class="chart-placeholder">
           <CustomChart
-            :chart-data="modalDetailsData.pressureData"
+            :chart-data="{ chartData: dataArray }"
             :chart-config="modalDetailsData.pressureConfig"
             :chart-option="{
               textStyle: {
@@ -61,73 +67,118 @@
         </div>
       </div>
     </div>
-  </Modal>
+  </BasicModal>
 </template>
-
-<script lang="ts" setup>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
   import { ref } from 'vue';
-  import { Modal } from 'ant-design-vue';
   import MiniBoard from '/@/components/Configurable/detail/MiniBoard.vue';
   import BlastDelta from '/@/components/Configurable/preset/BlastDelta.vue';
   import CustomChart from '/@/components/Configurable/detail/CustomChart.vue';
-  import { modalDetailsData } from '../monitor.data';
+  import { modalDetailsData, tagCellRender } from '../monitor.data';
+  import { concat, get, last, takeRight } from 'lodash-es';
+  import { h } from 'vue';
+  import { getGoafData } from '../monitor.api';
+  import { useIntervalFn } from '@vueuse/core';
+  import dayjs from 'dayjs';
+
+  export default defineComponent({
+    components: { BasicModal, MiniBoard, BlastDelta, CustomChart },
+    emits: ['close', 'register'],
+    setup(__, { emit }) {
+      const dataRef = ref<any>({});
+      const dataArray = ref<any[]>([]);
+
+      // 添加元素,数组最多15项,按队列排布
+      const push = (item) => {
+        item.readTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
+        dataArray.value = takeRight(concat(dataArray.value, item), 15);
+      };
+
+      // const chartData = computed(() => {
+      //   return {
+      //     readTime: dataArray.value.map((item) => item.readTime),
+      //     sourcePressure: dataArray.value.map((item) => item.sourcePressure),
+      //     o2Val: dataArray.value.map((item) => item.o2Val),
+      //     coVal: dataArray.value.map((item) => item.coVal),
+      //   };
+      // });
+      function getTagType(level: string) {
+        switch (level) {
+          case '1':
+            return 'red';
+          case '2':
+            return 'volcano';
+          case '3':
+            return 'orange';
+          case '4':
+            return 'success';
+          default:
+            return 'default';
+        }
+      }
 
-  // 控制弹框显隐
-  const visible = ref(false);
+      const [register] = useModalInner((d) => {
+        if (!d) return;
+        dataRef.value = d;
+        push(d);
+        resume();
+      });
 
-  const dataRef = ref<any>();
+      function contextRender({ value, tag }: any) {
+        if (tag) return tagCellRender(get(dataRef.value, value));
+        return h('span', get(dataRef.value, value));
+      }
 
-  // 外部调用显示弹框
-  const showModal = (record: any) => {
-    visible.value = true;
-    dataRef.value = record;
-  };
-  // 外部调用隐藏弹框
-  const hideModal = () => {
-    visible.value = false;
-  };
+      function fetchDetailData() {
+        const { mineCode, goafId } = dataRef.value;
+        getGoafData({ mineCode, goafId }).then((r) => {
+          dataRef.value = last(r);
+          push(dataRef.value);
+          // push(dataRef.value)
+        });
+      }
 
-  // 确定按钮回调
-  const handleOk = () => {
-    visible.value = false;
-    // 可添加确定后的业务逻辑
-  };
-  // 取消按钮回调
-  const handleCancel = () => {
-    visible.value = false;
-  };
+      const { pause, resume } = useIntervalFn(
+        () => {
+          fetchDetailData();
+        },
+        2000,
+        {
+          immediate: false,
+        }
+      );
 
-  // 获取基础信息value对应的标签样式类
-  const getBasicInfoTagClass = (value) => {
-    switch (value) {
-      case '闭内气体涌出':
-        return 'tag-danger';
-      case '低风险':
-        return 'tag-primary';
-      case '不可启封':
-        return 'tag-warning';
-      default:
-        return '';
-    }
-  };
-  // 暴露方法给父组件
-  defineExpose({
-    showModal,
-    hideModal,
+      function okHandler() {
+        pause();
+        emit('close');
+      }
+
+      return {
+        dataRef,
+        modalDetailsData,
+        dataArray,
+        get,
+        getTagType,
+        register,
+        contextRender,
+        okHandler,
+      };
+    },
   });
 </script>
-
-<style scoped>
+<style lang="less" scoped>
   .base-info {
     display: grid;
-    grid-template-columns: repeat(4, 1fr); /* 强制每行4列 */
+    grid-template-columns: repeat(3, 1fr); /* 强制每行4列 */
     grid-template-rows: auto auto; /* 两行自动高度 */
     gap: 16px 12px; /* 行列间距(行间距16px,列间距12px) */
     margin-bottom: 20px;
     padding: 20px;
-    border: 1px solid #f0f0f0;
+    border: 1px solid @border-color-base;
     border-radius: 10px;
-    background: #f8f9fc;
+    background: @card-bg-color;
   }
   .info-item {
     display: flex;
@@ -149,31 +200,15 @@
     overflow: hidden;
     text-overflow: ellipsis;
   }
-  .tag-danger {
-    color: #f5222d;
-    padding: 2px 6px;
-    border-radius: 4px;
-  }
-  .tag-primary {
-    color: #1890ff;
-    padding: 2px 6px;
-    border-radius: 4px;
-  }
-  .tag-warning {
-    color: #faad14;
-    padding: 2px 6px;
-    border-radius: 4px;
-  }
-
   .data-cards {
     display: grid;
     grid-template-columns: repeat(8, 1fr);
     gap: 16px;
     margin-bottom: 20px;
     padding: 20px;
-    border: 1px solid #f0f0f0;
+    border: 1px solid @border-color-base;
     border-radius: 10px;
-    background: #f8f9fc;
+    background: @card-bg-color;
   }
   .data-card {
     background: #fafafa;
@@ -197,10 +232,10 @@
     flex-wrap: wrap;
     gap: 16px;
     padding: 20px;
-    border: 1px solid #f0f0f0;
+    border: 1px solid @border-color-base;
     border-radius: 10px;
     /* background: black; */
-    background: #f8f9fc;
+    background: @card-bg-color;
   }
   .chart-item {
     flex: 1;

+ 44 - 0
src/views/monitor/sealedMonitor/hooks/form.ts

@@ -0,0 +1,44 @@
+import { last } from 'lodash';
+import { ref, computed } from 'vue';
+import { useRoute } from 'vue-router';
+import { getGoafSelectOption } from '../monitor.api';
+import { useMineStore } from '/@/store/modules/mine';
+import { findNodeAll, findPath } from '/@/utils/helper/treeHelper';
+
+export function useInitForm() {
+  const config = {
+    id: 'id',
+    pid: 'parentId',
+    children: 'childDepart',
+  };
+  const route = useRoute();
+  const mineStroe = useMineStore();
+  const mineCodes = ref<string[]>([]);
+  const getMineTree = computed(() => {
+    const id = last(route.fullPath.split('/'));
+    return findNodeAll(mineStroe.mineTree, (item) => item.id === id, config);
+  });
+  const paths = findPath(getMineTree.value, (item) => item.isLeaf, config);
+
+  mineCodes.value = paths.map((e) => e.id);
+
+  // 采空区选择器
+  const goafId = ref('');
+  const goafOptions = ref<any[]>([]);
+
+  function initGoafOptions() {
+    getGoafSelectOption({ mineCode: last(mineCodes.value) }).then(({ options, defaultValue }) => {
+      goafOptions.value = options;
+      goafId.value = defaultValue;
+    });
+  }
+  initGoafOptions();
+
+  return {
+    goafId,
+    goafOptions,
+    mineCodes,
+    getMineTree,
+    initGoafOptions,
+  };
+}

+ 51 - 51
src/views/monitor/sealedMonitor/index.vue

@@ -15,6 +15,7 @@
               children: 'childDepart',
             }"
             show-search
+            @change="initGoafOptions"
           >
             <template #displayRender="{ labels }">
               {{ labels[labels.length - 1] }}
@@ -22,7 +23,7 @@
           </a-cascader>
         </template>
         <template #action="{ record }">
-          <button @click="openModal(record, 'realtime')" class="action-btn">
+          <button @click="openModal(record)" class="action-btn">
             <SvgIcon name="details" />
           </button>
         </template>
@@ -42,6 +43,7 @@
               children: 'childDepart',
             }"
             show-search
+            @change="initGoafOptions"
           >
             <template #displayRender="{ labels }">
               {{ labels[labels.length - 1] }}
@@ -54,59 +56,79 @@
         <template #afterReset>
           <a-button type="primary" @click="onExportXls">导出</a-button>
         </template>
-        <template #action="{ record }">
-          <button @click="openModal(record, 'history')" class="action-btn">
+        <!-- <template #action="{ record }">
+          <button @click="openModal(record)" class="action-btn">
             <SvgIcon name="details" />
           </button>
-        </template>
+        </template> -->
       </BasicTable>
     </TabPane>
   </Tabs>
 
   <!-- 实时数据详情弹框 -->
-  <RealtimeDetailsModal ref="realtimeModalRef" />
+  <RealtimeDetailsModal @register="registerRealtimeModal" @close="resume" />
   <!-- 历史数据详情弹框 -->
-  <HistoricalDetailsModal ref="historyModalRef" />
+  <!-- <HistoricalDetailsModal @register="registerHistoryModal" @close="resume" /> -->
 </template>
 
 <script setup lang="ts">
-  import { computed, ref } from 'vue';
+  import { ref } from 'vue';
   import { BasicTable } from '/@/components/Table';
   import { Tabs, TabPane } from 'ant-design-vue';
   // 引入模拟数据
   import { columns, searchFormSchema, historicalColumns, historicalFormSchema } from './monitor.data';
   import RealtimeDetailsModal from './components/RealtimeDetailsModal.vue';
-  import HistoricalDetailsModal from './components/HistoricalDetailsModal.vue';
+  // import HistoricalDetailsModal from './components/HistoricalDetailsModal.vue';
   import { SvgIcon } from '/@/components/Icon';
-  import { getGoafData, getGoafHistory, getGoafSelectOption } from './monitor.api';
+  import { getGoafData, getGoafHistory } from './monitor.api';
   import { useListPage } from '/@/hooks/system/useListPage';
-  import { useRoute } from 'vue-router';
   import { last } from 'lodash-es';
-  import { useMineStore } from '/@/store/modules/mine';
-  import { findNodeAll, findPath } from '/@/utils/helper/treeHelper';
+  import { useModal } from '/@/components/Modal';
+  import { useIntervalFn } from '@vueuse/core';
+  import { useInitForm } from './hooks/form';
   // import { getGoafList } from '../../system/algorithm/algorithm.api';
 
   // 激活的Tab页签
+
+  // 处理矿名选择器相关的逻辑
+  const { goafId, goafOptions, mineCodes, getMineTree, initGoafOptions } = useInitForm();
   const activeTab = ref('realtime');
 
   // 注册实时数据表格
   const { tableContext: ctxRealtime } = useListPage({
     tableProps: {
-      api: getGoafData,
-      beforeFetch(params) {
-        params.mineCode = last(mineCodes.value);
-      },
+      // api: getGoafData,
+      // beforeFetch(params) {
+      //   params.mineCode = last(mineCodes.value);
+      // },
       columns,
       formConfig: {
         schemas: searchFormSchema,
         schemaGroupNames: ['常规查询'],
+        submitFunc: () => reloadRealtimeTable(true),
       },
       showIndexColumn: false,
       scroll: { x: 'max-content' },
     },
     pagination: false,
   });
-  const [registerRealtimeTable] = ctxRealtime;
+  const [registerRealtimeTable, { setTableData, setLoading }] = ctxRealtime;
+
+  function reloadRealtimeTable(showLoading: boolean = false) {
+    if (showLoading) {
+      setLoading(true);
+    }
+    return getGoafData({ mineCode: last(mineCodes.value) })
+      .then((res) => {
+        setTableData(res);
+      })
+      .finally(() => {
+        setLoading(false);
+      });
+  }
+
+  reloadRealtimeTable();
+  const { pause, resume } = useIntervalFn(reloadRealtimeTable, 10000);
 
   // 注册历史数据表格
   const { tableContext: ctxHistory, onExportXls } = useListPage({
@@ -124,6 +146,7 @@
       bordered: true,
       showIndexColumn: false,
       scroll: { x: 'max-content' },
+      showActionColumn: false,
     },
     exportConfig: {
       url: '/province/alarm/exportProvinceAlarmHistory',
@@ -134,43 +157,20 @@
   const [registerHistoryTable] = ctxHistory;
 
   // 弹窗引用
-  const realtimeModalRef = ref<any>(null);
-  const historyModalRef = ref<any>(null);
+  const [registerRealtimeModal, { openModal: openRealtimeModal }] = useModal();
+  // const [registerHistoryModal, { openModal: openHistoryModal }] = useModal();
 
   // 打开弹窗方法(区分实时/历史)
-  const openModal = (record, type) => {
-    if (type === 'realtime') {
-      // 可向实时弹窗传递当前记录数据
-      realtimeModalRef.value?.showModal(record);
-    } else {
-      // 可向历史弹窗传递当前记录数据
-      historyModalRef.value?.showModal(record);
-    }
-  };
-
-  const config = {
-    id: 'id',
-    pid: 'parentId',
-    children: 'childDepart',
+  const openModal = (record) => {
+    openRealtimeModal(true, record);
+    // if (type === 'realtime') {
+    //   // 可向实时弹窗传递当前记录数据
+    // } else {
+    //   // 可向历史弹窗传递当前记录数据
+    //   openHistoryModal(true, record);
+    // }
+    pause();
   };
-  const route = useRoute();
-  const mineStroe = useMineStore();
-  const mineCodes = ref<string[]>([]);
-  const getMineTree = computed(() => {
-    const id = last(route.fullPath.split('/'));
-    return findNodeAll(mineStroe.mineTree, (item) => item.id === id, config);
-  });
-  const paths = findPath(getMineTree.value, (item) => item.isLeaf, config);
-
-  mineCodes.value = paths.map((e) => e.id);
-
-  const goafId = ref('');
-  const goafOptions = ref<any[]>([]);
-
-  getGoafSelectOption({ mineCode: last(mineCodes.value) }).then(({ options, defaultValue }) => {
-    goafOptions.value = options;
-    goafId.value = defaultValue;
-  });
 </script>
 
 <style lang="less" scoped></style>

+ 195 - 522
src/views/monitor/sealedMonitor/monitor.data.ts

@@ -1,96 +1,119 @@
 import dayjs from 'dayjs';
-import { getGoafList, getMineData } from '../../system/algorithm/algorithm.api';
 import { BasicColumn } from '/@/components/Table';
 import { FormSchema } from '/@/components/Table';
 import { TreeItem } from '/@/components/Tree/index';
-import { getGoafData } from './monitor.api';
+import { ModuleDataChart } from '/@/components/Configurable/types';
+import { h } from 'vue';
+import { Tag } from 'ant-design-vue';
 
 // 实时数据相关
 export const columns: BasicColumn[] = [
-  {
-    title: '序号',
-    dataIndex: 'orderNo',
-    width: 60,
-  },
-  {
-    title: '区域',
-    dataIndex: 'enforcement',
-    width: 80,
-  },
+  // {
+  //   title: '序号',
+  //   dataIndex: 'orderNo',
+  //   width: 60,
+  // },
+  // {
+  //   title: '区域',
+  //   dataIndex: 'coalSeamName',
+  //   width: 80,
+  // },
   {
     title: '煤矿名称',
     dataIndex: 'mineName',
-    width: 180,
+    width: 200,
   },
   {
     title: '密闭名称',
-    dataIndex: 'sealedName',
-    width: 80,
+    dataIndex: 'devicePos',
+    width: 100,
   },
   {
     title: '所属煤层',
-    dataIndex: 'coalSeam',
-    width: 80,
+    dataIndex: 'coalSeamName',
+    width: 100,
   },
   {
-    title: '自燃倾向性',
-    dataIndex: 'riskLevel',
-    width: 80,
+    title: 'CO(ppm)',
+    dataIndex: 'coVal',
+    width: 100,
   },
   {
-    title: 'CO(ppm)',
-    dataIndex: 'COVal',
-    width: 80,
+    title: 'CO2(%)',
+    dataIndex: 'co2Val',
+    width: 100,
   },
   {
     title: 'CH4(%)',
-    dataIndex: 'CH4Val',
-    width: 80,
+    dataIndex: 'ch4Val',
+    width: 100,
   },
   {
     title: 'C2H2(ppm)',
-    dataIndex: 'C2H2Val',
-    width: 80,
+    dataIndex: 'c2h2Val',
+    width: 100,
+  },
+  {
+    title: 'C2H4(%)',
+    dataIndex: 'c2h4Val',
+    width: 100,
   },
   {
     title: 'O2(%)',
-    dataIndex: 'O2Val',
-    width: 80,
+    dataIndex: 'o2Val',
+    width: 100,
   },
   {
     title: '温度(℃)',
     dataIndex: 'temperature',
-    width: 80,
+    width: 100,
   },
   {
     title: '压差(Pa)',
-    dataIndex: 'pressureDiff',
-    width: 80,
+    dataIndex: 'sourcePressure',
+    width: 100,
   },
   {
-    title: '是否漏风',
-    dataIndex: 'leakage',
-    width: 80,
+    title: '自然发火隐患等级',
+    dataIndex: 'fireAlarm',
+    width: 100,
+    customRender({ record }) {
+      return tagCellRender(record.fireAlarm);
+    },
   },
   {
-    title: '自然发火隐患',
-    dataIndex: 'fireHazard',
-    width: 80,
+    title: '是否漏风',
+    dataIndex: 'leakageAlarm',
+    width: 100,
+    customRender({ record }) {
+      return tagCellRender(record.leakageAlarm);
+    },
   },
   {
-    title: '密闭启封判定',
-    dataIndex: 'unsealing',
-    width: 80,
+    title: '压差隐患等级',
+    dataIndex: 'sourcePressureAlarm',
+    width: 100,
+    customRender({ record }) {
+      return tagCellRender(record.sourcePressureAlarm);
+    },
   },
   {
-    title: '爆炸危险性',
-    dataIndex: 'explosionHazard',
-    width: 80,
+    title: '密闭启封判定',
+    dataIndex: 'unsealAlarm',
+    width: 100,
+    customRender({ record }) {
+      return tagCellRender(record.unsealAlarm);
+    },
   },
+  // {
+  //   title: '爆炸危险性',
+  //   dataIndex: 'explosionHazard',
+  //   width: 80,
+  // },
   {
     title: '更新时间',
-    dataIndex: 'updateTime',
-    width: 80,
+    dataIndex: 'readTime',
+    width: 100,
   },
 ];
 
@@ -136,61 +159,50 @@ export const searchFormSchema: FormSchema[] = [
   },
 ];
 
-export const minesData = [
-  {
-    orderNo: 101, // 序号
-    enforcement: '执法一处', // 区域
-    mineName: '神木市三江', // 煤矿名称
-    sealedName: '采空区密闭', // 密闭名称
-    coalSeam: 'XX煤层', // 所属煤层
-    riskLevel: 'Ⅰ类容易自燃', // 自燃倾向性(与搜索框选项label一致)
-    COVal: 24, // CO浓度(ppm)
-    CH4Val: 0, // CH4浓度(%)
-    C2H2Val: 0, // C2H2浓度(ppm)
-    O2Val: 20, // O2浓度(%)
-    temperature: 35, // 温度(℃)
-    pressureDiff: 50, // 压差(Pa)
-    leakage: '气体涌出', // 是否漏风
-    fireHazard: '低风险', // 自然发火隐患
-    unsealing: '不可启封', // 密闭启封判定
-    explosionHazard: '低风险', // 爆炸危险性
-    updateTime: '2025-11-17 15:00:40', // 更新时间
-  },
-];
-
-export const modalDetailsData = {
+export const modalDetailsData: {
+  basicInfo: Record<string, any>[];
+  board: Record<string, any>[];
+  gasConcentrationConfig: ModuleDataChart;
+  pressureConfig: ModuleDataChart;
+} = {
   basicInfo: [
     {
       label: '煤矿名称',
       value: 'mineName',
+      tag: false,
     },
     {
       label: '设备位置',
       value: 'devicePos',
+      tag: false,
     },
+    // {
+    //   label: '所属煤层',
+    //   value: 'coalSeamName',
+    // },
+    // {
+    //   label: '自燃情况',
+    //   value: 'Ⅰ类容易自燃',
+    // },
     {
-      label: '所属煤层',
-      value: 'coalSeamName',
-    },
-    {
-      label: '自燃情况',
-      value: 'Ⅰ类容易自燃',
+      label: '自然发火隐患等级',
+      value: 'fireAlarm',
+      tag: true,
     },
     {
       label: '是否漏风',
       value: 'leakageAlarm',
+      tag: true,
     },
     {
-      label: '自然发火隐患',
-      value: 'fireAlarm',
+      label: '压差隐患等级',
+      value: 'sourcePressureAlarm',
+      tag: true,
     },
     {
       label: '密闭启封判定',
       value: 'unsealAlarm',
-    },
-    {
-      label: '爆炸危险性',
-      value: 'explosionAlarm',
+      tag: true,
     },
   ],
   board: [
@@ -227,43 +239,21 @@ export const modalDetailsData = {
       value: 'sourcePressure',
     },
   ],
-  demoBlastData: {
-    // 爆炸三角形顶点坐标数据(JSON字符串格式)
-    btTriBlast: JSON.stringify({
-      A_x: 0,
-      A_y: 21,
-      B_x: 50,
-      B_y: 0,
-      E_x: 10,
-      E_y: 15,
-      F_x: 30,
-      F_y: 5,
-      G_x: 5,
-      G_y: 18,
-    }),
-    o2val: '12.5',
-    coval: '2000',
-    gasval: '5.2',
-    ch2val: '1500',
-    chval: '800',
-  },
   gasConcentrationConfig: {
     type: 'line_smooth', // 使用光滑曲线类型
     legend: { show: true },
     xAxis: [
       {
-        type: 'category',
-        dataKey: 'time',
+        show: true,
         name: '时间',
         axisLabel: { color: '#000000' },
-        nameTextStyle: { color: '#000' },
       },
     ],
     yAxis: [
       {
-        type: 'value',
         show: true,
         name: '浓度(%)',
+        position: 'left',
         splitLine: { show: false },
         axisLine: {
           show: true,
@@ -275,118 +265,132 @@ export const modalDetailsData = {
     ],
     series: [
       {
-        label: '气体浓度',
-        readFrom: 'gasData',
-        xprop: 'time',
-        yprop: 'value',
-        // color: '#000'
+        label: '氧气浓度',
+        readFrom: 'chartData',
+        xprop: 'readTime',
+        yprop: 'o2Val',
+      },
+      {
+        label: '一氧化碳浓度',
+        readFrom: 'chartData',
+        xprop: 'readTime',
+        yprop: 'coVal',
+      },
+      {
+        label: '二氧化碳浓度',
+        readFrom: 'chartData',
+        xprop: 'readTime',
+        yprop: 'co2Val',
       },
     ],
-  },
-  gasConcentrationData: {
-    gasData: [
-      // 示例数据,实际应从接口获取
-      { time: '00:00', value: 25.5 },
-      { time: '04:00', value: 26.3 },
-      { time: '08:00', value: 30.9 },
-      { time: '12:00', value: 27.8 },
-      { time: '16:00', value: 29.1 },
-      { time: '20:00', value: 25.5 },
-    ],
+    readFrom: '',
   },
   pressureConfig: {
     type: 'line', // 使用普通折线图类型
-    legend: { show: true, color: '#000000' },
-    xAxis: [{ type: 'category', dataKey: 'time', name: '时间', axisLabel: { color: '#000000' } }],
-    yAxis: [{ show: true, name: '压力(kPa)', axisLabel: { color: '#000000' } }],
-    series: [
-      { label: '内部压力', readFrom: 'chartdata', xprop: 'time', yprop: 'inner' },
-      { label: '外部压力', readFrom: 'chartdata', xprop: 'time', yprop: 'outer' },
-      { label: '压力差', readFrom: 'chartdata', xprop: 'time', yprop: 'diff' },
+    legend: { show: true },
+    xAxis: [
+      {
+        show: true,
+        name: '时间',
+        axisLabel: { color: '#000000' },
+      },
     ],
-  },
-  pressureData: {
-    chartdata: [
-      // 示例数据,实际应从接口获取
-      { time: '00:00', inner: 12, outer: 18, diff: 6 },
-      { time: '04:00', inner: 15, outer: 17, diff: 2 },
-      { time: '08:00', inner: 13, outer: 19, diff: 6 },
-      { time: '12:00', inner: 11, outer: 10, diff: 1 },
-      { time: '16:00', inner: 14, outer: 18, diff: 4 },
-      { time: '20:00', inner: 16, outer: 16, diff: 0 },
+    yAxis: [
+      {
+        show: true,
+        position: 'left',
+        name: '压力(kPa)',
+        axisLabel: { color: '#000000' },
+      },
+    ],
+    series: [
+      {
+        label: '压差',
+        readFrom: 'chartData',
+        xprop: 'readTime',
+        yprop: 'sourcePressure',
+      },
     ],
+    readFrom: '',
   },
 };
 
 // 历史数据相关
 export const historicalColumns: BasicColumn[] = [
-  {
-    title: '序号',
-    dataIndex: 'orderNo',
-  },
-  {
-    title: '区域',
-    dataIndex: 'enforcement',
-  },
+  // {
+  //   title: '序号',
+  //   dataIndex: 'orderNo',
+  //   width: 60,
+  // },
+  // {
+  //   title: '区域',
+  //   dataIndex: 'enforcement',
+  //   width: 100,
+  // },
   {
     title: '煤矿名称',
     dataIndex: 'mineName',
+    width: 200,
   },
   {
     title: '密闭名称',
-    dataIndex: 'sealedName',
+    dataIndex: 'devicePos',
+    width: 100,
   },
   {
     title: '所属煤层',
-    dataIndex: 'coalSeam',
+    dataIndex: 'coalSeamName',
+    width: 100,
   },
   {
-    title: '自燃倾向性',
-    dataIndex: 'riskLevel',
+    title: 'CO(ppm)',
+    dataIndex: 'coVal',
+    width: 100,
   },
   {
-    title: 'CO(ppm)',
-    dataIndex: 'COVal',
+    title: 'CO2(%)',
+    dataIndex: 'co2Val',
+    width: 100,
   },
   {
     title: 'CH4(%)',
-    dataIndex: 'CH4Val',
+    dataIndex: 'ch4Val',
+    width: 100,
   },
   {
     title: 'C2H2(ppm)',
-    dataIndex: 'C2H2Val',
+    dataIndex: 'c2h2Val',
+    width: 100,
+  },
+  {
+    title: 'C2H4(%)',
+    dataIndex: 'c2h4Val',
+    width: 100,
   },
   {
     title: 'O2(%)',
-    dataIndex: 'O2Val',
+    dataIndex: 'o2Val',
+    width: 100,
   },
   {
     title: '温度(℃)',
     dataIndex: 'temperature',
+    width: 100,
   },
   {
     title: '压差(Pa)',
-    dataIndex: 'pressureDiff',
-  },
-  {
-    title: '是否漏风',
-    dataIndex: 'leakage',
-  },
-  {
-    title: '自然发火隐患',
-    dataIndex: 'fireHazard',
-  },
-  {
-    title: '密闭启封判定',
-    dataIndex: 'unsealing',
-  },
-  {
-    title: '爆炸危险性',
-    dataIndex: 'explosionHazard',
+    dataIndex: 'sourcePressure',
+    width: 100,
   },
+  // {
+  //   title: '爆炸危险性',
+  //   dataIndex: 'explosionHazard',
+  //   width: 100,
+  // },
   {
     title: '更新时间',
-    dataIndex: 'updateTime',
+    dataIndex: 'createTime',
+    width: 100,
   },
 ];
 
@@ -478,28 +482,6 @@ export const historicalFormSchema: FormSchema[] = [
   },
 ];
 
-export const historicalMinesData = [
-  {
-    orderNo: 101, // 序号
-    enforcement: '执法一处', // 区域
-    mineName: '神木市三江', // 煤矿名称
-    sealedName: '采空区密闭', // 密闭名称
-    coalSeam: 'XX煤层', // 所属煤层
-    riskLevel: 'Ⅰ类容易自燃', // 自燃倾向性(与搜索框选项label一致)
-    COVal: 24, // CO浓度(ppm)
-    CH4Val: 0, // CH4浓度(%)
-    C2H2Val: 0, // C2H2浓度(ppm)
-    O2Val: 20, // O2浓度(%)
-    temperature: 35, // 温度(℃)
-    pressureDiff: 50, // 压差(Pa)
-    leakage: '气体涌出', // 是否漏风
-    fireHazard: '低风险', // 自然发火隐患
-    unsealing: '不可启封', // 密闭启封判定
-    explosionHazard: '低风险', // 爆炸危险性
-    updateTime: '2025-12-22 15:00:40', // 更新时间
-  },
-];
-
 export const treeData: TreeItem[] = [
   {
     title: '气体参数 ',
@@ -528,330 +510,21 @@ export const treeData: TreeItem[] = [
   },
 ];
 
-export const historicalMockChartData = [
-  {
-    time: '2025-12-22 00:00:00',
-    CO: 22.3,
-    CH4: 0.12,
-    C2H4: 0.35,
-    C2H2: 0.1,
-    CO2: 0.85,
-    O2: 19.5,
-    innerPressure: 101.32,
-    outerPressure: 101.1,
-    pressureDiff: 0.22,
-    temperature: 33.2,
-  },
-  {
-    time: '2025-12-22 01:00:00',
-    CO: 23.1,
-    CH4: 0.15,
-    C2H4: 0.42,
-    C2H2: 0.12,
-    CO2: 0.92,
-    O2: 19.7,
-    innerPressure: 101.38,
-    outerPressure: 101.15,
-    pressureDiff: 0.23,
-    temperature: 33.5,
-  },
-  {
-    time: '2025-12-22 02:00:00',
-    CO: 22.8,
-    CH4: 0.13,
-    C2H4: 0.38,
-    C2H2: 0.09,
-    CO2: 0.88,
-    O2: 19.6,
-    innerPressure: 101.41,
-    outerPressure: 101.18,
-    pressureDiff: 0.23,
-    temperature: 33.3,
-  },
-  {
-    time: '2025-12-22 03:00:00',
-    CO: 21.9,
-    CH4: 0.11,
-    C2H4: 0.31,
-    C2H2: 0.08,
-    CO2: 0.81,
-    O2: 19.4,
-    innerPressure: 101.35,
-    outerPressure: 101.12,
-    pressureDiff: 0.21,
-    temperature: 33.1,
-  },
-  {
-    time: '2025-12-22 04:00:00',
-    CO: 22.5,
-    CH4: 0.14,
-    C2H4: 0.36,
-    C2H2: 0.11,
-    CO2: 0.86,
-    O2: 19.5,
-    innerPressure: 101.39,
-    outerPressure: 101.16,
-    pressureDiff: 0.22,
-    temperature: 33.4,
-  },
-  {
-    time: '2025-12-22 05:00:00',
-    CO: 23.4,
-    CH4: 0.16,
-    C2H4: 0.45,
-    C2H2: 0.13,
-    CO2: 0.95,
-    O2: 19.8,
-    innerPressure: 101.43,
-    outerPressure: 101.2,
-    pressureDiff: 0.24,
-    temperature: 33.7,
-  },
-  {
-    time: '2025-12-22 06:00:00',
-    CO: 24.2,
-    CH4: 0.18,
-    C2H4: 0.51,
-    C2H2: 0.15,
-    CO2: 1.02,
-    O2: 20.0,
-    innerPressure: 101.47,
-    outerPressure: 101.23,
-    pressureDiff: 0.25,
-    temperature: 34.0,
-  },
-  {
-    time: '2025-12-22 07:00:00',
-    CO: 25.3,
-    CH4: 0.21,
-    C2H4: 0.58,
-    C2H2: 0.17,
-    CO2: 1.08,
-    O2: 20.2,
-    innerPressure: 101.52,
-    outerPressure: 101.27,
-    pressureDiff: 0.26,
-    temperature: 34.3,
-  },
-  {
-    time: '2025-12-22 08:00:00',
-    CO: 26.1,
-    CH4: 0.23,
-    C2H4: 0.65,
-    C2H2: 0.19,
-    CO2: 1.15,
-    O2: 20.4,
-    innerPressure: 101.56,
-    outerPressure: 101.3,
-    pressureDiff: 0.27,
-    temperature: 34.6,
-  },
-  {
-    time: '2025-12-22 09:00:00',
-    CO: 27.4,
-    CH4: 0.25,
-    C2H4: 0.72,
-    C2H2: 0.22,
-    CO2: 1.23,
-    O2: 20.6,
-    innerPressure: 101.6,
-    outerPressure: 101.33,
-    pressureDiff: 0.28,
-    temperature: 35.0,
-  },
-  {
-    time: '2025-12-22 10:00:00',
-    CO: 28.2,
-    CH4: 0.27,
-    C2H4: 0.78,
-    C2H2: 0.24,
-    CO2: 1.29,
-    O2: 20.8,
-    innerPressure: 101.63,
-    outerPressure: 101.35,
-    pressureDiff: 0.29,
-    temperature: 35.3,
-  },
-  {
-    time: '2025-12-22 11:00:00',
-    CO: 27.8,
-    CH4: 0.26,
-    C2H4: 0.75,
-    C2H2: 0.23,
-    CO2: 1.26,
-    O2: 20.7,
-    innerPressure: 101.61,
-    outerPressure: 101.34,
-    pressureDiff: 0.28,
-    temperature: 35.2,
-  },
-  {
-    time: '2025-12-22 12:00:00',
-    CO: 26.9,
-    CH4: 0.24,
-    C2H4: 0.69,
-    C2H2: 0.21,
-    CO2: 1.19,
-    O2: 20.5,
-    innerPressure: 101.58,
-    outerPressure: 101.32,
-    pressureDiff: 0.27,
-    temperature: 34.9,
-  },
-  {
-    time: '2025-12-22 13:00:00',
-    CO: 26.3,
-    CH4: 0.22,
-    C2H4: 0.64,
-    C2H2: 0.19,
-    CO2: 1.14,
-    O2: 20.3,
-    innerPressure: 101.55,
-    outerPressure: 101.3,
-    pressureDiff: 0.26,
-    temperature: 34.7,
-  },
-  {
-    time: '2025-12-22 14:00:00',
-    CO: 25.7,
-    CH4: 0.2,
-    C2H4: 0.59,
-    C2H2: 0.18,
-    CO2: 1.09,
-    O2: 20.1,
-    innerPressure: 101.53,
-    outerPressure: 101.28,
-    pressureDiff: 0.25,
-    temperature: 34.5,
-  },
-  {
-    time: '2025-12-22 15:00:00',
-    CO: 24.9,
-    CH4: 0.18,
-    C2H4: 0.53,
-    C2H2: 0.16,
-    CO2: 1.03,
-    O2: 19.9,
-    innerPressure: 101.49,
-    outerPressure: 101.25,
-    pressureDiff: 0.24,
-    temperature: 34.2,
-  },
-  {
-    time: '2025-12-22 16:00:00',
-    CO: 24.3,
-    CH4: 0.17,
-    C2H4: 0.49,
-    C2H2: 0.15,
-    CO2: 0.98,
-    O2: 19.8,
-    innerPressure: 101.46,
-    outerPressure: 101.22,
-    pressureDiff: 0.23,
-    temperature: 34.0,
-  },
-  {
-    time: '2025-12-22 17:00:00',
-    CO: 23.8,
-    CH4: 0.16,
-    C2H4: 0.46,
-    C2H2: 0.14,
-    CO2: 0.94,
-    O2: 19.7,
-    innerPressure: 101.44,
-    outerPressure: 101.21,
-    pressureDiff: 0.23,
-    temperature: 33.8,
-  },
-  {
-    time: '2025-12-22 18:00:00',
-    CO: 23.5,
-    CH4: 0.15,
-    C2H4: 0.43,
-    C2H2: 0.13,
-    CO2: 0.91,
-    O2: 19.6,
-    innerPressure: 101.42,
-    outerPressure: 101.19,
-    pressureDiff: 0.22,
-    temperature: 33.7,
-  },
-  {
-    time: '2025-12-22 19:00:00',
-    CO: 24.1,
-    CH4: 0.17,
-    C2H4: 0.48,
-    C2H2: 0.15,
-    CO2: 0.97,
-    O2: 19.8,
-    innerPressure: 101.45,
-    outerPressure: 101.22,
-    pressureDiff: 0.24,
-    temperature: 33.9,
-  },
-  {
-    time: '2025-12-22 20:00:00',
-    CO: 24.7,
-    CH4: 0.19,
-    C2H4: 0.52,
-    C2H2: 0.16,
-    CO2: 1.01,
-    O2: 20.0,
-    innerPressure: 101.48,
-    outerPressure: 101.24,
-    pressureDiff: 0.25,
-    temperature: 34.1,
-  },
-  {
-    time: '2025-12-22 21:00:00',
-    CO: 25.2,
-    CH4: 0.2,
-    C2H4: 0.56,
-    C2H2: 0.18,
-    CO2: 1.05,
-    O2: 20.1,
-    innerPressure: 101.51,
-    outerPressure: 101.26,
-    pressureDiff: 0.26,
-    temperature: 34.3,
-  },
-  {
-    time: '2025-12-22 22:00:00',
-    CO: 24.5,
-    CH4: 0.18,
-    C2H4: 0.5,
-    C2H2: 0.16,
-    CO2: 0.99,
-    O2: 19.9,
-    innerPressure: 101.47,
-    outerPressure: 101.23,
-    pressureDiff: 0.24,
-    temperature: 34.0,
-  },
-  {
-    time: '2025-12-22 23:00:00',
-    CO: 23.7,
-    CH4: 0.16,
-    C2H4: 0.45,
-    C2H2: 0.14,
-    CO2: 0.93,
-    O2: 19.7,
-    innerPressure: 101.43,
-    outerPressure: 101.2,
-    pressureDiff: 0.23,
-    temperature: 33.8,
-  },
-  {
-    time: '2025-11-18 00:00:00',
-    CO: 22.9,
-    CH4: 0.14,
-    C2H4: 0.39,
-    C2H2: 0.11,
-    CO2: 0.89,
-    O2: 19.6,
-    innerPressure: 101.37,
-    outerPressure: 101.17,
-    pressureDiff: 0.22,
-    temperature: 33.4,
-  },
-];
+function getTagType(level: string) {
+  switch (level) {
+    case '1':
+      return 'red';
+    case '2':
+      return 'volcano';
+    case '3':
+      return 'orange';
+    case '4':
+      return 'success';
+    default:
+      return 'default';
+  }
+}
+export function tagCellRender(record: any) {
+  if (!record) return h(Tag, { bordered: false, color: 'default' }, '-');
+  return h(Tag, { bordered: false, color: getTagType(record.alarmLevel) }, record.alarmName);
+}