Pārlūkot izejas kodu

[Feat 0000]首页开发及矿山基础信息-矿山信息页面开发

wangkeyi 5 mēneši atpakaļ
vecāks
revīzija
fe7f66759c
22 mainītis faili ar 2209 papildinājumiem un 27 dzēšanām
  1. 45 0
      mock/sys/menu.ts
  2. BIN
      src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-1.png
  3. BIN
      src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-2.png
  4. BIN
      src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-3.png
  5. BIN
      src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-4.png
  6. BIN
      src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-5.png
  7. BIN
      src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-B.png
  8. BIN
      src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-D.png
  9. BIN
      src/assets/images/sealedGoaf/configurable/table/table-label-A.png
  10. BIN
      src/assets/images/sealedGoaf/views/home/home-bg.png
  11. BIN
      src/assets/images/sealedGoaf/views/home/module-title.png
  12. 223 0
      src/components/Configurable/ModulePrimary.vue
  13. 84 0
      src/components/Configurable/detail/CustomChart.vue
  14. 61 0
      src/components/Configurable/detail/CustomTable.vue
  15. 153 1
      src/components/Configurable/detail/MiniBoard.vue
  16. 1 26
      src/components/Configurable/types.ts
  17. 230 0
      src/views/dashboard/SealedGoaf/components/MonitoringDetailsModal.vue
  18. 924 0
      src/views/dashboard/SealedGoaf/configurable.data.sealedGoaf.ts
  19. 118 0
      src/views/dashboard/SealedGoaf/index.vue
  20. 61 0
      src/views/dashboard/basicInfo/minesInfo/DeptModal.vue
  21. 213 0
      src/views/dashboard/basicInfo/minesInfo/dept.data.ts
  22. 96 0
      src/views/dashboard/basicInfo/minesInfo/index.vue

+ 45 - 0
mock/sys/menu.ts

@@ -3446,6 +3446,20 @@ export default [
             component: 'layouts/default/index',
             route: '1',
             children: [
+              {
+                path: '/dashboard/sealedGoafIndex',
+                component: 'dashboard/SealedGoaf',
+                route: '1',
+                meta: {
+                  keepAlive: true,
+                  internalOrExternal: false,
+                  icon: 'ant-design:windows-outlined',
+                  componentName: 'sealedGoafIndex',
+                  title: '采空区首页',
+                },
+                name: 'dashboard-sealedGoafIndex',
+                id: '9502685863ab87f0ad1134142788a385',
+              },
               {
                 path: '/dashboard/analysis',
                 component: 'dashboard/Analysis',
@@ -3513,6 +3527,37 @@ export default [
             name: 'dashboard',
             id: '1438108176273760258',
           },
+          {
+            redirect: null,
+            path: '/basicInfo',
+            component: 'layouts/default/index',
+            route: '1',
+            children: [
+              {
+                path: '/basicInfo/minesInfo',
+                component: 'dashboard/basicInfo/minesInfo',
+                route: '1',
+                meta: {
+                  keepAlive: true,
+                  internalOrExternal: false,
+                  icon: 'ant-design:windows-outlined',
+                  componentName: 'index',
+                  title: '矿山信息',
+                },
+                name: 'basicInfo-minesInfoIndex',
+                id: '9502685863ab87f0ad1134142788a377',
+              },
+            ],
+            meta: {
+              keepAlive: false,
+              internalOrExternal: false,
+              icon: 'ant-design:home-outlined',
+              componentName: 'index',
+              title: '矿山基础信息',
+            },
+            name: 'basicInfo',
+            id: '1439398677984878593',
+          },
           {
             redirect: null,
             path: '/isystem',

BIN
src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-1.png


BIN
src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-2.png


BIN
src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-3.png


BIN
src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-4.png


BIN
src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-5.png


BIN
src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-B.png


BIN
src/assets/images/sealedGoaf/configurable/miniBoard/board-bg-D.png


BIN
src/assets/images/sealedGoaf/configurable/table/table-label-A.png


BIN
src/assets/images/sealedGoaf/views/home/home-bg.png


BIN
src/assets/images/sealedGoaf/views/home/module-title.png


+ 223 - 0
src/components/Configurable/ModulePrimary.vue

@@ -0,0 +1,223 @@
+<template>
+  <div class="module-primary" :style="style">
+    <div v-if="moduleName" class="module-title">
+      <div class="common-navL" :class="{ 'cursor-pointer': !!moduleData.to }" @click="redirectTo">
+        <div class="navL-title">
+          {{ moduleName }}
+        </div>
+        <div class="navL-slot" v-if="header.show && header.slot.show">
+          (总计:{{ getFormattedText(selectedDevice, header.slot.value) }})
+        </div>
+      </div>
+
+      <div class="common-navR">
+        <!-- 下拉框 -->
+        <div class="common-navR-select" v-if="header.show && header.selector.show">
+          <a-select
+            style="width: 140px"
+            size="small"
+            placeholder="请选择"
+            v-model:value="selectedDeviceID"
+            allowClear
+            :options="options"
+            @change="selectHandler"
+          />
+        </div>
+      </div>
+    </div>
+    <div class="module-content">
+      <slot>
+        <Content style="height: 100%" :moduleData="moduleData" :data="selectedDevice" />
+      </slot>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import Content from './content.vue';
+  import { computed, watch } from 'vue';
+  import { useInitModule } from './hooks/useInit';
+  import { getFormattedText } from './hooks/helper';
+  import { openWindow } from '/@/utils';
+  // import { ModuleProps } from '../types';
+
+  const props = defineProps<{
+    /** 配置的详细模块信息 */
+    moduleData: any;
+    /** 配置的详细样式信息 */
+    showStyle: any;
+    /** 该模块配置中的设备标识符 */
+    deviceType: string;
+    /** api返回的数据 */
+    data: any;
+    moduleName: string;
+    visible: boolean;
+  }>();
+  const emit = defineEmits(['close', 'select']);
+
+  const { header } = props.moduleData;
+
+  const { selectedDeviceID, selectedDevice, options, init } = useInitModule(props.deviceType, props.moduleData);
+
+  const style = computed(() => {
+    const size = props.showStyle.size;
+    const position = props.showStyle.position;
+    return size + position;
+  });
+
+
+  //下拉框选项切换
+  function selectHandler(id) {
+    selectedDeviceID.value = id;
+    emit('select', selectedDevice);
+  }
+
+  function redirectTo() {
+    const { to } = props.moduleData;
+    if (!to) return;
+    openWindow(to);
+  }
+
+  watch(
+    () => props.data,
+    (d) => {
+      init(d);
+      if (!selectedDeviceID.value) {
+        selectedDeviceID.value = options.value[0]?.value;
+      }
+    },
+    {
+      immediate: true,
+    }
+  );
+</script>
+
+<style scoped lang="less">
+  @import '/@/design/theme.less';
+
+  .module-primary {
+    --image-module-title: url('/@/assets/images/sealedGoaf/views/home/module-title.png');
+
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    background-repeat: no-repeat;
+    background-position: center top;
+    background-size: 100% auto;
+    z-index: 2;
+
+    .module-title {
+      display: flex;
+      box-sizing: border-box;
+      align-items: center;
+      justify-content: space-between;
+      width: 100%;
+      height: 25px;
+      background: var(--image-module-title) no-repeat;
+      background-size: cover;
+      padding-left: 10px;
+
+      .common-navL {
+        display: flex;
+        color: #234e8e;
+        font-size: 18px;
+        margin-top: -15px;
+        .navL-title {
+          font-weight: 600;
+        }
+        .navL-slot{
+          padding-left: 20px;
+        }
+      }
+
+      .common-navR {
+        margin-top: -15px;
+      }
+      .common-navR-select {
+      :deep(.ant-select) {
+        .ant-select-selector {
+          background-color: #2b6ff0;
+          font-size: 16px;
+          cursor: pointer;
+          width: auto;
+          height: 32px;
+        }
+        .ant-select-selection-placeholder {
+          display: flex;
+          align-items: center;
+          color: #fff;
+        }
+        .ant-select-selection-search-input {
+          height: 100%;
+        }
+        .ant-select-selection-item{
+          color: #fff;
+        }
+        .ant-select-arrow{
+          color: #fff;
+        }
+      }
+    }
+    }
+
+    .module-content {
+      height: calc(100% - 38px);
+    }
+  }
+
+  // :deep(.ant-select-selector) {
+  //   height: 22px !important;
+  //   border: none !important;
+  //   // background-color: rgb(15 64 88) !important;
+  //   background-color: transparent !important;
+  //   color: #8087a1 !important;
+  // }
+
+  // :deep(.ant-select-selection-placeholder) {
+  //   color: #8087a1 !important;
+  // }
+
+  // :deep(.ant-select-arrow) {
+  //   color: #8087a1 !important;
+  // }
+
+  // :deep(.ant-picker) {
+  //   border: none !important;
+  //   background-color: rgb(15 64 88) !important;
+  //   box-shadow: none;
+  //   color: #a1dff8 !important;
+  // }
+
+  // :deep(.ant-picker-input > input) {
+  //   color: #a1dff8 !important;
+  //   text-align: center !important;
+  // }
+
+  // :deep(.ant-picker-separator) {
+  //   color: #a1dff8 !important;
+  // }
+
+  // :deep(.ant-picker-active-bar) {
+  //   display: none !important;
+  // }
+
+  // :deep(.ant-picker-suffix) {
+  //   color: #a1dff8 !important;
+  // }
+
+  // :deep(.ant-switch) {
+  //   min-width: 48px !important;
+  // }
+
+  // :deep(.ant-switch-checked) {
+  //   background-color: rgb(15 64 89) !important;
+  // }
+
+  // :deep(.ant-switch-handle::before) {
+  //   background-color: rgb(33 179 247) !important;
+  // }
+
+  // :deep(.ant-select-selection-item) {
+  //   color: #fff !important;
+  // }
+</style>

+ 84 - 0
src/components/Configurable/detail/CustomChart.vue

@@ -410,6 +410,90 @@
         }, []),
       };
     }
+    if (type === 'pie_drag') {
+      return {
+        legend: baseSeries.map((e) => {
+          return {
+            orient: 'vertical',
+            left: '54%',
+            top: '20%',
+            itemGap: 34,
+            itemWidth: 10,
+            itemHeight: 10,
+            align: 'left',
+            textStyle: {
+              fontSize: 20,
+              color: '#000',
+            },
+            data: e.data.map((e) => {
+              return `${e[0]}: ${e[1]}`;
+            }),
+          };
+        }),
+        graphic: {
+          elements: [
+            {
+              type: 'image',
+              style: {
+                // image: getAssetURL('home-container/pie.png'),
+                width: 20,
+                height: 100,
+              },
+              left: 'center',
+              top: 'center',
+            },
+          ],
+        },
+        tooltip: {
+          formatter: '{b}',
+        },
+        series: baseSeries.reduce((curr: EChartsOption[], serie) => {
+          curr.push({
+            radius: ['40%', '80%'],
+            center: ['25%', '50%'],
+            type: 'pie',
+            z: 10,
+            label: {
+              show: false,
+            },
+            labelLine: {
+              show: false,
+            },
+            itemStyle: {
+              opacity: 0.7,
+            },
+            padAngle: 5,
+            data: serie.data.map((e) => ({
+              name: `${e[0]}: ${e[1]}`,
+              value: e[1],
+            })),
+          });
+          curr.push({
+            radius: ['40%', '55%'],
+            center: ['25%', '50%'],
+            type: 'pie',
+            z: 5,
+            label: {
+              show: false,
+            },
+            labelLine: {
+              show: false,
+            },
+            animation: false,
+            tooltip: {
+              show: false,
+            },
+            padAngle: 6,
+            data: serie.data.map((e) => ({
+              name: `${e[0]}: ${e[1]}`,
+              value: e[1],
+            })),
+          });
+          return curr;
+        }, []),
+      };
+    }
+
 
     // 柱状图
     if (type === 'bar') {

+ 61 - 0
src/components/Configurable/detail/CustomTable.vue

@@ -54,6 +54,8 @@
   }
 
   .table__content {
+    --image-content-label-A: url('/@/assets/images/sealedGoaf/configurable/table/table-label-A.png');
+
     height: 100%;
     box-sizing: border-box;
     display: flex;
@@ -72,5 +74,64 @@
         font-size: 14px;
       }
     }
+    
+    .table__content_list {
+      height: calc(100% - 32px);
+      width: 400px;
+      display: flex;
+      flex-direction: column;
+      padding: 5px 0;
+      box-sizing: border-box;
+      overflow-y: auto;
+      .table__content_list_row {
+        width: 100%;
+        display: flex;
+        justify-content: space-around;
+        align-items: center;
+        color: #fff;
+        margin-bottom: 5px;
+        span {
+          display: inline-block;
+          text-align: center;
+        }
+      }
+    }
+
+    .table__content_label_A {
+      background-image: var(--image-content-label-A);
+      background-size: 100% 100%;
+      background-repeat: no-repeat;
+      color: #000000;
+    }
+    .table__content_list_A {
+      font-weight: bold;
+      font-size: 24px;
+    }
+    /* 第一个子元素:黑色 */
+    .table__content_list_row .table__content__list_item_A:nth-child(1) {
+      font-size: 12px;
+      text-align: left;
+      color: #000000;
+    }
+
+    /* 第二个子元素:蓝色 */
+    .table__content_list_row .table__content__list_item_A:nth-child(2) {
+      color: #1890ff;
+    }
+
+    /* 第三个子元素:黄色 */
+    .table__content_list_row .table__content__list_item_A:nth-child(3) {
+      color: #ffc107;
+    }
+
+    /* 第四个子元素:橙色 */
+    .table__content_list_row .table__content__list_item_A:nth-child(4) {
+      color: #ff7a45;
+    }
+
+    /* 第五个子元素:红色 */
+    .table__content_list_row .table__content__list_item_A:nth-child(5) {
+      color: #ff4d4f;
+    }
   }
 </style>

+ 153 - 1
src/components/Configurable/detail/MiniBoard.vue

@@ -74,7 +74,7 @@
       value?: string;
       // 告示牌布局,类型为:'val-top' | 'label-top'
       layout: string;
-      // 告示牌类型,类型为:'A' | 'B' | 'C' | 'D' | 'E' | 'F' |'New' | 'localFannew'
+      // 告示牌类型,类型为:'A' | 'B' | 'C' | 'D' 
       type?: string;
     }>(),
     {
@@ -106,6 +106,13 @@
   @import '/@/design/theme.less';
 
   .mini-board {
+    --image-board-bg-A-1: url('/@/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-1.png');
+    --image-board-bg-A-2: url('/@/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-2.png');
+    --image-board-bg-A-3: url('/@/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-3.png');
+    --image-board-bg-A-4: url('/@/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-4.png');
+    --image-board-bg-A-5: url('/@/assets/images/sealedGoaf/configurable/miniBoard/board-bg-A-5.png');
+    --image-board-bg-B: url('/@/assets/images/sealedGoaf/configurable/miniBoard/board-bg-B.png');
+    --image-board-bg-D: url('/@/assets/images/sealedGoaf/configurable/miniBoard/board-bg-D.png');
     height: 50px;
     line-height: 25px;
     width: 130px;
@@ -121,4 +128,149 @@
   .mini-board__value {
     white-space: nowrap;
   }
+  .mini-board_A {
+    width: 220px;
+    height: 50px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 0 20px 0 20px;
+    background-image: var(--image-board-bg-A-1);
+    background-size: 100% 100%;
+  }
+  .mini-board_A:nth-child(2) {
+    background-image: var(--image-board-bg-A-2);
+  }
+  .mini-board_A:nth-child(3) {
+    background-image: var(--image-board-bg-A-3);
+  }
+  .mini-board_A:nth-child(4) {
+    background-image: var(--image-board-bg-A-4);
+  }
+  .mini-board_A:nth-child(5) {
+    background-image: var(--image-board-bg-A-5);
+  }
+  .mini-board_A:nth-child(6) {
+    background-image: var(--image-board-bg-A-1);
+  }
+  .mini-board__label_A {
+    color: #000000;
+    font-size: 13px;
+    font-family: 'Microsoft YaHei';
+    font-weight: bold;
+    padding-bottom: 6px;
+  }
+  .mini-board__value_A {
+    width: 55px;
+    color: #000000;
+    font-size: 25px;
+    padding-bottom: 13px;
+    font-family: 'Microsoft YaHei';
+  }
+  .mini-board_B {
+    width: 100px;
+    height: 115px;
+    background-image: var(--image-board-bg-B);
+    background-size: 100% 100%;
+    padding-top: 42px;
+  }
+
+  .mini-board__label_B {
+    color: #000000;
+    font-size: 14px;
+    font-family: 'Microsoft YaHei';
+  }
+  .mini-board__value_B {
+    color: #000000;
+    font-size: 26px;
+    font-weight: bold;
+    font-family: 'Microsoft YaHei';
+    padding-bottom: 17px;
+  }
+  /* 1. 第一个容器:label和value为蓝色 */
+  .mini-board_B:nth-child(1) .mini-board__label_B,
+  .mini-board_B:nth-child(1) .mini-board__value_B {
+    color: #1890ff;
+  }
+
+  /* 2. 第二个容器:label和value为黄色 */
+  .mini-board_B:nth-child(2) .mini-board__label_B,
+  .mini-board_B:nth-child(2) .mini-board__value_B {
+    color: #36a64d;
+  }
+
+  /* 3. 第三个容器:label和value为橙色 */
+  .mini-board_B:nth-child(3) .mini-board__label_B,
+  .mini-board_B:nth-child(3) .mini-board__value_B {
+    color: #a97523;
+  }
+
+  /* 4. 第四个容器:label和value为红色 */
+  .mini-board_B:nth-child(4) .mini-board__label_B,
+  .mini-board_B:nth-child(4) .mini-board__value_B {
+    color: #d6666c;
+  }
+  .mini-board_C {
+    width: 100px;
+    height: 115px;
+    background-image: var(--image-board-bg-B);
+    background-size: 100% 100%;
+    padding-top: 42px;
+  }
+
+  .mini-board__label_C {
+    color: #000000;
+    font-size: 14px;
+    font-family: 'Microsoft YaHei';
+  }
+  .mini-board__value_C {
+    color: #000000;
+    font-size: 26px;
+    font-weight: bold;
+    font-family: 'Microsoft YaHei';
+    padding-bottom: 17px;
+  }
+  /* 1. 第一个容器:label和value为蓝色 */
+  .mini-board_C:nth-child(1) .mini-board__label_C,
+  .mini-board_C:nth-child(1) .mini-board__value_C {
+    color: #1890ff;
+  }
+
+  /* 2. 第二个容器:label和value为黄色 */
+  .mini-board_C:nth-child(2) .mini-board__label_C,
+  .mini-board_C:nth-child(2) .mini-board__value_C {
+    color: #ffc107;
+  }
+
+  /* 3. 第三个容器:label和value为橙色 */
+  .mini-board_C:nth-child(3) .mini-board__label_C,
+  .mini-board_C:nth-child(3) .mini-board__value_C {
+    color: #ff7a45;
+  }
+
+  /* 4. 第四个容器:label和value为红色 */
+  .mini-board_C:nth-child(4) .mini-board__label_C,
+  .mini-board_C:nth-child(4) .mini-board__value_C {
+    color: #ff4d4f;
+  }
+  .mini-board_D {
+    width: 96px;
+    height: 81px;
+    background-image: var(--image-board-bg-D);
+    background-size: 100% 100%;
+    padding-top: 12px;
+  }
+
+  .mini-board__label_D {
+    color: #000000;
+    font-size: 14px;
+    font-family: 'Microsoft YaHei';
+  }
+  .mini-board__value_D {
+    color: #2b6ff0;
+    font-size: 22px;
+    font-family: 'Microsoft YaHei';
+    padding-bottom: 8px;
+  }
+
 </style>

+ 1 - 26
src/components/Configurable/types.ts

@@ -138,31 +138,6 @@ export interface ModuleDataBoard extends ReadFrom {
     | 'B'
     | 'C'
     | 'D'
-    | 'E'
-    | 'F'
-    | 'G'
-    | 'H'
-    | 'I'
-    | 'New'
-    | 'New1'
-    | 'New2'
-    | 'New3'
-    | 'J'
-    | 'K'
-    | 'L'
-    | 'M'
-    | 'N'
-    | 'O'
-    | 'P'
-    | 'Q'
-    | 'R'
-    | 'S'
-    | 'T'
-    | 'U'
-    | 'CKQMB'
-    | 'CKQMB0'
-    | 'CKQMB1'
-    | 'CKQMB2';
   /** 展示牌布局,决定是 label 部分在上方或是 value 在上方 */
   layout: 'val-top' | 'label-top' | 'new-top' | 'new1-top' | 'new2-top' | 'new3-top';
   /** 核心配置,每个展示牌对应一项 */
@@ -322,7 +297,7 @@ export interface ModuleDataChart extends ReadFrom {
 
 export interface ModuleDataTable extends ReadFrom {
   /** 表格的预设样式 */
-  type: 'A' | 'B' | 'C' | 'D' | 'CKQMB';
+  type: 'A';
   /** 是否自动滚动 */
   autoScroll?: boolean;
   /** 核心配置,每个表格列对应一项 */

+ 230 - 0
src/views/dashboard/SealedGoaf/components/MonitoringDetailsModal.vue

@@ -0,0 +1,230 @@
+<template>
+  <Modal
+    v-model:visible="visible"
+    title="密闭监测详情"
+    width="1200px"
+    @ok="handleOk"
+    @cancel="handleCancel"
+    prefixCls="custom-modal"
+  >
+    <!-- 基础信息栏(修改布局:每行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)"
+        >
+          {{ item.value }}
+        </span>
+      </div>
+    </div>
+
+    <!-- 监测数据卡片 -->
+    <div class="data-cards">
+      <MiniBoard 
+        v-for="(item, index) in modalDetailsData.board" 
+        :key="index"
+        type="D"
+        :label="item.label"
+        :value="item.value"
+        layout="val-top"
+      />
+    </div>
+
+    <!-- 图表区域 -->
+    <div class="chart-area">
+      <div class="chart-item">
+        <div class="chart-title">爆炸三角形</div>
+        <div class="chart-placeholder">
+          <BlastDelta 
+            :posMonitor="modalDetailsData.demoBlastData"
+            canvasSize="{ width: 95%, height: 95% }" />
+          
+        </div>
+      </div>
+      <div class="chart-item">
+        <div class="chart-title">气体浓度曲线</div>
+        <div class="chart-placeholder">
+          <CustomChart 
+            :chart-data="modalDetailsData.gasConcentrationData" 
+            :chart-config="modalDetailsData.gasConcentrationConfig" 
+            style="height: 100%; width: 100%"
+          />
+        </div>
+      </div>
+      <div class="chart-item">
+        <div class="chart-title">内外压力及压差曲线</div>
+        <div class="chart-placeholder">
+          <CustomChart 
+          :chart-data="modalDetailsData.pressureData" 
+          :chart-config="modalDetailsData.pressureConfig" 
+          style="height: 100%; width: 100%"
+        />
+        </div>
+      </div>
+    </div>
+  </Modal>
+</template>
+
+<script setup>
+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 '../configurable.data.sealedGoaf'
+
+// 控制弹框显隐
+const visible = ref(false);
+// 外部调用显示弹框
+const showModal = () => {
+  visible.value = true;
+};
+// 外部调用隐藏弹框
+const hideModal = () => {
+  visible.value = false;
+};
+
+// 确定按钮回调
+const handleOk = () => {
+  visible.value = false;
+  // 可添加确定后的业务逻辑
+};
+// 取消按钮回调
+const handleCancel = () => {
+  visible.value = false;
+};
+
+// 获取基础信息value对应的标签样式类
+const getBasicInfoTagClass = (value) => {
+  switch (value) {
+    case '闭内气体涌出':
+      return 'tag-danger';
+    case '低风险':
+      return 'tag-primary';
+    case '不可启封':
+      return 'tag-warning';
+    default:
+      return '';
+  }
+};
+// 暴露方法给父组件
+defineExpose({
+  showModal,
+  hideModal
+});
+</script>
+
+<style scoped>
+
+.base-info {
+  display: grid;
+  grid-template-columns: repeat(4, 1fr); /* 强制每行4列 */
+  grid-template-rows: auto auto; /* 两行自动高度 */
+  gap: 16px 12px; /* 行列间距(行间距16px,列间距12px) */
+  margin-bottom: 20px;
+  padding: 20px;
+  border: 1px solid #f0f0f0;
+  border-radius: 10px;
+  background: #f8f9fc;
+}
+.info-item {
+  display: flex;
+  align-items: center;
+  /* 适配文字过长的情况 */
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.label {
+  color: #666;
+  margin-right: 8px;
+  min-width: 80px;
+  flex-shrink: 0; /* 标签宽度不收缩 */
+}
+.value {
+  color: #333;
+  flex: 1;
+  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-radius: 10px;
+  background: #f8f9fc;
+}
+.data-card {
+  background: #fafafa;
+  border-radius: 8px;
+  padding: 12px;
+  text-align: center;
+}
+.card-value {
+  font-size: 20px;
+  font-weight: bold;
+  color: #1890ff;
+  margin-bottom: 4px;
+}
+.card-label {
+  font-size: 14px;
+  color: #666;
+}
+
+.chart-area {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16px;
+  padding: 20px;
+  border: 1px solid #f0f0f0;
+  border-radius: 10px;
+  /* background: black; */
+  background: #f8f9fc;
+}
+.chart-item {
+  flex: 1;
+  min-width: 200px;
+}
+.chart-title {
+  font-size: 14px;
+  font-weight: 500;
+  margin-bottom: 8px;
+  color: #333;
+}
+.chart-placeholder {
+  width: 100%;
+  height: 150px;
+  border-radius: 4px;
+  overflow: hidden;
+}
+.chart-placeholder img {
+  width: 100%;
+  height: 100%;
+  object-fit: cover;
+}
+</style>

+ 924 - 0
src/views/dashboard/SealedGoaf/configurable.data.sealedGoaf.ts

@@ -0,0 +1,924 @@
+import type { Config } from '@/components/Configurable/types';
+
+export const testConfigSealedGoaf: Config[] = [
+  // 1. 矿井状况
+  {
+    deviceType: 'goafsInfo',
+    moduleName: '矿井状况',
+    pageType: 'sealed_goaf',
+    moduleData: {
+      header: {
+        show: true,
+        readFrom: '',
+        selector: { show: false, value: '' },
+        slot: { show: true, value: '365' },
+      },
+      background: { show: false, type: 'video', link: '' },
+      layout: {
+        direction: 'row',
+        items: [{ name: 'board', basis: '100%' }],
+      },
+      list: [],
+      board: [
+        {
+          type: 'A',
+          readFrom: '',
+          layout: 'label-top',
+          items: [
+            {
+              label: '生产矿井',
+              value: '219',
+            },
+            {
+              label: '建设矿井',
+              value: '219',
+            },
+            {
+              label: '停产停建',
+              value: '17',
+            },
+            {
+              label: '长期停产停建',
+              value: '17',
+            },
+            {
+              label: '实施关闭',
+              value: '2',
+            },
+            {
+              label: '情况变化',
+              value: '1',
+            },
+          ],
+        },
+      ],
+      chart: [],
+      gallery: [],
+      gallery_list: [],
+      table: [],
+      complex_list: [],
+      preset: [],
+    },
+    showStyle: {
+      size: 'width:440px;height:220px;',
+      version: '原版',
+      position: 'top:80px;left:20px;',
+      headerPosition: 'centerBottom',
+    },
+  },
+  // 2. 当日生产状态
+  {
+    deviceType: 'spray_auto',
+    moduleName: '当日生产状态',
+    pageType: 'sealed_goaf',
+    moduleData: {
+      header: {
+        show: true,
+        readFrom: '',
+        selector: { show: false, value: '' },
+        slot: { show: true, value: '211' },
+      },
+      background: { show: false, type: 'video', link: '' },
+      layout: {
+        direction: 'row',
+        items: [{ name: 'board', basis: '100%' }],
+      },
+      list: [],
+      board: [
+        {
+          type: 'A',
+          readFrom: '',
+          layout: 'label-top',
+          items: [
+            {
+              label: '正在生产',
+              value: '210',
+            },
+            {
+              label: '正在建设',
+              value: '27',
+            },
+            {
+              label: '停产',
+              value: '17',
+            },
+            {
+              label: '停工',
+              value: '1',
+            },
+          ],
+        },
+      ],
+      chart: [],
+      gallery: [],
+      gallery_list: [],
+      table: [],
+      complex_list: [],
+      preset: [],
+    },
+    showStyle: {
+      size: 'width:440px;height:160px;',
+      version: '原版',
+      position: 'top:300px;left:20px;',
+    },
+  },
+  // 3. 煤层自燃倾向性
+  {
+    deviceType: 'deviceInfo',
+    moduleName: '煤层自燃倾向性',
+    pageType: 'sealed_goaf',
+    moduleData: {
+      header: {
+        show: false,
+        readFrom: '',
+        selector: {
+          show: false,
+          value: '',
+        },
+        slot: {
+          show: false,
+          value: '',
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'chart',
+            basis: '100%',
+          },
+        ],
+      },
+      chart: [
+        {
+          type: 'pie_drag',
+          readFrom: '',
+          legend: { show: false, formatter: '{b}:{c}\n{d}%' },
+          xAxis: [{ show: false }],
+          yAxis: [{ show: false, name: '风量', position: 'left' }],
+          series: [{ readFrom: 'piechart', xprop: 'pos', yprop: 'val', label: '' }],
+        },
+      ],
+      gallery: [],
+      gallery_list: [],
+      table: [],
+      list: [],
+      complex_list: [],
+      preset: [],
+      mock: {
+        piechart: [
+          { pos: 'Ⅰ类容易自燃', val: 50 },
+          { pos: 'Ⅱ类自燃', val: 80 },
+          { pos: 'Ⅲ类不易自燃', val: 40 },
+        ],
+      },
+    },
+    showStyle: {
+      size: 'width:440px;height:280px;',
+      version: '原版',
+      position: 'top:460px;left:20px;',
+      headerPosition: 'centerBottom',
+    },
+  },
+  // 4. 联网状态
+  {
+    deviceType: '',
+    moduleName: '联网状态',
+    pageType: 'sealed_goaf',
+    moduleData: {
+      header: {
+        show: true,
+        readFrom: '',
+        selector: {
+          show: true,
+          value: '',
+        },
+        slot: {
+          show: false,
+          value: '',
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'board',
+            basis: '40%',
+            overflow: true,
+          },
+          {
+            name: 'table',
+            basis: '60%',
+            overflow: true,
+          },
+        ],
+      },
+      board: [
+        {
+          type: 'B',
+          readFrom: '',
+          layout: 'val-top',
+          items: [
+            {
+              label: '应接入',
+              value: '210',
+            },
+            {
+              label: '在线',
+              value: '27',
+            },
+            {
+              label: '中断',
+              value: '17',
+            },
+            {
+              label: '未接入',
+              value: '1',
+            },
+          ],
+        },
+      ],
+      chart: [],
+      gallery: [],
+      gallery_list: [],
+      table: [
+        {
+          type: 'A',
+          // parser: 'json',
+          readFrom: 'tableArray',
+          columns: [
+            {
+              name: ' ',
+              prop: 'index',
+            },
+            {
+              name: '应接入',
+              prop: 'yjr',
+            },
+            {
+              name: '在线',
+              prop: 'zx',
+            },
+            {
+              name: '中断',
+              prop: 'zd',
+            },
+            {
+              name: '未接入',
+              prop: 'wjr',
+            },
+          ],
+        },
+      ],
+      list: [],
+      complex_list: [],
+      preset: [],
+      mock: {
+        boardArray: [
+          {
+            label: '低风险',
+            value: '210',
+          },
+          {
+            label: '一般风险',
+            value: '27',
+          },
+          {
+            label: '较高风险',
+            value: '17',
+          },
+          {
+            label: '高风险',
+            value: '1',
+          },
+        ],
+        tableArray: [
+          {
+            index: '执法一处',
+            yjr: '50',
+            zx: '20',
+            zd: '0',
+            wjr: '0',
+          },
+          {
+            index: '执法二处',
+            yjr: '50',
+            zx: '20',
+            zd: '0',
+            wjr: '0',
+          },
+          {
+            index: '执法三处',
+            yjr: '50',
+            zx: '20',
+            zd: '0',
+            wjr: '0',
+          },
+          {
+            index: '执法四处',
+            yjr: '50',
+            zx: '20',
+            zd: '0',
+            wjr: '0',
+          },
+          {
+            index: '执法五处',
+            yjr: '50',
+            zx: '20',
+            zd: '0',
+            wjr: '0',
+          },
+          {
+            index: '执法六处',
+            yjr: '50',
+            zx: '20',
+            zd: '0',
+            wjr: '0',
+          },
+        ],
+      },
+    },
+    showStyle: {
+      size: 'width:440px;height:400px;',
+      version: '原版',
+      position: 'bottom:30px;left:20px;',
+    },
+  },
+  // 5. 密闭情况总览
+  {
+    deviceType: '',
+    moduleName: '密闭情况总览',
+    pageType: 'sealed_goaf',
+    moduleData: {
+      header: {
+        show: true,
+        readFrom: '',
+        selector: {
+          show: false,
+          value: '',
+        },
+        slot: {
+          show: true,
+          value: '211',
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'board',
+            basis: '40%',
+            overflow: true,
+          },
+          {
+            name: 'table',
+            basis: '60%',
+            overflow: true,
+          },
+        ],
+      },
+      board: [
+        {
+          type: 'C',
+          readFrom: '',
+          layout: 'val-top',
+          items: [
+            {
+              label: '低风险',
+              value: '210',
+            },
+            {
+              label: '一般风险',
+              value: '27',
+            },
+            {
+              label: '较高风险',
+              value: '17',
+            },
+            {
+              label: '高风险',
+              value: '1',
+            },
+          ],
+        },
+      ],
+      chart: [],
+      gallery: [],
+      gallery_list: [],
+      table: [
+        {
+          type: 'A',
+          // parser: 'json',
+          readFrom: 'tableArray',
+          columns: [
+            {
+              name: ' ',
+              prop: 'index',
+            },
+            {
+              name: '低风险',
+              prop: 'dfx',
+            },
+            {
+              name: '一般风险',
+              prop: 'ybfx',
+            },
+            {
+              name: '较高风险',
+              prop: 'jgfx',
+            },
+            {
+              name: '高风险',
+              prop: 'gfx',
+            },
+          ],
+        },
+      ],
+      list: [],
+      complex_list: [],
+      preset: [],
+      mock: {
+        boardArray: [
+          {
+            label: '低风险',
+            value: '210',
+          },
+          {
+            label: '一般风险',
+            value: '27',
+          },
+          {
+            label: '较高风险',
+            value: '17',
+          },
+          {
+            label: '高风险',
+            value: '1',
+          },
+        ],
+        tableArray: [
+          {
+            index: '执法一处',
+            dfx: '50',
+            ybfx: '20',
+            jgfx: '0',
+            gfx: '0',
+          },
+          {
+            index: '执法二处',
+            dfx: '50',
+            ybfx: '20',
+            jgfx: '0',
+            gfx: '0',
+          },
+          {
+            index: '执法三处',
+            dfx: '50',
+            ybfx: '20',
+            jgfx: '0',
+            gfx: '0',
+          },
+          {
+            index: '执法四处',
+            dfx: '50',
+            ybfx: '20',
+            jgfx: '0',
+            gfx: '0',
+          },
+          {
+            index: '执法五处',
+            dfx: '50',
+            ybfx: '20',
+            jgfx: '0',
+            gfx: '0',
+          },
+          {
+            index: '执法六处',
+            dfx: '50',
+            ybfx: '20',
+            jgfx: '0',
+            gfx: '0',
+          },
+        ],
+      },
+    },
+    showStyle: {
+      size: 'width:440px;height:400px;',
+      version: '原版',
+      position: 'top:20px;right:10px;',
+    },
+  },
+  // 6. 采空区密闭预警分析
+  {
+    deviceType: 'goafMonitoring',
+    moduleName: '采空区密闭预警分析',
+    pageType: 'sealed_goaf',
+    moduleData: {
+      header: {
+        show: true,
+        readFrom: '',
+        selector: {
+          show: true,
+          value: '',
+        },
+        slot: {
+          show: true,
+          value: '200',
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'board',
+            basis: '40%',
+            overflow: true,
+          },
+          {
+            name: 'table',
+            basis: '60%',
+            overflow: true,
+          },
+        ],
+      },
+      board: [
+        {
+          type: 'C',
+          readFrom: '',
+          layout: 'val-top',
+          items: [
+            {
+              label: '低风险',
+              value: '210',
+            },
+            {
+              label: '一般风险',
+              value: '27',
+            },
+            {
+              label: '较高风险',
+              value: '17',
+            },
+            {
+              label: '高风险',
+              value: '1',
+            },
+          ],
+        },
+      ],
+      chart: [],
+      gallery: [],
+      gallery_list: [],
+      table: [
+        {
+          type: 'A',
+          // parser: 'json',
+          readFrom: 'tableArray',
+          columns: [
+            {
+              name: ' ',
+              prop: 'index',
+            },
+            {
+              name: '低风险',
+              prop: 'dfx',
+            },
+            {
+              name: '一般风险',
+              prop: 'ybfx',
+            },
+            {
+              name: '较高风险',
+              prop: 'jgfx',
+            },
+            {
+              name: '高风险',
+              prop: 'gfx',
+            },
+          ],
+        },
+      ],
+      list: [],
+      complex_list: [],
+      preset: [],
+      mock: {
+        boardArray: [
+          {
+            label: '低风险',
+            value: '210',
+          },
+          {
+            label: '一般风险',
+            value: '27',
+          },
+          {
+            label: '较高风险',
+            value: '17',
+          },
+          {
+            label: '高风险',
+            value: '1',
+          },
+        ],
+        tableArray: [
+          {
+            index: '执法一处',
+            dfx: '50',
+            ybfx: '20',
+            jgfx: '0',
+            gfx: '0',
+          },
+          {
+            index: '执法二处',
+            dfx: '50',
+            ybfx: '20',
+            jgfx: '0',
+            gfx: '0',
+          },
+          {
+            index: '执法三处',
+            dfx: '50',
+            ybfx: '20',
+            jgfx: '0',
+            gfx: '0',
+          },
+          {
+            index: '执法四处',
+            dfx: '50',
+            ybfx: '20',
+            jgfx: '0',
+            gfx: '0',
+          },
+          {
+            index: '执法五处',
+            dfx: '50',
+            ybfx: '20',
+            jgfx: '0',
+            gfx: '0',
+          },
+        ],
+      },
+    },
+    showStyle: {
+      size: 'width:440px;height:400px;',
+      version: '原版',
+      position: 'top:430px;right:10px;',
+    },
+  },
+  // 7. 当日报警情况统计
+  {
+    deviceType: 'RealtimeMonitor',
+    moduleName: '当日报警情况统计',
+    pageType: 'sealed_goaf',
+    moduleData: {
+      header: {
+        show: false,
+        readFrom: '',
+        selector: {
+          show: false,
+          value: '',
+        },
+        slot: {
+          show: false,
+          value: '',
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'row',
+        items: [
+          {
+            name: 'board',
+            basis: '100%',
+          },
+        ],
+      },
+      board: [
+        {
+          type: 'D',
+          readFrom: '',
+          layout: 'val-top',
+          items: [
+            {
+              label: 'CO超限',
+              value: '210',
+            },
+            {
+              label: 'CH4超限',
+              value: '27',
+            },
+            {
+              label: 'C2H4超限',
+              value: '17',
+            },
+            {
+              label: 'C2H2超限',
+              value: '1',
+            },
+            {
+              label: 'O2超限',
+              value: '210',
+            },
+            {
+              label: '温度超限',
+              value: '27',
+            },
+            {
+              label: '压差超限',
+              value: '17',
+            },
+            {
+              label: '设备断连',
+              value: '1',
+            },
+          ],
+        },
+      ],
+      chart: [],
+      gallery: [],
+      gallery_list: [],
+      table: [],
+      list: [],
+      complex_list: [],
+      preset: [],
+    },
+    showStyle: {
+      size: 'width:440px;height:250px;',
+      version: '原版',
+      position: 'bottom:20px;right:10px;',
+    },
+  },
+];
+
+export const modalDetailsData:{} = {
+  basicInfo:[
+    {
+      label: '煤矿名称',
+      value: '神木市三江能源有限公司',
+    },
+    {
+      label: '密闭名称',
+      value: 'xxxx采空区密闭',
+    },
+    {
+      label: '所属煤层',
+      value: 'xxxx煤层',
+    },
+    {
+      label: '自燃情况',
+      value: 'Ⅰ类容易自燃',
+    },
+    {
+      label: '是否漏风',
+      value: '闭内气体涌出',
+    },
+    {
+      label: '自然发火隐患',
+      value: '低风险',
+    },
+    {
+      label: '密闭启封判定',
+      value: '不可启封',
+    },
+    {
+      label: '爆炸危险性',
+      value: '低风险',
+    },
+  ],
+  board: [
+    {
+      label: 'CO(ppm)',
+      value: '21',
+    },
+    {
+      label: 'CO2(PPM)',
+      value: '21',
+    },
+    {
+      label: 'O2(%)',
+      value: '24',
+    },
+    {
+      label: 'CH4(%)',
+      value: '17',
+    },
+    {
+      label: 'C2H4(ppm)',
+      value: '23',
+    },
+    {
+      label: 'C2H2(ppm)',
+      value: '14',
+    },
+    {
+      label: '温度(℃)',
+      value: '14',
+    },
+    {
+      label: '压差(Pa)',
+      value: '14',
+    },
+  ],
+  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', 
+      name: '时间', 
+      axisLabel: {color: '#000000'}, 
+      nameTextStyle: { color: '#000' },
+    }],
+    yAxis: [{ 
+      type: 'value',
+      show: true, 
+      name: '浓度(%)',
+      splitLine: { show: false },
+      axisLine: {
+        show: true,
+        lineStyle: { color: '#333' }
+      },
+      axisLabel: {color: '#000000'}, 
+      nameTextStyle: { color: '#000' },    }],
+    series: [
+      {
+        label: '气体浓度',
+        readFrom: 'gasData',
+        xprop: 'time',
+        yprop: 'value',
+        // color: '#000'
+      },
+    ],
+  },
+  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 },
+  ]},
+  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' },
+    ],
+  },
+  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},
+    ]
+  }
+}

+ 118 - 0
src/views/dashboard/SealedGoaf/index.vue

@@ -0,0 +1,118 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <div class="company-home">
+    <div class="title-select-area">
+      <Select
+        @change="handleDeviceChange"
+        :options="selectorOptions"
+        :fieldNames="fieldNames"
+        v-model:value="deviceId"
+        style="width: 200px; color: black"
+        class="title-select"
+        :dropdownStyle="{
+          width: '380px',
+          background: 'transparent',
+          borderBottom: '1px solid #ececec66',
+          backdropFilter: 'blur(50px)',
+          color: '#fff',
+        }"
+      />
+    </div>
+    <!-- 渲染所有模块 -->
+    <ModulePrimary
+      v-for="cfg in cfgs"
+      :key="cfg.deviceType + cfg.moduleName"
+      :show-style="cfg.showStyle"
+      :module-data="cfg.moduleData"
+      :module-name="cfg.moduleName"
+      :device-type="cfg.deviceType"
+      :data="data"
+      :visible="true"
+    />
+    <button @click="openModal">打开监测详情</button>
+    <!-- 监测详情弹框,放在这里是为了展示该组件而已,后续删除 -->
+    <MonitoringDetailsModal ref="monitoringModalRef" />
+  </div>
+</template>
+<script lang="ts" setup>
+  import { computed, onMounted, onUnmounted, ref } from 'vue';
+  import { Select } from 'ant-design-vue';
+  import { useInitConfigs, useInitPage } from '@/components/Configurable/hooks/useInit';
+  import { testConfigSealedGoaf } from './configurable.data.sealedGoaf';
+  import ModulePrimary from '/@/components/Configurable/ModulePrimary.vue';
+  import { useGlobSetting } from '/@/hooks/setting';
+  import MonitoringDetailsModal from './components/MonitoringDetailsModal.vue';
+
+  const { title = '省局采空区密闭监测与分析系统' } = useGlobSetting();
+  const { data, updateData, mainTitle } = useInitPage(title);
+
+  const cfgs = computed(() => configs.value);
+  const { configs, fetchConfigs } = useInitConfigs();
+
+  const deviceId = ref('0'); // 当前选中设备ID
+  const fieldNames = { label: 'name', value: 'id' }; // 下拉框字段映射
+  const selectorOptions = ref([
+    { name: '采空区密闭分析', id: '0' },
+    { name: '采空区密闭监测', id: '1' },
+  ]);
+  // 切换设备事件
+  function handleDeviceChange(param) {
+    console.log('切换下拉框选项');
+  }
+  onMounted(() => {
+    fetchConfigs('sealed_goaf').then(() => {
+      configs.value = testConfigSealedGoaf;
+    });
+  });
+
+  // 数据处理函数
+  onUnmounted(() => {});
+  const monitoringModalRef = ref(null);
+  const openModal = () => {
+    monitoringModalRef.value.showModal();
+  };
+</script>
+<style lang="less" scoped>
+  @import '/@/design/theme.less';
+
+  @font-face {
+    font-family: 'douyuFont';
+    src: url('/@/assets/font/douyuFont.otf');
+  }
+  .company-home {
+    --image-module-title: url('/@/assets/images/sealedGoaf/views/home/module-title.png');
+    --image-home-bg: url('/@/assets/images/sealedGoaf/views/home/home-bg.png');
+    width: 100%;
+    height: 100%;
+    color: @white;
+    position: relative;
+    background: var(--image-home-bg) no-repeat;
+    background-size: 100% 100%;
+    
+    .title-select-area {
+      display: inline-block;
+      position: absolute;
+      top: 15px;
+      left: 20px;
+      :deep(.title-select) {
+        .ant-select-selector {
+          width: 300px;
+          background-color: #2b6ff0;
+          box-shadow: none !important;
+          border: 1px solid #b3d8ff;
+          border-radius: 4px; /* 圆角 */
+          font-size: 16px;
+          color: #fff; /* 文字颜色 */
+          cursor: pointer;
+          width: auto;
+        }
+        .ant-select-selection-item{
+          color: #fff;
+        }
+        .ant-select-arrow{
+          color: #fff;
+        }
+      }
+    }
+  }
+</style>

+ 61 - 0
src/views/dashboard/basicInfo/minesInfo/DeptModal.vue

@@ -0,0 +1,61 @@
+<template>
+  <BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
+    <BasicForm @register="registerForm" />
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, computed, unref } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, useForm } from '/@/components/Form/index';
+  import { formSchema } from './dept.data';
+
+  import { getDeptList } from '/@/api/demo/system';
+  export default defineComponent({
+    name: 'DeptModal',
+    components: { BasicModal, BasicForm },
+    emits: ['success', 'register'],
+    setup(_, { emit }) {
+      const isUpdate = ref(true);
+
+      const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
+        labelWidth: 100,
+        schemas: formSchema,
+        showActionButtonGroup: false,
+      });
+
+      const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+        resetFields();
+        setModalProps({ confirmLoading: false });
+        isUpdate.value = !!data?.isUpdate;
+
+        if (unref(isUpdate)) {
+          setFieldsValue({
+            ...data.record,
+          });
+        }
+        const treeData = await getDeptList();
+        updateSchema({
+          field: 'parentDept',
+          componentProps: { treeData },
+        });
+      });
+
+      const getTitle = computed(() => (!unref(isUpdate) ? '新增部门' : '编辑部门'));
+
+      async function handleSubmit() {
+        try {
+          const values = await validate();
+          setModalProps({ confirmLoading: true });
+          // TODO custom api
+          console.log(values);
+          closeModal();
+          emit('success');
+        } finally {
+          setModalProps({ confirmLoading: false });
+        }
+      }
+
+      return { registerModal, registerForm, getTitle, handleSubmit };
+    },
+  });
+</script>

+ 213 - 0
src/views/dashboard/basicInfo/minesInfo/dept.data.ts

@@ -0,0 +1,213 @@
+import { BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Table';
+import { h } from 'vue';
+import { Tag } from 'ant-design-vue';
+
+export const columns: BasicColumn[] = [
+  {
+    title: '煤矿编号',
+    dataIndex: 'orderNo',
+  },
+  {
+    title: '所属执法处',
+    dataIndex: 'enforcement',
+  },
+  {
+    title: '煤矿名称',
+    dataIndex: 'mineName',
+  },
+  {
+    title: '煤矿简称',
+    dataIndex: 'mineAbbreviation',
+  },
+  {
+    title: '生产状态',
+    dataIndex: 'productStatus',
+    customRender: ({ record }) => {
+      const status = record.productStatus;
+      const enable = ~~status === 0;
+      const color = enable ? 'green' : 'red';
+      const text = enable ? '启用' : '停用';
+      return h(Tag, { color: color }, () => text);
+    },
+  },
+  {
+    title: '自燃情况',
+    dataIndex: 'riskLevel',
+  },
+  {
+    title: '接入状态',
+    dataIndex: 'connectStatus',
+  },
+  {
+    title: '在线状态',
+    dataIndex: 'onlineStatus',
+  },
+  {
+    title: '应接数量',
+    dataIndex: 'yingjieNum',
+  },
+  {
+    title: '已接数量',
+    dataIndex: 'yijieNum',
+  },
+  {
+    title: '未接数量',
+    dataIndex: 'weijieNum',
+  },
+];
+
+export const searchFormSchema: FormSchema[] = [
+  {
+    field: 'mineName',
+    label: '煤矿名称',
+    component: 'Input',
+    colProps: { span: 6 },
+  },
+  {
+    field: 'mineAbbreviation',
+    label: '煤矿简称',
+    component: 'Input',
+    colProps: { span: 6 },
+  },
+  {
+    field: 'productStatus',
+    label: '生产状态',
+    component: 'Select',
+    componentProps: {
+      options: [
+        { label: '拟建矿井', value: '0' },
+        { label: '正常生产矿井', value: '1' },
+        { label: '长期停产矿井', value: '1' },
+      ],
+    },
+    colProps: { span: 6 },
+  },
+  {
+    field: 'isConnected',
+    label: '是否需要接入',
+    component: 'Select',
+    componentProps: {
+      options: [
+        { label: '否', value: '0' },
+        { label: '是', value: '1' },
+      ],
+    },
+    colProps: { span: 6 },
+  },
+  
+  {
+    field: 'onlineStatus',
+    label: '在线状态',
+    component: 'Select',
+    componentProps: {
+      options: [
+        { label: '离线', value: '0' },
+        { label: '在线', value: '1' },
+      ],
+    },
+    colProps: { span: 6 },
+  },
+  {
+    field: 'riskLevel',
+    label: '风险等级',
+    component: 'Select',
+    componentProps: {
+      options: [
+        { label: 'Ⅰ类容易自燃', value: '0' },
+        { label: 'Ⅱ类自燃', value: '1' },
+        { label: 'Ⅲ类不易自燃', value: '2' },
+      ],
+    },
+    colProps: { span: 6 },
+  },
+  {
+    field: 'statusChange',
+    label: '状态变化',
+    component: 'Select',
+    componentProps: {
+      options: [
+        { label: '否', value: '0' },
+        { label: '是', value: '1' },
+      ],
+    },
+    colProps: { span: 6 },
+  },
+];
+
+export const formSchema: FormSchema[] = [
+  {
+    field: 'deptName',
+    label: '部门名称11111111',
+    component: 'Input',
+    required: true,
+  },
+  {
+    field: 'parentDept',
+    label: '上级部门',
+    component: 'TreeSelect',
+
+    componentProps: {
+      replaceFields: {
+        title: 'deptName',
+        key: 'id',
+        value: 'id',
+      },
+      getPopupContainer: () => document.body,
+    },
+    required: true,
+  },
+  {
+    field: 'orderNo',
+    label: '排序',
+    component: 'InputNumber',
+    required: true,
+  },
+  {
+    field: 'status',
+    label: '状态',
+    component: 'RadioButtonGroup',
+    defaultValue: '0',
+    componentProps: {
+      options: [
+        { label: '启用', value: '0' },
+        { label: '停用', value: '1' },
+      ],
+    },
+    required: true,
+  },
+  {
+    label: '备注',
+    field: 'remark',
+    component: 'InputTextArea',
+  },
+];
+
+export const minesData = [
+  {
+    orderNo:'61082400879',
+    enforcement:'执法二处',
+    mineName:'府谷县能源有限公司古城一号煤矿',
+    mineAbbreviation:'府谷县一号煤矿',
+    productStatus:'0',
+    riskLevel:'0',
+    connectStatus:'0',
+    onlineStatus:'0',
+    yingjieNum:'0',
+    yijieNum:'0',
+    weijieNum:'0',
+  },
+  {
+    orderNo:'61082400878',
+    enforcement:'执法二处',
+    mineName:'府谷县能源有限公司古城二号煤矿',
+    mineAbbreviation:'府谷县二号煤矿',
+    productStatus:'0',
+    riskLevel:'0',
+    connectStatus:'0',
+    onlineStatus:'0',
+    yingjieNum:'0',
+    yijieNum:'0',
+    weijieNum:'0',
+  }
+]

+ 96 - 0
src/views/dashboard/basicInfo/minesInfo/index.vue

@@ -0,0 +1,96 @@
+<template>
+  <div>
+    <BasicTable @register="registerTable">
+      <template #action="{ record }">
+        <TableAction
+          :actions="[
+            {
+              icon: 'clarity:note-edit-line',
+              onClick: handleEdit.bind(null, record),
+            },
+            {
+              icon: 'ant-design:delete-outlined',
+              color: 'error',
+              popConfirm: {
+                title: '是否确认删除',
+                confirm: handleDelete.bind(null, record),
+              },
+            },
+          ]"
+        />
+      </template>
+    </BasicTable>
+    <DeptModal @register="registerModal" @success="handleSuccess" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+
+  import { BasicTable, useTable, TableAction } from '/@/components/Table';
+
+  import { useModal } from '/@/components/Modal';
+  import DeptModal from './DeptModal.vue';
+
+  import { columns, searchFormSchema, minesData } from './dept.data';
+
+  export default defineComponent({
+    name: 'MinesInfo',
+    components: { BasicTable, DeptModal, TableAction },
+    setup() {
+      const [registerModal, { openModal }] = useModal();
+      const [registerTable, { reload }] = useTable({
+        // api: getDeptList,
+        dataSource: minesData,
+        columns,
+        formConfig: {
+          labelWidth: 120,
+          schemas: searchFormSchema,
+        },
+        pagination: false,
+        striped: false,
+        useSearchForm: true,
+        showTableSetting: true,
+        bordered: true,
+        showIndexColumn: false,
+        canResize: false,
+        actionColumn: {
+          width: 80,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          fixed: undefined,
+        },
+      });
+
+      function handleCreate() {
+        openModal(true, {
+          isUpdate: false,
+        });
+      }
+
+      function handleEdit(record: Recordable) {
+        openModal(true, {
+          record,
+          isUpdate: true,
+        });
+      }
+
+      function handleDelete(record: Recordable) {
+        console.log(record);
+      }
+
+      function handleSuccess() {
+        reload();
+      }
+
+      return {
+        registerTable,
+        registerModal,
+        handleCreate,
+        handleEdit,
+        handleDelete,
+        handleSuccess,
+      };
+    },
+  });
+</script>