Browse Source

1. 新增瓦斯评价单元监测页面
2. 瓦斯泵监测导入模型
3. 主风机模型替换
4. 公司端首页数据显示更改

hongrunxia 3 tháng trước cách đây
mục cha
commit
08b2055e1d

BIN
public/model/glft/ztfj/ztfj_2023-12-12.glb → public/model/glft/ztfj/ztfj_2024-11-26.glb


+ 36 - 19
src/hooks/vent/useSystemSelect.ts

@@ -4,6 +4,7 @@ import { defHttp } from '/@/utils/http/axios';
 type DeviceType = { deviceType: string; deviceName: string; datalist: any[] };
 type OptionType = { id: string; strsystype: string; systemname: string };
 const getTableList = (params) => defHttp.get({ url: '/safety/ventanalyManageSystem/list', params });
+// const getDeviceTableList = (params) => defHttp.get({ url: '/safety/ventanalyManageSystem/list', params });
 const systemList = (params) => defHttp.post({ url: '/monitor/device', params });
 
 /**
@@ -11,7 +12,7 @@ const systemList = (params) => defHttp.post({ url: '/monitor/device', params });
  * @param sysType 对应的设备/类型码,可在设备管理 -> 设备类型管理里查阅
  * @param changeModalType 即 optionValue(选择了的设备)变化后的回调,参数为该 option
  */
-export function useSystemSelect(sysType: string, changeModalType?: (param) => {}) {
+export function useSystemSelect(sysType: string, changeModalType?: (param) => void) {
   const options = ref<OptionType[]>([]);
   const optionValue = ref('');
   const deviceList = ref<DeviceType[]>([]);
@@ -20,7 +21,8 @@ export function useSystemSelect(sysType: string, changeModalType?: (param) => {}
   const deviceValue = ref({});
   const isRefresh = ref(true);
 
-  async function getDeviceList() {
+  /** 查询选中的场景下的关联设备监测数据 */
+  async function getDeviceList(isFirst = false) {
     const res = await systemList({ devicetype: 'sys', systemID: optionValue.value });
     const result = res.msgTxt;
     const deviceArr = <DeviceType[]>[];
@@ -38,39 +40,54 @@ export function useSystemSelect(sysType: string, changeModalType?: (param) => {}
       }
     });
     deviceList.value = deviceArr;
-    deviceActive.value = deviceArr[0].deviceType;
-    deviceChange(0);
+    if (isFirst) {
+      deviceChange(0);
+      // getSelectRow(deviceActive.value);
+    }
+    return deviceArr;
   }
-
+  /**查询场景类型下的场景列表 */
   async function getSysDataSource() {
-    const res = await getTableList({ strtype: sysType, pagetype: 'normal' });
-    if (options.value.length == 0) {
-      // 初始时选择第一条数据
-      options.value = res.records || [];
-      if (!optionValue.value) {
-        optionValue.value = options.value[0]['id'];
-        getDeviceList();
-        if (changeModalType) changeModalType(options.value[0]);
+    let res;
+    if (sysType.startsWith('sys_')) {
+      res = await getTableList({ strtype: sysType, pagetype: 'normal' });
+      if (options.value.length == 0) {
+        // 初始时选择第一条数据
+        options.value = res.records || [];
+      }
+    } else {
+      res = await systemList({ devicetype: sysType, pagetype: 'normal' });
+      if (!options.value || options.value.length == 0) {
+        // 初始时选择第一条数据
+        const datalist = res.msgTxt[0].datalist || [];
+        options.value = datalist.map((item) => {
+          return { id: item['deviceID'], strsystype: sysType, systemname: item['strinstallpos'] };
+        });
       }
     }
+    if (!optionValue.value) {
+      optionValue.value = options.value[0]['id'];
+      getDeviceList(true);
+      getSelectRow(optionValue.value);
+    }
   }
-
+  /**切换关联设备类型 */
   function deviceChange(index) {
     deviceValue.value = deviceList.value[index];
-    deviceActive.value = deviceType.value = deviceValue.value['deviceType'];
+    deviceActive.value = optionValue.value;
     isRefresh.value = false;
     nextTick(() => {
       isRefresh.value = true;
     });
   }
-
+  /** 切换场景 */
   async function getSelectRow(deviceID) {
     const currentData = options.value.find((item: any) => {
-      return item.id == deviceID;
+      return sysType.startsWith('sys_') ? item.id == deviceID : item.deviceID == deviceID;
     });
     optionValue.value = deviceID;
     if (changeModalType) changeModalType(currentData);
-    getDeviceList();
+    getDeviceList(true);
   }
 
   return {
@@ -88,6 +105,6 @@ export function useSystemSelect(sysType: string, changeModalType?: (param) => {}
     getSysDataSource,
     getSelectRow,
     deviceChange,
+    getDeviceList,
   };
 }
-

+ 4 - 3
src/layouts/default/header/index.vue

@@ -55,7 +55,8 @@
   </Header>
   <div :class="`${prefixCls}-action`" style="position: fixed; top: 30px; right: 20px; z-index: 999999">
     <div class="right-position">
-      <VoiceBroadcast />
+      <!-- 公司端不显示语音播报功能 -->
+      <VoiceBroadcast v-if="sysOrgCode == 'sdmtjtgsd'" />
       <UserDropDown v-if="showUserDropdown" :theme="getHeaderTheme" />
       <LoginSelect ref="loginSelectRef" @success="loginSelectOk" />
     </div>
@@ -128,8 +129,7 @@
 
       const { getShowTopMenu, getShowHeaderTrigger, getSplit, getIsMixMode, getMenuWidth, getIsMixSidebar } = useMenuSetting();
       const { getUseErrorHandle, getShowSettingButton, getSettingButtonPosition } = useRootSetting();
-      const { title } = useGlobSetting();
-
+      const { title, sysOrgCode } = useGlobSetting();
       const {
         getHeaderTheme,
         getShowFullScreen,
@@ -253,6 +253,7 @@
         getShowFullHeader,
         noHeadeLink,
         showUserDropdown,
+        sysOrgCode,
       };
     },
   });

+ 1 - 1
src/utils/threejs/main.worker.ts

@@ -53,7 +53,7 @@ export function initModalWorker() {
     'ztfj/dzp_2023-06-02.glb',
     'ztfj/fbm_2023-06-02.glb',
     'ztfj/ztfj-fc_2023-06-02.glb',
-    'ztfj/ztfj_2023-12-12.glb',
+    'ztfj/ztfj_2024-11-26.glb',
     'ztfj/ztfj-xj_2024-07-12.glb',
     'fire/laneway_2024-03-04.glb',
     'fire/laneway-device_2024-03-19.glb',

+ 7 - 2
src/views/vent/deviceManager/comment/warningTabel/BaseModal.vue

@@ -30,7 +30,7 @@
     deviceId: { type: String },
     monitorType: {
       type: String,
-      default: '2',
+      default: '2,3,9',
     },
   });
   const emit = defineEmits(['add', 'update', 'register']);
@@ -80,7 +80,7 @@
 
   async function getDevicePointList(strtype) {
     try {
-      const result = await workFacePointList({ deviceType: strtype, valueTypes: '2,3,9' });
+      const result = await workFacePointList({ deviceType: strtype, valueTypes: props.monitorType }); // 1控制点位、 2读取点位、3计算点位、9关联点位
       devicePointList.value = result;
     } catch (error) {
       devicePointList.value = [];
@@ -110,6 +110,11 @@
   }
 
   async function selectPoint(strtype) {
+    // 先将设备名称删除再赋值
+    const data = await getFieldsValue();
+    const deviceId = data['deviceId'];
+
+    debugger;
     if (strtype) {
       await getDevicePointList(strtype);
       openModal();

+ 2 - 1
src/views/vent/deviceManager/comment/warningTabel/index1.vue

@@ -42,10 +42,11 @@
 
   function selectWarning(id) {
     activeID.value = id;
+    getDataSource();
   }
 
   async function getDataSource() {
-    const result = await workFaceWarningList({ sysId: props.deviceId, monitorType: 1, alarmId: activeID.value, pageSize: 100000 });
+    const result = await workFaceWarningList({ sysId: props.deviceId, monitorType: 1, alarmId: activeID.value, pageSize: 100000 }); // 控制1 监测2
     dataSource.value = result.records;
   }
 

+ 1 - 1
src/views/vent/deviceManager/comment/warningTabel/index3.vue

@@ -21,7 +21,7 @@
       </a-table>
     </div>
   </div>
-  <BaseModal @register="register" @add="onSubmit" @update="onSubmit" :form-schemas="formSchemas" />
+  <BaseModal @register="register" @add="onSubmit" @update="onSubmit" :form-schemas="formSchemas" :monitor-type="'2,3,9'" />
 </template>
 
 <script lang="ts" setup>

+ 786 - 0
src/views/vent/gas/gasAssessment/gasAssessment.data.ts

@@ -0,0 +1,786 @@
+import { reactive, ref } from 'vue';
+import { BasicColumn } from '/@/components/Table';
+import echarts from '/@/utils/lib/echarts';
+import * as THREE from 'three';
+
+export const monitorNav = [
+  {
+    title: '一通三防综合管控',
+    isShow: true,
+  },
+  {
+    title: '通风监测与管控',
+    isShow: false,
+  },
+  {
+    title: '防灭火监测与管控',
+    isShow: false,
+  },
+  {
+    title: '防尘监测与管控',
+    isShow: false,
+  },
+  {
+    title: '瓦斯防治监测与管控',
+    isShow: false,
+  },
+];
+
+export const echartsOption = reactive({
+  tooltip: { trigger: 'axis', axisPointer: { lineStyle: { color: '#fff' } } },
+  legend: {
+    top: '-5',
+    icon: 'rect',
+    data: ['进风', '回风'],
+    right: '10px',
+    textStyle: { fontSize: 12, color: '#fff' },
+  },
+  grid: { x: 50, y: 50, x2: 12, y2: 40, bottom: '25', top: '10' },
+  xAxis: {
+    type: 'category',
+    boundaryGap: false,
+    axisLine: { lineStyle: { color: '#8EAFB9' } },
+    axisLabel: { color: '#ffffffcc' },
+    splitLine: { show: true, lineStyle: { color: '#57617B22', type: 'dashed' } },
+    data: [],
+  },
+  yAxis: [
+    {
+      type: 'value',
+      name: 'm³/min',
+      axisTick: {
+        show: false,
+      },
+      axisLine: { lineStyle: { show: true, color: '#8EAFB9' } },
+      axisLabel: { margin: 10, fontSize: 12, color: '#ffffffcc' },
+      splitLine: { show: true, lineStyle: { color: '#57617B22', type: 'dashed' } },
+    },
+  ],
+  series: [
+    {
+      name: '进风',
+      type: 'line',
+      smooth: true,
+      lineStyle: { width: 2 },
+      yAxisIndex: 0,
+      // markLine: {
+      //   data: [{ yAxis: 0, name: '需风量' }],
+      // },
+      areaStyle: {
+        color: new echarts.graphic.LinearGradient(
+          0,
+          0,
+          0,
+          1,
+          [
+            {
+              offset: 0,
+              color: 'rgba(185,150,248,0.3)',
+            },
+            {
+              offset: 0.8,
+              color: 'rgba(185,150,248,0)',
+            },
+          ],
+          false
+        ),
+        shadowColor: 'rgba(0, 0, 0, 0.1)',
+        shadowBlur: 10,
+      },
+      itemStyle: { color: '#B996F8' },
+      data: [],
+    },
+    {
+      name: '回风',
+      type: 'line',
+      smooth: true,
+      lineStyle: { width: 2 },
+      yAxisIndex: 0,
+      // markLine: {
+      //   data: [{ yAxis: 0, name: '需风量' }],
+      // },
+      areaStyle: {
+        color: new echarts.graphic.LinearGradient(
+          0,
+          0,
+          0,
+          1,
+          [
+            {
+              offset: 0,
+              color: 'rgba(3, 194, 236, 0.3)',
+            },
+            {
+              offset: 0.8,
+              color: 'rgba(3, 194, 236, 0)',
+            },
+          ],
+          false
+        ),
+        shadowColor: 'rgba(0, 0, 0, 0.1)',
+        shadowBlur: 10,
+      },
+      itemStyle: { color: '#03C2EC' },
+      data: [],
+    },
+  ],
+});
+
+export const ventParam = [
+  {
+    title: '允许超出风量(m³/min)',
+    value: '',
+    type: 'input',
+  },
+  {
+    title: '瓦斯浓度限值(%)',
+    value: '',
+    type: 'input',
+  },
+  {
+    title: '瓦斯持续超限时间(s)',
+    value: '',
+    type: 'input',
+  },
+  {
+    title: '风量调控策略',
+    value: '1',
+    type: 'radio',
+  },
+];
+
+export const warningConfig = reactive({
+  header: ['设备名称', '预警信息', '时间'],
+  data: [
+    ['火焰6', '严重报警', '03-05'],
+    ['测点43', '一般预警', '03-05'],
+    ['CO23', '一般预警', '03-05'],
+    ['测点6', '超高预警', '03-05'],
+    ['测点65', '超高预警', '03-05'],
+    ['温度4', '一般预警', '03-05'],
+    ['测点61', '一般预警', '03-05'],
+    ['测点87', '一般信息', '03-05'],
+  ],
+  index: false,
+  headerBGC: '#3d9dd45d',
+  oddRowBGC: '#009acd10',
+  evenRowBGC: '#009acd05',
+  align: ['center', 'center', 'center'],
+});
+
+export const locationConfig = reactive({
+  header: ['人名', '所在位置', '距离'],
+  data: [],
+  index: false,
+  columnWidth: [100, 200, 80],
+  headerBGC: '#3d9dd45d',
+  oddRowBGC: '#009acd10',
+  evenRowBGC: '#009acd05',
+  align: ['center', 'center', 'center'],
+});
+
+export const sensorColumns: BasicColumn[] = [
+  {
+    title: '名称',
+    dataIndex: 'strname',
+    width: 100,
+    align: 'center',
+  },
+  {
+    title: '实时值',
+    dataIndex: 'smokeval',
+    width: 80,
+    align: 'center',
+  },
+  {
+    title: '报警',
+    dataIndex: 'warnFlag',
+    width: 100,
+    align: 'center',
+  },
+];
+
+export const gateColumns: BasicColumn[] = [
+  {
+    title: '名称',
+    dataIndex: 'strname',
+    width: 100,
+    align: 'center',
+  },
+  {
+    title: '前门状态',
+    dataIndex: 'frontGateOpen',
+    width: 80,
+    align: 'center',
+  },
+  {
+    title: '后门状态',
+    dataIndex: 'rearGateOpen',
+    width: 80,
+    align: 'center',
+  },
+  {
+    title: '操作',
+    dataIndex: 'action',
+    width: 80,
+    align: 'center',
+  },
+];
+
+export const windowColumns: BasicColumn[] = [
+  {
+    title: '名称',
+    dataIndex: 'strname',
+    width: 100,
+    align: 'center',
+  },
+  {
+    title: '过风量',
+    dataIndex: 'forntm3',
+    width: 80,
+    align: 'center',
+  },
+  {
+    title: '操作',
+    dataIndex: 'action',
+    width: 80,
+    align: 'center',
+  },
+];
+
+export const windColumns: BasicColumn[] = [
+  {
+    title: '名称',
+    dataIndex: 'strname',
+    width: 100,
+    align: 'center',
+  },
+  {
+    title: '风量',
+    dataIndex: 'm3',
+    width: 80,
+    align: 'center',
+  },
+  {
+    title: '操作',
+    dataIndex: 'action',
+    width: 80,
+    align: 'center',
+  },
+];
+
+export const dustColumns: BasicColumn[] = [
+  {
+    title: '名称',
+    dataIndex: 'strname',
+    width: 100,
+    align: 'center',
+  },
+  {
+    title: '链接状态',
+    dataIndex: 'netStatus',
+    width: 80,
+    align: 'center',
+  },
+  {
+    title: '操作',
+    dataIndex: 'action',
+    width: 100,
+    align: 'center',
+  },
+];
+
+export const beamTubeColumns = [
+  {
+    gasval: '甲烷(%)',
+    ch2val: '乙烯(ppm)',
+  },
+  {
+    o2val: '氧气(%)',
+    chval: '乙炔(ppm)',
+  },
+  {
+    coval: '一氧化碳(ppm)',
+    co2val: '二氧化碳(%)',
+  },
+];
+
+export const groutColumns = [
+  {
+    flowRate: '流量(m³/min)',
+    pressure: '压力(Pa)',
+  },
+];
+
+export const nitrogenColumns = [
+  {
+    cumulativeFlow: '流量(m³/min)',
+    nitrogenPressure: '压力(Pa)',
+  },
+];
+
+export const sprayColumns: BasicColumn[] = [
+  {
+    title: '名称',
+    dataIndex: 'strname',
+    width: 100,
+    align: 'center',
+  },
+  {
+    title: '连接状态',
+    dataIndex: 'netStatus',
+    width: 80,
+    align: 'center',
+  },
+  {
+    title: '启停',
+    dataIndex: 'action',
+    width: 80,
+    align: 'center',
+  },
+];
+
+export const disasterParam = ref([
+  {
+    title: '触发灾变传感器',
+    value: '1',
+    type: 'select',
+    options: [
+      {
+        label: 'CO与烟雾',
+        value: '1',
+      },
+      {
+        label: 'CO',
+        value: '2',
+      },
+      {
+        label: '烟雾',
+        value: '3',
+      },
+    ],
+  },
+  {
+    title: 'CO浓度限值(ppm)',
+    value: '',
+    type: 'input',
+  },
+  {
+    title: 'CO报警持续时间(s)',
+    value: '',
+    type: 'input',
+  },
+  {
+    title: '烟雾报警持续时间(s)',
+    value: '',
+    type: 'input',
+  },
+]);
+
+export const compressorMonitor = [
+  {
+    title: '总吸风量',
+    code: 'windQuantity2',
+    unit: 'm³/min',
+  },
+  {
+    title: '总供风量',
+    code: 'windQuantity1',
+    unit: 'm³/min',
+  },
+  {
+    title: '局扇频率',
+    code: 'fHz',
+    unit: 'Hz',
+  },
+  {
+    title: '进风风窗当前面积',
+    code: 'jinArea',
+    unit: '㎡',
+  },
+  {
+    title: '回风风窗当前面积',
+    code: 'huiArea',
+    unit: '㎡',
+  },
+];
+
+export const compressorParam = [
+  {
+    title: 'O2浓度限值',
+    value: '',
+    type: 'input',
+  },
+  {
+    title: 'CO浓度限值',
+    value: '',
+    type: 'input',
+  },
+];
+
+export const compressorDeviceParam = [
+  {
+    title: '局扇频率调节(Hz)',
+    value: '',
+    type: 'input',
+  },
+  {
+    title: '进风风窗当前面积(㎡)',
+    value: '',
+    type: 'input',
+  },
+  {
+    title: '回风风窗当前面积(㎡)',
+    value: '',
+    type: 'input',
+  },
+];
+
+export const coalMachineDustParam = [
+  {
+    title: '内喷雾压力',
+    value: '',
+    unit: 'Pa',
+  },
+  {
+    title: '内喷雾流量',
+    value: '',
+    unit: 'm³/min',
+  },
+  {
+    title: '外喷雾压力',
+    value: '',
+    unit: 'Pa',
+  },
+  {
+    title: '外喷雾流量',
+    value: '',
+    unit: 'm³/min',
+  },
+];
+
+export const beltMachineDustParam = [
+  {
+    title: '全尘',
+    value: '',
+    unit: 'mg/m³',
+  },
+  {
+    title: '呼尘',
+    value: '',
+    unit: 'mg/m³',
+  },
+  {
+    title: '内喷雾压力',
+    value: '',
+    unit: 'Pa',
+  },
+  {
+    title: '内喷雾流量',
+    value: '',
+    unit: 'm³/min',
+  },
+  {
+    title: '外喷雾压力',
+    value: '',
+    unit: 'Pa',
+  },
+  {
+    title: '外喷雾流量',
+    value: '',
+    type: 'input',
+    unit: 'm³/min',
+  },
+];
+
+export const dustConfig = reactive({
+  header: ['编号', '位置', '触发', '故障诊断'],
+  data: [
+    ['001', '0m', '是', '正常'],
+    ['002', '2m', '是', '正常'],
+    ['003', '4m', '是', '正常'],
+    ['004', '6m', '是', '正常'],
+    ['005', '8m', '是', '正常'],
+    ['006', '10m', '是', '正常'],
+    ['007', '12m', '是', '正常'],
+  ],
+  index: false,
+  headerBGC: '#3d9dd45d',
+  oddRowBGC: '#009acd10',
+  evenRowBGC: '#009acd05',
+  align: ['center', 'center', 'center', 'center'],
+});
+
+export const gasMonitor = [
+  {
+    title: '甲烷浓度T0 (%)',
+    code: 'T0',
+  },
+  {
+    title: '甲烷浓度T1 (%)',
+    code: 'T1',
+  },
+  {
+    title: '甲烷浓度T2 (%)',
+    code: 'T2',
+  },
+  {
+    title: '二氧化碳浓度 (%)',
+    code: 'CO2',
+  },
+  {
+    title: '瓦斯抽采浓度 (%)',
+    code: 'gasC',
+  },
+  {
+    title: '瓦斯抽采混量 (m³/min)',
+    code: 'gasMixMass',
+  },
+  {
+    title: '瓦斯抽采纯量 (m³/min)',
+    code: 'gasMass',
+  },
+  {
+    title: '残余瓦斯含量 (m³/t)',
+    code: 'gasMass',
+  },
+  {
+    title: '累计抽采量 (m³)',
+    code: 'gasTotalMass',
+  },
+  {
+    title: '风压 (kPa)',
+    code: 'windPressure',
+  },
+];
+
+export const gasParamData = [
+  {
+    title: '走向长度 (m)',
+    code: 'lenH',
+  },
+  {
+    title: '倾向长度 (m)',
+    code: 'lenDip',
+  },
+  {
+    title: '煤层厚度 (m)',
+    code: 'thickness',
+  },
+  {
+    title: '煤层倾角 (°)',
+    code: 'angleDip',
+  },
+  {
+    title: '吸附常数a (cm³/gdaf)',
+    code: 'adsorbA',
+  },
+  {
+    title: '吸附常数b (MPa-l)',
+    code: 'adsorbB',
+  },
+  {
+    title: '水分Mad (%)',
+    code: 'waterMad',
+  },
+  {
+    title: '灰分Ad (%)',
+    code: 'dustAd',
+  },
+  {
+    title: '挥发分Vdaf (%)',
+    code: 'volatilizeAd',
+  },
+  {
+    title: '孔隙率 (m³)',
+    code: 'poreRate',
+  },
+  {
+    title: '真相对密度',
+    code: 'trueDensity',
+  },
+  {
+    title: '视相对密度',
+    code: 'apparentDensity',
+  },
+];
+
+export const currentGasMonitor = [
+  {
+    title: '原始瓦斯含量 (m³/t)',
+    code: 'gasOriginalMass',
+  },
+  {
+    title: '残余瓦斯含量 (m³/t)',
+    code: 'gasRemnantMass',
+  },
+  {
+    title: '残存瓦斯含量 (m³/t)',
+    code: 'gasSurviveMass',
+  },
+  {
+    title: '瓦斯压力 (MPa)',
+    code: 'gasTotalMass',
+  },
+  {
+    title: '煤层厚度 (m)',
+    code: 'currentThickness',
+  },
+  {
+    title: '煤层倾角 (°)',
+    code: 'currentAngleDip',
+  },
+  {
+    title: '地质构造',
+    code: 'geologicStructure',
+  },
+];
+
+export const gasPumpValve = [
+  {
+    title: '1#智能阀门',
+    code: 'valve1Val',
+    inputNum: 0,
+  },
+  {
+    title: '2#智能阀门',
+    code: 'valve2Val',
+    inputNum: 0,
+  },
+  {
+    title: '3#智能阀门',
+    code: 'valve3Val',
+    inputNum: 0,
+  },
+  {
+    title: '4#智能阀门',
+    code: 'valve4Val',
+    inputNum: 0,
+  },
+  {
+    title: '5#智能阀门',
+    code: 'valve5Val',
+    inputNum: 0,
+  },
+];
+
+export const highTensionNum = 3;
+export const lowTensionNum = 1;
+export const gasExtractionUnit = [
+  {
+    title: '负压 (kPa)',
+    code: 'nPressure',
+  },
+  {
+    title: 'CH4 (%)',
+    code: 'CH4  ',
+  },
+  {
+    title: '流量 (m³/min)',
+    code: 'flowRate',
+  },
+  {
+    title: '纯量 (m³/min)',
+    code: 'scalarRate',
+  },
+  // {
+  //   title: '累计抽采量 (m³)',
+  //   code: 'unitTotalMass',
+  // },
+];
+export const gasPump = [
+  {
+    title: '1#抽采泵',
+    code: 'extractionPump1',
+    value: '0',
+    ctrCode: 'gasPump1Open',
+  },
+  {
+    title: '1#抽采泵',
+    code: 'extractionPump1',
+    value: '0',
+    ctrCode: 'gasPump2Open',
+  },
+];
+export const gasPumpCtr = reactive({
+  gasPump1Open: '0',
+  gasPump2Open: '0',
+});
+export const gasUnitDetail = [
+  {
+    title: '开始日期',
+    code: 'startDay',
+    // unit: 'kPa',
+  },
+  {
+    title: '瓦斯储量',
+    code: 'CH4  ',
+    // unit: '%',
+  },
+  {
+    title: '抽采负压',
+    code: 'temperature',
+    // unit: '℃',
+  },
+  {
+    title: '抽采流量',
+    code: 'flowRate',
+    // unit: '万m³',
+  },
+  {
+    title: '气体温度',
+    code: 'scalarRate',
+    // unit: '万m³',
+  },
+  {
+    title: '甲烷浓度',
+    code: 'CH4',
+    // unit: '万m³',
+  },
+  {
+    title: '一氧化碳浓度',
+    code: 'CO',
+    // unit: '万m³',
+  },
+  {
+    title: '累计混量',
+    code: 'unitTotalMass',
+  },
+  {
+    title: '累计纯量',
+    code: 'unit=Mass',
+  },
+];
+
+export function getBezierControlPoint(A = { x: 1, y: 1 }, alpha_degrees = 45, d = 10) {
+  // 转换角度为弧度
+  const alpha_radians = (alpha_degrees * Math.PI) / 180;
+  // 计算 C 点的坐标
+  const C = {
+    x: A.x + d * Math.cos(alpha_radians),
+    y: A.y + d * Math.sin(alpha_radians),
+  };
+  return C;
+}
+
+function getBezierLine() {
+  const curve = new THREE.CubicBezierCurve(new THREE.Vector2(-10, 0), new THREE.Vector2(-5, 15), new THREE.Vector2(20, 15), new THREE.Vector2(10, 0));
+
+  const points = curve.getPoints(50);
+  const geometry = new THREE.BufferGeometry().setFromPoints(points);
+
+  const material = new THREE.LineBasicMaterial({ color: 0xff0000 });
+
+  // Create the final object to add to the scene
+  const curveObject = new THREE.Line(geometry, material);
+  return curveObject;
+}
+
+function getShape() {
+  const A = { x: 0.417, y: -0.24 };
+  const B = { x: 0.702, y: -0.24 };
+  const C = { x: 0.417, y: 0.018 };
+
+  const A1 = { x: 0.948, y: -0.24 };
+  const B1 = { x: 0.678, y: 0.467 };
+}

+ 409 - 0
src/views/vent/gas/gasAssessment/index.vue

@@ -0,0 +1,409 @@
+<template>
+  <CustomHeader
+    :fieldNames="{ label: 'systemname', value: 'id', options: 'children' }"
+    :options="options"
+    @change="getSelectRow"
+    :optionValue="optionValue"
+    >瓦斯抽采达标评判</CustomHeader
+  >
+  <a-spin tip="Loading..." :spinning="loading">
+    <div class="bg" style="">
+      <div id="workFace3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden; z-index: 1; top: 0"> </div>
+      <div
+        id="workFace3DCSS"
+        class="threejs-Object-CSS"
+        style="width: 100%; height: 100%; position: absolute; pointer-events: none; overflow: hidden; z-index: 1; top: 0"
+      >
+      </div>
+    </div>
+
+    <div id="gasUnitBox" class="modal-monitor vent-flex-row" style="display: none">
+      <div v-for="groupNum in monitorDataGroupNum" :key="groupNum" style="margin: 0 5px">
+        <FourBorderBg class="four-border-bg">
+          <div class="title">抽采单元{{ groupNum }}</div>
+          <div class="monitor-item" v-for="(gasUnit, index) in gasUnitDetail" :key="index">
+            <span class="monitor-title">{{ gasUnit.title }}:</span>
+            <span class="monitor-val">
+              <span class="val">
+                {{ selectData[groupNum - 1] && selectData[groupNum - 1][gasUnit.code] ? selectData[groupNum - 1][gasUnit.code] : '-' }}
+              </span>
+            </span>
+          </div>
+        </FourBorderBg>
+      </div>
+    </div>
+    <div class="monitor-container">
+      <div class="lr left-box">
+        <ventBox1>
+          <template #title>
+            <div>工作面瓦斯监控</div>
+          </template>
+          <template #container>
+            <div class="data-group">
+              <div class="data-item" v-for="(item, index) in gasMonitor" :key="index">
+                <div class="title">{{ item.title }}</div>
+                <div class="value">-</div>
+              </div>
+            </div>
+          </template>
+        </ventBox1>
+        <ventBox1 class="vent-margin-t-10">
+          <template #title>
+            <div>当前抽采地质测定 (<span class="param-set"> 参数设定 </span> ) </div>
+          </template>
+          <template #container>
+            <div class="data-group">
+              <div class="data-item" v-for="(item, index) in currentGasMonitor" :key="index">
+                <div class="title">{{ item.title }}</div>
+                <div class="value">-</div>
+              </div>
+            </div>
+          </template>
+        </ventBox1>
+        <ventBox1 class="vent-margin-t-10">
+          <template #title>
+            <div>工作面瓦斯抽采基础属性参数</div>
+          </template>
+          <template #container>
+            <div class="data-group">
+              <div class="data-item" v-for="(item, index) in gasParamData" :key="index">
+                <div class="title">{{ item.title }}</div>
+                <div class="value">-</div>
+              </div>
+            </div>
+          </template>
+        </ventBox1>
+      </div>
+      <div class="lr right-box">
+        <div class="item-box sensor-container">
+          <ventBox1>
+            <template #title>
+              <div>瓦斯抽采监测与控制</div>
+            </template>
+            <template #container>
+              <div class="parameter-title group-parameter-title"
+                ><SvgIcon class="icon" size="42" name="alarm-icon" /><span>抽采泵监测与控制</span></div
+              >
+              <div class="vent-margin-b-10 vent-padding-lr-5">
+                <div class="vent-flex-row-between vent-padding-lr-5 gas-pump-item" v-for="(item, index) in gasPump" :key="index">
+                  <div class="title">{{ item.title }}</div>
+                  <div
+                    ><span
+                      class="signal-round vent-margin-r-8"
+                      :class="{ 'signal-round-gry': item.value == '0', 'signal-round-blue': item.value == '1' }"
+                    ></span
+                    >{{ item.value == '0' ? '关闭' : '开启' }}</div
+                  >
+                  <a-switch
+                    v-model:checked="gasPumpCtr[item.ctrCode]"
+                    checked-children="开启"
+                    un-checked-children="关闭"
+                    checkedValue="1"
+                    unCheckedValue="0"
+                  />
+                </div>
+              </div>
+              <div class="parameter-title group-parameter-title vent-margin-t-15"
+                ><SvgIcon class="icon" size="42" name="alarm-icon" /><span>阀门开度管理</span></div
+              >
+              <div class="input-box">
+                <div v-for="(item, index) in gasPumpValve" :key="index" class="input-item">
+                  <div class="">{{ item.title }}</div>
+                  <div class="value">-</div>
+                  <a-input class="input-value" v-model="item.inputNum" placeholder="" />
+                  <span class="btn btn1">保存</span>
+                </div>
+              </div>
+              <div class="parameter-title group-parameter-title vent-margin-t-15"
+                ><SvgIcon class="icon" size="42" name="alarm-icon" /><span>高负压管路监测与控制</span></div
+              >
+              <div v-for="num in highTensionNum" :key="num">
+                <div class="vent-flex-row-between">
+                  <span class="base-title">抽采单元{{ num }}</span>
+                  <div class="detail">详情</div>
+                </div>
+                <div class="data-group vent-padding-lr-5">
+                  <div class="data-item" v-for="(item, index) in gasExtractionUnit" :key="index">
+                    <div class="title">{{ item.title }}</div>
+                    <div class="value">-</div>
+                  </div>
+                </div>
+              </div>
+              <div class="parameter-title group-parameter-title"
+                ><SvgIcon class="icon" size="42" name="alarm-icon" /><span>低负压管路监测与控制</span></div
+              >
+              <div v-for="num in lowTensionNum" :key="num">
+                <div class="vent-flex-row-between">
+                  <span class="base-title">抽采单元{{ num }}</span>
+                  <span class="detail">详情</span>
+                </div>
+                <div class="data-group vent-padding-lr-5">
+                  <div class="data-item" v-for="(item, index) in gasExtractionUnit" :key="index">
+                    <div class="title">{{ item.title }}</div>
+                    <div class="value">-</div>
+                  </div>
+                </div>
+              </div>
+            </template>
+          </ventBox1>
+        </div>
+      </div>
+    </div>
+  </a-spin>
+</template>
+
+<script setup lang="ts">
+  import FourBorderBg from '/@/components/vent/fourBorderBg.vue';
+  import { onBeforeMount, ref, onMounted, onUnmounted, nextTick, watch, computed } from 'vue';
+  import ventBox1 from '/@/components/vent/ventBox1.vue';
+  import { SvgIcon } from '/@/components/Icon';
+  import CustomHeader from '/@/components/vent/customHeader.vue';
+  import {
+    gasMonitor,
+    gasParamData,
+    currentGasMonitor,
+    gasPumpValve,
+    gasPump,
+    gasExtractionUnit,
+    highTensionNum,
+    lowTensionNum,
+    gasPumpCtr,
+    gasUnitDetail,
+  } from './gasAssessment.data';
+  import { mountedThree, destroy, setModelType, setCss3D } from './threejs/gasAssessmen.threejs';
+  import { useSystemSelect } from '/@/hooks/vent/useSystemSelect';
+
+  const loading = ref(false);
+  // 获取模型类型
+  const changeModalType = (currentData) => {
+    if (currentData) {
+      if (currentData['strsystype'] === 'sys_surface_caimei_modal_1') {
+        // 单进单回
+        modalType = 'workFace1';
+      } else if (currentData['strsystype'] === 'sys_surface_caimei_modal_3') {
+        // 双进单回
+        modalType = 'workFace3';
+      } else if (currentData['strsystype'] === 'sys_surface_caimei_modal_4') {
+        // 双进双回
+        modalType = 'workFace4';
+      } else {
+        modalType = 'workFace3';
+      }
+    } else {
+      modalType = 'workFace3';
+    }
+
+    gasUnitNum.value = 4;
+    setModelType(modalType, gasUnitNum.value, true);
+  };
+
+  const { options, optionValue, deviceType, isRefresh, deviceActive, deviceList, deviceValue, getSelectRow, getSysDataSource, getDeviceList } =
+    useSystemSelect('sys_surface_caimei', changeModalType);
+
+  const gasUnitNum = ref(4);
+  let modalType = 'workFace1';
+
+  // // 监测数据
+  const selectData = ref([]);
+  const monitorDataGroupNum = ref(gasUnitNum);
+  // // https获取监测数据
+  let timer: null | NodeJS.Timeout = null;
+  function getMonitor(flag?) {
+    if (Object.prototype.toString.call(timer) === '[object Null]') {
+      timer = setTimeout(
+        async () => {
+          if (deviceActive.value) {
+            await getDeviceList();
+          }
+          if (timer) {
+            timer = null;
+          }
+          await getMonitor();
+          loading.value = false;
+        },
+        flag ? 0 : 1000
+      );
+    }
+  }
+
+  onBeforeMount(() => {});
+
+  onMounted(async () => {
+    loading.value = true;
+
+    timer = null;
+
+    mountedThree().then(async () => {
+      // gasUnitNum.value = Math.ceil(Math.random() * 10)
+      gasUnitNum.value = 4;
+      loading.value = false;
+      // nextTick(() => {
+      //   setModelType(modalType, gasUnitNum.value, true);
+      // });
+      await getSysDataSource();
+      nextTick(async () => {
+        await getMonitor(true);
+        setCss3D();
+      });
+    });
+  });
+  onUnmounted(() => {
+    if (timer) {
+      clearTimeout(timer);
+      timer = undefined;
+    }
+    destroy();
+  });
+</script>
+
+<style lang="less">
+  @import '/@/design/vent/modal.less';
+
+  .@{ventSpace}-select-dropdown {
+    background: #ffffff !important;
+    border-bottom: 1px solid rgba(236, 236, 236, 0.4);
+    backdrop-filter: blur(10px);
+
+    .@{ventSpace}-select-item-option-selected,
+    .@{ventSpace}-select-item-option-active {
+      background-color: #ffffff33 !important;
+    }
+
+    .@{ventSpace}-select-item:hover {
+      background-color: #ffffff33 !important;
+    }
+  }
+</style>
+
+<style lang="less" scoped>
+  @ventSpace: zxm;
+  @import '/@/design/vent/modal.less';
+  @import '@/views/vent/monitorManager/comment/less/workFace.less';
+  .bg {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    overflow: hidden;
+    position: absolute;
+    pointer-events: auto;
+    z-index: 0;
+  }
+  :deep(.monitor-container) {
+    pointer-events: none;
+  }
+  .modal-monitor {
+    position: absolute;
+    z-index: -1;
+    flex-direction: row-reverse;
+    :deep(.main-container) {
+      background-color: #00000078;
+    }
+    .monitor-item {
+      width: 180px;
+      display: flex;
+      flex-direction: row;
+      width: auto;
+      margin-bottom: 3px;
+      .monitor-title {
+        width: 120px;
+        color: #7af5ff;
+        font-weight: 400;
+        font-size: 13px;
+      }
+      .monitor-val {
+        color: #ffb700;
+        display: flex;
+        width: auto;
+
+        .val {
+          width: 60px;
+          font-size: 13px;
+          text-align: center;
+        }
+
+        .unit {
+          color: #ffffffbb;
+          font-size: 13px;
+        }
+      }
+    }
+    .title {
+      text-align: center;
+    }
+  }
+  .left-box {
+    width: 360px;
+  }
+  .gas-pump-item {
+    padding: 3px 0;
+  }
+
+  .param-set {
+    color: #45d3fd;
+    cursor: pointer;
+    &:hover {
+      color: #38a6c8;
+    }
+  }
+
+  .input-item {
+    margin: 3px 0 !important;
+    .value {
+      width: 80px;
+      text-align: center;
+    }
+  }
+  .data-group {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: space-between;
+    padding-bottom: 8px;
+    .data-item {
+      width: calc(50% - 10px);
+      display: flex;
+      justify-content: space-between;
+      line-height: 24px;
+      background-image: linear-gradient(to right, #39a3ff00, #39a3ff10, #39a3ff02);
+      margin: 4px 0;
+    }
+    .value {
+      color: #00eefffe;
+    }
+    .data-item1 {
+      width: 100%;
+      line-height: 24px;
+      background-image: linear-gradient(to right, #39a3ff00, #39a3ff10, #39a3ff02);
+      margin: 4px 0;
+    }
+  }
+
+  .base-title {
+    line-height: 26px;
+    position: relative;
+    padding-left: 15px;
+    color: #9bf2ff;
+    &::after {
+      content: '';
+      position: absolute;
+      display: block;
+      width: 4px;
+      height: 12px;
+      top: 8px;
+      left: 5px;
+      background: #45d3fd;
+      border-radius: 4px;
+    }
+  }
+
+  .detail {
+    border: 1px solid #9bf2ff88;
+    padding: 0 5px;
+    background-color: #ffffff11;
+    margin-right: 4px;
+    &:hover {
+      background-color: #ffffff05;
+    }
+  }
+</style>

+ 224 - 0
src/views/vent/gas/gasAssessment/threejs/gasAssessmen.threejs.base.ts

@@ -0,0 +1,224 @@
+import * as THREE from 'three';
+import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
+import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass.js';
+import { setModalCenter, setTag3D, gradientColors } from '/@/utils/threejs/util';
+import { CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
+
+// import * as dat from 'dat.gui';
+// const gui = new dat.GUI();
+// gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
+
+class GasAssessmen {
+  model;
+  modelName = 'workFace';
+  group: THREE.Object3D = new THREE.Object3D();
+  planeGroup: THREE.Group = new THREE.Group();
+  bloomComposer: EffectComposer | null = null;
+  finalComposer: EffectComposer | null = null;
+  outlinePass: OutlinePass | null = null;
+  positions: THREE.Vector3[][] = [];
+  bloomLayer = new THREE.Layers();
+  darkMaterial = new THREE.MeshBasicMaterial({ color: 'black', transparent: true, side: THREE.DoubleSide });
+  materials = {};
+  glob = {
+    ENTIRE_SCENE: 0,
+    BLOOM_SCENE: 10,
+    N: 100,
+  };
+  locationTexture: THREE.Texture | null = null;
+  warningLocationTexture: THREE.Texture | null = null;
+  errorLocationTexture: THREE.Texture | null = null;
+  playerStartClickTime1 = new Date().getTime();
+  playerStartClickTime2 = new Date().getTime();
+  planeNum = 0;
+
+  constructor(model) {
+    this.model = model;
+    this.group.name = this.modelName;
+  }
+  addLight() {
+    // const _this = this;
+    const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
+    directionalLight.position.set(-196, 150, 258);
+    this.group.add(directionalLight);
+    directionalLight.target = this.group;
+  }
+
+  render() {
+    this.model.renderer?.render(this.model.scene as THREE.Scene, this.model.camera as THREE.PerspectiveCamera);
+  }
+  // 绘制抽采单元
+  setPlanes = (n, colors = new Array(n).fill(new THREE.Color('rgb(100%, 0%, 0%)'))) => {
+    colors = gradientColors('#00FF2C', '#FF0000', n, 2);
+    this.planeNum = n;
+    const lenScale = 0.77 / n;
+    const planeGeo = new THREE.PlaneGeometry();
+    planeGeo.applyMatrix4(new THREE.Matrix4().makeTranslation(-1, 0, 0));
+    for (let i = 0; i < n; i++) {
+      const material = new THREE.MeshBasicMaterial({ color: colors[i], transparent: true, opacity: 0.6, depthTest: false, depthWrite: false });
+      const plane = new THREE.Mesh(planeGeo, material);
+      plane.name = 'unit' + i;
+      plane.rotation.x = -Math.PI / 2;
+      plane.scale.set(lenScale - 0.001, 0.375, 1.0);
+      plane.position.set(0.282 - lenScale * (i - 0.5), 0.015, 0.142);
+      this.planeGroup.add(plane);
+    }
+  };
+
+  // 清除抽采单元绘制面
+  clearPlanes = () => {
+    for (let i = 0; i < this.planeNum; i++) {
+      const plane = this.planeGroup.getObjectByName(`unit${i}`);
+      const label = this.planeGroup.getObjectByName(`planeText${i}`);
+      if (plane) this.planeGroup.remove(plane);
+      if (label) this.planeGroup.remove(label);
+    }
+  };
+  // 抽采单元内容显示
+  setCss3D = () => {
+    const obj = this.group.getObjectByName(`unitText`);
+    if (!obj) {
+      const element = document.getElementById(`gasUnitBox`) as HTMLElement;
+      if (element) {
+        const gasUnitCSS3D = new CSS3DObject(element);
+        gasUnitCSS3D.name = `unitText`;
+        gasUnitCSS3D.scale.set(0.0009, 0.0009, 0.0009);
+        gasUnitCSS3D.position.set(-0.1, 0.11, 0.05);
+        gasUnitCSS3D.lookAt(-0.1, 0.5, 1);
+        this.planeGroup.add(gasUnitCSS3D);
+      }
+    }
+    for (let i = 0; i < this.planeNum; i++) {
+      const lenScale = 0.77 / this.planeNum;
+      const label = setTag3D(`抽采单元${i + 1}`, 'gas_unit_text');
+      label.scale.set(0.0018, 0.0018, 1); //根据相机渲染范围控制HTML 3D标签尺寸
+      label.position.set(0.282 - lenScale * (i + 0.5), 0.015, 0.142);
+      label.name = 'planeText' + i;
+      this.planeGroup.add(label);
+    }
+  };
+  // 显示或隐藏抽采单元显示内容
+  changeCss3D = (isHide) => {
+    for (let i = 0; i < this.planeNum; i++) {
+      const obj = this.group.getObjectByName(`unitText${i}`);
+      if (obj) {
+        obj.visible = isHide;
+      }
+    }
+  };
+  // 清除抽采单元显示内容
+  clearCss3D = () => {
+    const obj = this.group.getObjectByName(`unitText`);
+    if (obj) this.group.remove(obj);
+    const element = document.getElementById(`gasUnitBox`) as HTMLElement;
+    if (element) {
+      element.remove();
+    }
+    for (let i = 0; i < this.planeNum; i++) {
+      const label = this.planeGroup.getObjectByName(`planeText${i}`);
+      if (label) this.planeGroup.remove(label);
+    }
+  };
+
+  getPositions(num = 40) {
+    const curve1 = new THREE.LineCurve3(new THREE.Vector3(-595.2, 0.046, -2.863), new THREE.Vector3(595.2, 0.046, -2.863)); // 前
+    const curve2 = new THREE.LineCurve3(new THREE.Vector3(-595.065, 0.014, 1.696), new THREE.Vector3(595.048, 0.014, 1.696)); // 中
+    const curve3 = new THREE.LineCurve3(new THREE.Vector3(0.0, 0.0, 190.611), new THREE.Vector3(0.0, 0.0, -190.611)); // 后‘
+
+    const len1 = curve1.getLength();
+    const len2 = curve2.getLength();
+    const len3 = curve3.getLength();
+
+    const unit = (len1 + len2 + len3) / num;
+    const num1 = Math.floor(len1 / unit);
+    const num2 = Math.floor(len2 / unit);
+    const num3 = Math.floor(len3 / unit);
+
+    const points1 = curve1.getPoints(num1);
+    const points2 = curve2.getPoints(num2);
+    const points3 = curve3.getPoints(num3);
+
+    this.positions = [points1, points2, points3];
+  }
+
+  darkenNonBloomed(obj) {
+    if (obj.isMesh && this.bloomLayer.test(obj.layers) === false) {
+      const opacity = obj.material.opacity;
+      this.materials[obj.uuid] = obj.material;
+      obj.material = this.darkMaterial.clone();
+      obj.material.opacity = opacity;
+    }
+  }
+
+  restoreMaterial(obj) {
+    if (this.materials[obj.uuid]) {
+      obj.material = this.materials[obj.uuid];
+      delete this.materials[obj.uuid];
+    }
+  }
+
+  /* 点击 */
+  mousedownModel(rayCaster: THREE.Raycaster) {
+    this.render();
+  }
+
+  mouseUpModel() {
+    //
+  }
+
+  setModalType(modalType) {
+    const workFace2 = this.group.getObjectByName('workFace2-1');
+    const workFace1 = this.group.getObjectByName('workFace1-1');
+    if (workFace2 && workFace1) {
+      if (modalType === 'workFace1') {
+        // 单进单回
+        workFace2.visible = false;
+        // workFace3.visible = false;
+        workFace1.visible = true;
+        workFace1.add(this.planeGroup);
+        this.planeGroup.visible = false;
+        this.planeGroup.position.set(-0.35, 0.14, -0.21);
+      } else if (modalType === 'workFace3') {
+        // 双进单回
+        workFace1.visible = false;
+        // workFace3.visible = false;
+        workFace2.visible = true;
+        workFace2.add(this.planeGroup);
+        this.planeGroup.visible = false;
+        this.planeGroup.position.set(-0.35, 0.14, -0.21);
+      }
+      setModalCenter(this.group);
+    }
+  }
+
+  mountedThree() {
+    return new Promise(async (resolve) => {
+      this.model.renderer.sortObjects = true;
+      this.model.orbitControls.update();
+      this.model.setGLTFModel(['workFace2-1', 'workFace1-1'], this.group).then(async () => {
+        this.group.children.forEach((object: THREE.Object3D) => {
+          if (object.name.startsWith('workFace')) {
+            setModalCenter(object);
+          }
+        });
+        this.group.name = this.modelName;
+        this.group.scale.set(2.5, 2.5, 2.5);
+
+        this.getPositions(this.glob.N);
+        this.addLight();
+
+        resolve(null);
+      });
+    });
+  }
+
+  destroy() {
+    this.model.clearGroup(this.group);
+    this.model = null;
+    this.group = null;
+    this.bloomComposer?.dispose();
+    this.finalComposer?.dispose();
+  }
+}
+
+export default GasAssessmen;

+ 128 - 0
src/views/vent/gas/gasAssessment/threejs/gasAssessmen.threejs.ts

@@ -0,0 +1,128 @@
+import * as THREE from 'three';
+import UseThree from '@/utils/threejs/useThree';
+import GasAssessmen from './gasAssessmen.threejs.base';
+import { animateCamera } from '/@/utils/threejs/util';
+import useEvent from '@/utils/threejs/useEvent';
+
+// 模型对象、 文字对象
+let model,
+  workFaceObj: GasAssessmen | undefined,
+  group,
+  fiberType = 'workFace'; // workerFaceFiber
+
+const { mouseDownFn, mousemoveFn, mouseUpFn } = useEvent();
+
+// 鼠标点击、松开事件
+const mouseEvent = (event) => {
+  if (event.button == 0 && group) {
+    model.canvasContainer?.addEventListener('mousemove', mousemove);
+    const groud = group.getObjectByName('groud');
+    const intakewind = group.getObjectByName('workFace-jin');
+    const returnwind = group.getObjectByName('workFace-hui');
+    mouseDownFn(model, [groud, intakewind, returnwind], event);
+    console.log('摄像头控制信息', model.orbitControls, model.camera);
+  }
+};
+
+const mouseUp = () => {
+  if (!model) return;
+  model.canvasContainer?.removeEventListener('mousemove', mousemove);
+  mouseUpFn(model, 0.2);
+  workFaceObj?.mouseUpModel.call(workFaceObj);
+};
+
+const mousemove = () => {
+  mousemoveFn();
+};
+
+const addMouseEvent = () => {
+  // 定义鼠标点击事件
+  model.canvasContainer?.addEventListener('mousedown', mouseEvent.bind(null));
+  model.canvasContainer?.addEventListener('pointerup', mouseUp);
+};
+
+const render = () => {
+  if (model && model.isRender) {
+    model.animationId = requestAnimationFrame(render);
+    model.css3dRender?.render(model.scene as THREE.Scene, model.camera as THREE.PerspectiveCamera);
+    model.stats?.update();
+    model.orbitControls?.update();
+    model.camera?.updateMatrixWorld();
+    workFaceObj?.render();
+  }
+};
+
+export const setCss3D = () => {
+  workFaceObj?.setCss3D();
+};
+export const clearCss3D = () => {
+  workFaceObj?.clearCss3D();
+};
+
+// 切换风窗类型
+export const setModelType = (type, n = Math.ceil(Math.random() * 4), isShowPlane) => {
+  fiberType = type;
+  return new Promise((resolve) => {
+    if (workFaceObj) {
+      workFaceObj.clearPlanes();
+      group = workFaceObj.group;
+
+      workFaceObj.setModalType(type);
+      workFaceObj?.setPlanes(n);
+      showOrHideGasPlane(isShowPlane);
+      const oldControlsPosition = { x: -0.022168, y: 0.074739, z: 0.009219 };
+      const oldCameraPosition = { x: 0.02608027449507061, y: 10.420592466573055, z: 9.726605606617316 };
+      const newCameraPosition = { x: -0.33026163847606776, y: 1.1838248418373518, z: 2.110543112500774 };
+      const newControlsPosition = { x: -0.340818043813578, y: 0.08681864035231544, z: -0.015240539361923166 };
+
+      if (model.scene.getObjectByName('workFace')) {
+        model.camera.position.set(oldCameraPosition.x, oldCameraPosition.y, oldCameraPosition.z + 20);
+        model.orbitControls.target.set(oldControlsPosition.x, oldControlsPosition.y, oldControlsPosition.z);
+      }
+      setTimeout(async () => {
+        resolve(null);
+        if (!model.scene.getObjectByName('workFace')) {
+          model.scene.add(workFaceObj?.group);
+        }
+
+        await animateCamera(oldCameraPosition, oldControlsPosition, newCameraPosition, newControlsPosition, model, 0.8);
+      }, 600);
+    }
+  });
+};
+
+export const showOrHideGasPlane = (isShowPlane) => {
+  if (workFaceObj) {
+    if (isShowPlane) {
+      workFaceObj.planeGroup.visible = true;
+    } else {
+      workFaceObj.planeGroup.visible = false;
+    }
+  }
+};
+
+export const mountedThree = () => {
+  return new Promise(async (resolve) => {
+    model = new UseThree('#workFace3D', '#workFace3DCSS');
+    model.setEnvMap('test1');
+    model.renderer.toneMappingExposure = 1.0;
+    // model.renderer = 1;
+    workFaceObj = new GasAssessmen(model);
+    await workFaceObj.mountedThree();
+
+    addMouseEvent();
+    render();
+    resolve(null);
+  });
+};
+
+export const destroy = () => {
+  if (model) {
+    model.isRender = false;
+    workFaceObj?.destroy();
+    workFaceObj = undefined;
+    model.destroy();
+    model = null;
+    group = null;
+  }
+};

+ 10 - 0
src/views/vent/gas/gasHome/gasHome.api.ts

@@ -0,0 +1,10 @@
+import { defHttp } from '/@/utils/http/axios';
+
+enum Api {
+  list = '/monitor/system',
+}
+/**
+ * 列表接口
+ * @param params
+ */
+export const list = (params) => defHttp.post({ url: Api.list, params });

+ 16 - 7
src/views/vent/gas/gasHome/index.vue

@@ -1,22 +1,31 @@
 <!-- eslint-disable vue/multi-word-component-names -->
 <template>
   <div class="scene-box">
-    <customHeader :options="options" @change="getSelectRow" :optionValue="optionValue"> 瓦斯抽采综合管控系统 </customHeader>
     <!-- <CustomHeader class="w-1710px ml-100px mt-20px" :badges="headerBadges" /> -->
-    <template v-if="activeKey === 'gasHome'">
-      <CustomBadges class="w-1710px ml-100px mt-50px" :badges="headerBadges" />
-      <GasMonitor :device="deviceValue" />
+    <customHeader :options="options" @change="getSelectRow" :optionValue="optionValue"> 瓦斯抽采综合管控系统 </customHeader>
+    <CustomBadges class="w-1710px ml-100px mt-50px" :badges="headerBadges" />
+    <GasMonitor :device="deviceValue" />
+    <!-- <template v-if="activeKey === 'gasHome'">
+      
+    </template>
+    <template v-if="activeKey === 'gasPump'">
+      <gasPumpMonitor />
+    </template>
+    <template v-if="activeKey === 'gasStandard'">
+      <GasAssessmentHome />
     </template>
-    <BottomMenu :navList="navList" @change="changeActive" />
+    <BottomMenu :navList="navList" @change="changeActive" /> -->
   </div>
 </template>
 <script lang="ts" setup>
   import { ref, onMounted } from 'vue';
   import CustomHeader from '/@/components/vent/customHeader.vue';
   import CustomBadges from './components/customHeader.vue';
-  import BottomMenu from '/@/views/vent/comment/components/bottomMenu.vue';
+  // import GasAssessmentHome from './components/gasAssessmentHome.vue';
+  // import gasPumpMonitor from '../gasPumpMonitor/index.vue';
+  // import BottomMenu from '/@/views/vent/comment/components/bottomMenu.vue';
   import { useSystemSelect } from '/@/hooks/vent/useSystemSelect';
-  import { navList } from './gasHome.data';
+  // import { navList } from './gasHome.data';
   import GasMonitor from './components/gasMonitor.vue';
 
   const activeKey = ref('gasHome');

+ 32 - 4
src/views/vent/gas/gasPumpMonitor/index.vue

@@ -1,5 +1,13 @@
 <!-- eslint-disable vue/multi-word-component-names -->
 <template>
+  <div
+    v-show="activeKey == 'deviceMonitor'"
+    class="bg"
+    style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; overflow: hidden"
+  >
+    <div id="gas3DCSS" style="width: 100%; height: 100%; top: 0; left: 0; position: absolute; overflow: hidden"> </div>
+    <div id="gasPump3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden"> </div>
+  </div>
   <div class="scene-box">
     <customHeader :fieldNames="calcFieldNames" :options="options" @change="getSelectRow" :optionValue="optionValue">瓦斯抽采泵站监测</customHeader>
     <div class="center-container">
@@ -35,7 +43,7 @@
   </div>
 </template>
 <script lang="ts" setup>
-  import { ref, onMounted, computed } from 'vue';
+  import { ref, onMounted, computed, onUnmounted } from 'vue';
   import customHeader from '/@/components/vent/customHeader.vue';
   import { useSystemSelect } from '/@/hooks/vent/useSystemSelect';
   import BottomMenu from '/@/views/vent/comment/components/bottomMenu.vue';
@@ -43,11 +51,23 @@
   import { navList } from './gasPumpMonitor.data';
   import GasPumpMonitor from './components/monitor.vue';
   import GasMonitorChart from './components/monitorChart.vue';
+  import { mountedThree, destroy, setModelType } from './threejs/gasPump.threejs';
 
   const activeKey = ref('deviceMonitor');
-
+  const changeModalType = (currentData) => {
+    if (currentData) {
+      if (currentData.deviceType == 'pump_over') {
+        setModelType('gasPump');
+      } else if (currentData.deviceType.startsWith('pump_under')) {
+        setModelType('gasPumpUnder');
+      }
+    } else {
+      setModelType('gasPump');
+    }
+    setModelType('gasPump');
+  };
   const { options, optionValue, deviceType, isRefresh, deviceActive, deviceList, deviceValue, getSelectRow, getSysDataSource, deviceChange } =
-    useSystemSelect('sys_gasstation');
+    useSystemSelect('pump', changeModalType);
 
   function changeActive(activeValue) {
     activeKey.value = activeValue;
@@ -62,7 +82,15 @@
   });
 
   onMounted(() => {
-    getSysDataSource();
+    mountedThree().then(async () => {
+      await getSysDataSource();
+      // await getDeviceList();
+      getSelectRow(optionValue.value);
+    });
+  });
+
+  onUnmounted(() => {
+    destroy();
   });
 </script>
 

+ 51 - 0
src/views/vent/gas/gasPumpMonitor/threejs/gasPump.threejs.over.ts

@@ -0,0 +1,51 @@
+import * as THREE from 'three';
+
+// import * as dat from 'dat.gui';
+// const gui = new dat.GUI();
+// gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
+
+class gasPumpBase {
+  model;
+  modelName = 'gasPump';
+  group: THREE.Object3D | null = null;
+
+  constructor(model) {
+    this.model = model;
+  }
+
+  addLight() {
+    const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
+    directionalLight.position.set(-217, 500, -347);
+    this.group?.add(directionalLight);
+    directionalLight.target = this.group as THREE.Object3D;
+
+    // gui.add(directionalLight.position, 'x', -500, 800);
+    // gui.add(directionalLight.position, 'y', -500, 800);
+    // gui.add(directionalLight.position, 'z', -500, 800);
+
+    // gui.add(pointLight2.position, 'x', -300, 300);
+    // gui.add(pointLight2.position, 'y', -300, 300);
+    // gui.add(pointLight2.position, 'z', -300, 300);
+  }
+
+  mountedThree() {
+    return new Promise((resolve) => {
+      this.model.setGLTFModel([this.modelName]).then((gltf) => {
+        this.group = gltf[0];
+        if (this.group) {
+          // this.group?.scale.set(0.1, 0.1, 0.1);
+          // this.group.position.y += 40;
+          resolve(null);
+          this.addLight();
+        }
+      });
+    });
+  }
+
+  destroy() {
+    this.model.clearGroup(this.group);
+    this.model = null;
+    this.group = null;
+  }
+}
+export default gasPumpBase;

+ 125 - 0
src/views/vent/gas/gasPumpMonitor/threejs/gasPump.threejs.ts

@@ -0,0 +1,125 @@
+import * as THREE from 'three';
+import UseThree from '@/utils/threejs/useThree';
+import gasPumpBase from './gasPump.threejs.over';
+import gasPumpUnder from './gasPump.threejs.under';
+import { animateCamera, setModalCenter } from '/@/utils/threejs/util';
+import useEvent from '@/utils/threejs/useEvent';
+
+// 模型对象、 文字对象
+let model: UseThree | undefined,
+  gasPumpBaseObj: gasPumpBase | undefined,
+  gasPumpUnderObj: gasPumpUnder | undefined,
+  group: THREE.Object3D | undefined,
+  gasPumpType = 'gasPump';
+
+const { mouseDownFn } = useEvent();
+
+// 鼠标点击事件
+const mouseEvent = (event) => {
+  if (event.button == 0) {
+    mouseDownFn(<UseThree>model, <THREE.Object3D>group, event, (intersects) => {
+      if (gasPumpType === 'gasPump') {
+        // gasPumpBaseObj.mousedownModel.call(gasPumpBaseObj, intersects);
+      }
+    });
+    console.log('摄像头控制信息', model?.orbitControls, model?.camera);
+  }
+};
+
+const addMouseEvent = () => {
+  // 定义鼠标点击事件
+  model?.canvasContainer?.addEventListener('mousedown', mouseEvent.bind(null));
+};
+
+const render = () => {
+  if (model && model.isRender) {
+    model.animationId = requestAnimationFrame(render);
+    model.css3dRender?.render(model.scene as THREE.Scene, model.camera as THREE.PerspectiveCamera);
+    model.stats?.update();
+  }
+};
+
+export const addgasPumpText = (selectData) => {
+  if (gasPumpType === 'gasPump') {
+    // return gasPumpBaseObj.addgasPumpText.call(gasPumpBaseObj, selectData);
+  }
+};
+
+// 切换模型类型
+export const setModelType = (type) => {
+  gasPumpType = type;
+  return new Promise((resolve) => {
+    if (gasPumpType === 'gasPump' && gasPumpBaseObj && gasPumpBaseObj.group) {
+      if (model?.scene?.getObjectByName('gasPumpUnder') && gasPumpUnderObj && gasPumpUnderObj.group) {
+        model.scene.remove(gasPumpUnderObj.group);
+      }
+      group = gasPumpBaseObj.group;
+      const oldCameraPosition = { x: 15.9074, y: 5.40264, z: 27.12551 };
+      setTimeout(async () => {
+        model?.scene?.add(group);
+        await animateCamera(
+          oldCameraPosition,
+          { x: 0.544, y: 0.3335, z: 0.29222 },
+          { x: 0.023152871520227228, y: 1.7620626479822787, z: 4.392848946180296 },
+          { x: 0.045006601924383244, y: -0.005265718129095471, z: 0.49085310514161723 },
+          model,
+          0.6
+        );
+      }, 300);
+
+      resolve(null);
+    }
+    if (gasPumpType === 'gasPumpUnder' && gasPumpUnderObj && gasPumpUnderObj.group) {
+      if (model?.scene?.getObjectByName('gasPump') && gasPumpBaseObj && gasPumpBaseObj.group) {
+        model.scene.remove(gasPumpBaseObj.group);
+      }
+      gasPumpUnderObj.addCssText();
+      group = gasPumpUnderObj.group;
+      const oldCameraPosition = { x: 15.9074, y: 5.40264, z: 27.12551 };
+      setTimeout(async () => {
+        model?.scene?.add(group);
+        await animateCamera(
+          oldCameraPosition,
+          { x: 0.544, y: 0.3335, z: 0.29222 },
+          { x: -0.18283701989485915, y: 1.5585182112304712, z: 6.23432935897143 },
+          { x: -0.15497121991536436, y: 0.3354979232986092, z: -0.10561004136342216 },
+          model,
+          0.6
+        );
+      }, 300);
+
+      resolve(null);
+    }
+  });
+};
+
+export const mountedThree = () => {
+  return new Promise(async (resolve) => {
+    model = new UseThree('#gasPump3D', '#gas3DCSS');
+    model.setEnvMap('test2');
+    model.renderer.toneMappingExposure = 1.0;
+    // model.renderer.outputEncoding = THREE.sRGBEncoding;
+    gasPumpBaseObj = new gasPumpBase(model);
+    await gasPumpBaseObj.mountedThree();
+
+    gasPumpUnderObj = new gasPumpUnder(model);
+    await gasPumpUnderObj.mountedThree();
+
+    addMouseEvent();
+    // render();
+    model.animate();
+    resolve(null);
+  });
+};
+
+export const destroy = () => {
+  if (model) {
+    model.isRender = false;
+    console.log('场景销毁前信息----------->', model.renderer?.info);
+    gasPumpBaseObj?.destroy();
+    gasPumpBaseObj = undefined;
+    group = undefined;
+    model.destroy();
+    model = undefined;
+  }
+};

+ 78 - 0
src/views/vent/gas/gasPumpMonitor/threejs/gasPump.threejs.under.ts

@@ -0,0 +1,78 @@
+import * as THREE from 'three';
+import { CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
+// import * as dat from 'dat.gui';
+// const gui = new dat.GUI();
+// gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
+
+class gasPumpUnder {
+  model;
+  modelName = 'gasPumpUnder';
+  group: THREE.Object3D | null = null;
+
+  constructor(model) {
+    this.model = model;
+  }
+
+  addLight() {
+    const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
+    directionalLight.position.set(-48, 107, 36);
+    this.group?.add(directionalLight);
+    directionalLight.target = this.group as THREE.Object3D;
+
+    // gui.add(directionalLight.position, 'x', -500, 800);
+    // gui.add(directionalLight.position, 'y', -500, 800);
+    // gui.add(directionalLight.position, 'z', -500, 800);
+
+    // const pointLight2 = new THREE.PointLight(0xffffff, 2, 500);
+    // pointLight2.position.set(-113, 29, 10);
+    // // light2.castShadow = true
+    // pointLight2.shadow.bias = -0.05;
+    // this.group?.add(pointLight2);
+
+    // gui.add(pointLight2.position, 'x', -500, 500);
+    // gui.add(pointLight2.position, 'y', -500, 500);
+    // gui.add(pointLight2.position, 'z', -500, 500);
+  }
+
+  addCssText = () => {
+    if (!this.group) return;
+    if (!this.group.getObjectByName('text1')) {
+      const element = document.getElementById('FlowSensor') as HTMLElement;
+      if (element) {
+        const parentElement = document.getElementById('gas3DCSS') as HTMLElement;
+        parentElement.appendChild(element);
+        const fanLocalCSS3D = new CSS3DObject(element);
+        fanLocalCSS3D.name = 'text1';
+        fanLocalCSS3D.scale.set(0.007, 0.007, 0.007);
+        fanLocalCSS3D.position.set(0, 1.6, 0);
+        this.group.add(fanLocalCSS3D);
+      }
+    }
+  };
+
+  clearCssText = () => {
+    const fanLocalCSS3D = this.group?.getObjectByName('text1') as THREE.Object3D;
+    this.group?.remove(fanLocalCSS3D);
+  };
+
+  mountedThree() {
+    return new Promise((resolve) => {
+      this.model.setGLTFModel([this.modelName]).then((gltf) => {
+        this.group = gltf[0];
+        if (this.group) {
+          // this.group?.scale.set(0.1, 0.1, 0.1);
+          // this.group.position.y += 40;
+          resolve(null);
+          this.addLight();
+        }
+      });
+    });
+  }
+
+  destroy() {
+    this.model.clearGroup(this.group);
+    this.model = null;
+    this.group = null;
+  }
+}
+export default gasPumpUnder;

+ 8 - 8
src/views/vent/home/billboard/billboard.data.ts

@@ -390,19 +390,19 @@ export const VENTILATION_STATUS_TREE_CONFIG = {
       suffix: '',
     },
     {
-      prefix: '1号风机风量:',
-      prop: 'Fan1m3',
+      prefix: '风机风量:',
+      prop: 'flow_merge',
       suffix: '(m³/min)',
     },
     {
-      prefix: '2号风机风量:',
-      prop: 'Fan2m3',
-      suffix: '(m³/min)',
+      prefix: '风机风压',
+      prop: 'fy_merge',
+      suffix: '(Pa)',
     },
     {
-      prefix: '频率:',
-      prop: 'FanFreqHz',
-      suffix: 'Hz',
+      prefix: '风机漏风率',
+      prop: 'leakage',
+      suffix: '%',
     },
     {
       prefix: '三区阻力分布:',

+ 163 - 80
src/views/vent/home/clique/components/dialog-modal.vue

@@ -22,8 +22,9 @@
     </div>
     <div class="modal-card1">
       <div class="left-modal">
-        <div class="value-m">{{ valueM }}</div>
-        <div class="label-m">{{ labelM }}</div>
+        <div class="value-m">{{ valueM }}Pa</div>
+        <!-- <div class="label-m">{{ labelM }}</div> -->
+        <div class="label-m">关键阻力关键阻力关键阻力关键阻力关键阻力</div>
       </div>
       <div class="right-modal">
         <div class="modal-zl" v-for="(item, index) in zlList" :key="index">
@@ -51,6 +52,13 @@
         <span class="dw">%</span>
       </div>
     </div>
+    <div class="modal-card3">
+      <div class="modal-wind" v-for="(item, index) in windLfList1" :key="index">
+        <span class="text">{{ item.label }}</span>
+        <span class="num">{{ item.value }}</span>
+        <span class="dw">%</span>
+      </div>
+    </div>
     <!-- <div class="modal-card3">
       <div class="warn-left">
         <div class="vent-l">
@@ -117,8 +125,12 @@
   ]);
 
   let windLfList = reactive([
+    { label: '总回风量', value: '0' },
+    { label: '总进风量', value: '0' },
+  ]);
+  let windLfList1 = reactive([
+    { label: '总计划风量', value: '0' },
     { label: '有效风量率', value: '0' },
-    { label: '矿井漏风率', value: '0' },
   ]);
 
   // let vent = reactive({
@@ -173,7 +185,7 @@
   // 根据新的数据更新依赖数据,核心方法
   function update(newC) {
     if (JSON.stringify(newC) != '{}') {
-      modalCard[0]['value'] = newC.sys_data.totallength || 0;
+      modalCard[0]['value'] = newC.sys_data.flength || 0;
       modalCard[1]['value'] = newC.sys_data.personCount || 0;
       modalCard[2]['value'] = newC.sys_data.vehicleCount || 0;
 
@@ -189,9 +201,10 @@
       zlList[1]['percent'] = ((zlList[1]['value'] / valueM.value) * 100).toFixed(2);
       zlList[2]['percent'] = ((zlList[2]['value'] / valueM.value) * 100).toFixed(2);
 
-      windLfList[0].value = newC.sys_data.useM3Perent || '0';
-      const base = parseFloat(newC.sys_data.zongfengliang);
-      windLfList[1].value = (((base - parseFloat(newC.sys_data.zongjinfeng)) / base) * 100).toFixed(2);
+      windLfList[0].value = newC.sys_data.totalRetM3 || '0';
+      windLfList[1].value = newC.sys_data.totalIntM3 || '0';
+      windLfList1[0].value = newC.sys_data.totalPlanM3 || '0';
+      windLfList1[1].value = newC.sys_data.useM3Perent || '0';
 
       // vent.value = newC.majorpath_data[majorIndex].majorpath.drag_total;
       // gas.value = newC.majorpath_data[majorIndex].majorpath.m3_total;
@@ -229,7 +242,7 @@
   .dialogModal {
     position: relative;
     width: 568px;
-    height: 340px;
+    height: 400px;
     background: url('/@/assets/images/company/area-card2.png') no-repeat;
     background-size: 100% 100%;
     pointer-events: none;
@@ -331,26 +344,26 @@
 
       .left-modal {
         position: relative;
-        width: 95px;
+        width: 185px;
         height: 95px;
         background: url('../../../../../assets/images/company/zfx.png') no-repeat center;
         background-size: 100% 100%;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
 
         .value-m {
-          position: absolute;
-          top: 50%;
-          left: 50%;
-          transform: translate(-50%, -50%);
           font-family: 'douyuFont';
           font-size: 14px;
           color: #3df6ff;
+          margin-top: 5px;
         }
 
         .label-m {
-          position: absolute;
-          bottom: 2px;
-          width: 100%;
-          font-size: 10px;
+          padding: 0 2px;
+          margin-top: 5px;
+          font-size: 14px;
           text-align: center;
           color: #fff;
         }
@@ -474,6 +487,7 @@
       margin: 10px 0;
       padding: 0 10px;
       display: flex;
+      flex-wrap: wrap;
       justify-content: space-between;
       align-items: center;
       box-sizing: border-box;
@@ -534,96 +548,165 @@
 
     .modal-card3 {
       position: absolute;
-      top: 302px;
+      top: 310px;
       left: 50%;
       transform: translate(-50%, 0);
-      height: 110px;
+      height: 60px;
       width: 90%;
-      padding: 0px 10px;
-      box-sizing: border-box;
+      margin: 10px 0;
+      padding: 0 10px;
       display: flex;
+      flex-wrap: wrap;
       justify-content: space-between;
       align-items: center;
+      box-sizing: border-box;
       background: url('../../../../../assets/images/company/area3.png') no-repeat center;
       background-size: 100% 100%;
 
-      .warn-left {
+      .modal-wind {
         position: relative;
-        width: 206px;
-        height: 85px;
-        background: url('../../../../../assets/images/company/warn-left.png') no-repeat center;
+        width: 50%;
+        height: 34px;
 
-        .vent-l {
+        .text {
           position: absolute;
-          top: 10px;
-          left: 0;
-          width: 80%;
-          display: flex;
-          justify-content: space-around;
+          top: 50%;
+          left: 40px;
+          transform: translate(0, -50%);
+          color: #fff;
+          font-size: 14px;
         }
 
-        .gas-l {
+        .num {
           position: absolute;
-          top: 52px;
-          left: 0;
-          width: 80%;
-          display: flex;
-          justify-content: space-around;
+          top: 50%;
+          right: 45px;
+          transform: translate(0, -50%);
+          color: #fff;
+          font-family: 'douyuFont';
+          font-size: 14px;
         }
-      }
 
-      .warn-c {
-        position: relative;
-        width: 90px;
-        height: 92px;
-        background: url('../../../../../assets/images/company/warn-center.png') no-repeat center;
-        .warn-icon {
+        .dw {
           position: absolute;
-          left: 50%;
           top: 50%;
-          transform: translate(-50%, -85%);
-          width: 50px;
-          height: 50px;
-          background: url('../../../../../assets/images/company/icon1.png') no-repeat center;
+          right: 12px;
+          transform: translate(0, -50%);
+          color: #fff;
         }
-      }
-
-      .warn-right {
-        position: relative;
-        width: 206px;
-        height: 85px;
-        background: url('../../../../../assets/images/company/warn-right.png') no-repeat center;
 
-        .fire-r {
-          position: absolute;
-          top: 10px;
-          right: 0;
-          width: 80%;
-          display: flex;
-          justify-content: space-around;
+        &:nth-child(1) {
+          background: url('../../../../../assets/images/company/green.png') no-repeat center;
+          background-size: 100% 100%;
         }
 
-        .dust-r {
-          position: absolute;
-          top: 52px;
-          right: 0;
-          width: 80%;
-          display: flex;
-          justify-content: space-around;
+        &:nth-child(2) {
+          background: url('../../../../../assets/images/company/purple.png') no-repeat center;
+          background-size: 100% 100%;
         }
-      }
 
-      .warn-label {
-        font-family: 'douyuFont';
-        font-size: 14px;
-        color: #31fbcc;
-        line-height: 27px;
-      }
+        &:nth-child(1) .num {
+          color: #31fbcc;
+        }
 
-      .warn-value {
-        color: #fff;
-        font-size: 14px;
+        &:nth-child(2) .num {
+          color: #97a3fa;
+        }
       }
     }
+
+    // .modal-card3 {
+    //   position: absolute;
+    //   top: 302px;
+    //   left: 50%;
+    //   transform: translate(-50%, 0);
+    //   height: 110px;
+    //   width: 90%;
+    //   padding: 0px 10px;
+    //   box-sizing: border-box;
+    //   display: flex;
+    //   justify-content: space-between;
+    //   align-items: center;
+    //   background: url('../../../../../assets/images/company/area3.png') no-repeat center;
+    //   background-size: 100% 100%;
+
+    //   .warn-left {
+    //     position: relative;
+    //     width: 206px;
+    //     height: 85px;
+    //     background: url('../../../../../assets/images/company/warn-left.png') no-repeat center;
+
+    //     .vent-l {
+    //       position: absolute;
+    //       top: 10px;
+    //       left: 0;
+    //       width: 80%;
+    //       display: flex;
+    //       justify-content: space-around;
+    //     }
+
+    //     .gas-l {
+    //       position: absolute;
+    //       top: 52px;
+    //       left: 0;
+    //       width: 80%;
+    //       display: flex;
+    //       justify-content: space-around;
+    //     }
+    //   }
+
+    //   .warn-c {
+    //     position: relative;
+    //     width: 90px;
+    //     height: 92px;
+    //     background: url('../../../../../assets/images/company/warn-center.png') no-repeat center;
+    //     .warn-icon {
+    //       position: absolute;
+    //       left: 50%;
+    //       top: 50%;
+    //       transform: translate(-50%, -85%);
+    //       width: 50px;
+    //       height: 50px;
+    //       background: url('../../../../../assets/images/company/icon1.png') no-repeat center;
+    //     }
+    //   }
+
+    //   .warn-right {
+    //     position: relative;
+    //     width: 206px;
+    //     height: 85px;
+    //     background: url('../../../../../assets/images/company/warn-right.png') no-repeat center;
+
+    //     .fire-r {
+    //       position: absolute;
+    //       top: 10px;
+    //       right: 0;
+    //       width: 80%;
+    //       display: flex;
+    //       justify-content: space-around;
+    //     }
+
+    //     .dust-r {
+    //       position: absolute;
+    //       top: 52px;
+    //       right: 0;
+    //       width: 80%;
+    //       display: flex;
+    //       justify-content: space-around;
+    //     }
+    //   }
+
+    //   .warn-label {
+    //     font-family: 'douyuFont';
+    //     font-size: 14px;
+    //     color: #31fbcc;
+    //     line-height: 27px;
+    //   }
+
+    //   .warn-value {
+    //     color: #fff;
+    //     font-size: 14px;
+    //   }
+    // }
   }
 </style>

+ 0 - 6
src/views/vent/monitorManager/mainFanMonitor/mainWind.threejs.ts

@@ -757,14 +757,8 @@ class mainWindRect {
         if (fbmGroup) fbmGroup.position.z = fbmGroup.position.z + 5;
         if (fcGroup) fcGroup.position.z = fcGroup.position.z + 5;
 
-        const mesh1 = ztfjGroup?.getObjectByName('TWO00'); //前
-        const mesh2 = ztfjGroup?.getObjectByName('ONE00'); //后
-        // mesh1?.renderOrder = 100;
-        // mesh2?.renderOrder = 100;
-
         const mesh = ztfjGroup?.getObjectByName('jizu06') as THREE.Mesh; //前
         if (mesh && mesh.material) this.oldMaterial = mesh.material as THREE.MeshStandardMaterial;
-
         await this.initMotor();
         resolve(null);
         this.initWindow();

+ 4 - 4
src/views/vent/monitorManager/windrectMonitor/index.vue

@@ -124,11 +124,11 @@
         <span>同时运行数量:</span>
         <a-input-number v-model:value="runNum" :min="1" :max="10" />
       </div> -->
-      <div class="vent-flex-row">
+      <!-- <div class="vent-flex-row">
         <div v-for="(criticalPath, index) in criticalPathList" :key="index" class="button-box" @click="selectCriticalPath(criticalPath.id)">{{
           criticalPath.systemname
         }}</div>
-      </div>
+      </div> -->
     </div>
     <div>
       <ModalTable ref="modalTable" deviceType="windrect_list" />
@@ -649,7 +649,7 @@
   function controlDevice(passWord, type) {
     try {
       if (type == 'sing') {
-        testWind({ ids: [selectData.deviceID], maxnum: runNum.value, password: passWord || globalConfig?.simulatedPassword }).then((res) => {
+        testWind({ ids: [selectData.deviceID], password: passWord || globalConfig?.simulatedPassword }).then((res) => {
           if (res && res.success === false) {
             message.error(res.message);
           } else {
@@ -663,7 +663,7 @@
         });
       } else if (type == 'multiple') {
         const ids = toRaw(modalTable.value.selectedRowKeys);
-        testWind({ ids: ids, maxnum: runNum.value, password: passWord || globalConfig?.simulatedPassword }).then((res) => {
+        testWind({ ids: ids, password: passWord || globalConfig?.simulatedPassword }).then((res) => {
           if (res && res.success === false) {
             message.error(res.message);
           } else {

+ 9 - 9
src/views/vent/monitorManager/windrectMonitor/windrect.threejs.ts

@@ -16,10 +16,10 @@ import gsap from 'gsap';
 // 模型对象、 文字对象
 let model: UseThree, //
   group: THREE.Object3D,
-  lmWindRectObj: lmWindRect,
-  zdWindRectObj: zdWindRect,
+  lmWindRectObj: lmWindRect = null,
+  zdWindRectObj: zdWindRect = null,
   dsWindRectObj: dsWindRect,
-  lmWindRectSideObj: lmWindRectSide,
+  lmWindRectSideObj: lmWindRectSide = null,
   ddWindRectObj: ddWindRect,
   fixedWindRectObj: fixedWindRect,
   windRectType = 'lmWindRect';
@@ -130,12 +130,12 @@ export const setModelType = (type) => {
     lmGsap.pause();
     lmGsap.kill();
   }
-  lmWindRectObj.deviceRunState = '';
-  dsWindRectObj.isRun = false;
-
-  lmWindRectSideObj.deviceRunState = '';
-  lmWindRectSideObj.tanTouRunState = '';
-  debugger;
+  if (lmWindRectObj) lmWindRectObj.deviceRunState = '';
+  if (dsWindRectObj) dsWindRectObj.isRun = false;
+  if (lmWindRectSideObj) {
+    lmWindRectSideObj.deviceRunState = '';
+    lmWindRectSideObj.tanTouRunState = '';
+  }
   return new Promise((resolve) => {
     if (windRectType === 'lmWindRect' && lmWindRectObj && lmWindRectObj.group) {
       // 显示双道风窗