Sfoglia il codice sorgente

[Feat 0000]矿端首页开发

wangkeyi 1 mese fa
parent
commit
1dfb000e70

+ 27 - 1
public/js/global.js

@@ -8,7 +8,7 @@ const __STATIC_ROUTES__ = [
     children: [
       {
         path: '/dashboard/sealedgoaf',
-        component: '/dashboard/SealedGoaf',
+        component: '/dashboard/SealedGoafMine',
         meta: {
           keepAlive: true,
           internalOrExternal: false,
@@ -18,6 +18,19 @@ const __STATIC_ROUTES__ = [
         },
         name: 'dashboard-sealedgoaf',
       },
+      {
+        path: '/dashboard/sealedgoaf',
+        component: '/dashboard/SealedGoafMine',
+        meta: {
+          keepAlive: true,
+          internalOrExternal: false,
+          icon: '',
+          componentName: 'SealedGoafMine',
+          title: '老空区永久密闭首页',
+        },
+        name: 'dashboard-sealedgoaf-mine',
+      },
+
       // {
       //     path: '/dashboard/analysis',
       //     component: 'dashboard/Analysis',
@@ -354,6 +367,19 @@ const __STATIC_ROUTES__ = [
         },
         name: 'cadFile',
       },
+      {
+        path: '/manage/mapView',
+        component: '/system/cadFile/mapView/index',
+        meta: {
+          keepAlive: true,
+          internalOrExternal: false,
+          icon: '',
+          componentName: 'index',
+          title: '图纸布点',
+          hideMenu: true,
+        },
+        name: 'cadFile-mapView',
+      },
       {
         path: '/manage/model',
         component: '/system/algorithm/index',

+ 9 - 1
src/components/Configurable/content.vue

@@ -65,6 +65,14 @@
         <template v-if="config.name === 'partition'">
           <Partition class="content__module" :type="config.type" :label="config.label" :icon="config.icon" />
         </template>
+        <template v-if="config.name === 'board_table'">
+          <BoardTable 
+            class="content__module" 
+            :board-configs="config.config.boardConfigs" 
+            :table-config="config.config.table" 
+            :table-data="config.data" 
+          />
+        </template>
         <!-- <template v-if="config.key === 'fire_control'">
         <FIreControl class="content__module" />
       </template>
@@ -98,6 +106,7 @@
   import BlastDelta from './preset/BlastDelta.vue';
   import QHCurve from './preset/QHCurve.vue';
   import Partition from './preset/partition.vue';
+  import BoardTable from './preset/BoardTable.vue';
 
   const props = defineProps<{
     data: any;
@@ -294,7 +303,6 @@
           break;
         }
       }
-      // console.log(arr,'arr---')
       return arr;
     }, []);
   });

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

@@ -181,4 +181,56 @@
       color: #c45656;
     }
   }
+
+  .table__content_label_C {
+    background-image: var(--image-content-label-A);
+    background-size: 100% 100%;
+    background-repeat: no-repeat;
+    color: #000000;
+    width: 100% !important;
+  }
+
+  .table__content_list_C {
+    width: 100% !important;
+    font-weight: bold;
+    font-size: 15px;
+    color: #000000;
+  }
+  .table__content_list_row{
+    color: #000000 !important;
+  }
+  // /* 第一个子元素:红色 */
+  .table__content_list_row .table__content__list_item_C:nth-child(1) {
+    color: #ff0000;
+  }
+
+
+  .table__content_label_D {
+    background-image: var(--image-content-label-A);
+    background-size: 100% 100%;
+    background-repeat: no-repeat;
+    color: #000000;
+    width: 100% !important;
+  }
+
+  .table__content_list_D {
+    width: 100% !important;
+    font-weight: bold;
+    font-size: 15px;
+    color: #000000;
+    text-align: center;
+  }
+  .table__content_list_row{
+    color: #000000 !important;
+  }
+
+  .table__content_list_row .table__content__list_item_D:nth-child(1) {
+    width: 50px;
+  }
+  .table__content_list_row .table__content__list_item_D:nth-child(3) {
+    color: #2b6ff0;
+  }
+  .table__content_list_row .table__content__list_item_D:nth-child(4) {
+    color: #107f30;
+  }
 </style>

+ 41 - 0
src/components/Configurable/detail/MiniBoard.vue

@@ -261,4 +261,45 @@
     // width: 55px;
     font-size: 20px;
   }
+  // 矿端首页特定版本F
+  .mini-board_F {
+    width: 210px;
+    height: 43px;
+    display: flex;
+    justify-content: space-between;
+    align-items: end;
+    padding: 0 12px 0 20px;
+    background-image: var(--image-board-bg-A-1);
+    background-size: 100% 100%;
+  }
+  .mini-board_F:nth-child(2) {
+    background-image: var(--image-board-bg-A-2);
+  }
+  .mini-board_F:nth-child(3) {
+    background-image: var(--image-board-bg-A-3);
+  }
+  .mini-board_F:nth-child(4) {
+    background-image: var(--image-board-bg-A-4);
+  }
+  .mini-board_F:nth-child(5) {
+    background-image: var(--image-board-bg-A-5);
+  }
+  .mini-board_F:last-child {
+    margin: 0 auto 0 5px;
+  }
+  .mini-board__label_F {
+    color: #000000;
+    font-size: 137x;
+    font-family: 'Source Han Sans SC';
+    font-style: normal;
+    font-weight: 700;
+    padding-bottom: 5px;
+  }
+  .mini-board__value_F {
+    width: 55px;
+    color: #000000;
+    font-size: 26px;
+    padding-bottom: 10px;
+    font-family: 'DDIN-Bold';
+  }
 </style>

+ 494 - 0
src/components/Configurable/preset/BoardTable.vue

@@ -0,0 +1,494 @@
+<!-- e:\code\work\goaf-monitoring-system\src\components\Configurable\preset\BoardTable.vue -->
+<template>
+  <div class="board-table-container">
+    <!-- Table 区域 -->
+    <div class="table-section" v-if="tableConfig && tableData.length > 0">
+      <div class="table__content">
+        <!-- 表头 -->
+        <div class="table__content_label" :class="`table__content_label_${tableConfig.type}`">
+          <!-- 单选框列占位(固定宽度) -->
+          <div 
+            v-if="showRadio" 
+            :style="{ width: radioColumnWidth }" 
+            class="label-t table__content__list_item_radio"
+          >
+            <!-- 表头单选框位置留空 -->
+          </div>
+          <!-- 数据列头 -->
+          <div 
+            class="label-t" 
+            v-for="(item, index) in tableColumns" 
+            :key="`header-${index}`" 
+            :style="{ flexBasis: dataColumnFlexBasis }"
+          >
+            {{ item.name }}
+          </div>
+        </div>
+        <!-- 表格内容 -->
+        <div class="table__content_list" :class="`table__content_list_${tableConfig.type}`">
+          <div 
+            class="table__content_list_row" 
+            v-for="(row, rowIndex) in tableData" 
+            :key="`row-${rowIndex}`"
+            :class="{ 'active-row': selectedRowIndex === rowIndex }"
+            @click="handleRowClick(rowIndex)"
+          >
+            <!-- 第一列:单选框(固定宽度) -->
+            <div 
+              v-if="showRadio" 
+              :style="{ width: radioColumnWidth }" 
+              class="table__content__list_item_radio"
+            >
+              <input 
+                type="radio" 
+                :name="radioGroupName" 
+                :checked="selectedRowIndex === rowIndex"
+                @click.stop="handleRowClick(rowIndex)"
+              />
+            </div>
+            <!-- 其他列(平分剩余空间) -->
+            <div 
+              v-for="(col, colIndex) in tableColumns" 
+              :key="`cell-${rowIndex}-${colIndex}`" 
+              :style="{ flexBasis: dataColumnFlexBasis }" 
+              :class="`table__content__list_item_${tableConfig.type}`"
+            >
+              <slot :name="col.prop" :scope="row">
+                <span>{{ getter(row, col.prop) }}</span>
+              </slot>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- Board 区域 - 支持多个 board 配置 -->
+    <div class="board-section">
+      <div 
+        v-for="(boardCfg, boardIndex) in boardConfigList" 
+        :key="`board-section-${boardIndex}`"
+        >
+        <div v-if="boardCfg.title" class="board-title">
+          <div class="board-title-text">{{boardCfg.title}}</div>
+        </div>
+        <div class="board-list">
+          <MiniBoard
+            v-for="(item, itemIndex) in getBoardItems(boardCfg, boardIndex)"
+            :key="`board-${boardIndex}-${itemIndex}`"
+            :label="item.label"
+            :value="item.value"
+            :layout="boardCfg.layout || 'val-top'"
+            :type="boardCfg.type || 'D'"
+          />
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { computed, ref, watch, onMounted } from 'vue';
+  import { get, isNil } from 'lodash-es';
+  import MiniBoard from '../detail/MiniBoard.vue';
+
+  interface BoardItem {
+    label: string;
+    value: string | number;
+  }
+
+  interface TableColumn {
+    name: string;
+    prop: string;
+  }
+
+  interface BoardConfig {
+    type?: string;
+    layout?: string;
+    title?: string;
+    readFrom?: string;
+    items?: BoardItem[];
+  }
+
+  interface TableConfig {
+    type?: string;
+    columns?: TableColumn[];
+    readFrom?: string;
+  }
+
+  const props = withDefaults(
+    defineProps<{
+      boardConfig?: BoardConfig;
+      boardConfigs?: BoardConfig[];
+      tableConfig?: TableConfig;
+      tableData?: any[];
+      showRadio?: boolean;
+      defaultValue?: string;
+      radioWidth?: number; // 单选框列宽度
+    }>(),
+    {
+      showRadio: true,
+      defaultValue: '-',
+      radioWidth: 40, // 默认 40px
+      tableData: () => [],
+      boardConfig: () => ({}),
+      boardConfigs: () => [],
+      tableConfig: () => ({}),
+    }
+  );
+
+  // 当前选中的行索引
+  const selectedRowIndex = ref<number>(0);
+  const uniqueId = ref(`bt-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`);
+  const radioGroupName = computed(() => `board-table-radio-${uniqueId.value}`);
+
+  // 处理后的 board 数据
+  const boardItemsList = ref<BoardItem[][]>([]);
+
+  // board 配置列表(兼容单个 boardConfig 和多个 boardConfigs)
+  const boardConfigList = computed(() => {
+    if (props.boardConfigs && props.boardConfigs.length > 0) {
+      return props.boardConfigs;
+    }
+    if (props.boardConfig && Object.keys(props.boardConfig).length > 0) {
+      return [props.boardConfig];
+    }
+    return [];
+  });
+
+  // 单选框列固定宽度
+  const radioColumnWidth = computed(() => {
+    return `${props.radioWidth}px`;
+  });
+
+  // 数据列平分剩余空间
+  const dataColumnFlexBasis = computed(() => {
+    const columnCount = props.tableConfig?.columns?.length || 1;
+    return Math.fround(100 / columnCount) + '%';
+  });
+
+  // 表格列
+  const tableColumns = computed(() => {
+    return props.tableConfig?.columns || [];
+  });
+
+  // 获取表格数据值
+  function getter(o: any, p: string) {
+    const d = get(o, p);
+    return isNil(d) ? props.defaultValue : d === '' ? props.defaultValue : d;
+  }
+  // 获取指定 board 的 items
+  function getBoardItems(boardCfg: BoardConfig, boardIndex: number) {
+    return boardItemsList.value[boardIndex] || [];
+  }
+
+ function updateBoardData(rowData: any) {
+    if (!rowData) return;
+
+    boardItemsList.value = boardConfigList.value.map(boardCfg => {
+      if (!boardCfg?.items) return [];
+
+      return boardCfg.items.map(item => {
+        const valueStr = String(item.value || '');
+        const match = valueStr.match(/\$\{(.+?)\}/);
+        
+        let newValue = item.value;
+        if (match && match[1]) {
+          const fieldKey = match[1];
+          newValue = rowData[fieldKey] !== undefined ? rowData[fieldKey] : item.value;
+        }
+        
+        return {
+          label: item.label,
+          value: newValue,
+        };
+      });
+    });
+  }  // 根据选中行更新 board 数据(内部自动处理联动)
+
+  // 处理行点击
+  function handleRowClick(index: number) {
+    if (selectedRowIndex.value === index) return;
+    
+    selectedRowIndex.value = index;
+    const rowData = props.tableData[index];
+    
+    // 自动更新 board 数据
+    updateBoardData(rowData);
+  }
+
+  // 监听选中行变化,自动更新 board
+  watch(selectedRowIndex, (newIndex) => {
+    if (props.tableData[newIndex]) {
+      updateBoardData(props.tableData[newIndex]);
+    }
+  });
+
+  // 监听 tableData 变化,重置选中状态
+  watch(() => props.tableData, (newData) => {
+    if (newData && newData.length > 0) {
+      selectedRowIndex.value = 0;
+      updateBoardData(newData[0]);
+    }
+  }, { immediate: true });
+
+  // 初始化时加载第一行数据
+  onMounted(() => {
+    if (props.tableData && props.tableData.length > 0) {
+      updateBoardData(props.tableData[0]);
+    }
+  });
+</script>
+
+<style lang="less" scoped>
+  @import '/@/design/theme.less';
+  
+  @font-face {
+    font-family: 'douyuFont';
+    src: url('/@/assets/font/douyuFont.otf');
+  }
+
+  .board-table-container {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    box-sizing: border-box;
+    overflow:hidden;
+  }
+
+  .board-section {
+    height: 70%;
+    min-height: 450px;
+    flex: none;
+    overflow: hidden;
+    padding: 10px 0;
+    .board-title {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      width: 100%;
+      height: 25px;
+      background: var(--image-module-title) no-repeat;
+      background-size: cover;
+      padding-left: 10px;
+      .board-title-text {
+        color: #103d82;
+        font-size: 16px;
+        font-style: normal;
+        font-family: 'Microsoft YaHei';
+        font-weight: 700;
+        margin-top: -10px;
+      }
+    }
+
+    .board-list {
+      display: flex;
+      flex-wrap: wrap;
+      justify-content: space-around;
+      padding: 10px 0;
+    }
+    :deep(.mini-board){
+      margin-bottom: 10px;
+    }
+  }
+
+  .table-section {
+    height: 30%;
+    flex: none;
+    overflow: hidden;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .table__content {
+    --image-content-label-A: url('/@/assets/images/sealedGoaf/configurable/table/table-label-A.png');
+
+    height: 100%;
+    box-sizing: border-box;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding: 5px 0;
+
+    .table__content_label {
+      width: 400px;
+      height: 32px;
+      display: flex;
+      justify-content: space-around;
+      align-items: center;
+      .label-t {
+        text-align: center;
+        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;
+      width: 100%;
+      padding-left: 10px;
+    }
+
+    .table__content_list_A {
+      width: 100%;
+      padding-left: 10px;
+      font-weight: bold;
+      font-size: 28px;
+    }
+    /* 第一个子元素:黑色 */
+    .table__content_list_row .table__content__list_item_A:nth-child(1) {
+      font-size: 14px;
+      text-align: left;
+      color: #000000;
+    }
+
+    /* 第二个子元素:蓝色 */
+    .table__content_list_row .table__content__list_item_A:nth-child(2) {
+      color: #0052cc;
+    }
+
+    /* 第三个子元素:黄色 */
+    .table__content_list_row .table__content__list_item_A:nth-child(3) {
+      color: #b39f01;
+    }
+
+    /* 第四个子元素:橙色 */
+    .table__content_list_row .table__content__list_item_A:nth-child(4) {
+      color: #e6a23d;
+    }
+
+    /* 第五个子元素:红色 */
+    .table__content_list_row .table__content__list_item_A:nth-child(5) {
+      color: #c45656;
+    }
+
+    .table__content_label_B {
+      background-image: var(--image-content-label-A);
+      background-size: 100% 100%;
+      background-repeat: no-repeat;
+      color: #000000;
+      width: 100%;
+      padding-left: 10px;
+    }
+
+    .table__content_list_B {
+      width: 100%;
+      padding-left: 10px;
+      font-weight: bold;
+      font-size: 28px;
+    }
+    /* 第一个子元素:黑色 */
+    .table__content_list_row .table__content__list_item_B:nth-child(1) {
+      font-size: 14px;
+      text-align: left;
+      color: #000000;
+    }
+
+    /* 第二个子元素:蓝色 */
+    .table__content_list_row .table__content__list_item_B:nth-child(2) {
+      color: #0052cc;
+    }
+
+    /* 第三个子元素:绿色 */
+    .table__content_list_row .table__content__list_item_B:nth-child(3) {
+      color: #4caf50;
+    }
+
+    /* 第四个子元素:橙色 */
+    .table__content_list_row .table__content__list_item_B:nth-child(4) {
+      color: #c97800;
+    }
+
+    /* 第五个子元素:红色 */
+    .table__content_list_row .table__content__list_item_B:nth-child(5) {
+      color: #c45656;
+    }
+  }
+
+  .table__content_label_C {
+    background-image: var(--image-content-label-A);
+    background-size: 100% 100%;
+    background-repeat: no-repeat;
+    color: #000000;
+    width: 100% !important;
+  }
+
+  .table__content_list_C {
+    width: 100% !important;
+    font-weight: bold;
+    font-size: 15px;
+    color: #000000;
+  }
+  .table__content_list_row{
+    color: #000000 !important;
+  }
+  .table__content_list_row .table__content__list_item_C:nth-child(1) {
+    color: #ff0000;
+  }
+
+  .table__content_label_D {
+    background-image: var(--image-content-label-A);
+    background-size: 100% 100%;
+    background-repeat: no-repeat;
+    color: #000000;
+    width: 100% !important;
+  }
+
+  .table__content_list_D {
+    width: 100% !important;
+    font-weight: bold;
+    font-size: 15px;
+    color: #000000;
+    text-align: center;
+  }
+  .table__content_list_row{
+    color: #000000 !important;
+  }
+
+  .table__content_list_row .table__content__list_item_D:nth-child(1) {
+    width: 50px;
+  }
+  .table__content_list_row .table__content__list_item_D:nth-child(3) {
+    color: #2b6ff0;
+  }
+  .table__content_list_row .table__content__list_item_D:nth-child(4) {
+    color: #107f30;
+  }
+
+  // 单选框列样式(固定宽度)
+  .table__content__list_item_radio {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    flex-shrink: 0; // 防止被压缩
+
+    input[type='radio'] {
+      cursor: pointer;
+      width: 14px;
+      height: 14px;
+    }
+  }
+</style>

+ 3 - 3
src/components/Configurable/types.ts

@@ -79,7 +79,7 @@ export interface ModuleData {
     direction: 'column' | 'row';
     items: {
       /** 分区名称,对应下方的配置 */
-      name: 'board' | 'list' | 'chart' | 'table' | 'gallery' | 'complex_list' | 'gallery_list' | 'blast_delta' | 'qh_curve' | 'partition';
+      name: 'board' | 'list' | 'chart' | 'table' | 'gallery' | 'complex_list' | 'gallery_list' | 'blast_delta' | 'qh_curve' | 'partition' | 'board_table';
       /** 分区大小 */
       basis: string;
       overflow?: boolean;
@@ -133,7 +133,7 @@ export interface CommonItem {
 
 export interface ModuleDataBoard extends ReadFrom {
   /** 展示牌预设的背景类型 */
-  type: 'A' | 'B' | 'C' | 'D' | 'E';
+  type: 'A' | 'B' | 'C' | 'D' | 'E' |'F';
   /** 展示牌布局,决定是 label 部分在上方或是 value 在上方 */
   layout: 'val-top' | 'label-top' | 'new-top' | 'new1-top' | 'new2-top' | 'new3-top';
   /** 核心配置,每个展示牌对应一项 */
@@ -295,7 +295,7 @@ export interface ModuleDataChart extends ReadFrom {
 
 export interface ModuleDataTable extends ReadFrom {
   /** 表格的预设样式 */
-  type: 'A' | 'B';
+  type: 'A' | 'B' | 'C'| 'D';
   /** 是否自动滚动 */
   autoScroll?: boolean;
   /** 核心配置,每个表格列对应一项 */

+ 428 - 0
src/views/dashboard/SealedGoafMine/configurable.data.sealedGoafMine.ts

@@ -0,0 +1,428 @@
+import type { Config } from '@/components/Configurable/types';
+import { title } from 'process';
+
+export const testConfigSealedGoaf: Config[] = [
+  // 1. 密闭统计
+  {
+    deviceType: 'goaf_statistics',
+    moduleName: '密闭统计',
+    pageType: 'sealed_goaf_mine',
+    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%' }],
+      },
+      list: [],
+      board: [
+        {
+          type: 'F',
+          readFrom: 'goafStatusNum',
+          layout: 'label-top',
+          items: [
+            {
+              label: '设备总数',
+              value: '${total}',
+            },
+            {
+              label: '正常',
+              value: '${status1}',
+            },
+            {
+              label: '未知',
+              value: '${unknown}',
+            },
+            {
+              label: '断线',
+              value: '${status0}',
+            },
+            {
+              label: '报警',
+              value: '${alarm}',
+            },
+          ],
+        },
+      ],
+      chart: [],
+      gallery: [],
+      gallery_list: [],
+      table: [],
+      complex_list: [],
+      preset: [],
+    },
+    showStyle: {
+      size: 'width:440px;height:170px;',
+      version: '原版',
+      position: 'top:70px;left:25px;',
+    },
+  },
+
+  // 2. 密闭预警统计
+  {
+    deviceType: 'warning_statistics',
+    moduleName: '密闭预警统计',
+    pageType: 'sealed_goaf_mine',
+    moduleData: {
+      header: {
+        show: false,
+        readFrom: '',
+        selector: {
+          show: false,
+          value: '',
+        },
+        slot: {
+          show: false,
+          value: '',
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'board',
+            basis: '100%',
+          },
+        ],
+      },
+      board: [
+        {
+          type: 'C',
+          readFrom: 'goafAlarmNum[0]',
+          layout: 'val-top',
+          items: [
+            {
+              label: '低风险',
+              value: '${alarm1}',
+            },
+            {
+              label: '一般风险',
+              value: '${alarm2}',
+            },
+            {
+              label: '较高风险',
+              value: '${alarm3}',
+            },
+            {
+              label: '高风险',
+              value: '${alarm4}',
+            },
+          ],
+        },
+      ],
+      chart: [],
+      gallery: [],
+      gallery_list: [],
+      table: [],
+      list: [],
+      complex_list: [],
+      preset: [],
+    },
+    showStyle: {
+      size: 'width:440px;height:210px;',
+      version: '原版',
+      position: 'top:250px;left:25px;',
+    },
+  },
+  // 3.预警信息列表
+  {
+    deviceType: 'warning_list',
+    moduleName: '预警信息列表',
+    pageType: 'sealed_goaf_mine',
+    moduleData: {
+      header: {
+        show: true,
+        readFrom: '',
+        selector: {
+          show: false,
+          value: '',
+        },
+        slot: {
+          show: false,
+          value: '',
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'table',
+            basis: '100%',
+            overflow: true,
+          },
+        ],
+      },
+      board: [],
+      chart: [],
+      gallery: [],
+      gallery_list: [],
+      table: [
+        {
+          type: 'C',
+          // parser: 'json',
+          readFrom: 'provinceAlarm.records',
+          columns: [
+            {
+              name: '告警类型',
+              prop: 'alarmTypeCont',
+            },
+            {
+              name: '安装位置',
+              prop: 'devicePos',
+            },
+            {
+              name: '告警描述',
+              prop: 'alarmName',
+            },
+          ],
+        },
+      ],
+      list: [],
+      complex_list: [],
+      preset: [],
+    },
+    showStyle: {
+      size: 'width:440px;height:420px;',
+      version: '原版',
+      position: 'top:470px;left:25px;',
+    },
+  },
+  // 4.  密闭内墙详情展示
+  {
+    deviceType: 'detail_inner_display',
+    moduleName: '密闭详情展示',
+    pageType: 'sealed_goaf_mine',
+    moduleData: {
+      header: {
+        show: false,
+        readFrom: '',
+        selector: {
+          show: false,
+          value: '',
+        },
+        slot: {
+          show: false,
+          value: '',
+        },
+      },
+      background: {
+        show: false,
+        type: 'video',
+        link: '',
+      },
+      layout: {
+        direction: 'column',
+        items: [
+          {
+            name: 'board_table',
+            basis: '100%',
+            overflow: true,
+          },
+        ],
+      },
+      board: [],
+      chart: [],
+      gallery: [],
+      gallery_list: [],
+      table: [],
+      list: [],
+      complex_list: [],
+      preset: [
+        {
+          readFrom: 'monitorData',
+          boardConfigs: [
+            {
+              type: 'D',
+              layout: 'val-top',
+              title : '密闭内详情',
+              items: [
+                { label: '甲烷', value: '${ch4Val}' },
+                { label: '一氧化碳', value: '${coVal}' },
+                { label: '二氧化碳', value: '${co2Val}' },
+                { label: '氧气', value: '${o2Val}' },
+                { label: '乙烯', value: '${c2h2Val}' },
+                { label: '乙炔', value: '${c2h4Val}' },
+                { label: '压差', value: '${sourcePressure}' },
+                { label: '温度', value: '${temperature}' },
+              ],
+            },
+            {
+              type: 'D',
+              layout: 'val-top',
+              title : '密闭外详情',
+              items: [
+                { label: '甲烷', value: '${ch4ValOut}' },
+                { label: '一氧化碳', value: '${coValOut}' },
+                { label: '二氧化碳', value: '${co2ValOut}' },
+                { label: '氧气', value: '${o2ValOut}' },
+                { label: '乙烯', value: '${c2h2ValOut}' },
+                { label: '乙炔', value: '${c2h4ValOut}' },
+                { label: '压差', value: '${sourcePressure}' },
+                { label: '温度', value: '${temperatureOut}' },
+              ],
+            },
+          ],
+          table: {
+            type: 'D',
+            readFrom: '',
+            columns: [
+              { name: '安装位置', prop: 'devicePos' },
+              { name: '预警等级', prop: 'alarmLevel' },
+              { name: '状态', prop: 'gjMineStatus' },
+            ],
+          },
+        },
+      ],
+    },
+    showStyle: {
+      size: 'width:440px;height:800px;',
+      version: '原版',
+      position: 'top:30px;right:25px;',
+    },
+  },
+    // 4.  密闭墙外详情展示
+  // {
+  //   deviceType: 'detail_outer_display',
+  //   moduleName: '密闭墙外详情展示',
+  //   pageType: 'sealed_goaf_mine',
+  //   moduleData: {
+  //     header: {
+  //       show: false,
+  //       readFrom: '',
+  //       selector: {
+  //         show: false,
+  //         value: '',
+  //       },
+  //       slot: {
+  //         show: false,
+  //         value: '',
+  //       },
+  //     },
+  //     background: {
+  //       show: false,
+  //       type: 'video',
+  //       link: '',
+  //     },
+  //     layout: {
+  //       direction: 'column',
+  //       items: [
+  //         {
+  //           name: 'board_table',
+  //           basis: '100%',
+  //           overflow: true,
+  //         },
+  //       ],
+  //     },
+  //     board: [],
+  //     chart: [],
+  //     gallery: [],
+  //     gallery_list: [],
+  //     table: [],
+  //     list: [],
+  //     complex_list: [],
+  //     preset: [
+  //       {
+  //         readFrom: 'monitorData',
+  //         board: {
+  //           type: 'D',
+  //           layout: 'val-top',
+  //           items: [
+  //             { label: '甲烷', value: '${ch4Val}' },
+  //             { label: '一氧化碳', value: '${coVal}' },
+  //             { label: '二氧化碳', value: '${co2Val}' },
+  //             { label: '氧气', value: '${o2Val}' },
+  //             { label: '乙烯', value: '${c2h2Val}' },
+  //             { label: '乙炔', value: '${c2h4Val}' },
+  //             { label: '压差', value: '${dailyYaCha}' },
+  //             { label: '温度', value: '${temperature}' },
+  //           ],
+  //         },
+  //         table: {
+  //           type: 'D',
+  //           readFrom: '',
+  //           columns: [
+  //             { name: '安装位置', prop: 'devicePos' },
+  //             { name: '预警等级', prop: 'alarmLevel' },
+  //             { name: '状态统计', prop: 'gjMineStatus' },
+  //           ],
+  //         },
+  //       },
+  //     ],
+  //   },
+  //   showStyle: {
+  //     size: 'width:440px;height:420px;',
+  //     version: '原版',
+  //     position: 'top:460px;right:25px;',
+  //   },
+  // },
+  // // 6. 煤层自燃倾向性
+  // {
+  //   deviceType: 'coalSeam_fire',
+  //   moduleName: '煤层自燃倾向性',
+  //   pageType: 'sealed_goaf_mine',
+  //   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: 'coalSeamFireData', xprop: 'coalSeamLevel', yprop: 'num', label: '' }],
+  //       },
+  //     ],
+  //     gallery: [],
+  //     gallery_list: [],
+  //     table: [],
+  //     list: [],
+  //     complex_list: [],
+  //     preset: [],
+  //   },
+  //   showStyle: {
+  //     size: 'width:440px;height:210px;',
+  //     version: '原版',
+  //     position: 'top:650px;right:25px;',
+  //   },
+  // },
+];

+ 155 - 0
src/views/dashboard/SealedGoafMine/index.vue

@@ -0,0 +1,155 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <div class="company-home">
+    <!-- 渲染所有模块 -->
+    <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"
+    />
+  </div>
+  <div class="workFace-content">
+    <div id="map3dContainer"></div>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { computed, onMounted, onUnmounted, ref, watch, nextTick } from 'vue';
+  import { useInitConfigs, useInitPage } from '@/components/Configurable/hooks/useInit';
+  import { testConfigSealedGoaf } from './configurable.data.sealedGoafMine';
+  import { getGoafData, getCoalSeamFireNum, getGoafStatusNum, getGoafAlarmNum, getProvinceAlarm } from './sealedGoafMine.api';
+  import ModulePrimary from '/@/components/Configurable/ModulePrimary.vue';
+  import { useGlobSetting } from '/@/hooks/setting';
+  import { useAppStore } from '/@/store/modules/app';
+  // 导入地图相关的方法
+  import { initMap2d, renderGoafMarkers } from '/@/views/system/cadFile/app';
+  import { getGoafList } from '/@/views/system/cadFile/cad.api';
+
+  const { title = '老空区永久密闭监测与分析系统' } = useGlobSetting();
+  const { data, updateData } = useInitPage(title);
+  const appStore = useAppStore();
+
+  const cfgs = computed(() => configs.value);
+  const { configs, fetchConfigs } = useInitConfigs();
+  const goafeData = ref({
+    monitorData: null,
+    coalSeamFireData: null,
+    goafStatusNum: null,
+    goafAlarmNum: null,
+    provinceAlarm: null,
+
+  }); // 所有数据汇总
+  const mineCode = ref('610801006584'); //暂时写死
+  const goafList = ref<any[]>([]);
+
+  async function fetchHomeData() {
+    try {
+      // 异步获取所有接口数据(并行请求提升性能)
+      const [monitorData,  coalSeamFireData, goafStatusNum , goafAlarmNum, provinceAlarm] = await Promise.all([
+        getGoafData({mineCodeList: mineCode.value}), // 密闭监测详情
+        getCoalSeamFireNum(appStore.simpleMapParams), // 煤层自燃倾向数据
+        getGoafStatusNum({}), // 密闭统计
+        getGoafAlarmNum({}),  // 预警统计
+        getProvinceAlarm({mineCodeList: mineCode.value}), // 预警信息列表
+      ]);
+
+      
+      if (provinceAlarm?.records) {
+        const alarmTypeMap = {
+          leakageAlarm: "密闭漏风状态报警",
+          sourcePressureAlarm: "内外压差风险报警",
+          fireAlarm: "自燃发火隐患报警",
+          fireAlarmOut:"密闭外自燃发火报警",
+          unsealAlarm: "火区密闭启封报警",
+          explosionAlarm: "密闭爆炸危险性报警",
+          overLimitAlarm: "超限报警",
+          lateReport: "数据延迟上报预警",
+        };
+
+        // 遍历列表,把 alarmType 替换成中文
+        provinceAlarm.records = provinceAlarm.records.map(item => {
+          item.alarmTypeCont = alarmTypeMap[item.alarmType] || item.alarmType;
+          return item;
+        });
+      }
+
+      // 把接口数据赋值给响应式变量(备用)
+      goafeData.value = { monitorData, coalSeamFireData, goafStatusNum, goafAlarmNum, provinceAlarm };
+      // 更新页面数据
+      updateData(goafeData.value);
+    } catch (error) {
+      console.error('数据获取/配置更新失败:', error);
+    }
+  }
+
+  watch(() => appStore.getSimpleMapParams, fetchHomeData);
+
+  onMounted(() => {
+    fetchHomeData(); // 赋值更新后的配置到configs(触发组件重新渲染)
+
+    // 先获取基础配置(若有接口获取配置则保留,否则直接用本地testConfigSealedGoaf)
+    fetchConfigs('sealed_goaf_mine').then(() => {
+      if (configs.value.length === 0) {
+        configs.value = [...testConfigSealedGoaf]; // 解构触发响应式更新
+      }
+    });
+  });
+  onMounted(() => {
+    nextTick(async () => {
+      await initMap2d();
+      try {
+        // 调用接口
+        const res = await getGoafList({
+          order: "desc",
+          mineCode: mineCode.value,
+        });
+        goafList.value = res || [];
+        await renderGoafMarkers(goafList.value); // 渲染标记
+      } catch (error) {
+        goafList.value = [];
+        console.error("接口请求失败:", error);
+      }
+    });
+  });
+
+  // 数据处理函数
+  onUnmounted(() => {});
+</script>
+<style lang="less" scoped>
+  @import '/@/design/theme.less';
+
+  @font-face {
+    font-family: 'douyuFont';
+    src: url('/@/assets/font/douyuFont.otf');
+  }
+
+  #map3dContainer {
+    position: absolute;
+    background: transparent;
+    width: 100%;
+    height: 100% !important;
+    top: 0;
+    left: 0;
+  }
+  .company-home {
+    position: fixed;
+    width: 100%;
+    height: 100%;
+    color: @white;
+    background-image: linear-gradient(90deg, @map-bg 0%, @map-bg 20%, transparent 30%, transparent 70%, @map-bg 80%, @map-bg 100%);
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+    z-index: @layout-basic-z-index;
+    // 允许点击穿透以支持下面的地图进行交互
+    pointer-events: none;
+  }
+
+  :deep(.ant-select-selection-item) {
+    display: flex;
+    align-items: center;
+  }
+</style>

+ 47 - 0
src/views/dashboard/SealedGoafMine/sealedGoafMine.api.ts

@@ -0,0 +1,47 @@
+import { defHttp } from '/@/utils/http/axios';
+
+enum Api {
+  getGoafData = '/province/device/getGoafData',
+  getCoalSeamFireNum = '/province/homeData/getCoalSeamFireNum',
+  getGoafStatusNum = '/province/homeData/getGoafStatusNum',
+  getGoafAlarmNum = '/province/homeData/getGoafAlarmNum',
+  getProvinceAlarm = '/province/alarm/getProvinceAlarm',
+}
+
+// 查询密闭监测数据
+export function getGoafData(params: any) {
+  return defHttp.post({ url: Api.getGoafData, params }, { joinParamsToUrl: true });
+}
+
+// 查询煤层自燃倾向数量统计
+export function getCoalSeamFireNum(params) {
+  return defHttp.post({
+    url: Api.getCoalSeamFireNum,
+    params,
+  })
+};
+
+// 查询密闭统计
+export function getGoafStatusNum(params) {
+  return defHttp.post({
+    url: Api.getGoafStatusNum,
+    params,
+  })
+};
+
+// 查询预警统计
+export function getGoafAlarmNum(params) {
+  return defHttp.post({
+    url: Api.getGoafAlarmNum,
+    params,
+  })
+};
+
+// 查询预警信息列表
+export function getProvinceAlarm(params) {
+  return defHttp.post({
+    url: Api.getProvinceAlarm,
+    params,
+  }, 
+  { joinParamsToUrl: true })
+};