Browse Source

1. 新增上湾风窗模型,完成风窗动画调试
2. 局部风机、主风机监测列表添加序号
3. 传感器去掉单选
4. 多灾预警融合界面优化

hongrunxia 3 days ago
parent
commit
6eb9934d8a
28 changed files with 1416 additions and 1048 deletions
  1. 4 0
      src/api/sys/model/userModel.ts
  2. 16 1
      src/api/sys/user.ts
  3. 1 1
      src/design/public.less
  4. 19 1
      src/hooks/vent/useAutoLogin.ts
  5. 4 1
      src/router/guard/permissionGuard.ts
  6. 1 1
      src/views/dashboard/Analysis/homePage/network.vue
  7. 3 2
      src/views/vent/comment/EditRowTable.vue
  8. 59 61
      src/views/vent/deviceManager/comment/editWarnTable/index.vue
  9. 35 28
      src/views/vent/deviceManager/comment/warningTabel/index.vue
  10. 0 7
      src/views/vent/deviceManager/comment/warningTabel/warning.data.ts
  11. 13 3
      src/views/vent/home/colliery/index.vue
  12. 524 517
      src/views/vent/monitorManager/alarmMonitor/common/closeWall.vue
  13. 73 72
      src/views/vent/monitorManager/alarmMonitor/common/warnFire-bd.vue
  14. 106 105
      src/views/vent/monitorManager/alarmMonitor/common/warnFire-brt.vue
  15. 1 1
      src/views/vent/monitorManager/alarmMonitor/index.vue
  16. 8 6
      src/views/vent/monitorManager/comment/DeviceEcharts.vue
  17. 3 7
      src/views/vent/monitorManager/comment/FanDeviceEcharts.vue
  18. 1 1
      src/views/vent/monitorManager/comment/GroupMonitorTable.vue
  19. 203 71
      src/views/vent/monitorManager/comment/components/DeviceBaseInfo.vue
  20. 8 2
      src/views/vent/monitorManager/deviceMonitor/components/device/index.vue
  21. 1 1
      src/views/vent/monitorManager/mainFanMonitor/index.vue
  22. 3 1
      src/views/vent/monitorManager/safetyMonitor/index.vue
  23. 1 0
      src/views/vent/monitorManager/sensorMonitor/index.vue
  24. 0 46
      src/views/vent/monitorManager/windowMonitor/dandaoFcYjl.threejs.ts
  25. 1 1
      src/views/vent/monitorManager/windowMonitor/index.vue
  26. 0 101
      src/views/vent/monitorManager/windowMonitor/shuangdaoFc.threejs.ts
  27. 302 0
      src/views/vent/monitorManager/windowMonitor/shuangdaoFcSw.threejs.ts
  28. 26 10
      src/views/vent/monitorManager/windowMonitor/window.threejs.ts

+ 4 - 0
src/api/sys/model/userModel.ts

@@ -22,6 +22,10 @@ export interface RoleInfo {
   value: string;
 }
 
+export interface TokenInfo {
+  token: string;
+}
+
 /**
  * @description: Login interface return value
  */

+ 16 - 1
src/api/sys/user.ts

@@ -1,5 +1,5 @@
 import { defHttp } from '/@/utils/http/axios';
-import { LoginParams, LoginResultModel, GetUserInfoModel, AutoLoginParams } from './model/userModel';
+import { LoginParams, LoginResultModel, GetUserInfoModel, AutoLoginParams, TokenInfo } from './model/userModel';
 
 import { ErrorMessageMode } from '/#/axios';
 import { useMessage } from '/@/hooks/web/useMessage';
@@ -16,6 +16,7 @@ enum Api {
   Logout = '/sys/logout',
   autoLogin = '/sys/autoLogin',
   GetUserInfo = '/sys/user/getUserInfo',
+  tokenLogin = '/sys/luanLogin',
   // 获取系统权限
   // 1、查询用户拥有的按钮/表单访问权限
   // 2、所有权限
@@ -94,6 +95,20 @@ export function phoneLoginApi(params: LoginParams, mode: ErrorMessageMode = 'mod
   );
 }
 
+export function tokenLogin(params: TokenInfo, mode: ErrorMessageMode = 'modal') {
+  return defHttp.get<LoginResultModel>(
+    {
+      url: Api.tokenLogin,
+      headers: {
+        token: params.token,
+      },
+    },
+    {
+      errorMessageMode: mode,
+    }
+  );
+}
+
 /**
  * @description: getUserInfo
  */

+ 1 - 1
src/design/public.less

@@ -10,7 +10,7 @@
 
 ::-webkit-scrollbar {
   width: 10px !important;
-  height: 4px;
+  height: 10px !important;
 }
 
 // ::-webkit-scrollbar-track {

+ 19 - 1
src/hooks/vent/useAutoLogin.ts

@@ -4,12 +4,13 @@ import { RouteLocationNormalized } from 'vue-router';
 import { useMessage } from '../web/useMessage';
 import { AUTO_LOGIN_URL_QUERY } from '/@/router/constant';
 import { AxiosError } from 'axios';
+import { tokenLogin } from '/@/api/sys/user';
 
 /** 自动登录功能的Hook,该Hook是为了部署在同一局域网内的多套系统之间能够无缝切换 */
 export function useAutoLogin() {
+  const userStore = useUserStore();
   /** 获取自动登录的url */
   function getUrl(baseUrl: string, extraQuery: Record<string, string> = {}) {
-    const userStore = useUserStore();
     const qs = QueryString.stringify({
       [AUTO_LOGIN_URL_QUERY.key]: AUTO_LOGIN_URL_QUERY.val,
       realname: userStore.getUserInfo.realname,
@@ -32,6 +33,13 @@ export function useAutoLogin() {
 
     return false;
   }
+  /** 根据路由是否携带token,判断是否走根据token获取人员信息的接口试下假登录 */
+  function tokenValidateRoute(route: RouteLocationNormalized) {
+    if (route.query && Object.keys(route.query).length == 1 && route.query['token']) {
+      return true;
+    }
+    return false;
+  }
 
   /** 用在路由守卫里,执行自动登录的逻辑,如果存在符合自动登录标准的query则执行自动登录,返回是否自动登录
    *
@@ -65,6 +73,14 @@ export function useAutoLogin() {
     }
   }
 
+  async function doTokenLogin(token: string) {
+    const res = await tokenLogin({ token });
+    if (res['success']) {
+      userStore.setToken(token);
+      userStore.setUserInfo(res['']);
+    }
+  }
+
   return {
     /** 启用单点登录功能来跳转新的页面,参数与window.open一致 */
     open,
@@ -74,5 +90,7 @@ export function useAutoLogin() {
     getUrl,
     /** 判断当前路由是否需要自动登录,本方法是同步方法,可以用于事先判断 */
     validateRoute,
+    tokenValidateRoute,
+    doTokenLogin,
   };
 }

+ 4 - 1
src/router/guard/permissionGuard.ts

@@ -41,7 +41,7 @@ const glob = useGlobSetting();
 export function createPermissionGuard(router: Router) {
   const userStore = useUserStoreWithOut();
   const permissionStore = usePermissionStoreWithOut();
-  const { doAutoLogin, validateRoute } = useAutoLogin();
+  const { doAutoLogin, doTokenLogin, validateRoute, tokenValidateRoute } = useAutoLogin();
 
   router.beforeEach(async (to, from, next) => {
     RootRoute.redirect = glob.homePath || PageEnum.BASE_HOME;
@@ -67,6 +67,9 @@ export function createPermissionGuard(router: Router) {
       // 自动登录后会动态添加路由,此处应当重定向到fullPath,否则会加载404页面内容
       return next({ path: to.fullPath, replace: true, query: to.query });
     }
+    if (tokenValidateRoute(to)) {
+      await doTokenLogin(to.query['token'] as string);
+    }
     // 如果指定了需要模拟登录则执行模拟登录,覆盖原有的登录信息
     if (to.query[MOCK_LOGIN_URL_QUERY.key] === MOCK_LOGIN_URL_QUERY.val) {
       await userStore.mockLogin({ goHome: false });

+ 1 - 1
src/views/dashboard/Analysis/homePage/network.vue

@@ -857,7 +857,7 @@
     pointer-events: auto;
 
     &::-webkit-scrollbar {
-      width: 4px;
+      width: 8px;
       height: 8px;
       background-color: #f5f5f500;
     }

+ 3 - 2
src/views/vent/comment/EditRowTable.vue

@@ -71,7 +71,7 @@
               title: '',
               dataSource: props.dataSource,
               rowKey: props.rowKey,
-              clickToRowSelect: false,
+              clickToRowSelect: props.isRadio ? true : false,
               columns: props.columns as BasicColumn[],
               showIndexColumn: false,
               showTableSetting: false,
@@ -106,7 +106,7 @@
               title: '',
               api: props.list,
               rowKey: props.rowKey,
-              clickToRowSelect: false,
+              clickToRowSelect: props.isRadio ? true : false,
               columns: props.columns as BasicColumn[],
               showIndexColumn: false,
               showTableSetting: false,
@@ -262,6 +262,7 @@
         reload,
         setSelectedRowKeys,
         getDataSource,
+        getSelectRows,
       });
 
       return {

+ 59 - 61
src/views/vent/deviceManager/comment/editWarnTable/index.vue

@@ -1,75 +1,73 @@
 <template>
-    <div class="editWarnTable">
-        <a-form :model="formStates" labelAlign="center" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
-            <a-form-item label="所属煤层:">
-                <a-select v-model:value="formStates.ssmc" placeholder="请选择...">
-                    <a-select-option v-for="item in mcList" :value="item.value">{{ item.label }}</a-select-option>
-                </a-select>
-            </a-form-item>
-            <a-form-item label="绿色预警CO:">
-                <a-input v-model:value="formStates.lsco" placeholder="请输入..." />
-            </a-form-item>
-            <a-form-item label="绿色预警CO/CO₂:">
-                <a-input v-model:value="formStates.lsco2" placeholder="请输入..." />
-            </a-form-item>
-            <a-form-item label="黄色预警CO:">
-                <a-input v-model:value="formStates.hsco" placeholder="请输入..." />
-            </a-form-item>
-            <a-form-item label="黄色预警CO/CO₂:">
-                <a-input v-model:value="formStates.hsco2" placeholder="请输入..." />
-            </a-form-item>
-            <a-form-item label="黄色预警C₂H₄:">
-                <a-input v-model:value="formStates.hsc2h4" placeholder="请输入..." />
-            </a-form-item>
-            <a-form-item label="黄色预警C3H8/C2H6:">
-                <a-input v-model:value="formStates.hsc2h6" placeholder="请输入..." />
-            </a-form-item>
-            <a-form-item label="红色预警CO:">
-                <a-input v-model:value="formStates.rsco" placeholder="请输入..." />
-            </a-form-item>
-            <a-form-item label="红色预警CO/CO₂:">
-                <a-input v-model:value="formStates.rsco2" placeholder="请输入..." />
-            </a-form-item>
-            <a-form-item label="红色预警C₂H₄:">
-                <a-input v-model:value="formStates.rsc2h4" placeholder="请输入..." />
-            </a-form-item>
-            <a-form-item label="红色预警C3H8/C2H6:">
-                <a-input v-model:value="formStates.rsc2h6" placeholder="请输入..." />
-            </a-form-item>
-        </a-form>
-    </div>
+  <div class="editWarnTable">
+    <a-form :model="formStates" labelAlign="center" :label-col="{ span: 4 }" :wrapper-col="{ span: 20 }">
+      <a-form-item label="所属煤层:">
+        <a-select v-model:value="formStates.ssmc" placeholder="请选择...">
+          <a-select-option v-for="item in mcList" :value="item.value">{{ item.label }}</a-select-option>
+        </a-select>
+      </a-form-item>
+      <a-form-item label="绿色预警CO:">
+        <a-input v-model:value="formStates.lsco" placeholder="请输入..." />
+      </a-form-item>
+      <a-form-item label="绿色预警CO/CO₂:">
+        <a-input v-model:value="formStates.lsco2" placeholder="请输入..." />
+      </a-form-item>
+      <a-form-item label="黄色预警CO:">
+        <a-input v-model:value="formStates.hsco" placeholder="请输入..." />
+      </a-form-item>
+      <a-form-item label="黄色预警CO/CO₂:">
+        <a-input v-model:value="formStates.hsco2" placeholder="请输入..." />
+      </a-form-item>
+      <a-form-item label="黄色预警C₂H₄:">
+        <a-input v-model:value="formStates.hsc2h4" placeholder="请输入..." />
+      </a-form-item>
+      <a-form-item label="黄色预警C3H8/C2H6:">
+        <a-input v-model:value="formStates.hsc2h6" placeholder="请输入..." />
+      </a-form-item>
+      <a-form-item label="红色预警CO:">
+        <a-input v-model:value="formStates.rsco" placeholder="请输入..." />
+      </a-form-item>
+      <a-form-item label="红色预警CO/CO₂:">
+        <a-input v-model:value="formStates.rsco2" placeholder="请输入..." />
+      </a-form-item>
+      <a-form-item label="红色预警C₂H₄:">
+        <a-input v-model:value="formStates.rsc2h4" placeholder="请输入..." />
+      </a-form-item>
+      <a-form-item label="红色预警C3H8/C2H6:">
+        <a-input v-model:value="formStates.rsc2h6" placeholder="请输入..." />
+      </a-form-item>
+    </a-form>
+  </div>
 </template>
 
 <script setup lang="ts">
-import { ref, reactive, watch,onMounted } from 'vue'
-import {sysTypeWarnList} from '../../../monitorManager/alarmMonitor/common.api.ts'
+  import { ref, reactive, watch, onMounted } from 'vue';
+  import { sysTypeWarnList } from '../../../monitorManager/alarmMonitor/common.api.ts';
 
-let formStates = reactive({})
-let mcList=reactive<any[]>([])
+  let formStates = reactive({});
+  let mcList = reactive<any[]>([]);
 
-//获取煤层列表
+  //获取煤层列表
 
-async function getMenuList() {
-    let res = await sysTypeWarnList({ type: 'fire' })
-    mcList.length=0
-    if(res.fire && res.fire.length!=0){
-        res.fire.forEach(el=>{
-            mcList.push({label:el.systemname,value:el.id})
-        })
+  async function getMenuList() {
+    let res = await sysTypeWarnList({ type: 'fire' });
+    mcList.length = 0;
+    if (res.fire && res.fire.length != 0) {
+      res.fire.forEach((el) => {
+        mcList.push({ label: el.systemname, value: el.id });
+      });
     }
-}
-onMounted(()=>{
-    getMenuList() 
-})
-
-
+  }
+  onMounted(() => {
+    getMenuList();
+  });
 </script>
 
 <style lang="less" scoped>
-.warnTargetFire-brt {
+  .warnTargetFire-brt {
     width: 100%;
     height: 600px;
     padding: 15px;
-    box-sizing: border-box
-}
-</style>
+    box-sizing: border-box;
+  }
+</style>

+ 35 - 28
src/views/vent/deviceManager/comment/warningTabel/index.vue

@@ -9,6 +9,7 @@
       @save-or-update="saveOrUpdateParent"
       @delete-by-id="parentDeleteById"
       @row-change="changeParentRow"
+      row-key="id"
       :isAdd="true"
       :isRadio="true"
       :scroll="{ y: 200 }"
@@ -38,6 +39,7 @@
       @save-or-update="saveOrUpdateChild"
       @delete-by-id="childDeleteById"
       :isAdd="true"
+      row-key="id"
       style="margin-top: 10px"
       :scroll="{ y: 200 }"
     />
@@ -51,7 +53,7 @@
   import { warningColumns, levelColumns } from './warning.data';
   import { list, limitList, edit, save, limitSave, limitEdit, deleteById, limitDeleteById } from './warning.api';
   import { list as pointList } from '../pointTabel/point.api';
-  import { defineProps, ref, nextTick, inject, onMounted, onBeforeMount } from 'vue';
+  import { defineProps, ref, nextTick, onBeforeMount, onMounted } from 'vue';
 
   const props = defineProps({
     deviceId: { type: String },
@@ -62,7 +64,7 @@
   });
   const ParentRef = ref();
   const options = ref([]);
-  const RefChildComponent = ref();
+  const RefChildComponent = ref(null);
   const warningProId = ref('');
   const currentParent = ref({});
   const refresh = ref(true);
@@ -71,22 +73,22 @@
   async function saveOrUpdateParent(record) {
     try {
       if (record.id) {
-        currentParent.value = record;
         await edit({ ...record });
       } else {
+        // await save({ ...record, deviceid: props.deviceId });
         await save({ ...record, deviceid: props.deviceId, devicetype: props.pointType });
       }
       // refreshParent.value = false;
+      // nextTick(() => {
+      //   refreshParent.value = true;
+      // });
       if (ParentRef.value) {
-        await ParentRef.value.reload();
-        nextTick(() => {
-          const parentList = ParentRef.value.getDataSource();
-          if (record.id) {
-            ParentRef.value.setSelectedRowKeys([record.id]);
-          } else {
-            ParentRef.value.setSelectedRowKeys([parentList[0]['id']]);
-          }
-        });
+        const parentList = ParentRef.value.getDataSource();
+        if (record.id) {
+          ParentRef.value.setSelectedRowKeys([record.id]);
+        } else {
+          ParentRef.value.setSelectedRowKeys([parentList[0]['id']]);
+        }
       }
     } catch (error) {}
   }
@@ -94,6 +96,7 @@
     if (record.id) {
       await limitEdit({ ...record });
     } else {
+      // await limitSave({ ...record, limitid: warningProId.value, code: currentParent.value['monitorcode'] });
       await limitSave({
         ...record.editValueRefs,
         limitid: warningProId.value,
@@ -102,14 +105,17 @@
         deviceid: props.deviceId,
       });
     }
-    // refresh.value = false;
-    if (RefChildComponent.value) {
-      await RefChildComponent.value.reload();
-      nextTick(() => {
-        const childList = RefChildComponent.value.getDataSource();
-        RefChildComponent.value.setSelectedRowKeys([childList[0]['id']]);
-      });
-    }
+    refresh.value = false;
+    nextTick(() => {
+      refresh.value = true;
+    });
+    // if (RefChildComponent.value) {
+    //   // await RefChildComponent.value.reload();
+    //   nextTick(() => {
+    //     const childList = RefChildComponent.value.getDataSource();
+    //     RefChildComponent.value.setSelectedRowKeys([childList[0]['id']]);
+    //   });
+    // }
   }
   function parentDeleteById(id, reload) {
     deleteById({ id: id }, reload);
@@ -118,12 +124,14 @@
     limitDeleteById({ id: id }, reload);
   }
   function changeParentRow(id, rowData) {
-    warningProId.value = id;
-    currentParent.value = rowData;
-    refresh.value = false;
-    nextTick(() => {
-      refresh.value = true;
-    });
+    if (id) {
+      warningProId.value = id;
+      currentParent.value = rowData;
+      refresh.value = false;
+      nextTick(() => {
+        refresh.value = true;
+      });
+    }
   }
   function getLabel(code) {
     const obj = options.value.find((item) => item['valuecode'] === code);
@@ -138,10 +146,9 @@
   });
   onMounted(async () => {
     if (ParentRef.value) {
-      await ParentRef.value.reload();
       nextTick(() => {
         const parentList = ParentRef.value.getDataSource();
-        ParentRef.value.setSelectedRowKeys([parentList[0]['id']]);
+        if (parentList && parentList.length > 0) ParentRef.value.setSelectedRowKeys([parentList[0]['id']]);
       });
     }
   });

+ 0 - 7
src/views/vent/deviceManager/comment/warningTabel/warning.data.ts

@@ -59,13 +59,6 @@ export const warningColumns: BasicColumn[] = [
     dataIndex: 'monitorcode',
     width: 150,
     editRow: true,
-    editComponent: 'Input',
-    editRule: async (text) => {
-      if (!text) {
-        return '请选择';
-      }
-      return '';
-    },
   },
   {
     title: '修正参数', // 给点位设置系数,调整点位值

+ 13 - 3
src/views/vent/home/colliery/index.vue

@@ -7,7 +7,9 @@
           <span>{{ nowTimeWeek }}</span>
           <span>{{ nowTime }}</span>
         </div>
-        <div class="main-title">{{ title }}</div>
+        <div class="main-title"
+          ><img v-if="hasPermission('home:logo')" class="logo" :src="`${baseUrl}/sys/common/static/${logoUrl}`" />{{ title }}</div
+        >
       </div>
       <div class="home-contents">
         <div class="left-content">
@@ -107,6 +109,7 @@
   const { hasPermission } = usePermission();
 
   const { title, logoUrl, sysOrgCode } = useGlobSetting();
+  const baseUrl = VUE_APP_URL.baseUrl;
   const actions = getActions();
   let timer: NodeJS.Timeout | null = null;
   let fanLocalList = reactive<any[]>([]); //局部风机数据
@@ -397,8 +400,15 @@
         top: 50%;
         transform: translate(-50%, -50%);
         color: #fff;
-        font-size: 24px;
-        font-family: 'douyuFont';
+        font-size: 28px;
+        font-weight: 600;
+        display: flex;
+        align-items: center;
+        .logo {
+          width: 32px;
+          height: 32px;
+          margin-right: 5px;
+        }
       }
     }
 

+ 524 - 517
src/views/vent/monitorManager/alarmMonitor/common/closeWall.vue

@@ -8,8 +8,7 @@
             <!-- <div class="text-value">{{ topContent.position }}</div> -->
             <div class="text-value">
               <a-select v-model:value="selectData" style="width: 360px" @change="changeSelect">
-                <a-select-option v-for="file in selectList" :key="file.label" :value="file.value">{{ file.label
-                  }}</a-select-option>
+                <a-select-option v-for="file in selectList" :key="file.label" :value="file.value">{{ file.label }}</a-select-option>
               </a-select>
             </div>
           </div>
@@ -27,24 +26,30 @@
       <div class="box-container">
         <div class="text1">
           <span>预警等级 : </span>
-          <span :class="{
-            value1: topContent.warnLevel == '绿色预警',
-            value2: topContent.warnLevel == '黄色预警',
-            value3: topContent.warnLevel == '红色预警',
-          }">{{ topContent.warnLevel || '-' }}</span>
+          <span
+            :class="{
+              value1: topContent.warnLevel == '绿色预警',
+              value2: topContent.warnLevel == '黄色预警',
+              value3: topContent.warnLevel == '红色预警',
+            }"
+            >{{ topContent.warnLevel || '-' }}</span
+          >
         </div>
         <div class="text1">
           <span>煤自燃阶段 : </span>
           <span>{{ topContent.smokeJd || '-' }}</span>
         </div>
-
       </div>
     </div>
     <div class="content">
       <div class="title-b">采空区密闭参数</div>
       <div class="card-btn">
-        <div :class="activeIndex == index ? 'box-container1' : 'box-container'" v-for="(item, index) in mbList"
-          :key="index" @click="btnClick(item, index)">
+        <div
+          :class="activeIndex == index ? 'box-container1' : 'box-container'"
+          v-for="(item, index) in mbList"
+          :key="index"
+          @click="btnClick(item, index)"
+        >
           <div class="box-label">
             <span> {{ item.label }}</span>
             <span>{{ item.dw }}</span>
@@ -66,609 +71,611 @@
       <div class="echart-box">
         <div class="left-echartbox">
           <div class="title-f">
-            <div class="title-text">{{ `${type}趋势` }}&nbsp; <span style="color: red">{{ netStatus != 1 ?
-              '(设备未连接)' :
-              '' }}</span></div>
+            <div class="title-text"
+              >{{ `${type}趋势` }}&nbsp; <span style="color: red">{{ netStatus != 1 ? '(设备未连接)' : '' }}</span></div
+            >
           </div>
           <div class="echarts-box">
             <echartLine1 :echartDataSg="echartDataSg1" :lengedDataName="echartDataSg1.lengedDataName" />
           </div>
         </div>
         <div class="right-echartbox">
-          <warnZb :widthV="widthV" :heightV="heightV" :coordDw="coordDw" :widthCanvas="widthCanvas"
-            :heightCanvas="heightCanvas" :warnLevel="topContent.warnLevel"></warnZb>
+          <warnZb
+            :widthV="widthV"
+            :heightV="heightV"
+            :coordDw="coordDw"
+            :widthCanvas="widthCanvas"
+            :heightCanvas="heightCanvas"
+            :warnLevel="topContent.warnLevel"
+          />
         </div>
-
       </div>
     </div>
   </div>
 </template>
 
 <script lang="ts" setup>
-import { onMounted, ref, reactive, watch, defineProps } from 'vue';
-import echartLine1 from './echartLine1.vue';
-import warnZb from './warnZb.vue'
-
-let props = defineProps({
-  listData: Object,
-});
-
-let selectSj = ref<any[]>([])
-let selectData = ref('')
-let selectList = reactive<any[]>([])
-let widthV = ref('75%')
-let heightV = ref('80%')
-let coordDw = ref<any[]>([47, 95])
-let widthCanvas = ref(562)
-let heightCanvas = ref(316)
-//设备连接状态
-let netStatus = ref(0)
-//密闭-顶部区域数据
-let topContent = reactive({
-  temperature: 0,
-  position: '',
-  time: '',
-  warnLevel: '',
-  smokeJd: '',
-});
-//密闭参数列表
-let mbList = reactive([
-  {
-    label: 'O₂',
-    dw: '(%)',
-    label1: '浓度',
-    label2: '时间',
-    label3: '位置',
-    nd: '0',
-    time1: '',
-    address: '',
-  },
-  {
-    label: 'CO',
-    dw: '(ppm)',
-    label1: '浓度',
-    label2: '时间',
-    label3: '位置',
-    nd: '0',
-    time1: '',
-    address: '',
-  },
-  {
-    label: 'CO₂',
-    dw: '(%)',
-    label1: '浓度',
-    label2: '时间',
-    label3: '位置',
-    nd: '0',
-    time1: '',
-    address: '',
-  },
-  {
-    label: 'CH₄',
-    dw: '(%)',
-    label1: '浓度',
-    label2: '时间',
-    label3: '位置',
-    nd: '0',
-    time1: '',
-    address: '',
-  },
-  {
-    label: 'C₂H₂',
-    dw: '(ppm)',
-    label1: '浓度',
-    label2: '时间',
-    label3: '位置',
-    nd: '0',
-    time1: '',
-    address: '',
-  },
-  {
-    label: 'C₂H₄',
-    dw: '(ppm)',
-    label1: '浓度',
-    label2: '时间',
-    label3: '位置',
-    nd: '0',
-    time1: '',
-    address: '',
-  },
-]);
-
-//当前密闭参数激活选项
-let activeIndex = ref(0);
-//当前激活密闭参数类型
-let type = ref('O₂');
-
-let echartDataSg1 = reactive({
-  xData: [],
-  yData: [],
-  lengedData: 'O₂',
-  lengedDataName: '(%)',
-});
-let echartDataSgList = reactive<any[]>([]);
-
-//密闭参数选项切换
-function btnClick(item, ind) {
-  activeIndex.value = ind;
-  type.value = item.label;
-  echartDataSg1.xData.length = 0;
-  echartDataSg1.yData.length = 0;
-  echartDataSg1.lengedData = type.value;
-  echartDataSg1.lengedDataName = item.dw;
-
-  switch (type.value) {
-    case 'O₂':
-      echartDataSgList.forEach((el) => {
-        echartDataSg1.xData.push(el.time);
-        echartDataSg1.yData.push(el.o2val);
-      });
-      break;
-    case 'C₂H₄':
-      echartDataSgList.forEach((el) => {
-        echartDataSg1.xData.push(el.time);
-        echartDataSg1.yData.push(el.ch2val);
-      });
-      break;
-    case 'CO':
-      echartDataSgList.forEach((el) => {
-        echartDataSg1.xData.push(el.time);
-        echartDataSg1.yData.push(el.coval);
-      });
-      break;
-    case 'CH₄':
-      echartDataSgList.forEach((el) => {
-        echartDataSg1.xData.push(el.time);
-        echartDataSg1.yData.push(el.chval);
-      });
-      break;
-    case 'CO₂':
-      echartDataSgList.forEach((el) => {
-        echartDataSg1.xData.push(el.time);
-        echartDataSg1.yData.push(el.co2val);
-      });
-      break;
-    case 'C₂H₂':
-      echartDataSgList.forEach((el) => {
-        echartDataSg1.xData.push(el.time);
-        echartDataSg1.yData.push(el.gasval);
-      });
-      break;
-  }
-}
-
-function changeSelect(val) {
-  selectData.value = val
-  let data = selectSj.value.filter(v => v.strinstallpos == selectData.value)[0]
-  topContent.time = data.readTime || '--';
-  topContent.warnLevel = data.syswarnLevel_str
-  topContent.smokeJd = data.syswarnLevel_des
-
-  mbList[0].nd = data.readData.o2val || '--';
-  mbList[1].nd = data.readData.coval || '--';
-  mbList[2].nd = data.readData.co2val || '--';
-  mbList[3].nd = data.readData.chval || '--';
-  mbList[4].nd = data.readData.ch2val || '--';
-  mbList[5].nd = data.readData.gasval || '--';
-  mbList.forEach((el) => {
-    el.time1 = data ? data.readTime.substring(0, data.readTime.lastIndexOf(':')) : '--';
-    el.address = data ? data.strinstallpos : '--';
+  import { onMounted, ref, reactive, watch, defineProps } from 'vue';
+  import echartLine1 from './echartLine1.vue';
+  import warnZb from './warnZb.vue';
+
+  let props = defineProps({
+    listData: Object,
   });
-  netStatus.value = data['netStatus']
-}
 
-watch(
-  () => props.listData,
-  (val) => {
-    console.log(val, 'val---');
+  let selectSj = ref<any[]>([]);
+  let selectData = ref('');
+  let selectList = reactive<any[]>([]);
+  let widthV = ref('75%');
+  let heightV = ref('80%');
+  let coordDw = ref<any[]>([47, 95]);
+  let widthCanvas = ref(562);
+  let heightCanvas = ref(316);
+  //设备连接状态
+  let netStatus = ref(0);
+  //密闭-顶部区域数据
+  let topContent = reactive({
+    temperature: 0,
+    position: '',
+    time: '',
+    warnLevel: '',
+    smokeJd: '',
+  });
+  //密闭参数列表
+  let mbList = reactive([
+    {
+      label: 'O₂',
+      dw: '(%)',
+      label1: '浓度',
+      label2: '时间',
+      label3: '位置',
+      nd: '0',
+      time1: '',
+      address: '',
+    },
+    {
+      label: 'CO',
+      dw: '(ppm)',
+      label1: '浓度',
+      label2: '时间',
+      label3: '位置',
+      nd: '0',
+      time1: '',
+      address: '',
+    },
+    {
+      label: 'CO₂',
+      dw: '(%)',
+      label1: '浓度',
+      label2: '时间',
+      label3: '位置',
+      nd: '0',
+      time1: '',
+      address: '',
+    },
+    {
+      label: 'CH₄',
+      dw: '(%)',
+      label1: '浓度',
+      label2: '时间',
+      label3: '位置',
+      nd: '0',
+      time1: '',
+      address: '',
+    },
+    {
+      label: 'C₂H₂',
+      dw: '(ppm)',
+      label1: '浓度',
+      label2: '时间',
+      label3: '位置',
+      nd: '0',
+      time1: '',
+      address: '',
+    },
+    {
+      label: 'C₂H₄',
+      dw: '(ppm)',
+      label1: '浓度',
+      label2: '时间',
+      label3: '位置',
+      nd: '0',
+      time1: '',
+      address: '',
+    },
+  ]);
+
+  //当前密闭参数激活选项
+  let activeIndex = ref(0);
+  //当前激活密闭参数类型
+  let type = ref('O₂');
+
+  let echartDataSg1 = reactive({
+    xData: [],
+    yData: [],
+    lengedData: 'O₂',
+    lengedDataName: '(%)',
+  });
+  let echartDataSgList = reactive<any[]>([]);
+
+  //密闭参数选项切换
+  function btnClick(item, ind) {
+    activeIndex.value = ind;
+    type.value = item.label;
     echartDataSg1.xData.length = 0;
     echartDataSg1.yData.length = 0;
-    echartDataSgList.length = 0;
-    selectList.length = 0
-    if (JSON.stringify(val) != '{}') {
-      if (val.bundletube.length != 0) {
-        selectSj.value = val.bundletube
-        selectSj.value.forEach(el => {
-          selectList.push({ label: el.strinstallpos, value: el.strinstallpos })
-        })
-        selectData.value = selectData.value ? selectData.value : selectList[0].value
-        let dataVal = selectData.value ? selectSj.value.filter(v => v.strinstallpos == selectData.value)[0] : selectSj.value[0];
-        topContent.temperature = val.temperature[0] ? val.temperature[0].readData.temperature : '--';
-        // topContent.position = dataVal.strinstallpos || '--';
-        topContent.time = dataVal.readTime || '--';
-        topContent.warnLevel = dataVal.syswarnLevel_str
-        topContent.smokeJd = dataVal.syswarnLevel_des
-
-        mbList[0].nd = dataVal.readData.o2val || '--';
-        mbList[1].nd = dataVal.readData.coval || '--';
-        mbList[2].nd = dataVal.readData.co2val || '--';
-        mbList[3].nd = dataVal.readData.chval || '--';
-        mbList[4].nd = dataVal.readData.ch2val || '--';
-        mbList[5].nd = dataVal.readData.gasval || '--';
-        mbList.forEach((el) => {
-          el.time1 = dataVal ? dataVal.readTime.substring(0, dataVal.readTime.lastIndexOf(':')) : '--';
-          el.address = dataVal ? dataVal.strinstallpos : '--';
+    echartDataSg1.lengedData = type.value;
+    echartDataSg1.lengedDataName = item.dw;
+
+    switch (type.value) {
+      case 'O₂':
+        echartDataSgList.forEach((el) => {
+          echartDataSg1.xData.push(el.time);
+          echartDataSg1.yData.push(el.o2val);
         });
-        netStatus.value = dataVal['netStatus']
-        dataVal.history.forEach((v) => {
-          echartDataSg1.xData.push(v.time);
-          if (echartDataSg1.lengedData == 'O₂') {
-            echartDataSg1.yData.push(v.o2val);
-          } else if (echartDataSg1.lengedData == 'C₂H₄') {
-            echartDataSg1.yData.push(v.ch2val);
-          } else if (echartDataSg1.lengedData == 'CO') {
-            echartDataSg1.yData.push(v.coval);
-          } else if (echartDataSg1.lengedData == 'CH₄') {
-            echartDataSg1.yData.push(v.chval);
-          } else if (echartDataSg1.lengedData == 'CO₂') {
-            echartDataSg1.yData.push(v.co2val);
-          } else if (echartDataSg1.lengedData == 'C₂H₂') {
-            echartDataSg1.yData.push(v.gasval);
-          }
-          echartDataSgList.push(v);
+        break;
+      case 'C₂H₄':
+        echartDataSgList.forEach((el) => {
+          echartDataSg1.xData.push(el.time);
+          echartDataSg1.yData.push(el.ch2val);
         });
-      } else {
-        topContent.temperature = 0;
-        // topContent.position = '--';
-        topContent.time = '--';
-        topContent.warnLevel = '--';
-        topContent.smokeJd = '--'
-        mbList[0].nd = '--';
-        mbList[1].nd = '--';
-        mbList[2].nd = '--';
-        mbList[3].nd = '--';
-        mbList[4].nd = '--';
-        mbList[5].nd = '--';
-        mbList.forEach((el) => {
-          el.time1 = '--';
-          el.address = '--';
+        break;
+      case 'CO':
+        echartDataSgList.forEach((el) => {
+          echartDataSg1.xData.push(el.time);
+          echartDataSg1.yData.push(el.coval);
         });
-      }
+        break;
+      case 'CH₄':
+        echartDataSgList.forEach((el) => {
+          echartDataSg1.xData.push(el.time);
+          echartDataSg1.yData.push(el.chval);
+        });
+        break;
+      case 'CO₂':
+        echartDataSgList.forEach((el) => {
+          echartDataSg1.xData.push(el.time);
+          echartDataSg1.yData.push(el.co2val);
+        });
+        break;
+      case 'C₂H₂':
+        echartDataSgList.forEach((el) => {
+          echartDataSg1.xData.push(el.time);
+          echartDataSg1.yData.push(el.gasval);
+        });
+        break;
     }
-  },
-  { immediate: true, deep: true }
-);
+  }
+
+  function changeSelect(val) {
+    selectData.value = val;
+    let data = selectSj.value.filter((v) => v.strinstallpos == selectData.value)[0];
+    topContent.time = data.readTime || '--';
+    topContent.warnLevel = data.syswarnLevel_str;
+    topContent.smokeJd = data.syswarnLevel_des;
+
+    mbList[0].nd = data.readData.o2val || '--';
+    mbList[1].nd = data.readData.coval || '--';
+    mbList[2].nd = data.readData.co2val || '--';
+    mbList[3].nd = data.readData.chval || '--';
+    mbList[4].nd = data.readData.ch2val || '--';
+    mbList[5].nd = data.readData.gasval || '--';
+    mbList.forEach((el) => {
+      el.time1 = data ? data.readTime.substring(0, data.readTime.lastIndexOf(':')) : '--';
+      el.address = data ? data.strinstallpos : '--';
+    });
+    netStatus.value = data['netStatus'];
+  }
+
+  watch(
+    () => props.listData,
+    (val) => {
+      console.log(val, 'val---');
+      echartDataSg1.xData.length = 0;
+      echartDataSg1.yData.length = 0;
+      echartDataSgList.length = 0;
+      selectList.length = 0;
+      if (JSON.stringify(val) != '{}') {
+        if (val.bundletube.length != 0) {
+          selectSj.value = val.bundletube;
+          selectSj.value.forEach((el) => {
+            selectList.push({ label: el.strinstallpos, value: el.strinstallpos });
+          });
+          selectData.value = selectData.value ? selectData.value : selectList[0].value;
+          let dataVal = selectData.value ? selectSj.value.filter((v) => v.strinstallpos == selectData.value)[0] : selectSj.value[0];
+          topContent.temperature = val.temperature[0] ? val.temperature[0].readData.temperature : '--';
+          // topContent.position = dataVal.strinstallpos || '--';
+          topContent.time = dataVal.readTime || '--';
+          topContent.warnLevel = dataVal.syswarnLevel_str;
+          topContent.smokeJd = dataVal.syswarnLevel_des;
+
+          mbList[0].nd = dataVal.readData.o2val || '--';
+          mbList[1].nd = dataVal.readData.coval || '--';
+          mbList[2].nd = dataVal.readData.co2val || '--';
+          mbList[3].nd = dataVal.readData.chval || '--';
+          mbList[4].nd = dataVal.readData.ch2val || '--';
+          mbList[5].nd = dataVal.readData.gasval || '--';
+          mbList.forEach((el) => {
+            el.time1 = dataVal ? dataVal.readTime.substring(0, dataVal.readTime.lastIndexOf(':')) : '--';
+            el.address = dataVal ? dataVal.strinstallpos : '--';
+          });
+          netStatus.value = dataVal['netStatus'];
+          dataVal.history.forEach((v) => {
+            echartDataSg1.xData.push(v.time);
+            if (echartDataSg1.lengedData == 'O₂') {
+              echartDataSg1.yData.push(v.o2val);
+            } else if (echartDataSg1.lengedData == 'C₂H₄') {
+              echartDataSg1.yData.push(v.ch2val);
+            } else if (echartDataSg1.lengedData == 'CO') {
+              echartDataSg1.yData.push(v.coval);
+            } else if (echartDataSg1.lengedData == 'CH₄') {
+              echartDataSg1.yData.push(v.chval);
+            } else if (echartDataSg1.lengedData == 'CO₂') {
+              echartDataSg1.yData.push(v.co2val);
+            } else if (echartDataSg1.lengedData == 'C₂H₂') {
+              echartDataSg1.yData.push(v.gasval);
+            }
+            echartDataSgList.push(v);
+          });
+        } else {
+          topContent.temperature = 0;
+          // topContent.position = '--';
+          topContent.time = '--';
+          topContent.warnLevel = '--';
+          topContent.smokeJd = '--';
+          mbList[0].nd = '--';
+          mbList[1].nd = '--';
+          mbList[2].nd = '--';
+          mbList[3].nd = '--';
+          mbList[4].nd = '--';
+          mbList[5].nd = '--';
+          mbList.forEach((el) => {
+            el.time1 = '--';
+            el.address = '--';
+          });
+        }
+      }
+    },
+    { immediate: true, deep: true }
+  );
 </script>
 
 <style lang="less" scoped>
-.closeWall {
-  width: 100%;
-  height: 100%;
-  padding: 20px;
-  box-sizing: border-box;
-
-  .title {
+  .closeWall {
     width: 100%;
-    height: 17%;
-    margin-bottom: 20px;
-    display: flex;
-    justify-content: space-between;
-    background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
-    background-size: 100% 100%;
-    align-items: center;
-
-    .box-container {
-      display: flex;
-
-
-      &:nth-child(1) {
-        justify-content: space-around;
-        align-items: center;
-        flex: 2;
-        height: 100%;
-        border-right: 2px solid;
-        border-image: linear-gradient(to bottom, transparent, rgba(2, 70, 136, 1), transparent) 1 1 1;
-      }
+    height: 100%;
+    padding: 20px;
+    box-sizing: border-box;
 
-      &:nth-child(2) {
-        flex-direction: column;
-        flex: 1;
-        justify-content: space-around;
-        align-items: center;
-        height: 73%;
-      }
+    .title {
+      width: 100%;
+      height: 17%;
+      margin-bottom: 20px;
+      display: flex;
+      justify-content: space-between;
+      background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
+      background-size: 100% 100%;
+      align-items: center;
 
-      .contents {
-        height: 73%;
+      .box-container {
+        display: flex;
 
         &:nth-child(1) {
-          width: 40%;
-          display: flex;
+          justify-content: space-around;
+          align-items: center;
+          flex: 2;
+          height: 100%;
+          border-right: 2px solid;
+          border-image: linear-gradient(to bottom, transparent, rgba(2, 70, 136, 1), transparent) 1 1 1;
+        }
+
+        &:nth-child(2) {
           flex-direction: column;
+          flex: 1;
           justify-content: space-around;
+          align-items: center;
+          height: 73%;
+        }
+
+        .contents {
+          height: 73%;
 
-          .text {
-            font-size: 14px;
+          &:nth-child(1) {
+            width: 40%;
             display: flex;
+            flex-direction: column;
+            justify-content: space-around;
+
+            .text {
+              font-size: 14px;
+              display: flex;
+              align-items: center;
+
+              .text-label {
+                color: #b3b8cc;
+                font-weight: bold;
+              }
+
+              .text-value {
+                font-family: 'douyuFont';
+                color: #3df6ff;
+                margin-left: 10px;
+              }
+            }
+          }
+
+          &:nth-child(2) {
+            width: 40%;
+            display: flex;
+            justify-content: center;
             align-items: center;
 
-            .text-label {
-              color: #b3b8cc;
-              font-weight: bold;
+            img {
+              position: relative;
+              width: 23%;
+              height: 100%;
+              background: url('../../../../../assets/images/fire/pj.svg') no-repeat center;
+              background-size: 50% 50%;
             }
 
-            .text-value {
+            .text {
               font-family: 'douyuFont';
+              font-size: 28px;
+              margin: 0px 15px;
               color: #3df6ff;
-              margin-left: 10px;
+            }
+
+            .dw {
+              font-size: 14px;
+              color: #b3b8cc;
             }
           }
         }
 
-        &:nth-child(2) {
-          width: 40%;
-          display: flex;
-          justify-content: center;
-          align-items: center;
+        .text1 {
+          width: 90%;
+          height: 30px;
+          line-height: 30px;
+          font-size: 14px;
+          color: #b3b8cc;
+          font-weight: bold;
 
-          img {
-            position: relative;
-            width: 23%;
-            height: 100%;
-            background: url('../../../../../assets/images/fire/pj.svg') no-repeat center;
-            background-size: 50% 50%;
-          }
+          span {
+            display: inline-block;
 
-          .text {
-            font-family: 'douyuFont';
-            font-size: 28px;
-            margin: 0px 15px;
-            color: #3df6ff;
-          }
+            &:nth-child(1) {
+              width: 160px;
+              text-align: right;
+            }
 
-          .dw {
-            font-size: 14px;
-            color: #b3b8cc;
+            &:nth-child(2) {
+              font-family: 'douyuFont';
+              color: #3df6ff;
+              margin-left: 10px;
+            }
           }
-        }
-      }
 
-      .text1 {
-        width: 90%;
-        height: 30px;
-        line-height: 30px;
-        font-size: 14px;
-        color: #b3b8cc;
-        font-weight: bold;
-
-        span {
-          display: inline-block;
-
-          &:nth-child(1) {
-            width: 160px;
-            text-align: right;
+          .value1 {
+            color: rgb(145, 230, 9) !important;
           }
 
-          &:nth-child(2) {
-            font-family: 'douyuFont';
-            color: #3df6ff;
-            margin-left: 10px;
+          .value2 {
+            // color: rgb(0, 242, 255) !important;
+            color: #ffff35 !important;
           }
-        }
-
-        .value1 {
-          color: rgb(145, 230, 9) !important;
-        }
 
-        .value2 {
-          // color: rgb(0, 242, 255) !important;
-          color: #ffff35 !important;
-        }
-
-        .value3 {
-          // color: #ffff35 !important;
-          color: #ff0000 !important;
-        }
+          .value3 {
+            // color: #ffff35 !important;
+            color: #ff0000 !important;
+          }
 
-        .value4 {
-          color: #ffbe69 !important;
-        }
+          .value4 {
+            color: #ffbe69 !important;
+          }
 
-        .value5 {
-          color: #ff6f00 !important;
-        }
+          .value5 {
+            color: #ff6f00 !important;
+          }
 
-        .value6 {
-          color: #ff0000 !important;
+          .value6 {
+            color: #ff0000 !important;
+          }
         }
       }
     }
-  }
 
-  .content {
-    width: 100%;
-    height: calc(83% - 20px);
-    padding: 10px;
-    background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
-    background-size: 100% 100%;
-    box-sizing: border-box;
-
-    .title-b {
-      height: 30px;
-      line-height: 30px;
-      font-family: 'douyuFont';
-      font-size: 14px;
-      color: #fff;
-      // color: #3df6ff;
-    }
+    .content {
+      width: 100%;
+      height: calc(83% - 20px);
+      padding: 10px;
+      background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
+      background-size: 100% 100%;
+      box-sizing: border-box;
 
-    .card-btn {
-      height: 28%;
-      margin-bottom: 10px;
-      display: flex;
-      justify-content: space-between;
-
-      .box-container {
-        position: relative;
-        width: 16%;
-        height: 100%;
-        background: url('../../../../../assets/images/fire/1.png') no-repeat center;
-        background-size: 100% 100%;
-        cursor: pointer;
-
-        .box-label {
-          position: absolute;
-          left: 50%;
-          top: 2px;
-          transform: translate(-50%);
-          color: #fff;
-        }
+      .title-b {
+        height: 30px;
+        line-height: 30px;
+        font-family: 'douyuFont';
+        font-size: 14px;
+        color: #fff;
+        // color: #3df6ff;
+      }
 
-        .box-item {
-          position: absolute;
-          left: 50%;
-          transform: translate(-50%, 0);
-          width: 89%;
-          height: 16%;
-          padding: 0px 10px;
-          display: flex;
-          justify-content: space-between;
-          align-items: center;
-          background: url('../../../../../assets/images/fire/contetn.png') no-repeat center;
+      .card-btn {
+        height: 28%;
+        margin-bottom: 10px;
+        display: flex;
+        justify-content: space-between;
+
+        .box-container {
+          position: relative;
+          width: 16%;
+          height: 100%;
+          background: url('../../../../../assets/images/fire/1.png') no-repeat center;
           background-size: 100% 100%;
+          cursor: pointer;
 
-          .text-t {
-            width: 17%;
+          .box-label {
+            position: absolute;
+            left: 50%;
+            top: 2px;
+            transform: translate(-50%);
             color: #fff;
-            font-size: 12px;
           }
 
-          .text-v {
-            width: 83%;
-            font-family: 'douyuFont';
-            font-size: 10px;
-            color: #3df6ff;
+          .box-item {
+            position: absolute;
+            left: 50%;
+            transform: translate(-50%, 0);
+            width: 89%;
+            height: 16%;
+            padding: 0px 10px;
             display: flex;
-            justify-content: flex-end;
-          }
-        }
+            justify-content: space-between;
+            align-items: center;
+            background: url('../../../../../assets/images/fire/contetn.png') no-repeat center;
+            background-size: 100% 100%;
 
-        .box-item1 {
-          top: 24%;
-        }
+            .text-t {
+              width: 17%;
+              color: #fff;
+              font-size: 12px;
+            }
 
-        .box-item2 {
-          top: 50%;
-        }
+            .text-v {
+              width: 83%;
+              font-family: 'douyuFont';
+              font-size: 10px;
+              color: #3df6ff;
+              display: flex;
+              justify-content: flex-end;
+            }
+          }
 
-        .box-item3 {
-          top: 75%;
-        }
-      }
+          .box-item1 {
+            top: 24%;
+          }
 
-      .box-container1 {
-        position: relative;
-        width: 16%;
-        height: 100%;
-        background: url('../../../../../assets/images/fire/2.png') no-repeat center;
-        background-size: 100% 100%;
-        cursor: pointer;
-
-        .box-label {
-          position: absolute;
-          left: 50%;
-          top: 2px;
-          transform: translate(-50%);
-          color: #fff;
+          .box-item2 {
+            top: 50%;
+          }
+
+          .box-item3 {
+            top: 75%;
+          }
         }
 
-        .box-item {
-          position: absolute;
-          left: 50%;
-          transform: translate(-50%, 0);
-          width: 89%;
-          height: 16%;
-          padding: 0px 10px;
-          display: flex;
-          justify-content: space-between;
-          align-items: center;
-          background: url('../../../../../assets/images/fire/contetn.png') no-repeat center;
+        .box-container1 {
+          position: relative;
+          width: 16%;
+          height: 100%;
+          background: url('../../../../../assets/images/fire/2.png') no-repeat center;
           background-size: 100% 100%;
+          cursor: pointer;
 
-          .text-t {
-            width: 17%;
+          .box-label {
+            position: absolute;
+            left: 50%;
+            top: 2px;
+            transform: translate(-50%);
             color: #fff;
-            font-size: 12px;
           }
 
-          .text-v {
-            width: 83%;
-            font-family: 'douyuFont';
-            font-size: 10px;
-            color: #3df6ff;
+          .box-item {
+            position: absolute;
+            left: 50%;
+            transform: translate(-50%, 0);
+            width: 89%;
+            height: 16%;
+            padding: 0px 10px;
             display: flex;
-            justify-content: flex-end;
+            justify-content: space-between;
+            align-items: center;
+            background: url('../../../../../assets/images/fire/contetn.png') no-repeat center;
+            background-size: 100% 100%;
+
+            .text-t {
+              width: 17%;
+              color: #fff;
+              font-size: 12px;
+            }
+
+            .text-v {
+              width: 83%;
+              font-family: 'douyuFont';
+              font-size: 10px;
+              color: #3df6ff;
+              display: flex;
+              justify-content: flex-end;
+            }
           }
-        }
 
-        .box-item1 {
-          top: 19%;
-        }
+          .box-item1 {
+            top: 19%;
+          }
 
-        .box-item2 {
-          top: 41%;
-        }
+          .box-item2 {
+            top: 41%;
+          }
 
-        .box-item3 {
-          top: 63%;
+          .box-item3 {
+            top: 63%;
+          }
         }
       }
-    }
 
-    .echart-box {
-      display: flex;
-      height: calc(72% - 41px);
+      .echart-box {
+        display: flex;
+        height: calc(72% - 41px);
 
+        .left-echartbox {
+          width: calc(50% - 6px);
+          margin-right: 6px;
+          border: 1px solid #114aac;
+          border-radius: 5px;
 
-      .left-echartbox {
-        width: calc(50% - 6px);
-        margin-right: 6px;
-        border: 1px solid #114aac;
-        border-radius: 5px;
+          .title-f {
+            height: 40px;
+            padding: 0px 10px;
+            box-sizing: border-box;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
 
-        .title-f {
-          height: 40px;
-          padding: 0px 10px;
-          box-sizing: border-box;
-          display: flex;
-          justify-content: space-between;
-          align-items: center;
+            .title-text {
+              font-family: 'douyuFont';
+              font-size: 14px;
+              color: #fff;
+              // color: #3df6ff;
+            }
+          }
 
-          .title-text {
-            font-family: 'douyuFont';
-            font-size: 14px;
-            color: #fff;
-            // color: #3df6ff;
+          .echarts-box {
+            height: calc(100% - 40px);
+            padding: 0px 10px;
+            box-sizing: border-box;
           }
         }
 
-        .echarts-box {
-          height: calc(100% - 40px);
-          padding: 0px 10px;
-          box-sizing: border-box;
+        .right-echartbox {
+          width: calc(50% - 6px);
+          margin-left: 6px;
+          border: 1px solid #114aac;
+          border-radius: 5px;
         }
       }
+    }
+  }
 
-      .right-echartbox {
-        width: calc(50% - 6px);
-        margin-left: 6px;
-        border: 1px solid #114aac;
-        border-radius: 5px;
-      }
+  :deep(.zxm-select:not(.zxm-select-customize-input) .zxm-select-selector) {
+    border: 1px solid #3ad8ff77 !important;
+    background-color: #ffffff00 !important;
+  }
 
-    }
+  :deep(.zxm-select-selection-item) {
+    color: #fff !important;
+  }
+  :deep(.zxm-select-arrow) {
+    color: #fff;
   }
-}
-
-:deep(.zxm-select:not(.zxm-select-customize-input) .zxm-select-selector) {
-  border: 1px solid #3ad8ff77 !important;
-  background-color: #ffffff00 !important;
-}
-
-:deep(.zxm-select-selection-item) {
-  color: #fff !important;
-}
-:deep(.zxm-select-arrow){
-  color: #fff;
-}
 </style>

+ 73 - 72
src/views/vent/monitorManager/alarmMonitor/common/warnFire-bd.vue

@@ -1,87 +1,89 @@
 <template>
-    <div class="warnTargetFire-brt">
-        <div class="top-area">
-            <a-table :columns="columns" :data-source="tableData" bordered :pagination="false" :scroll="{ y: 250 }">
-                <template #bodyCell="{ column, text }">
-                    <template v-if="column.dataIndex === 'alarmdes' || column.dataIndex === 'alarmInfo'">
-                        <div v-for="item in text.split(',')" :key="item">{{ item }}</div>
-                    </template>
-                </template>
-            </a-table>
-        </div>
-        <div class="bot-area">
-            <warnZb :widthV="widthV" :heightV="heightV" :coordDw="coordDw" :widthCanvas="widthCanvas"
-                :heightCanvas="heightCanvas"></warnZb>
-        </div>
+  <div class="warnTargetFire-brt">
+    <div class="top-area">
+      <a-table :columns="columns" :data-source="tableData" bordered :pagination="false" :scroll="{ y: 250 }">
+        <template #bodyCell="{ column, text }">
+          <template v-if="column.dataIndex === 'alarmdes' || column.dataIndex === 'alarmInfo'">
+            <div v-for="item in text.split(',')" :key="item">{{ item }}</div>
+          </template>
+        </template>
+      </a-table>
     </div>
+    <div class="bot-area">
+      <warnZb :widthV="widthV" :heightV="heightV" :coordDw="coordDw" :widthCanvas="widthCanvas" :heightCanvas="heightCanvas" />
+    </div>
+  </div>
 </template>
 <script setup lang="ts">
-import { ref, reactive,watch } from 'vue'
-import warnZb from './warnZb.vue'
-let props=defineProps({
-    tableList:{
-        type:Array,
-        default:()=>{
-            return []
-        }
-    }
-})
+  import { ref, reactive, watch } from 'vue';
+  import warnZb from './warnZb.vue';
+  let props = defineProps({
+    tableList: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+  });
 
-let widthV = ref('80%')
-let heightV = ref('80%')
-let coordDw = ref<any[]>([50, 94])
-let widthCanvas = ref(1240)
-let heightCanvas = ref(364)
-let tableData = ref<any[]>([])
+  let widthV = ref('80%');
+  let heightV = ref('80%');
+  let coordDw = ref<any[]>([50, 94]);
+  let widthCanvas = ref(1240);
+  let heightCanvas = ref(364);
+  let tableData = ref<any[]>([]);
 
-let columns = reactive([
+  let columns = reactive([
     {
-        title: '序号',
-        dataIndex: '',
-        key: 'rowIndex',
-        width: 80,
-        align: 'center',
-        customRender: ({ index }) => {
-            return `${index + 1}`;
-        },
+      title: '序号',
+      dataIndex: '',
+      key: 'rowIndex',
+      width: 80,
+      align: 'center',
+      customRender: ({ index }) => {
+        return `${index + 1}`;
+      },
     },
     {
-        title: '预警等级',
-        dataIndex: 'level',
-        align: 'center',
+      title: '预警等级',
+      dataIndex: 'level',
+      align: 'center',
     },
     {
-        title: '煤自燃阶段',
-        dataIndex: 'alarmName',
-        align: 'center',
+      title: '煤自燃阶段',
+      dataIndex: 'alarmName',
+      align: 'center',
     },
     {
-        title: '指标气体',
-        align: 'center',
-        dataIndex: 'alarmInfo',
+      title: '指标气体',
+      align: 'center',
+      dataIndex: 'alarmInfo',
     },
     {
-        title: '指标气体浓度范围',
-        align: 'center',
-        dataIndex: 'alarmdes',
+      title: '指标气体浓度范围',
+      align: 'center',
+      dataIndex: 'alarmdes',
     },
     {
-        title: '温度',
-        align: 'center',
-        dataIndex: 'temperature',
+      title: '温度',
+      align: 'center',
+      dataIndex: 'temperature',
     },
-])
-
-watch(()=>props.tableList,(newV,oldV)=>{
-    if(newV.length!=0){
-        tableData.value=newV
-    }
-},{immediate:true,deep:true})
+  ]);
 
+  watch(
+    () => props.tableList,
+    (newV, oldV) => {
+      if (newV.length != 0) {
+        tableData.value = newV;
+      }
+    },
+    { immediate: true, deep: true }
+  );
 </script>
 
 <style lang="less" scoped>
-.warnTargetFire-brt {
+  .warnTargetFire-brt {
     width: 100%;
     height: 100%;
     margin: 15px 0px 0px 0px;
@@ -91,17 +93,16 @@ watch(()=>props.tableList,(newV,oldV)=>{
     box-sizing: border-box;
 
     .top-area {
-        height: 40%;
-        margin-bottom: 15px;
-        background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
-        background-size: 100% 100%;
+      height: 40%;
+      margin-bottom: 15px;
+      background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
+      background-size: 100% 100%;
     }
 
     .bot-area {
-        height: calc(60% - 15px);
-        background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
-        background-size: 100% 100%;
-
+      height: calc(60% - 15px);
+      background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
+      background-size: 100% 100%;
     }
-}
-</style>
+  }
+</style>

+ 106 - 105
src/views/vent/monitorManager/alarmMonitor/common/warnFire-brt.vue

@@ -1,122 +1,124 @@
 <template>
-    <div class="warnTargetFire-brt">
-        <div class="top-area">
-            <a-table :columns="columns" :data-source="tableData" bordered :pagination="false" :scroll="{ y: 250 }">
-                <template #bodyCell="{ column, text }">
-                    <template v-if="column.dataIndex === 'alarmdes' || column.dataIndex === 'alarmInfo'">
-                        <div v-for="item in text.split(',')" :key="item">{{ item }}</div>
-                    </template>
-                </template>
-            </a-table>
-        </div>
-        <div class="bot-area">
-            <warnZb :widthV="widthV" :heightV="heightV" :coordDw="coordDw" :widthCanvas="widthCanvas"
-                :heightCanvas="heightCanvas"></warnZb>
-        </div>
+  <div class="warnTargetFire-brt">
+    <div class="top-area">
+      <a-table :columns="columns" :data-source="tableData" bordered :pagination="false" :scroll="{ y: 250 }">
+        <template #bodyCell="{ column, text }">
+          <template v-if="column.dataIndex === 'alarmdes' || column.dataIndex === 'alarmInfo'">
+            <div v-for="item in text.split(',')" :key="item">{{ item }}</div>
+          </template>
+        </template>
+      </a-table>
     </div>
+    <div class="bot-area">
+      <warnZb :widthV="widthV" :heightV="heightV" :coordDw="coordDw" :widthCanvas="widthCanvas" :heightCanvas="heightCanvas" />
+    </div>
+  </div>
 </template>
 <script setup lang="ts">
-import { ref, reactive, watch } from 'vue'
-import { useGlobSetting } from '/@/hooks/setting';
-import warnZb from './warnZb.vue'
-let props = defineProps({
+  import { ref, reactive, watch } from 'vue';
+  import { useGlobSetting } from '/@/hooks/setting';
+  import warnZb from './warnZb.vue';
+  let props = defineProps({
     tableList: {
-        type: Array,
-        default: () => {
-            return []
-        }
-    }
-})
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+  });
 
-let widthV = ref('80%')
-let heightV = ref('80%')
-let coordDw = ref<any[]>([50, 94])
-let widthCanvas = ref(1240)
-let heightCanvas = ref(364)
-let tableData = ref<any[]>([])
+  let widthV = ref('80%');
+  let heightV = ref('80%');
+  let coordDw = ref<any[]>([50, 94]);
+  let widthCanvas = ref(1240);
+  let heightCanvas = ref(364);
+  let tableData = ref<any[]>([]);
 
-let columns = reactive([
+  let columns = reactive([
     {
-        title: '序号',
-        dataIndex: '',
-        key: 'rowIndex',
-        width: 80,
-        align: 'center',
-        customRender: ({ index }) => {
-            return `${index + 1}`;
-        },
+      title: '序号',
+      dataIndex: '',
+      key: 'rowIndex',
+      width: 80,
+      align: 'center',
+      customRender: ({ index }) => {
+        return `${index + 1}`;
+      },
     },
     {
-        title: '预警等级',
-        dataIndex: 'level',
-        align: 'center',
+      title: '预警等级',
+      dataIndex: 'level',
+      align: 'center',
     },
     {
-        title: '煤自燃阶段',
-        dataIndex: 'alarmName',
-        align: 'center',
+      title: '煤自燃阶段',
+      dataIndex: 'alarmName',
+      align: 'center',
     },
     {
-        title: '指标气体',
-        align: 'center',
-        dataIndex: 'alarmInfo',
+      title: '指标气体',
+      align: 'center',
+      dataIndex: 'alarmInfo',
     },
     {
-        title: '指标气体浓度范围',
-        align: 'center',
-        dataIndex: 'alarmdes',
+      title: '指标气体浓度范围',
+      align: 'center',
+      dataIndex: 'alarmdes',
     },
     {
-        title: '温度',
-        align: 'center',
-        dataIndex: 'temperature',
+      title: '温度',
+      align: 'center',
+      dataIndex: 'temperature',
     },
-])
+  ]);
 
-watch(() => props.tableList, (newV, oldV) => {
-    let { sysOrgCode } = useGlobSetting();
-    if (sysOrgCode == 'A02A02') {
+  watch(
+    () => props.tableList,
+    (newV, oldV) => {
+      let { sysOrgCode } = useGlobSetting();
+      if (sysOrgCode == 'A02A02') {
         tableData.value = [
-            {
-                "alarmType": "fireWarn",
-                "alarmdes": "<79.1,<0.12,",
-                "level": "绿色预警",
-                "temperature": "0-120℃",
-                "alarmName": "缓慢氧化阶段(潜伏期)",
-                "id": "1811650465072791911",
-                "alarmInfo": "一氧化碳,一氧化碳/二氧化碳,",
-                "alarmcode": "coval,coCo2,"
-            },
-            {
-                "alarmType": "fireWarn",
-                "alarmdes": "79.1-1653.6,0.12-0.46,<2.4,",
-                "level": "黄色预警",
-                "temperature": "120-200℃",
-                "alarmName": "加速氧化阶段(自热期)",
-                "id": "1811650534094258912",
-                "alarmInfo": "一氧化碳,一氧化碳/二氧化碳,乙烯,",
-                "alarmcode": "coval,coCo2,ch2val,"
-            },
-            {
-                "alarmType": "fireWarn",
-                "alarmdes": ">1653.6,>0.46,>2.4,>0.0,",
-                "level": "红色预警",
-                "temperature": ">200℃",
-                "alarmName": "剧烈氧化阶段(燃烧期)",
-                "id": "1811650769583423913",
-                "alarmInfo": "一氧化碳,一氧化碳/二氧化碳,乙烯,乙炔,",
-                "alarmcode": "coval,coCo2,ch2val,chval,"
-            }
-        ]
-    } else {
-        tableData.value = newV
-    }
-}, { immediate: true, deep: true })
-
+          {
+            alarmType: 'fireWarn',
+            alarmdes: '<79.1,<0.12,',
+            level: '绿色预警',
+            temperature: '0-120℃',
+            alarmName: '缓慢氧化阶段(潜伏期)',
+            id: '1811650465072791911',
+            alarmInfo: '一氧化碳,一氧化碳/二氧化碳,',
+            alarmcode: 'coval,coCo2,',
+          },
+          {
+            alarmType: 'fireWarn',
+            alarmdes: '79.1-1653.6,0.12-0.46,<2.4,',
+            level: '黄色预警',
+            temperature: '120-200℃',
+            alarmName: '加速氧化阶段(自热期)',
+            id: '1811650534094258912',
+            alarmInfo: '一氧化碳,一氧化碳/二氧化碳,乙烯,',
+            alarmcode: 'coval,coCo2,ch2val,',
+          },
+          {
+            alarmType: 'fireWarn',
+            alarmdes: '>1653.6,>0.46,>2.4,>0.0,',
+            level: '红色预警',
+            temperature: '>200℃',
+            alarmName: '剧烈氧化阶段(燃烧期)',
+            id: '1811650769583423913',
+            alarmInfo: '一氧化碳,一氧化碳/二氧化碳,乙烯,乙炔,',
+            alarmcode: 'coval,coCo2,ch2val,chval,',
+          },
+        ];
+      } else {
+        tableData.value = newV;
+      }
+    },
+    { immediate: true, deep: true }
+  );
 </script>
 
 <style lang="less" scoped>
-.warnTargetFire-brt {
+  .warnTargetFire-brt {
     width: 100%;
     height: 100%;
     margin: 15px 0px 0px 0px;
@@ -126,17 +128,16 @@ watch(() => props.tableList, (newV, oldV) => {
     box-sizing: border-box;
 
     .top-area {
-        height: 40%;
-        margin-bottom: 15px;
-        background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
-        background-size: 100% 100%;
+      height: 40%;
+      margin-bottom: 15px;
+      background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
+      background-size: 100% 100%;
     }
 
     .bot-area {
-        height: calc(60% - 15px);
-        background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
-        background-size: 100% 100%;
-
+      height: calc(60% - 15px);
+      background: url('../../../../../assets/images/fire/bj1.png') no-repeat center;
+      background-size: 100% 100%;
     }
-}
-</style>
+  }
+</style>

+ 1 - 1
src/views/vent/monitorManager/alarmMonitor/index.vue

@@ -231,7 +231,7 @@
             </div>
             <div class="item-monitor-box">
               <span class="title">通风监测预警</span>
-              <span :class="centerData.tf ? 'value' : 'value1'">{{ centerData.tf == '正常' ? '低风险' : centerData.tf }}</span>
+              <span :class="centerData.tf !== '异常' ? 'value' : 'value1'">{{ centerData.tf == '正常' ? '低风险' : centerData.tf }}</span>
             </div>
           </div>
         </div>

+ 8 - 6
src/views/vent/monitorManager/comment/DeviceEcharts.vue

@@ -180,12 +180,13 @@
     },
     setup(props) {
       const globalConfig = inject('globalConfig');
+      const stationType = ref('plc1');
       let historyList;
-      if (globalConfig.History_Type == 'vent') {
-        historyList = (params) => defHttp.get({ url: '/safety/ventanalyMonitorData/listdays', params });
-      } else {
-        historyList = (params) => defHttp.post({ url: '/monitor/history/getHistoryData', params });
-      }
+      // if (globalConfig.History_Type == 'vent') {
+      //   historyList = (params) => defHttp.get({ url: '/safety/ventanalyMonitorData/listdays', params });
+      // } else {
+      //   historyList = (params) => defHttp.post({ url: '/monitor/history/getHistoryData', params });
+      // }
       const chartsType = ref('history');
       const deviceId = ref('');
       const options = ref([]);
@@ -272,7 +273,7 @@
               let res;
               if (props.dataSource['stationtype'] !== 'redis') {
                 resultXAxisPropType.value = 'ttime';
-
+                historyList = (params) => defHttp.get({ url: '/safety/ventanalyMonitorData/listdays', params });
                 const datas = await historyList({
                   ttime_begin: newHistoryParams.ttime_begin,
                   ttime_end: newHistoryParams.ttime_end,
@@ -291,6 +292,7 @@
                 }
                 total.value = datas['datalist'].total;
               } else {
+                historyList = (params) => defHttp.post({ url: '/monitor/history/getHistoryData', params });
                 resultXAxisPropType.value = 'time';
                 res = await historyList({
                   pageSize: pageSize.value,

+ 3 - 7
src/views/vent/monitorManager/comment/FanDeviceEcharts.vue

@@ -227,11 +227,6 @@
     setup(props) {
       const globalConfig = inject('globalConfig');
       let historyList;
-      if (globalConfig.History_Type == 'vent') {
-        historyList = (params) => defHttp.get({ url: '/safety/ventanalyMonitorData/listdays', params });
-      } else {
-        historyList = (params) => defHttp.post({ url: '/monitor/history/getHistoryData', params });
-      }
       const chartsType = ref('history');
       const deviceId = ref('');
       const options = ref([]);
@@ -321,9 +316,9 @@
             const device = options.value.find((device) => device['deviceID'] === newDeviceId);
             if (device) {
               let res;
-              if (globalConfig.History_Type == 'vent') {
+              if (props.dataSource['stationtype'] !== 'redis') {
                 resultXAxisPropType.value = 'ttime';
-
+                historyList = (params) => defHttp.get({ url: '/safety/ventanalyMonitorData/listdays', params });
                 const datas = await historyList({
                   ttime_begin: newHistoryParams.ttime_begin,
                   ttime_end: newHistoryParams.ttime_end,
@@ -342,6 +337,7 @@
                 }
                 total.value = datas['datalist'].total;
               } else {
+                historyList = (params) => defHttp.post({ url: '/monitor/history/getHistoryData', params });
                 resultXAxisPropType.value = 'time';
                 res = await historyList({
                   pageSize: pageSize.value,

+ 1 - 1
src/views/vent/monitorManager/comment/GroupMonitorTable.vue

@@ -322,7 +322,7 @@
   :deep(.@{ventSpace}-table-body) {
     height: auto !important;
     &::-webkit-scrollbar {
-      height: 5px !important;
+      height: 10px !important;
     }
   }
   :deep(.jeecg-basic-table .@{ventSpace}-table-wrapper .@{ventSpace}-table-title) {

+ 203 - 71
src/views/vent/monitorManager/comment/components/DeviceBaseInfo.vue

@@ -5,13 +5,14 @@
 </template>
 <script lang="ts" setup>
 
-import { onMounted, ref, defineEmits, onUnmounted, watch, PropType, nextTick } from 'vue';
+import { onMounted, ref, defineEmits, onUnmounted, watch, PropType, nextTick, computed } from 'vue';
 import { BasicModal, useModalInner } from '/@/components/Modal';
 import { BasicForm, useForm } from '/@/components/Form/index';
 import { FormSchema } from '/@/components/Form';
 import { getFormSchemaColumns } from '/@/hooks/web/useWebColumns';
 import { list as substationList } from '/@/views/vent/deviceManager/substationTabel/substation.api';
 import {list, updateDeviceInfo, updateReportInfo } from '../comment.api'
+import { getAutoScrollContainer } from '/@/utils/common/compUtils';
 
 const emit = defineEmits(['close', 'register'])
 const props = defineProps({
@@ -29,64 +30,192 @@ const tabType = ref('deviceInfo')
 const formSchema = ref<FormSchema[]>([])
 const formData = ref({})
 const deviceTypeName = ref('')
+const deviceType = computed(() => props.deviceType)
 
-const arrToFormColumns = (tableHeaderColumns = [], devicetype) => {
-  const columnList: any[] = [];
-  tableHeaderColumns.forEach((item: any) => {
-    let columnsItem;
-    if (item.type == 1 || item.type == 10) {
-      columnsItem = {
-        label: item.des, //_dictText
-        field: item.monitorcode,
-        component: item.type == 1 ? 'Input' : item.type == 10 ? 'InputTextArea' : '',
-      };
-    } else {
-      if (item.type == 2 && item['monitorcode'] == 'nsubstationid') {
-        columnsItem = {
-          label: item.des, //_dictText
-          field: item.monitorcode,
-          component: 'ApiSelect',
-          componentProps: {
-            api: substationList,
-            labelField: 'strname',
-            valueField: 'id',
-          },
-        };
-      }
-      if (item.type == 3) {
-        columnsItem = {
-          label: item.des, //_dictText
-          field: item.monitorcode,
-          component: 'RadioGroup',
-          defaultValue: 1,
-          componentProps: () => {
-            return {
-              options: [
-                { label: '是', value: 1, key: '1' },
-                { label: '否', value: 0, key: '2' },
-              ],
-              stringToNumber: true,
-            };
-          },
-        };
-      }
-      if (item.type == 4) {
+// const arrToFormColumns = (tableHeaderColumns = [], devicetype) => {
+//   const columnList: any[] = [];
+//   tableHeaderColumns.forEach((item: any) => {
+//     let columnsItem;
+//     if (item.type == 1 || item.type == 10) {
+//       columnsItem = {
+//         label: item.des, //_dictText
+//         field: item.monitorcode,
+//         component: item.type == 1 ? 'Input' : item.type == 10 ? 'InputTextArea' : '',
+//       };
+//     } else {
+//       if (item.type == 2 && item['monitorcode'] == 'nsubstationid') {
+//         columnsItem = {
+//           label: item.des, //_dictText
+//           field: item.monitorcode,
+//           component: 'ApiSelect',
+//           componentProps: {
+//             api: substationList,
+//             labelField: 'strname',
+//             valueField: 'id',
+//           },
+//         };
+//       }
+//       if (item.type == 3) {
+//         columnsItem = {
+//           label: item.des, //_dictText
+//           field: item.monitorcode,
+//           component: 'RadioGroup',
+//           defaultValue: 1,
+//           componentProps: () => {
+//             return {
+//               options: [
+//                 { label: '是', value: 1, key: '1' },
+//                 { label: '否', value: 0, key: '2' },
+//               ],
+//               stringToNumber: true,
+//             };
+//           },
+//         };
+//       }
+//       if (item.type == 4) {
+//         columnsItem = {
+//           label: item.des, //_dictText
+//           field: item.monitorcode,
+//           component: 'JDictSelectTag',
+//           componentProps: {
+//             dictCode: item.dict,
+//             placeholder: '请选择',
+//             stringToNumber: true,
+//           },
+//         };
+//       }
+//     }
+//     columnList.push(columnsItem);
+//   });
+//   formSchema.value = columnList
+//   if(tabType.value === 'deviceInfo'){
+//     formSchema.value.unshift(
+//       {
+//         label: '设备id', //_dictText
+//         field: 'id',
+//         component: 'Input',
+//         componentProps: {
+//           disabled: true,
+//           show: false
+//         },
+//       },
+//       {
+//         label: '点表',
+//         field: 'strtype',
+//         component: 'JDictSelectTag',
+//         componentProps: {
+//           dictCode: `${devicetype.split('_')[0]}kind`,
+//           placeholder: '请选择点表',
+//         },
+//       })
+//       formSchema.value.push(
+//       {
+//         label: '备用分站',
+//         field: 'stationids',
+//         component: 'ApiSelect',
+//         componentProps: {
+//           api: substationList,
+//           labelField: 'strname',
+//           valueField: 'id',
+//         },
+//       },
+//     )
+//   }else{
+//     formSchema.value.unshift(
+//       {
+//         label: '设备id', //_dictText
+//         field: 'id',
+//         component: 'Input',
+//         componentProps: {
+//           disabled: true,
+//           show: false
+//         },
+//       })
+//   }
+// };
+
+const arrToFormColumns = (tableHeaderColumns = []) => {
+    const columnList: any[] = [];
+    tableHeaderColumns.forEach((item: any) => {
+      let columnsItem;
+      if (item.type == 1 || item.type == 10) {
         columnsItem = {
           label: item.des, //_dictText
           field: item.monitorcode,
-          component: 'JDictSelectTag',
-          componentProps: {
-            dictCode: item.dict,
-            placeholder: '请选择',
-            stringToNumber: true,
-          },
+          component: item.type == 1 ? 'Input' : item.type == 10 ? 'InputTextArea' : '',
         };
+      } else {
+        if (item.type == 2 && item['monitorcode'] == 'nsubstationid') {
+          columnsItem = {
+            label: item.des, //_dictText
+            field: item.monitorcode,
+            component: 'ApiSelect',
+            componentProps: {
+              api: substationList,
+              labelField: 'strname',
+              valueField: 'id',
+            },
+          };
+        }
+        if (item.type == 3) {
+          columnsItem = {
+            label: item.des, //_dictText
+            field: item.monitorcode,
+            component: 'RadioGroup',
+            defaultValue: 1,
+            componentProps: () => {
+              return {
+                options: [
+                  { label: '是', value: 1, key: '1' },
+                  { label: '否', value: 0, key: '2' },
+                ],
+                stringToNumber: true,
+              };
+            },
+          };
+        }
+        if (item.type == 4) {
+          columnsItem = {
+            label: item.des, //_dictText
+            field: item.monitorcode,
+            component: 'JDictSelectTag',
+            componentProps: {
+              dictCode: item.dict,
+              placeholder: '请选择',
+              // stringToNumber: true,
+            },
+          };
+        }
+        // date日期
+        if (item.type == 8) {
+          columnsItem = {
+            label: item.des, //_dictText
+            field: item.monitorcode,
+            component: 'DatePicker',
+            componentProps: {
+              showTime: false,
+              valueFormat: 'YYYY-MM-DD',
+              getPopupContainer: getAutoScrollContainer,
+            },
+          };
+        }
+        // 日期+时间
+        if (item.type == 9) {
+          columnsItem = {
+            label: item.des, //_dictText
+            field: item.monitorcode,
+            component: 'DatePicker',
+            componentProps: {
+              showTime: true,
+              valueFormat: 'YYYY-MM-DD HH:mm:ss',
+              getPopupContainer: getAutoScrollContainer,
+            },
+          };
+        }
       }
-    }
-    columnList.push(columnsItem);
-  });
-  formSchema.value = columnList
-  if(tabType.value === 'deviceInfo'){
+      columnList.push(columnsItem);
+    });
+    formSchema.value = columnList;
     formSchema.value.unshift(
       {
         label: '设备id', //_dictText
@@ -94,7 +223,6 @@ const arrToFormColumns = (tableHeaderColumns = [], devicetype) => {
         component: 'Input',
         componentProps: {
           disabled: true,
-          show: false
         },
       },
       {
@@ -102,11 +230,13 @@ const arrToFormColumns = (tableHeaderColumns = [], devicetype) => {
         field: 'strtype',
         component: 'JDictSelectTag',
         componentProps: {
-          dictCode: `${devicetype.split('_')[0]}kind`,
+          dictCode: `${deviceType.value}kind`,
           placeholder: '请选择点表',
+          // stringToNumber: true,
         },
-      })
-      formSchema.value.push(
+      }
+    );
+    formSchema.value.push(
       {
         label: '备用分站',
         field: 'stationids',
@@ -117,21 +247,23 @@ const arrToFormColumns = (tableHeaderColumns = [], devicetype) => {
           valueField: 'id',
         },
       },
-    )
-  }else{
-    formSchema.value.unshift(
       {
-        label: '设备id', //_dictText
-        field: 'id',
-        component: 'Input',
-        componentProps: {
-          disabled: true,
-          show: false
+        label: '是否显示',
+        field: 'linkId',
+        component: 'RadioGroup',
+        defaultValue: 1,
+        componentProps: () => {
+          return {
+            options: [
+              { label: '是', value: 1, key: '1' },
+              { label: '否', value: 0, key: '2' },
+            ],
+            stringToNumber: true,
+          };
         },
-      })
-  }
-};
-
+      }
+    );
+  };
 // 注册 modal
 const [register, { closeModal, setModalProps }] = useModalInner(async (data) => {
   tabType.value = data.type
@@ -160,7 +292,7 @@ function getColumns() {
     const arr = deviceTypeName.value.split('_')
     formSchemaArr = getFormSchemaColumns(tabType.value === 'deviceInfo' ? arr[0] + '_edit' : arr[0] + '_input') || []
   }
-  arrToFormColumns(formSchemaArr, deviceTypeName.value)
+  arrToFormColumns(formSchemaArr)
 } 
 
 watch(() => props.deviceType, (devicetype) => {

+ 8 - 2
src/views/vent/monitorManager/deviceMonitor/components/device/index.vue

@@ -738,9 +738,15 @@ async function getDataSource() {
 
 function goLocation(record) {
   if(record['deviceType'] == 'person_bd' || record['deviceType'] == 'car_bd'){
-    actions.setGlobalState({ locationId: record.devNum, locationObj: null, pageObj: null });
+    actions.setGlobalState({ locationId: record.devNum, locationObj: null, pageObj: null, type: record['deviceType'].split('_')[0] });
   }else{
-    actions.setGlobalState({ locationId: record.deviceID, locationObj: null, pageObj: null });
+    if(deviceType.value.startsWith('location')){
+      actions.setGlobalState({ locationId: record.deviceID, locationObj: null, pageObj: null, type: 'person' });
+    }else if(deviceType.value.startsWith('vehicle')) {
+      actions.setGlobalState({ locationId: record.deviceID, locationObj: null, pageObj: null, type: 'car' });
+    }else{
+      actions.setGlobalState({ locationId: record.deviceID, locationObj: null, pageObj: null });
+    }
   }
 }
 

+ 1 - 1
src/views/vent/monitorManager/mainFanMonitor/index.vue

@@ -1470,8 +1470,8 @@
   });
 
   onUnmounted(() => {
-    destroy();
     removeCamera();
+    destroy();
     if (timer) {
       clearTimeout(timer);
       timer = undefined;

+ 3 - 1
src/views/vent/monitorManager/safetyMonitor/index.vue

@@ -349,7 +349,9 @@
 
   function updateSubstation() {
     if (subStation.value) {
-      initSubStation({ substationID: subStation.value });
+      initSubStation({ substationID: subStation.value }).then(() => {
+        message.success('分站同步完成!');
+      });
     } else {
       message.warning('请选择分站!');
     }

+ 1 - 0
src/views/vent/monitorManager/sensorMonitor/index.vue

@@ -17,6 +17,7 @@
               />
               <MonitorTable
                 ref="SensorMonitorRef"
+                :is-show-select="false"
                 :columnsType="deviceKind + '_monitor'"
                 :dataSource="dataSource"
                 design-scope="modelsensor_monitor"

+ 0 - 46
src/views/vent/monitorManager/windowMonitor/dandaoFcYjl.threejs.ts

@@ -238,52 +238,6 @@ class singleWindowYjl {
     }
   }
 
-  async initCamera(dom1?) {
-    const videoPlayer1 = dom1;
-    let monitorPlane: THREE.Mesh | null = null;
-    const canvas = await getTextCanvas(320, 180, '', 'noSinge.png');
-    const textMap = new THREE.CanvasTexture(canvas); // 关键一步
-    const textMaterial = new THREE.MeshBasicMaterial({
-      map: textMap, // 设置纹理贴图
-      transparent: true,
-      side: THREE.DoubleSide, // 这里是双面渲染的意思
-    });
-    textMaterial.blending = THREE.CustomBlending;
-    monitorPlane = this.group?.getObjectByName('noPlayer');
-    if (monitorPlane) {
-      monitorPlane.material = textMaterial;
-    } else {
-      const planeGeometry = new THREE.PlaneGeometry(100, 100); // 平面3维几何体PlaneGeometry
-      monitorPlane = new THREE.Mesh(planeGeometry, textMaterial);
-      textMaterial.dispose();
-      planeGeometry.dispose();
-    }
-    const videoPlayer = this.group.getObjectByName('player1');
-    if (videoPlayer) {
-      this.model.clearMesh(videoPlayer);
-      this.group.remove(videoPlayer);
-    }
-    const noPlayer1 = this.group.getObjectByName('noPlayer1');
-    if (noPlayer1) {
-      this.model.clearMesh(noPlayer1);
-      this.group.remove(noPlayer1);
-    }
-    if (!videoPlayer1 && videoPlayer1 === null) {
-      monitorPlane.name = 'noPlayer1';
-      monitorPlane.scale.set(0.015, 0.007, 0.011);
-      monitorPlane.position.set(4.04, 0.02, -0.46);
-      this.group?.add(monitorPlane);
-    } else if (videoPlayer1) {
-      const mesh = renderVideo(this.group, videoPlayer1, 'player1');
-      if (mesh) {
-        mesh?.scale.set(-0.038, 0.029, 1);
-        mesh?.position.set(-4.302, 0.15, -0.23);
-        mesh.rotation.y = -Math.PI;
-        this.group.add(mesh);
-      }
-    }
-  }
-
   mountedThree() {
     return new Promise((resolve) => {
       this.model.setGLTFModel(['ddFc-yjl'], this.group).then(() => {

+ 1 - 1
src/views/vent/monitorManager/windowMonitor/index.vue

@@ -181,7 +181,7 @@
     fluent
   />
   <HandleModal :modal-is-show="modalIsShow" :modal-title="modalTitle" :modal-type="modalType" @handle-ok="handleOK" @handle-cancel="handleCancel" />
-  <DeviceBaseInfo @register="regModal" :device-type="selectData['deviceType']" />
+  <DeviceBaseInfo @register="regModal" :device-type="deviceType" />
 </template>
 
 <script setup lang="ts">

+ 0 - 101
src/views/vent/monitorManager/windowMonitor/shuangdaoFc.threejs.ts

@@ -13,8 +13,6 @@ class doubleWindow {
     frontWindow: <THREE.Mesh[]>[],
     backWindow: <THREE.Mesh[]>[],
   };
-  playerStartClickTime1 = new Date().getTime();
-  playerStartClickTime2 = new Date().getTime();
 
   constructor(model) {
     this.model = model;
@@ -259,105 +257,6 @@ class doubleWindow {
       });
     }
   }
-
-  async initCamera(dom1?, dom2?) {
-    const videoPlayer1 = dom1;
-    const videoPlayer2 = dom2;
-    let monitorPlane: THREE.Mesh | null = null;
-    if (!videoPlayer1 || !videoPlayer2) {
-      const textArr = [
-        {
-          text: `无信号输入`,
-          font: 'normal 40px Arial',
-          color: '#009900',
-          strokeStyle: '#002200',
-          x: 170,
-          y: 40,
-        },
-      ];
-      const canvas = await getTextCanvas(320, 180, '', 'noSinge.png');
-      let textMaterial: THREE.MeshBasicMaterial | null = null;
-      if (canvas) {
-        const textMap = new THREE.CanvasTexture(canvas); // 关键一步
-        textMaterial = new THREE.MeshBasicMaterial({
-          map: textMap, // 设置纹理贴图
-          transparent: true,
-          side: THREE.DoubleSide, // 这里是双面渲染的意思
-        });
-        textMaterial.blending = THREE.CustomBlending;
-
-        const planeGeometry = new THREE.PlaneGeometry(100, 100); // 平面3维几何体PlaneGeometry
-        monitorPlane = new THREE.Mesh(planeGeometry, textMaterial);
-
-        textMaterial.dispose();
-        planeGeometry.dispose();
-        textMap.dispose();
-      }
-    }
-    const player1 = this.group.getObjectByName('player1');
-    if (player1) {
-      this.model.clearMesh(player1);
-      this.group.remove(player1);
-    }
-    const noPlayer1 = this.group.getObjectByName('noPlayer1');
-    if (noPlayer1) {
-      this.model.clearMesh(noPlayer1);
-      this.group.remove(noPlayer1);
-    }
-    if (!videoPlayer1 && videoPlayer1 === null) {
-      if (monitorPlane && !this.group.getObjectByName('noPlayer1')) {
-        const planeMesh = monitorPlane.clone();
-        planeMesh.name = 'noPlayer1';
-        planeMesh.scale.set(0.011, 0.0053, 0.012);
-        planeMesh.position.set(-4.3, 0.13, -0.23);
-        this.group?.add(planeMesh.clone());
-      }
-    } else if (videoPlayer1) {
-      try {
-        const mesh = renderVideo(this.group, videoPlayer1, 'player1');
-        if (mesh) {
-          mesh?.scale.set(-0.034, 0.024, 1);
-          mesh?.position.set(-3.332, 0.11, -0.23);
-          mesh.rotation.y = -Math.PI;
-          this.group.add(mesh);
-        }
-      } catch (error) {
-        console.log('视频信号异常');
-      }
-    }
-    const player2 = this.group.getObjectByName('player2');
-    if (player2) {
-      this.model.clearMesh(player2);
-      this.group.remove(player2);
-    }
-    const noPlayer2 = this.group.getObjectByName('noPlayer2');
-    if (noPlayer2) {
-      this.model.clearMesh(noPlayer2);
-      this.group.remove(noPlayer2);
-    }
-    if (!videoPlayer2 && videoPlayer2 === null) {
-      if (monitorPlane && !this.group.getObjectByName('noPlayer2')) {
-        const planeMesh = monitorPlane.clone();
-        planeMesh.name = 'noPlayer2';
-        planeMesh.scale.set(0.0085, 0.0056, 0.012);
-        planeMesh.position.set(4.29, 0.02, -0.41);
-        this.group?.add(planeMesh.clone());
-      }
-    } else if (videoPlayer2) {
-      try {
-        const mesh = renderVideo(this.group, videoPlayer2, 'player2');
-        if (mesh) {
-          mesh?.scale.set(-0.034, 0.024, 1);
-          mesh?.position.set(-3.332, 0.11, -0.23);
-          mesh.rotation.y = -Math.PI;
-          this.group.add(mesh);
-        }
-      } catch (error) {
-        console.log('视频信号异常');
-      }
-    }
-  }
-
   mountedThree(playerDom) {
     return new Promise((resolve) => {
       this.model.setGLTFModel(['sdFc'], this.group).then(() => {

+ 302 - 0
src/views/vent/monitorManager/windowMonitor/shuangdaoFcSw.threejs.ts

@@ -0,0 +1,302 @@
+import * as THREE from 'three';
+import { getTextCanvas, renderVideo } from '/@/utils/threejs/util';
+import gsap from 'gsap';
+
+class doubleWindow {
+  model;
+  modelName = 'sdFc';
+  group: THREE.Object3D = new THREE.Object3D();
+  animationTimer;
+  isLRAnimation = true;
+  direction = 1;
+  windowsActionArr = {
+    frontWindow: <THREE.Mesh[]>[],
+    backWindow: <THREE.Mesh[]>[],
+  };
+  constructor(model) {
+    this.model = model;
+    // this.group.name = 'ddFc';
+  }
+  // // 重置摄像头
+  // const resetCamera = () => {
+  //   this.model.camera.position.set(30.328, 58.993, 148.315);
+  //   this.model.camera.rotation.set(-27.88, 14.35, 7.47);
+  //   this.model.orbitControls?.update();
+  //   this.model.camera.updateProjectionMatrix();
+  // };
+
+  addLight = () => {
+    if (!this.model) return;
+
+    const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
+    directionalLight.position.set(-110, 150, 647);
+    this.group?.add(directionalLight);
+    // directionalLight.target = group;
+
+    const pointLight2 = new THREE.PointLight(0xffffff, 1, 150);
+    pointLight2.position.set(-101, 34, 16);
+    pointLight2.shadow.bias = 0.05;
+    this.group.add(pointLight2);
+
+    const pointLight3 = new THREE.PointLight(0xffffff, 1, 150);
+    pointLight3.position.set(19, 25, -7);
+    pointLight3.shadow.bias = 0.05;
+    this.group.add(pointLight3);
+
+    const pointLight6 = new THREE.PointLight(0xffffff, 1, 300);
+    pointLight6.position.set(51, 51, 9);
+    pointLight6.shadow.bias = 0.05;
+    this.group.add(pointLight6);
+  };
+
+  // 设置模型位置
+  setModalPosition() {
+    this.group?.scale.set(22, 22, 22);
+    this.group?.position.set(-35, 25, 15);
+  }
+
+  addMonitorText(selectData) {
+    if (!this.group) {
+      return;
+    }
+    const screenDownText = VENT_PARAM['modalText']
+      ? VENT_PARAM['modalText']
+      : History_Type['type'] == 'remote'
+      ? `国能神东煤炭集团监制`
+      : '煤炭科学技术研究院有限公司研制';
+
+    const screenDownTextX = 120 - (screenDownText.length - 10) * 6;
+    const textArr = [
+      {
+        text: `远程定量调节自动风窗`,
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 110,
+        y: 90,
+      },
+      {
+        text: `${selectData.OpenDegree ? '开度值(%)' : selectData.forntArea ? '过风面积(㎡)' : '过风面积(㎡)'}:`,
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 5,
+        y: 145,
+      },
+      {
+        text: selectData.OpenDegree
+          ? Number(`${selectData.OpenDegree}`).toFixed(2)
+          : selectData.forntArea
+          ? Number(`${selectData.forntArea}`).toFixed(2)
+          : '-',
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 330,
+        y: 145,
+      },
+      {
+        text: `${selectData.frontRearDP ? '风窗压差(Pa)' : selectData.windSpeed ? '风速(m/s)' : '通信状态'}:`,
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 5,
+        y: 200,
+      },
+      {
+        text: `${
+          selectData.frontRearDP
+            ? selectData.frontRearDP
+            : selectData.windSpeed
+            ? selectData.windSpeed
+            : selectData.netStatus == '0'
+            ? '断开'
+            : '连接'
+        }`,
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 330,
+        y: 200,
+      },
+      {
+        text: `${selectData.fWindowM3 ? '过风量(m³/min)' : '风窗道数'}: `,
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 5,
+        y: 256,
+      },
+      {
+        text: `${selectData.fWindowM3 ? selectData.fWindowM3 : selectData.nwindownum}`,
+        font: 'normal 30px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: 330,
+        y: 256,
+      },
+      {
+        text: screenDownText,
+        font: 'normal 28px Arial',
+        color: '#009900',
+        strokeStyle: '#002200',
+        x: screenDownTextX,
+        y: 302,
+      },
+    ];
+
+    getTextCanvas(726, 546, textArr, '').then((canvas: HTMLCanvasElement) => {
+      const textMap = new THREE.CanvasTexture(canvas); // 关键一步
+      const textMaterial = new THREE.MeshBasicMaterial({
+        // 关于材质并未讲解 实操即可熟悉                 这里是漫反射类似纸张的材质,对应的就有高光类似金属的材质.
+        map: textMap, // 设置纹理贴图
+        transparent: true,
+        side: THREE.DoubleSide, // 这里是双面渲染的意思
+      });
+      textMap.dispose();
+      textMaterial.blending = THREE.CustomBlending;
+      const monitorPlane = this.group?.getObjectByName('monitorText');
+      if (monitorPlane) {
+        monitorPlane.material = textMaterial;
+      } else {
+        const planeGeometry = new THREE.PlaneGeometry(570, 346); // 平面3维几何体PlaneGeometry
+        const planeMesh = new THREE.Mesh(planeGeometry, textMaterial);
+        planeMesh.name = 'monitorText';
+        planeMesh.scale.set(0.0025, 0.003, 0.002);
+        planeMesh.position.set(3.71, -0.042, -0.23);
+        this.group?.add(planeMesh);
+      }
+    });
+  }
+
+  /* 提取风门序列帧,初始化前后门动画 */
+  initAnimation() {
+    const meshArr01: THREE.Object3D[] = [];
+    const meshArr02: THREE.Object3D[] = [];
+    const windowGroup = new THREE.Group();
+    const fcObj = this.group.getObjectByName('ddFc');
+    windowGroup.name = 'hiddenGroup';
+    const leftObjNames = ['FCshanye03', 'FCshanye01', 'FCshanye02', 'FCshanye12', 'FCshanye11', 'FCshanye10'];
+    const rightObjNames = ['FCshanye04', 'FCshanye05', 'FCshanye06', 'FCshanye07', 'FCshanye08', 'FCshanye09'];
+    leftObjNames.filter((name) => {
+      const obj = fcObj?.getObjectByName(name);
+      if (obj) {
+        obj.rotateOnAxis(new THREE.Vector3(0, 1, 0), 0);
+        meshArr01.push(obj);
+      }
+    });
+    rightObjNames.filter((name) => {
+      const obj = fcObj?.getObjectByName(name);
+      if (obj) {
+        obj.rotateOnAxis(new THREE.Vector3(0, 1, 0), 0);
+        meshArr02.push(obj);
+      }
+    });
+    this.windowsActionArr.frontWindow = meshArr01;
+    this.windowsActionArr.backWindow = meshArr02;
+    this.group?.add(windowGroup);
+  }
+
+  play(rotationParam, flag) {
+    if (this.windowsActionArr.frontWindow.length <= 0 || this.windowsActionArr.backWindow.length <= 0) {
+      return;
+    }
+    if (flag === 1) {
+      // 前风窗动画
+      this.windowsActionArr.frontWindow.forEach((mesh) => {
+        gsap.to(mesh.rotation, {
+          y: THREE.MathUtils.degToRad(rotationParam.frontDeg1),
+          duration: (1 / 9) * Math.abs(rotationParam.frontDeg1 - mesh.rotation.y),
+          overwrite: true,
+        });
+      });
+    } else if (flag === 2) {
+      // 后风窗动画
+      this.windowsActionArr.backWindow.forEach((mesh) => {
+        gsap.to(mesh.rotation, {
+          y: THREE.MathUtils.degToRad(rotationParam.backDeg1),
+          duration: (1 / 9) * Math.abs(rotationParam.backDeg1 - mesh.rotation.y),
+          overwrite: true,
+        });
+      });
+    } else if (flag === 0) {
+      ([...this.windowsActionArr.frontWindow, ...this.windowsActionArr.backWindow] as THREE.Mesh[]).forEach((mesh) => {
+        gsap.to(mesh.rotation, {
+          y: 0,
+          overwrite: true,
+        });
+      });
+    }
+  }
+
+  /* 点击风窗,风窗全屏 */
+  mousedownModel(intersects: THREE.Intersection<THREE.Object3D<THREE.Event>>[]) {
+    this.isLRAnimation = false;
+    if (this.animationTimer) {
+      clearTimeout(this.animationTimer);
+      this.animationTimer = null;
+    }
+    // 判断是否点击到视频
+    intersects.find((intersect) => {
+      const mesh = intersect.object;
+      if (mesh.name === 'player1') {
+        if (new Date().getTime() - this.playerStartClickTime1 < 400) {
+          // 双击,视频放大
+          if (this.player1) {
+            this.player1.requestFullscreen();
+          }
+        }
+        this.playerStartClickTime1 = new Date().getTime();
+        return true;
+      }
+      return false;
+    });
+  }
+
+  mouseUpModel() {
+    // 10s后开始摆动
+    if (!this.animationTimer && !this.isLRAnimation) {
+      this.animationTimer = setTimeout(() => {
+        this.isLRAnimation = true;
+      }, 10000);
+    }
+  }
+
+  /* 风门动画 */
+  render() {
+    if (!this.model) {
+      return;
+    }
+    if (this.isLRAnimation && this.group) {
+      // 左右摇摆动画
+      if (Math.abs(this.group.rotation.y) >= 0.2) {
+        this.direction = -this.direction;
+        this.group.rotation.y += 0.00002 * 30 * this.direction;
+      } else {
+        this.group.rotation.y += 0.00002 * 30 * this.direction;
+      }
+    }
+  }
+
+  mountedThree(playerDom) {
+    return new Promise((resolve) => {
+      this.model.setGLTFModel('ddFc').then((gltf) => {
+        const fcModal = gltf[0];
+        fcModal.name = 'ddFc';
+        this.group?.add(fcModal);
+        this.setModalPosition();
+        this.initAnimation();
+        this.addLight();
+        resolve(null);
+      });
+    });
+  }
+
+  destroy() {
+    this.model.clearGroup(this.group);
+    this.windowsActionArr.frontWindow = undefined;
+    this.model = null;
+    this.group = null;
+  }
+}
+export default doubleWindow;

+ 26 - 10
src/views/vent/monitorManager/windowMonitor/window.threejs.ts

@@ -6,7 +6,6 @@ import singleWindowXk from './dandaoFcXk.threejs';
 import { animateCamera } from '/@/utils/threejs/util';
 import useEvent from '../../../../utils/threejs/useEvent';
 import { useGlobSetting } from '/@/hooks/setting';
-import { modal } from 'vxe-table';
 
 // import * as dat from 'dat.gui';
 // const gui = new dat.GUI();
@@ -98,11 +97,20 @@ export const addMonitorText = (selectData) => {
 
 export function computePlay(data, maxarea, isFirst = false) {
   if (windowType === 'doubleWindow' || windowType === 'singleWindow') {
-    if (!maxarea) maxarea = 90;
-    rotationParam.frontDeg0 = (90 / maxarea) * Number(isFirst ? 0 : data.forntArea);
-    rotationParam.backDeg0 = (90 / maxarea) * Number(isFirst ? 0 : data.rearArea);
-    rotationParam.frontDeg1 = (90 / maxarea) * Number(data.forntArea) || 0;
-    rotationParam.backDeg1 = (90 / maxarea) * Number(data.rearArea) || 0;
+    if (data.OpenDegree || data.OpenDegree1 || data.OpenDegree2) {
+      maxarea = 90;
+      rotationParam.frontDeg0 = (90 / maxarea) * Number(isFirst ? 0 : data.OpenDegree1);
+      rotationParam.backDeg0 = (90 / maxarea) * Number(isFirst ? 0 : data.OpenDegree2);
+      rotationParam.frontDeg1 = (90 / maxarea) * Number(data.OpenDegree1) || 0;
+      rotationParam.backDeg1 = (90 / maxarea) * Number(data.OpenDegree2) || 0;
+    } else {
+      if (!maxarea) maxarea = 90;
+      rotationParam.frontDeg0 = (90 / maxarea) * Number(isFirst ? 0 : data.forntArea);
+      rotationParam.backDeg0 = (90 / maxarea) * Number(isFirst ? 0 : data.rearArea);
+      rotationParam.frontDeg1 = (90 / maxarea) * Number(data.forntArea) || 0;
+      rotationParam.backDeg1 = (90 / maxarea) * Number(data.rearArea) || 0;
+    }
+
     if (!rotationParam.frontDeg1 && !rotationParam.backDeg1) {
       // 当返回值有误时默认关闭
       play(rotationParam, 0);
@@ -152,7 +160,7 @@ export const play = (rotationParam, flag) => {
 export const setModelType = (type) => {
   // if (!model || !model.scene) return;
   const { sysOrgCode } = useGlobSetting();
-  // sysOrgCode = 'sdmtjtyjlmk';
+  // const sysOrgCode = 'sdmtjtyjlmk';
   windowType = type;
   return new Promise((resolve) => {
     // 显示双道风窗
@@ -217,15 +225,15 @@ export const setModelType = (type) => {
 };
 
 export const mountedThree = (playerDom) => {
-  const { sysOrgCode } = useGlobSetting();
-  // sysOrgCode = 'sdmtjtyjlmk';
+  // const { sysOrgCode } = useGlobSetting();
+  const sysOrgCode = 'sdmtjtswmk';
   return new Promise(async (resolve) => {
     model = new UseThree('#window3D');
     if (!model || !model.renderer || !model.camera) return;
     model.setEnvMap('test1');
 
     model.camera.position.set(100, 0, 1000);
-    doubleWindowObj = new doubleWindow(model);
+
     singleWindowXkObj = new singleWindowXk(model);
     if (sysOrgCode === 'sdmtjtbetmk') {
       const singleWindowBet = await import('./dandaoFcBet.threejs');
@@ -237,6 +245,14 @@ export const mountedThree = (playerDom) => {
     } else {
       singleWindowObj = new singleWindow(model);
     }
+
+    if (sysOrgCode === 'sdmtjtswmk') {
+      const doubleWindow = await import('./shuangdaoFcSw.threejs');
+      if (doubleWindow) doubleWindowObj = new doubleWindow.default(model);
+    } else {
+      doubleWindowObj = new doubleWindow(model);
+    }
+
     doubleWindowObj.mountedThree(playerDom);
     singleWindowXkObj.mountedThree();
     singleWindowObj.mountedThree(playerDom);