Просмотр исходного кода

Merge branch 'master' of http://39.97.59.228:8013/lxh/gas-injection

lxh 1 месяц назад
Родитель
Сommit
3cf70448c5

BIN
src/assets/images/gasInjection/syq/modal-bg.png


+ 3 - 0
src/assets/images/gasInjection/syq/modal-export.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="14.647" height="15" viewBox="0 0 14.647 15">
+  <path id="路径_57882" data-name="路径 57882" d="M151.721,132.366l-2.4,2.4L147.549,133l2.4-2.4-1.909-1.98h5.586v5.727Zm-5.162-3.818v1.2h-4.6a.668.668,0,0,0-.707.707v10.111a.668.668,0,0,0,.707.707h9.687a.668.668,0,0,0,.707-.707v-4.879h1.2v4.667a2.083,2.083,0,0,1-2.121,2.121H142.1a2.083,2.083,0,0,1-2.121-2.121V130.6a2.083,2.083,0,0,1,2.121-2.121h4.455Zm-2.828,7.424h6.152v1.273h-6.152Zm0-2.475h2.475v1.273h-2.475V133.5Zm0,4.95h6.152v1.273h-6.152Z" transform="translate(-139.483 -127.977)" fill="#fff" stroke="rgba(0,0,0,0)" stroke-miterlimit="10" stroke-width="1"/>
+</svg>

BIN
src/assets/images/gasInjection/syq/modal-top-bg.png


+ 2 - 2
src/router/routes/index.ts

@@ -38,9 +38,9 @@ export const LoginRoute: AppRouteRecordRaw = {
   path: '/login',
   name: 'Login',
   //新版后台登录,如果想要使用旧版登录放开即可
-  // component: () => import('/@/views/sys/login/Login.vue'),
+  component: () => import('/@/views/sys/login/Login.vue'),
   //数据中心登录
-  component: () => import('/@/views/sys/login/LoginDataCenter.vue'),
+  // component: () => import('/@/views/sys/login/LoginDataCenter.vue'),
   // 内页登录
   // component: () => import('/@/views/sys/login/LoginNeiye.vue'),
   // component: () => import('/@/views/system/loginmini/MiniLogin.vue'),

+ 1 - 0
src/utils/threejs/useThree.ts

@@ -544,6 +544,7 @@ class UseThree {
       (this.camera as THREE.PerspectiveCamera).aspect = this.canvasContainer.clientWidth / this.canvasContainer.clientHeight;
       // 刷新相机矩阵
       this.camera?.updateProjectionMatrix();
+      this.orbitControls?.update();
     }
     // 设置场景尺寸
     this.renderer?.setSize(this.canvasContainer.clientWidth, this.canvasContainer.clientHeight);

+ 1 - 2
src/views/monitor/mynews/DynamicNotice.vue

@@ -11,8 +11,7 @@
   const currentModal = shallowRef<Nullable<ComponentOptions>>(null);
   const formData = ref<any>(props.formData);
 
-  const componentType = {
-  };
+  const componentType = {};
 
   /**
    * 跟换组件和传值事件

+ 2 - 1
src/views/sys/login/Login.vue

@@ -9,7 +9,8 @@
     <div class="top-header">
       <div class="top-bg"></div>
       <div class="login-icon"></div>
-      <div class="title">{{ title }}</div>
+      <!-- <div class="title">{{ title }}</div> -->
+      <div class="title">注气驱替监管系统</div>
     </div>
 
     <div class="flex center">

+ 4 - 3
src/views/system/user/user.data.ts

@@ -27,9 +27,10 @@ export const columns: BasicColumn[] = [
     width: 100,
     customRender: ({ value }) => {
       const nameList = [];
-      value.forEach((item) => {
-        nameList.push(item['roleName']);
-      });
+      if (value)
+        value.forEach((item) => {
+          nameList.push(item['roleName']);
+        });
       return nameList.toString();
     },
   },

+ 11 - 8
src/views/vent/home/configurable/components/gasInject/DetailInfo.vue

@@ -28,10 +28,13 @@
         <zqMonitorDetail :isShowExport="false" :tableColumn="tableColumnCc" :optionDetail="optionDetailCc">
         </zqMonitorDetail>
       </template>
- <template v-if="deviceType == 'gas_cc_line'">
+      <template v-if="deviceType == 'gas_cc_line'">
         <curveEchartDetail :sysType="'Cc'" :isShowExport="false" :tableColumn="tableColumnCc">
         </curveEchartDetail>
       </template>
+      <template v-if="deviceType == 'syq-env-monitor'">
+        <SyqDetails />
+      </template>
     </a-modal>
   </div>
 </template>
@@ -40,8 +43,8 @@
 import { computed, reactive, ref } from 'vue'
 import curveEchartDetail from './curveEchartDetail.vue'
 import zqMonitorDetail from './zqMonitorDetail.vue'
-import { tableColumnSj, tableColumnHj,tableColumnCc, optionDetailZq, optionDetailCc } from '../gasInject/gasInject.data'
-
+import { tableColumnSj, tableColumnHj, tableColumnCc, optionDetailZq, optionDetailCc } from '../gasInject/gasInject.data'
+import SyqDetails from './SyqDetails.vue';
 let props = defineProps({
   deviceType: {
     type: String
@@ -63,17 +66,17 @@ let $emit = defineEmits(['closeModal'])
 
 //弹窗标题
 let modalTitle = computed(() => {
-  if (props.deviceType == 'cc_gas_nd' || props.deviceType == 'cc_gas_ll' || props.deviceType=='gas_cc_line') {
+  if (props.deviceType == 'cc_gas_nd' || props.deviceType == 'cc_gas_ll' || props.deviceType == 'gas_cc_line') {
     return '抽采参数时程曲线'
-  } else if (props.deviceType == 'gas_zq-yl' || props.deviceType=='gas_zq_paramline') {
+  } else if (props.deviceType == 'gas_zq-yl' || props.deviceType == 'gas_zq_paramline') {
     return '注气参数时程曲线'
   } else if (props.deviceType == 'gas_zq_sj') {
     return '注气数据监测'
-  }else if(props.deviceType=='gas_zq_hj'){
+  } else if (props.deviceType == 'gas_zq_hj') {
     return '环境监测'
-  }else if(props.deviceType=='gas_zq_video'){
+  } else if (props.deviceType == 'gas_zq_video') {
     return '历史数据'
-  }else if(props.deviceType=='gas_cc_detail'){
+  } else if (props.deviceType == 'gas_cc_detail') {
     return '抽采数据监测'
   }
 })

+ 403 - 0
src/views/vent/home/configurable/components/gasInject/SyqDetails.vue

@@ -0,0 +1,403 @@
+<template>
+  <div class="main-container">
+    <!-- 顶部操作栏 -->
+    <div class="modal-top-bar">
+      <div class="time-picker-wrap">
+        <span class="label">时间:</span>
+        <div class="date-input-group">
+          <!-- <input v-model="startDate" type="date" class="date-input" @change="handleTimeChange" />
+          <span class="separator">—</span>
+          <input v-model="endDate" type="date" class="date-input" @change="handleTimeChange" /> -->
+          <a-range-picker
+            v-model:value="timeRange"
+            separator="—"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD"
+            placeholder=""
+            @change="handleTimeChange"
+            class="date-range-picker"
+            :dropdown-class-name="'custom-range-dropdown'"
+          />
+        </div>
+      </div>
+      <div class="button-area">
+        <button class="export-btn" @click="handleExport">
+          <div class="icon"></div>
+          数据导出
+        </button>
+      </div>
+    </div>
+
+    <!-- 环境监测表格 -->
+    <div class="table-wrap">
+      <table class="monitor-table">
+        <thead>
+          <tr>
+            <th rowspan="2">时间</th>
+            <th colspan="3" class="th-bg">注气区域(定向钻场)</th>
+            <th colspan="4" class="th-bg">抽采区域(回风巷)</th>
+          </tr>
+          <tr>
+            <!-- 注气区域子列 -->
+            <th>甲烷浓度 (%)</th>
+            <th>氧气浓度 (%)</th>
+            <th>温度 (℃)</th>
+            <!-- 抽采区域子列 -->
+            <th>甲烷浓度 (%)</th>
+            <th>氧气浓度 (%)</th>
+            <th>温度 (℃)</th>
+            <th>风速 (m/s)</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr v-for="(row, index) in tableData" :key="index">
+            <td>{{ row.time }}</td>
+            <td>{{ row.injectionMethane }}</td>
+            <td>{{ row.injectionOxygen }}</td>
+            <td>{{ row.injectionTemp }}</td>
+            <td>{{ row.extractionMethane }}</td>
+            <td>{{ row.extractionOxygen }}</td>
+            <td>{{ row.extractionTemp }}</td>
+            <td>{{ row.extractionWindSpeed }}</td>
+          </tr>
+          <tr v-if="!tableData || tableData.length === 0">
+            <td colspan="8" class="empty-tip">暂无数据</td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+
+    <!-- 趋势折线图 -->
+    <div class="chart-wrap">
+      <div ref="chartRef" class="monitor-chart"></div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { ref, watch, onMounted, onUnmounted } from 'vue';
+  import * as echarts from 'echarts';
+  import type { EChartsOption } from 'echarts';
+  const timeRange = ref<[string, string]>(['2026-03-12', '2026-03-13']);
+
+  // 表格数据
+  const tableData = ref([
+    {
+      time: '2026-03-12 00:00',
+      injectionMethane: 0.25,
+      injectionOxygen: 20.8,
+      injectionTemp: 22.5,
+      extractionMethane: 0.32,
+      extractionOxygen: 20.5,
+      extractionTemp: 23.1,
+      extractionWindSpeed: 1.2,
+    },
+    {
+      time: '2026-03-12 01:00',
+      injectionMethane: 0.28,
+      injectionOxygen: 20.7,
+      injectionTemp: 22.6,
+      extractionMethane: 0.35,
+      extractionOxygen: 20.4,
+      extractionTemp: 23.2,
+      extractionWindSpeed: 1.3,
+    },
+    {
+      time: '2026-03-12 01:00',
+      injectionMethane: 0.28,
+      injectionOxygen: 20.7,
+      injectionTemp: 22.6,
+      extractionMethane: 0.35,
+      extractionOxygen: 20.4,
+      extractionTemp: 23.2,
+      extractionWindSpeed: 1.3,
+    },
+    {
+      time: '2026-03-12 01:00',
+      injectionMethane: 0.28,
+      injectionOxygen: 20.7,
+      injectionTemp: 22.6,
+      extractionMethane: 0.35,
+      extractionOxygen: 20.4,
+      extractionTemp: 23.2,
+      extractionWindSpeed: 1.3,
+    },
+    {
+      time: '2026-03-12 01:00',
+      injectionMethane: 0.28,
+      injectionOxygen: 20.7,
+      injectionTemp: 22.6,
+      extractionMethane: 0.35,
+      extractionOxygen: 20.4,
+      extractionTemp: 23.2,
+      extractionWindSpeed: 1.3,
+    },
+  ]);
+
+  // 图表数据
+  const chartData = ref({
+    xAxisData: ['4.07 03:00', '4.07 05:00', '4.08 04:00', '4.09 03:00', '4.09 05:00', '4.10 04:00'],
+    series: [
+      { name: '指标1', data: [0.8, 1.0, 0.9, 1.5, 0.8, 1.6], color: '#00ff88' },
+      { name: '指标2', data: [0.4, 0.5, 0.7, 1.0, 0.4, 1.2], color: '#ffaa00' },
+      { name: '指标3', data: [0.9, 1.3, 1.2, 0.9, 0.9, 1.3], color: '#00ddff' },
+    ],
+  });
+
+  // 内部状态
+  const chartRef = ref<HTMLElement>();
+  let chartInstance: echarts.ECharts | null = null;
+
+  // 监听 chartData 变化,自动重新渲染图表
+  watch(
+    chartData,
+    () => {
+      initChart();
+    },
+    { deep: true }
+  );
+
+  const handleTimeChange = () => {
+    console.log('time-change', timeRange.value);
+  };
+  const handleExport = () => {
+    console.log('导出数据');
+  };
+
+  // 图表初始化
+  const initChart = () => {
+    if (!chartRef.value) return;
+    if (chartInstance) chartInstance.dispose();
+    chartInstance = echarts.init(chartRef.value);
+
+    const seriesList = chartData.value.series.map((item) => ({
+      name: item.name,
+      type: 'line',
+      smooth: true,
+      symbol: 'none',
+      data: item.data,
+      lineStyle: { width: 2, color: item.color },
+      areaStyle: {
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          { offset: 0, color: item.color + '80' },
+          { offset: 1, color: item.color + '00' },
+        ]),
+      },
+    }));
+
+    const option: EChartsOption = {
+      backgroundColor: 'transparent',
+      tooltip: { trigger: 'axis', backgroundColor: 'rgba(0,20,40,0.8)', borderColor: '#00aaff', textStyle: { color: '#fff' } },
+      legend: { right: '5%', top: '3%', textStyle: { color: '#fff' }, itemWidth: 10, itemHeight: 10 },
+      grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true },
+      xAxis: {
+        type: 'category',
+        boundaryGap: false,
+        data: chartData.value.xAxisData,
+        axisLine: { lineStyle: { color: 'rgba(0,170,255,0.3)' } },
+        axisLabel: { color: '#aaccff' },
+        splitLine: { show: false },
+      },
+      yAxis: {
+        type: 'value',
+        min: 0,
+        // 修复:调整 Y 轴最大值,避免数据超出显示范围(也可动态计算最大值)
+        max: 2,
+        axisLine: { show: false },
+        axisLabel: { color: '#aaccff' },
+        splitLine: { lineStyle: { color: 'rgba(0,170,255,0.1)' } },
+      },
+      series: seriesList,
+    };
+
+    chartInstance.setOption(option);
+  };
+
+  const resizeChart = () => chartInstance?.resize();
+
+  onMounted(() => {
+    window.addEventListener('resize', resizeChart);
+    initChart();
+  });
+
+  onUnmounted(() => {
+    window.removeEventListener('resize', resizeChart);
+    chartInstance?.dispose();
+    chartInstance = null;
+  });
+</script>
+
+<style scoped lang="less">
+  .main-container {
+    width: 100%;
+    height: 610px;
+    overflow: hidden;
+    padding: 0 35px;
+  }
+  // 顶部操作栏
+  .modal-top-bar {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin: 16px 0;
+    padding: 0 20px;
+    background-image: url('/@/assets/images/gasInjection/syq/modal-top-bg.png');
+    background-size: 100% 100%;
+    background-repeat: no-repeat;
+    background-position: top center;
+  }
+
+  .time-picker-wrap {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+
+    .label {
+      color: #aaccff;
+      font-size: 14px;
+    }
+
+    .date-input-group {
+      display: flex;
+      align-items: center;
+      gap: 4px;
+      background: rgba(0, 30, 60, 0.6);
+      border: 1px solid rgba(0, 170, 255, 0.4);
+      padding: 4px 8px;
+      border-radius: 4px;
+
+      &:hover {
+        border-color: #00aaff;
+      }
+    }
+
+    .date-input-group {
+      padding: 0;
+
+      :deep(.zxm-picker) {
+        background: rgba(0, 30, 60, 0.6);
+        border: 1px solid rgba(0, 170, 255, 0.4);
+
+        &:hover {
+          border-color: #00aaff;
+        }
+      }
+
+      :deep(.zxm-picker-input > input) {
+        color: #ffffff;
+        font-size: 14px;
+      }
+
+      :deep(.zxm-picker-range-separator) {
+        color: #aaccff;
+      }
+
+      :deep(.zxm-picker-suffix) {
+        color: #aaccff;
+      }
+
+      :deep(.zxm-picker-clear) {
+        color: #fff;
+      }
+    }
+  }
+  .button-area {
+    border: 1px solid #00aaff;
+    border-radius: 5px;
+    padding: 2px;
+    margin: 5px 0;
+  }
+
+  .export-btn {
+    height: 25px;
+    background: linear-gradient(90deg, #0077ff 0%, #00aaff 100%);
+    border: 1px solid #00aaff;
+    color: #ffffff;
+    padding: 8px 16px;
+    border-radius: 4px;
+    font-size: 14px;
+    cursor: pointer;
+    display: flex;
+    align-items: center;
+    gap: 6px;
+
+    &:hover {
+      background: linear-gradient(90deg, #0088ff 0%, #00bbff 100%);
+      box-shadow: 0 0 15px rgba(0, 170, 255, 0.5);
+    }
+
+    .icon {
+      width: 15px;
+      height: 15px;
+      background-image: url('/@/assets/images/gasInjection/syq/modal-export.svg');
+      background-size: 100% 100%;
+      background-repeat: no-repeat;
+      background-position: top center;
+    }
+  }
+
+  // 表格样式
+  .table-wrap {
+    margin-bottom: 20px;
+    max-height: 235px;
+    overflow-y: auto;
+    border-bottom: 1px solid #2893b2;
+
+    // 滚动条样式
+    &::-webkit-scrollbar {
+      width: 2px;
+      height: 6px;
+    }
+
+    &::-webkit-scrollbar-thumb {
+      background: rgba(0, 170, 255, 0.3);
+    }
+  }
+
+  .monitor-table {
+    width: 100%;
+    border-collapse: collapse;
+    color: #ffffff;
+    font-size: 14px;
+
+    td {
+      padding: 8px 12px;
+      text-align: center;
+    }
+
+    th {
+      border: 1px solid #2893b2;
+      padding: 8px 12px;
+      text-align: center;
+      background: #103967;
+      color: #2fb8d3;
+      font-weight: 500;
+    }
+    .th-bg {
+      background-color: #1b578e;
+    }
+    tbody tr {
+      background: rgb(11, 35, 66, 0.3);
+    }
+    tbody tr:nth-child(odd) {
+      background: rgb(13, 44, 82, 0.8);
+    }
+
+    .empty-tip {
+      color: #aaccff;
+      padding: 20px;
+    }
+  }
+
+  // 图表容器
+  .chart-wrap {
+    width: 100%;
+    height: 280px;
+    background: rgb(17, 40, 71, 0.5);
+
+    .monitor-chart {
+      width: 100%;
+      height: 100%;
+    }
+  }
+</style>

+ 95 - 90
src/views/vent/home/configurable/components/gasInject/navMenu.vue

@@ -2,120 +2,125 @@
   <div class="nav-menu">
     <div class="menu-item" v-for="(item, index) in menuList" :key="index" @click="handlerClick(index, item)">
       <div
-        :class="{ 'menu-item-label': index != menuList.length - 1, 'menu-item-label-1': index == menuList.length - 1, 'bg-position': index == menuList.length - 1, 'active-menu': activeIndex == index, 'unactive-menu': activeIndex != index }">
-        {{ item.name }}</div>
+        :class="{
+          'menu-item-label': index != menuList.length - 1,
+          'menu-item-label-1': index == menuList.length - 1,
+          'bg-position': index == menuList.length - 1,
+          'active-menu': activeIndex == index,
+          'unactive-menu': activeIndex != index,
+        }"
+      >
+        {{ item.name }}</div
+      >
       <div v-if="index != menuList.length - 1" class="menu-item-icon"></div>
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue'
-
-let menuList = ref([
-  { name: '设备监测', code: 'device' },
-  { name: '试验区', code: 'syq' },
-  { name: '主界面', code: 'zjm' },
-  { name: '注气系统', code: 'zqxt' },
-  { name: '抽采系统', code: 'ccxt' },
-])
-let activeIndex = ref<number>(2)
-let $emit = defineEmits(['toggleMenu'])
-
-
-//选项切换
-function handlerClick(index, item) {
-  activeIndex.value = index
-  $emit('toggleMenu', item.code)
-}
-
+  import { ref } from 'vue';
+
+  let menuList = ref([
+    // { name: '设备监测', code: 'device' },
+    { name: '试验区', code: 'syq' },
+    { name: '主界面', code: 'zjm' },
+    { name: '注气系统', code: 'zqxt' },
+    { name: '抽采系统', code: 'ccxt' },
+  ]);
+  let activeIndex = ref<number>(1);
+  let $emit = defineEmits(['toggleMenu']);
+
+  //选项切换
+  function handlerClick(index, item) {
+    activeIndex.value = index;
+    $emit('toggleMenu', item.code);
+  }
 </script>
 
 <style lang="less" scoped>
-@import '/@/design/theme.less';
+  @import '/@/design/theme.less';
 
-@{theme-deepblue} {
-  .nav-menu {
-    --image-menu-center: url('@/assets/images/themify/deepblue/home-container/configurable/gasInjection/1-5.png');
-    --image-menu-bg-L: url('@/assets/images/themify/deepblue/home-container/configurable/gasInjection/1-4.png');
-    --image-menu-bg-R: url('@/assets/images/themify/deepblue/home-container/configurable/gasInjection/1-3.png');
+  @{theme-deepblue} {
+    .nav-menu {
+      --image-menu-center: url('@/assets/images/themify/deepblue/home-container/configurable/gasInjection/1-5.png');
+      --image-menu-bg-L: url('@/assets/images/themify/deepblue/home-container/configurable/gasInjection/1-4.png');
+      --image-menu-bg-R: url('@/assets/images/themify/deepblue/home-container/configurable/gasInjection/1-3.png');
+    }
   }
-}
-
-.nav-menu {
-  --image-menu-center: url('@/assets/images/gasInjection/1-5.png');
-  --image-menu-bg-L: url('@/assets/images/gasInjection/1-4.png');
-  --image-menu-bg-R: url('@/assets/images/gasInjection/1-3.png');
-  display: flex;
-  justify-content: space-between;
-  width: 100%;
-  height: 100%;
-  padding: 9px 0px 0px 35px;
-  box-sizing: border-box;
-
-  .menu-item {
-    width: 20%;
-    height: 100%;
-    display: flex;
-    cursor: pointer;
 
-    &:nth-child(1) {
-      .menu-item-icon {
-        background: var(--image-menu-bg-R) no-repeat center;
+  .nav-menu {
+    --image-menu-center: url('@/assets/images/gasInjection/1-5.png');
+    --image-menu-bg-L: url('@/assets/images/gasInjection/1-4.png');
+    --image-menu-bg-R: url('@/assets/images/gasInjection/1-3.png');
+    display: flex;
+    justify-content: space-between;
+    width: 100%;
+    height: 100%;
+    padding: 9px 0px 0px 35px;
+    box-sizing: border-box;
+
+    .menu-item {
+      width: 20%;
+      height: 100%;
+      display: flex;
+      cursor: pointer;
+
+      &:nth-child(1) {
+        .menu-item-icon {
+          background: var(--image-menu-bg-R) no-repeat center;
+        }
       }
-    }
 
-    &:nth-child(2) {
-      .menu-item-icon {
-        background: var(--image-menu-bg-R) no-repeat center;
+      &:nth-child(2) {
+        .menu-item-icon {
+          background: var(--image-menu-bg-R) no-repeat center;
+        }
       }
-    }
 
-    &:nth-child(3) {
-      .menu-item-icon {
-        background: var(--image-menu-bg-L) no-repeat center;
+      &:nth-child(3) {
+        .menu-item-icon {
+          background: var(--image-menu-bg-L) no-repeat center;
+        }
       }
-    }
 
-    &:nth-child(4) {
-      .menu-item-icon {
-        background: var(--image-menu-bg-L) no-repeat center;
+      &:nth-child(4) {
+        .menu-item-icon {
+          background: var(--image-menu-bg-L) no-repeat center;
+        }
       }
     }
-  }
 
-  .menu-item-label {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    width: calc(100% - 33px);
-    font-size: 13px;
-    font-family: 'douyuFont';
-  }
+    .menu-item-label {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      width: calc(100% - 33px);
+      font-size: 13px;
+      font-family: 'douyuFont';
+    }
 
-  .menu-item-label-1 {
-    display: flex;
-    align-items: center;
-    width: 100%;
-    font-size: 13px;
-    padding-left: 15px;
-    font-family: 'douyuFont';
-  }
+    .menu-item-label-1 {
+      display: flex;
+      align-items: center;
+      width: 100%;
+      font-size: 13px;
+      padding-left: 15px;
+      font-family: 'douyuFont';
+    }
 
-  .menu-item-icon {
-    width: 33px;
-  }
+    .menu-item-icon {
+      width: 33px;
+    }
 
-  .active-menu {
-    height: 100%;
-    background: var(--image-menu-center) no-repeat bottom;
-    background-size: 100% 100%;
-  }
+    .active-menu {
+      height: 100%;
+      background: var(--image-menu-center) no-repeat bottom;
+      background-size: 100% 100%;
+    }
 
-  .bg-position {
-    background-position: -2px 0;
-    background-size: 78% 100%;
+    .bg-position {
+      background-position: -2px 0;
+      background-size: 78% 100%;
+    }
   }
-
-}
 </style>

+ 15 - 9
src/views/vent/home/configurable/components/three3D.vue

@@ -7,7 +7,6 @@
   import UseThree from '/@/utils/threejs/useThree';
   import { animateCamera } from '/@/utils/threejs/util';
   import * as THREE from 'three';
-  import useEvent from '/@/utils/threejs/useEvent';
 
   const props = defineProps<{
     modalName: string;
@@ -36,11 +35,11 @@
           newP: { x: -2.211555197992825, y: 27.130029732875393, z: 2.3018919451652007 },
           newT: { x: -2.211555197992825, y: -8.604453425019353, z: 2.301856157557903 },
         },
-        jdds: {
+        zhuqi: {
           render: null,
           group: modalGroup ? modalGroup : null,
-          newP: { x: 0.22197787154285728, y: 29.010792085965782, z: 2.477736279196267 },
-          newT: { x: 0.22197787154285728, y: -8.604453177192061, z: 2.477698375233975 },
+          newP: { x: -45.69228602978097, y: 49.59721939545517, z: 2.6454258202266985 },
+          newT: { x: 9.289291846942458, y: -21.608842010051386, z: 2.7675348357947906 },
         },
       };
       await initModal();
@@ -58,11 +57,8 @@
   };
 
   const customModal = () => {
-    if (props.modalName == 'workFace11') {
-      const DiXing = modalGroup.getObjectByName('PouMian01')?.getObjectByName('DiXing')?.getObjectByName('DiXing_1');
-      if (DiXing) {
-        DiXing.visible = false;
-      }
+    if (props.modalName == 'zhuqi') {
+      //
     }
   };
 
@@ -86,6 +82,14 @@
     });
   };
 
+  const resizeRenderer = () => {
+    if (modal) modal.resizeRenderer();
+  };
+
+  const getModal = () => {
+    return modal;
+  };
+
   watch(
     () => props.modalName,
     async (val) => {
@@ -112,6 +116,8 @@
     modalGroup = null;
     modal = null;
   });
+
+  defineExpose({ resizeRenderer, getModal });
 </script>
 <style lang="less" scoped>
   #three3D {

+ 4 - 3
src/views/vent/home/configurable/configurable.data.ts

@@ -967,7 +967,7 @@ export const testConfigGasInjectSy: Config[] = [
     deviceType: 'workface-info',
     moduleName: '工作面信息',
     pageType: 'gas_injection',
-    showDetail: true,
+    showDetail: false,
     moduleData: {
       header: {
         show: false,
@@ -1027,7 +1027,7 @@ export const testConfigGasInjectSy: Config[] = [
     deviceType: 'device-status',
     moduleName: '设备及管路状态',
     pageType: 'gas_injection',
-    showDetail: true,
+    showDetail: false,
     moduleData: {
       header: {
         show: false,
@@ -1091,9 +1091,10 @@ export const testConfigGasInjectSy: Config[] = [
     },
   },
   {
-    deviceType: 'env-monitor',
+    deviceType: 'syq-env-monitor',
     moduleName: '试验区环境监测',
     pageType: 'gas_injection_syq',
+    showDetail: true,
     moduleData: {
       header: {
         show: false,

+ 228 - 175
src/views/vent/home/configurable/gasInjection.vue

@@ -1,11 +1,5 @@
 <template>
   <div class="company-home">
-    <div v-if="menuName !== 'syq'" :class="menuName == 'zjm' ?  'vent-modal' : 'vent-modal-1'">
-      <!-- <VentModal /> -->
-    </div>
-    <div v-if="menuName === 'syq'" class="syq-modal">
-      <!-- <VentModal /> -->
-    </div>
     <div class="top-bg">
       <div class="main-title">{{ mainTitle }}</div>
     </div>
@@ -14,215 +8,274 @@
         <navMenu @toggleMenu="toggleMenu"></navMenu>
       </div>
       <template v-if="menuName == 'zjm'">
-        <div class="main-status">
-          运行中
-        </div>
-        <ModuleGasInject v-for="cfg in configs" :key="cfg.deviceType" :show-style="cfg.showStyle"
-          :module-data="cfg.moduleData" :module-name="cfg.moduleName" :device-type="cfg.deviceType" :data="data"
-          :visible="true" :visible-detail="cfg.showDetail" />
+        <div class="main-status"> 运行中 </div>
+        <ModuleGasInject
+          v-for="cfg in configs"
+          :key="cfg.deviceType"
+          :show-style="cfg.showStyle"
+          :module-data="cfg.moduleData"
+          :module-name="cfg.moduleName"
+          :device-type="cfg.deviceType"
+          :data="data"
+          :visible="true"
+          :visible-detail="cfg.showDetail"
+        />
       </template>
       <template v-else>
-        <ModuleGasInject v-for="cfg in configs" :key="cfg.deviceType" :show-style="cfg.showStyle"
-          :module-data="cfg.moduleData" :module-name="cfg.moduleName" :device-type="cfg.deviceType" :data="data"
-          :visible="true" :visible-detail="cfg.showDetail" />
+        <ModuleGasInject
+          v-for="cfg in configs"
+          :key="cfg.deviceType"
+          :show-style="cfg.showStyle"
+          :module-data="cfg.moduleData"
+          :module-name="cfg.moduleName"
+          :device-type="cfg.deviceType"
+          :data="data"
+          :visible="true"
+          :visible-detail="cfg.showDetail"
+        />
       </template>
-
+      <div :class="{ 'vent-modal': menuName == 'zjm', 'vent-modal-1': menuName == 'syq' || menuName == 'zqxt' || menuName == 'ccxt' }">
+        <div class="modal-box">
+          <Three3D ref="three3D" :modalName="'zhuqi'" class="modal-3d" />
+        </div>
+      </div>
+      <!-- <div v-if="menuName === 'syq'" class="syq-modal">
+        </div> -->
     </div>
   </div>
 </template>
 <script lang="ts" setup>
-import { onMounted, onUnmounted, ref, computed } from 'vue';
-import { useInitConfigs, useInitPage } from './hooks/useInit';
-import ModuleGasInject from './components/ModuleGasInject.vue';
-import navMenu from './components/gasInject/navMenu.vue'
-// import { useRoute } from 'vue-router';
-import VentModal from '/@/components/vent/micro/ventModal.vue';
-import { getHomeData } from './configurable.api';
-// import { useRoute } from 'vue-router';
-import { testConfigGasInject, testConfigGasInjectZq, testConfigGasInjectCc, testConfigGasInjectSy } from './configurable.data';
-const { configs, fetchConfigs } = useInitConfigs();
-const { mainTitle, data, updateData } = useInitPage('注气驱替智能管控系统');
-// const route = useRoute();
-let interval: number | undefined;
-let menuName = ref('zjm')
-
-//选项切换
-function toggleMenu(param) {
-  menuName.value = param
-  switch (menuName.value) {
-    case 'zjm':
-      configs.value = testConfigGasInject;
-      break;
-    case 'syq':
-      configs.value = testConfigGasInjectSy;
-      break;
-    case 'zqxt':
-      configs.value = testConfigGasInjectZq;
-      break;
-    case 'ccxt':
-      configs.value = testConfigGasInjectCc
-      break;
+  import { onMounted, onUnmounted, ref, computed, nextTick } from 'vue';
+  import { useInitConfigs, useInitPage } from './hooks/useInit';
+  import ModuleGasInject from './components/ModuleGasInject.vue';
+  import navMenu from './components/gasInject/navMenu.vue';
+  import Three3D from './components/three3D.vue';
+  // import { useRoute } from 'vue-router';
+  import VentModal from '/@/components/vent/micro/ventModal.vue';
+  import { getHomeData } from './configurable.api';
+  // import { useRoute } from 'vue-router';
+  import { testConfigGasInject, testConfigGasInjectZq, testConfigGasInjectCc, testConfigGasInjectSy } from './configurable.data';
+  import { animateCamera } from '/@/utils/threejs/util';
+
+  const { configs, fetchConfigs } = useInitConfigs();
+  const { mainTitle, data, updateData } = useInitPage('注气驱替智能管控系统');
+  // const route = useRoute();
+  const three3D = ref(null);
+  let interval: number | undefined;
+  let menuName = ref('zjm');
+
+  //选项切换
+  function toggleMenu(param) {
+    menuName.value = param;
+    switch (menuName.value) {
+      case 'zjm':
+        configs.value = testConfigGasInject;
+        break;
+      case 'syq':
+        configs.value = testConfigGasInjectSy;
+        break;
+      case 'zqxt':
+        configs.value = testConfigGasInjectZq;
+        break;
+      case 'ccxt':
+        configs.value = testConfigGasInjectCc;
+        break;
+    }
+
+    // 刷新/
+    nextTick(async () => {
+      three3D.value?.resizeRenderer();
+      const modal = three3D.value.getModal();
+      if (modal) {
+        const oldCamera = modal.camera;
+        const oldCameraPosition = { x: oldCamera.position.x, y: oldCamera.position.y, z: oldCamera.position.z };
+        if (param == 'zqxt') {
+          const newP = { x: -26.587483577770445, y: -1.885170491810538, z: 39.104309663143255 };
+          const newT = { x: 10.919881491980828, y: -4.7228274957026946, z: 38.87645926712004 };
+          await animateCamera(oldCameraPosition, { x: 0, y: 0, z: 0 }, newP, newT, modal);
+        } else {
+          const newP = { x: -45.69228602978097, y: 49.59721939545517, z: 2.6454258202266985 };
+          const newT = { x: 9.289291846942458, y: -21.608842010051386, z: 2.7675348357947906 };
+          await animateCamera(oldCameraPosition, { x: 0, y: 0, z: 0 }, newP, newT, modal);
+        }
+      }
+    });
   }
-}
-onMounted(() => {
-  // fetchConfigs('vent_new').then(() => {
-  configs.value = testConfigGasInject;
-  // updateEnhancedConfigs(configs.value);
-
-  getHomeData({}).then(updateData);
-  // });
-  setInterval(() => {
+  onMounted(() => {
+    // fetchConfigs('vent_new').then(() => {
+    configs.value = testConfigGasInject;
+    // updateEnhancedConfigs(configs.value);
+
     getHomeData({}).then(updateData);
-  }, 60000);
-});
+    // });
+    setInterval(() => {
+      getHomeData({}).then(updateData);
+    }, 60000);
+  });
 
-onUnmounted(() => {
-  clearInterval(interval);
-});
+  onUnmounted(() => {
+    clearInterval(interval);
+  });
 </script>
+
 <style lang="less" scoped>
-@import '/@/design/theme.less';
+  @import '/@/design/theme.less';
+
+  @{theme-deepblue} {
+    .company-home {
+      --image-modal-top: url('@/assets/images/gasInjection/1-1.png');
+      --image-modal-status: url('@/assets/images/gasInjection/3-1.png');
+      --image-modal-center: url('@/assets/images/gasInjection/1-2.png');
+    }
+  }
 
-@{theme-deepblue} {
   .company-home {
     --image-modal-top: url('@/assets/images/gasInjection/1-1.png');
     --image-modal-status: url('@/assets/images/gasInjection/3-1.png');
     --image-modal-center: url('@/assets/images/gasInjection/1-2.png');
-  }
-}
-
-.company-home {
-  --image-modal-top: url('@/assets/images/gasInjection/1-1.png');
-  --image-modal-status: url('@/assets/images/gasInjection/3-1.png');
-  --image-modal-center: url('@/assets/images/gasInjection/1-2.png');
-  width: 100%;
-  height: 100%;
-  color: @white;
-  position: relative;
-  background: url('@/assets/images/vent/homeNew/bg.png') no-repeat center;
-
-  .top-bg {
     width: 100%;
-    height: 66px;
-    background: var(--image-modal-top) no-repeat center;
-    background-size: 100% 100%;
-    position: absolute;
-    z-index: 1;
+    height: 100%;
+    color: @white;
+    position: relative;
+    background: url('@/assets/images/vent/homeNew/bg.png') no-repeat center;
 
-    .main-title {
+    .top-bg {
+      width: 100%;
       height: 66px;
-      font-family: 'douyuFont';
-      font-size: 20px;
-      letter-spacing: 2px;
+      background: var(--image-modal-top) no-repeat center;
+      background-size: 100% 100%;
+      position: absolute;
+      z-index: 1;
+
+      .main-title {
+        height: 66px;
+        font-family: 'douyuFont';
+        font-size: 20px;
+        letter-spacing: 2px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+      }
+
+      .top-nav {
+        position: absolute;
+        top: 0;
+        width: 880px;
+        height: 100%;
+        display: flex;
+        justify-content: flex-start;
+      }
+    }
+
+    .main-container {
+      position: absolute;
+      top: 66px;
+      width: 100%;
+      height: calc(100% - 66px);
+      padding: 0px 10px;
+      box-sizing: border-box;
+    }
+
+    .main-status {
       display: flex;
       justify-content: center;
       align-items: center;
+      width: 440px;
+      height: 80px;
+      font-size: 18px;
+      font-family: 'douyuFont';
+      margin: 10px 0px;
+      background: var(--image-modal-status);
+      background-size: 100% 100%;
     }
 
-    .top-nav {
+    .module-dropdown {
+      padding: 10px;
+      background-image: @vent-configurable-dropdown;
+      border-bottom: 2px solid @vent-configurable-home-light-border;
+      color: @vent-font-color;
       position: absolute;
-      top: 0;
-      width: 880px;
-      height: 100%;
-      display: flex;
-      justify-content: flex-start;
+      top: 70px;
+      right: 460px;
     }
-  }
 
-  .main-container {
-    position: absolute;
-    top: 66px;
-    width: 100%;
-    height: calc(100% - 66px);
-    padding: 0px 10px;
-    box-sizing: border-box;
+    .module-dropdown-original {
+      padding: 10px;
+      background-image: @vent-configurable-dropdown;
+      border-bottom: 2px solid @vent-configurable-home-light-border;
+      color: @vent-font-color;
+      position: absolute;
+      top: 70px;
+      right: 460px;
+    }
+
+    .module-trigger-button {
+      color: @vent-font-color;
+      background-image: @vent-configurable-dropdown;
+      border: none;
+      border-bottom: 2px solid @vent-configurable-home-light-border;
+    }
+
+    .nav-cards {
+      position: absolute;
+      left: 50%;
+      top: 0px;
+      transform: translate(-50%, 0);
+      width: 691px;
+      height: 58px;
+      background: var(--image-modal-center) no-repeat;
+      background-size: 100% 100%;
+    }
   }
 
-  .main-status {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    width: 440px;
-    height: 80px;
-    font-size: 18px;
-    font-family: 'douyuFont';
-    margin: 10px 0px;
-    background: var(--image-modal-status);
-    background-size: 100% 100%;
+  :deep(.loading-box) {
+    position: unset;
   }
 
+  .modal-box {
+    width: 100%;
+    height: 100%;
+    position: relative;
+    pointer-events: auto;
+    padding: 20px;
+  }
 
-  .module-dropdown {
-    padding: 10px;
-    background-image: @vent-configurable-dropdown;
-    border-bottom: 2px solid @vent-configurable-home-light-border;
-    color: @vent-font-color;
+  // 试验区模型区域样式
+  .syq-modal {
     position: absolute;
-    top: 70px;
-    right: 460px;
+    top: 135px;
+    right: 20px;
+    width: calc(100% - 510px);
+    height: 515px;
+    background: url('@/assets/images/gasInjection/syq/modal-bg.png') no-repeat;
+    background-size: 100% 100%;
   }
 
-  .module-dropdown-original {
-    padding: 10px;
-    background-image: @vent-configurable-dropdown;
-    border-bottom: 2px solid @vent-configurable-home-light-border;
-    color: @vent-font-color;
+  .vent-modal {
     position: absolute;
     top: 70px;
-    right: 460px;
-  }
-
-  .module-trigger-button {
-    color: @vent-font-color;
-    background-image: @vent-configurable-dropdown;
-    border: none;
-    border-bottom: 2px solid @vent-configurable-home-light-border;
+    left: 50%;
+    transform: translate(-50%, 0px);
+    width: calc(100% - 920px);
+    height: 505px;
+    background: url(/src/assets/images/gasInjection/syq/modal-bg.png) no-repeat;
+    background-size: 100% 100%;
+    pointer-events: auto;
+    background-color: transparent !important;
   }
-
-  .nav-cards {
+  .vent-modal-1 {
     position: absolute;
-    left: 50%;
-    top: 0px;
-    transform: translate(-50%, 0);
-    width: 691px;
-    height: 58px;
-    background: var(--image-modal-center) no-repeat;
+    top: 70px;
+    left: 460px;
+    width: calc(100% - 470px);
+    height: 505px;
+    background: url(/src/assets/images/gasInjection/syq/modal-bg.png) no-repeat;
     background-size: 100% 100%;
+    pointer-events: auto;
+    background-color: transparent !important;
+  }
+  .modal-3d {
+    padding: 10px;
+    width: calc(100% - 20px) !important;
   }
-}
-
-:deep(.loading-box) {
-  position: unset;
-}
-
-// 试验区模型区域样式
-.syq-modal {
-  position: absolute;
-  top: 135px;
-  right: 20px;
-  width: calc(100% - 510px);
-  height: 515px;
-  background: url('@/assets/images/gasInjection/syq/modal-bg.png') no-repeat;
-  background-size: 100% 100%;
-}
-
-.vent-modal {
-  position: absolute;
-  top: 134px;
-  left: 50%;
-  transform: translate(-50%, 0px);
-  width: calc(100% - 920px);
-  height: 505px;
-  background: url(/src/assets/images/gasInjection/syq/modal-bg.png) no-repeat;
-  background-size: 100% 100%;
-}
-.vent-modal-1 {
-  position: absolute;
-  top: 134px;
-  left: 460px;
-  width: calc(100% - 470px);
-  height: 505px;
-  background: url(/src/assets/images/gasInjection/syq/modal-bg.png) no-repeat;
-  background-size: 100% 100%;
-}
 </style>