Bladeren bron

设备管理样式修改、监测自测修改

hrx 2 jaren geleden
bovenliggende
commit
4d5141cd6f
53 gewijzigde bestanden met toevoegingen van 1091 en 447 verwijderingen
  1. 2 1
      .env.development
  2. 2 2
      .env.production
  3. BIN
      public/model/glft/cf/dscf.glb
  4. BIN
      public/model/glft/jbfj/jbfj_hd.glb
  5. 0 1
      src/App.vue
  6. 1 1
      src/components/Application/src/AppLogo.vue
  7. 2 2
      src/components/Form/src/types/form.ts
  8. 8 1
      src/components/Table/src/BasicTable.vue
  9. 6 6
      src/components/jeecg/OnLine/JPopupOnlReport.vue
  10. 47 6
      src/design/vent/index.less
  11. 33 12
      src/design/vent/modal.less
  12. 3 6
      src/layouts/default/content/index.vue
  13. 12 2
      src/layouts/default/header/index.less
  14. 9 0
      src/layouts/default/header/index.vue
  15. 1 0
      src/layouts/default/index.vue
  16. 1 5
      src/views/sys/micro/index.vue
  17. 7 7
      src/views/system/address/index.vue
  18. 3 3
      src/views/system/category/index.vue
  19. 4 4
      src/views/system/depart/index.vue
  20. 4 4
      src/views/system/departUser/index.vue
  21. 31 29
      src/views/system/dict/index.vue
  22. 2 2
      src/views/system/menu/index.vue
  23. 28 25
      src/views/system/role/index.vue
  24. 1 1
      src/views/system/user/index.vue
  25. 38 1
      src/views/vent/deviceManager/comment/NormalTable.vue
  26. 18 16
      src/views/vent/deviceManager/damperTabel/index.vue
  27. 16 14
      src/views/vent/deviceManager/deviceColumns/index.vue
  28. 17 15
      src/views/vent/deviceManager/fanTabel/index.vue
  29. 15 13
      src/views/vent/deviceManager/ledTabel/index.vue
  30. 17 15
      src/views/vent/deviceManager/pointTabel/index.vue
  31. 15 13
      src/views/vent/deviceManager/sensorTabel/index.vue
  32. 23 21
      src/views/vent/deviceManager/substationTabel/index.vue
  33. 16 14
      src/views/vent/deviceManager/tableColumns/index.vue
  34. 17 15
      src/views/vent/deviceManager/windWindowTabel/index.vue
  35. 17 15
      src/views/vent/deviceManager/windfindingTabel/index.vue
  36. 18 16
      src/views/vent/deviceManager/workingFace/index.vue
  37. 7 1
      src/views/vent/monitorManager/comment/GroupMonitorTable.vue
  38. 23 9
      src/views/vent/monitorManager/comment/MonitorTable.vue
  39. 6 4
      src/views/vent/monitorManager/fanLocalMonitor/fanLocal.three.ts
  40. 50 12
      src/views/vent/monitorManager/fanLocalMonitor/index.vue
  41. 1 3
      src/views/vent/monitorManager/gateMonitor/detail.vue
  42. 7 4
      src/views/vent/monitorManager/gateMonitor/gate.threejs.ts
  43. 180 85
      src/views/vent/monitorManager/gateMonitor/index.vue
  44. 64 0
      src/views/vent/monitorManager/gateMonitor/modal.vue
  45. 42 9
      src/views/vent/monitorManager/mainFanMonitor/index.vue
  46. 2 1
      src/views/vent/monitorManager/mainFanMonitor/main.threejs.ts
  47. 80 11
      src/views/vent/monitorManager/mainFanMonitor/mainWind.threejs.ts
  48. 69 4
      src/views/vent/monitorManager/sensorMonitor/index.vue
  49. 44 8
      src/views/vent/monitorManager/windowMonitor/index.vue
  50. 71 0
      src/views/vent/monitorManager/windowMonitor/modal.vue
  51. 2 2
      src/views/vent/monitorManager/windrectMonitor/index.vue
  52. 3 3
      src/views/vent/monitorManager/windrectMonitor/longmen.threejs.ts
  53. 6 3
      src/views/vent/monitorManager/windrectMonitor/windrect.threejs.ts

+ 2 - 1
.env.development

@@ -24,5 +24,6 @@ VITE_GLOB_DOMAIN_URL=http://47.94.222.6:9999
 VITE_GLOB_API_URL_PREFIX=
 
 #微前端qiankun应用,命名必须以VITE_APP_SUB_开头,jeecg-app-1为子应用的项目名称,也是子应用的路由父路径
-VITE_APP_SUB_APP = [["micro-need-air", "//182.92.126.35:8099/"], ["micro-vent-3dModal", "//localhost:8091/"], ["micro-fire-front", "//localhost:8090/"]]
+#VITE_APP_SUB_APP = [["micro-need-air", "//182.92.126.35:8099/"], ["micro-vent-3dModal", "//localhost:8091/"], ["micro-fire-front", "//localhost:8090/"]]
+VITE_APP_SUB_APP = [["micro-vent-3dModal", "//localhost:8091/"], ["micro-need-air", "//localhost:8099/"]]
 

+ 2 - 2
.env.production

@@ -37,5 +37,5 @@ VITE_USE_PWA = false
 VITE_LEGACY = false
 
 #微前端qiankun应用,命名必须以VITE_APP_SUB_开头,jeecg-app-1为子应用的项目名称,也是子应用的路由父路径
-VITE_APP_SUB_APP = [["micro-need-air", "//182.92.126.35:8099/"], ["micro-vent-3dModal", "//47.94.222.6:7121/"]]
-#VITE_APP_SUB_APP = [["micro-need-air", "//182.92.126.35:8099/"], ["micro-vent-3dModal", "//127.0.0.1:30000/"]]
+#VITE_APP_SUB_APP = [["micro-need-air", "//182.92.126.35:8099/"], ["micro-vent-3dModal", "//47.94.222.6:7121/"]]
+VITE_APP_SUB_APP = [["micro-need-air", "//127.0.0.1:20000/"], ["micro-vent-3dModal", "//127.0.0.1:30000/"]]

BIN
public/model/glft/cf/dscf.glb


BIN
public/model/glft/jbfj/jbfj_hd.glb


+ 0 - 1
src/App.vue

@@ -35,7 +35,6 @@
   if (screen.height === body.height && screen.width === body.width) {
     height.value = 1080;
   }
-  console.log('[ 屏幕可视高 ] >', height.value, body.height);
 
   useTitle();
 </script>

+ 1 - 1
src/components/Application/src/AppLogo.vue

@@ -82,7 +82,7 @@
     }
 
     &__title {
-      font-size: 16px;
+      font-size: 18px;
       font-weight: 700;
       transition: all 0.5s;
       line-height: normal;

+ 2 - 2
src/components/Form/src/types/form.ts

@@ -195,9 +195,9 @@ export interface FormSchema {
 
   // 这个属性自定义的 用于自定义的业务 比如在表单打开的时候修改表单的禁用状态,但是又不能重写componentProps,因为他的内容太多了,所以使用dynamicDisabled和buss实现
   buss?: any;
-  
+
   //label字数控制(label宽度)
-  labelLength?: number
+  labelLength?: number;
 }
 export interface HelpComponentProps {
   maxWidth: string;

+ 8 - 1
src/components/Table/src/BasicTable.vue

@@ -17,7 +17,14 @@
     <!-- antd v3 升级兼容,阻止数据的收集,防止控制台报错 -->
     <!-- https://antdv.com/docs/vue/migration-v3-cn -->
     <a-form-item-rest>
-      <Table ref="tableElRef" v-bind="getBindValues" :rowClassName="getRowClassName" v-show="getEmptyDataIsShowTable" @resizeColumn="handleResizeColumn" @change="handleTableChange">
+      <Table
+        ref="tableElRef"
+        v-bind="getBindValues"
+        :rowClassName="getRowClassName"
+        v-show="getEmptyDataIsShowTable"
+        @resizeColumn="handleResizeColumn"
+        @change="handleTableChange"
+      >
         <template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
           <slot :name="item" v-bind="data || {}"></slot>
         </template>

+ 6 - 6
src/components/jeecg/OnLine/JPopupOnlReport.vue

@@ -6,12 +6,12 @@
           <template v-for="(item, index) in queryInfo">
             <template v-if="item.hidden === '1'">
               <a-col :md="6" :sm="24" :key="'query' + index" v-show="toggleSearchStatus">
-                <SearchFormItem :formElRef="formRef" :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></SearchFormItem>
+                <SearchFormItem :formElRef="formRef" :queryParam="queryParam" :item="item" :dictOptions="dictOptions" />
               </a-col>
             </template>
             <template v-else>
               <a-col :md="6" :sm="24" :key="'query' + index">
-                <SearchFormItem :formElRef="formRef" :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></SearchFormItem>
+                <SearchFormItem :formElRef="formRef" :queryParam="queryParam" :item="item" :dictOptions="dictOptions" />
               </a-col>
             </template>
           </template>
@@ -64,7 +64,7 @@
   import { usePopBiz } from '/@/components/jeecg/OnLine/hooks/usePopBiz';
   import { useMessage } from '/@/hooks/web/useMessage';
   import { useRoute } from 'vue-router';
-  
+
   export default defineComponent({
     name: 'JPopupOnlReport',
     components: {
@@ -91,9 +91,9 @@
       const attrs = useAttrs();
       const tableScroll = ref({ x: true });
       const route = useRoute();
-      console.log('route.query = ',route.query)
-      const getBindValue = Object.assign({}, {routeQuery: route.query}, unref(props), unref(attrs));
-      
+      console.log('route.query = ', route.query);
+      const getBindValue = Object.assign({}, { routeQuery: route.query }, unref(props), unref(attrs));
+
       const [
         {
           visibleChange,

+ 47 - 6
src/design/vent/index.less

@@ -5,6 +5,7 @@
 
 .vent {
   background-color: #03114c !important;
+  // background-color: #031d4c !important; //031d4c
 }
 /* 表单 */
 .vent-form {
@@ -81,6 +82,8 @@
     .ant-select-dropdown {
       border-bottom: 1px solid #ececec66;
       background: #fff;
+      left: 0px !important;
+      top: 36px !important;
     }
     .ant-upload.ant-upload-select-picture-card,
     .ant-input-affix-wrapper {
@@ -97,6 +100,11 @@
         color: #000 !important;
       }
     }
+    .ant-btn-primary {
+      .anticon {
+        color: #fff !important;
+      }
+    }
   }
 }
 .vent-modal {
@@ -201,12 +209,12 @@
 }
 
 .ant-card {
-  border: 1px solid #4d7ad855;
-  border-radius: 2px;
-  background-color: @vent-transparent !important;
-  -webkit-backdrop-filter: blur(8px);
-  backdrop-filter: blur(8px);
-  box-shadow: 0 0 10px #5984e055 inset;
+  border: 1px solid #44d3ff70 !important;
+  border-radius: 2px !important;
+  -webkit-backdrop-filter: blur(8px) !important;
+  backdrop-filter: blur(8px) !important;
+  box-shadow: 0 0 20px #44b4ff33 inset;
+  background-color: #ffffff11 !important;
   .ant-tree {
     background-color: @vent-transparent !important;
     color: @vent-font-color !important;
@@ -276,3 +284,36 @@
     }
   }
 }
+
+.device-manager-box {
+  margin: 10px 8px;
+  height: calc(100% - 30px);
+  padding-bottom: 10px;
+  // border: 1px solid #447fff55;
+  border: 1px solid #44d3ff70;
+  border-radius: 2px;
+  // background-color: #001d3055;
+  -webkit-backdrop-filter: blur(8px);
+  backdrop-filter: blur(8px);
+  box-shadow: 0 0 20px #44b4ff33 inset;
+  background-color: #ffffff11;
+  // background-color: #00b3ff12;
+  .ant-table-thead > tr > th {
+    color: #8ee3fa !important;
+    font-weight: 600;
+  }
+}
+
+.ant-btn-primary {
+  border-color: #91e9fe !important;
+  background: #275088 !important;
+}
+
+.ant-btn:hover,
+.ant-btn:focus {
+  background: #27508899 !important;
+  border-color: #91e9fe99 !important;
+}
+.ant-btn-link {
+  color: #00e7ff !important;
+}

+ 33 - 12
src/design/vent/modal.less

@@ -1,17 +1,30 @@
 .bg {
   width: 100%;
   height: 100%;
-  //background: url('/@/assets/images/vent/bg.png');
+  background: url('/@/assets/images/vent/bg4.png') no-repeat;
+  background-size: cover;
   //background-repeat: no-repeat;
-  //background-size: cover;
   position: relative;
-
+  &::before {
+    content: '';
+    width: 100%;
+    height: 100%;
+    display: block;
+    position: absolute;
+    left: 0;
+    top: 0;
+    background: #03114ccc;
+  }
   .threejs-Object-CSS {
     .elementContent {
-      background-color: rgb(20 143 221 / 40%);
-      box-shadow: 0px 0px 12px rgb(0 128 255 / 75%);
-      border: 1px solid rgb(127 177 255 / 75%);
-      padding: 10px 20px 0px 20px;
+      // background-color: rgb(20 143 221 / 40%);
+      // box-shadow: 0px 0px 12px rgb(0 128 255 / 75%);
+      // border: 1px solid rgb(127 177 255 / 75%);
+      // padding: 10px 20px 0px 20px;
+      background-color: rgba(0, 0, 0, 0.3);
+      box-shadow: 0px 0px 40px rgb(0 90 131 / 55%) inset;
+      border: 2px solid rgb(153 176 195 / 55%);
+      padding: 15px 20px 0px 20px;
       color: #efefef;
       &::before {
         content: '';
@@ -31,7 +44,7 @@
         position: absolute;
         width: 21px;
         height: 21px;
-        border: 4px solid #755cf8;
+        border: 4px solid #f2a811;
         background: rgba(173, 204, 253, 0.75);
         bottom: -55px;
         right: -85px;
@@ -205,13 +218,13 @@
       }
     }
     .button-disable {
-      border: 1px solid #66989e;
+      border: 1px solid #66989e !important;
 
       &:hover {
-        background: none;
+        background: none !important;
       }
       &::before {
-        background: linear-gradient(#78c8fd55, #49d2fc55);
+        background: linear-gradient(#1fa6cbcc, #127cb5cc) !important;
       }
       // &::after{
       //   background: linear-gradient( #75c8ff55, #45d1fc55);
@@ -296,7 +309,8 @@
       bottom: 0;
       height: 100%;
       pointer-events: auto;
-      background: linear-gradient(#00daff33, #2081ff11);
+      // background: linear-gradient(#00daff33, #2081ff11);
+      background: linear-gradient(#0091aa33, #2081ff11);
       // background: radial-gradient(circle at 50% 80%, #3df6ff33, #0038b433);
       backdrop-filter: blur(5px);
       overflow-y: hidden;
@@ -320,6 +334,13 @@
       }
       .vent-table {
         overflow-y: auto;
+        .ant-table-column-title,
+        .ant-table-thead > tr > th {
+          color: #39f2ff !important;
+        }
+        .ant-progress-text {
+          color: #fff !important;
+        }
       }
       .ant-tabs-nav {
         margin-bottom: 0px !important;

+ 3 - 6
src/layouts/default/content/index.vue

@@ -60,15 +60,12 @@
 
       const getShowFullHeader = computed(() => {
         const route = unref(currentRoute);
-        return getShowFullHeaderRef && !route.path.startsWith('/micro-');
-      });
-      onBeforeMount(() => {
-        const route = unref(currentRoute);
         if (!route.path.startsWith('/micro-')) {
-          document.getElementsByName('body')[0];
-          // debugger;
+          document.body.removeAttribute('class', 'style-styleTwo');
         }
+        return getShowFullHeaderRef && !route.path.startsWith('/micro-');
       });
+      onBeforeMount(() => {});
       onMounted(() => {
         //注册openQianKun
         // console.log('window.qiankunStarted------>', window.qiankunStarted);

+ 12 - 2
src/layouts/default/header/index.less

@@ -181,11 +181,18 @@
   }
 
   &--light {
-    background-color: transparent !important;
-    border: none;
+    // background-color: transparent !important;
+
     // border-bottom: 1px solid @header-light-bottom-border-color;
     // border-left: 1px solid @header-light-bottom-border-color;
 
+    // background: linear-gradient(#02050c 0%, #03114c 100%);
+    // border: none;
+    background: linear-gradient(#003f77, #0a134c);
+    border-bottom: 1px solid #81aabf01;
+    padding-bottom: 2px;
+    box-shadow: 0 0 20px #44caff55 inset;
+
     .@{header-prefix-cls}-logo {
       //color: @text-color-base;
       color: #0a8fe9;
@@ -257,4 +264,7 @@
 .vent-header {
   height: 120px !important;
   background: url('/src/assets/images/vent/header-bg.png') no-repeat !important;
+  border: none !important;
+  padding-bottom: 0px !important;
+  box-shadow: none !important;
 }

+ 9 - 0
src/layouts/default/header/index.vue

@@ -4,6 +4,9 @@
     <div :class="`${prefixCls}-left`">
       <!-- logo -->
       <AppLogo v-if="getShowHeaderLogo || getIsMobile" :class="`${prefixCls}-logo`" :theme="getHeaderTheme" :style="getLogoWidth" />
+      <div v-if="!currentRoute.path.startsWith('/monitorChannel/monitor-')" style="margin-top: 5px; color: #aaa; margin-left: 10px; font-weight: 600"
+        >/{{ currentRoute.meta.title }}</div
+      >
       <!-- <LayoutTrigger
         v-if="(getShowContent && getShowHeaderTrigger && !getSplit && !getIsMixSidebar) || getIsMobile"
         :theme="getHeaderTheme"
@@ -252,4 +255,10 @@
     }
     //update-end---author:scott ---date::2022-09-30  for:默认隐藏顶部菜单面包屑--------------
   }
+  // background: linear-gradient(#003f77, #0a134c);
+  //   // background: linear-gradient(#02050c 0%, #03114c 100%);
+  //   // border: none;
+  //   border-bottom: 1px solid #81aabf01;
+  //   padding-bottom: 2px;
+  //   box-shadow: 0 0 20px #44caff55 inset;
 </style>

+ 1 - 0
src/layouts/default/index.vue

@@ -81,6 +81,7 @@
 
     > .ant-layout {
       min-height: 100%;
+      background-color: #ffffff00 !important;
     }
 
     &-main {

+ 1 - 5
src/views/sys/micro/index.vue

@@ -1,12 +1,8 @@
 <template>
-  <!-- <div id="content"></div> -->
+  <div></div>
 </template>
 <script lang="ts" setup>
   import { onMounted } from 'vue';
-  // import registerApps from '/@/qiankun';
-  import { useGlobSetting } from '/@/hooks/setting';
-  const globSetting = useGlobSetting();
-  // const openQianKun = globSetting.openQianKun;
   onMounted(() => {
     //注册openQianKun
     // if (openQianKun == 'true') {

+ 7 - 7
src/views/system/address/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <a-row :class="['p-4', `${prefixCls}--box`]" type="flex" :gutter="10" style="max-height: 800px">
+  <a-row :class="['p-4', `${prefixCls}--box`]" type="flex" :gutter="10" style="max-height: 800px; margin-top: 10px">
     <a-col :xl="6" :lg="24" :md="24" style="margin-bottom: 10px">
       <DepartLeftTree ref="leftTree" @select="onTreeSelect" />
     </a-col>
@@ -87,11 +87,11 @@
 <style lang="less" scoped>
   @import './index.less';
   .table-box {
-    border: 1px solid #4d7ad855;
-    border-radius: 2px;
-    background-color: #ffffff00 !important;
-    -webkit-backdrop-filter: blur(8px);
-    backdrop-filter: blur(8px);
-    box-shadow: 0 0 10px #5984e055 inset;
+    border: 1px solid #44d3ff70 !important;
+    border-radius: 2px !important;
+    -webkit-backdrop-filter: blur(8px) !important;
+    backdrop-filter: blur(8px) !important;
+    box-shadow: 0 0 20px #44b4ff33 inset;
+    background-color: #ffffff11 !important;
   }
 </style>

+ 3 - 3
src/views/system/category/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div class="device-manager-box">
     <!--引用表格-->
     <BasicTable
       @register="registerTable"
@@ -17,14 +17,14 @@
           <template #overlay>
             <a-menu>
               <a-menu-item key="1" @click="batchHandleDelete">
-                <Icon icon="ant-design:delete-outlined"></Icon>
+                <Icon icon="ant-design:delete-outlined" />
                 删除
               </a-menu-item>
             </a-menu>
           </template>
           <a-button
             >批量操作
-            <Icon icon="ant-design:down-outlined"></Icon>
+            <Icon icon="ant-design:down-outlined" />
           </a-button>
         </a-dropdown>
       </template>

+ 4 - 4
src/views/system/depart/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <a-row :class="['p-4', `${prefixCls}--box`]" type="flex" :gutter="10">
+  <a-row :class="['p-4', `${prefixCls}--box`]" type="flex" :gutter="10" style="margin-top: 10px">
     <a-col :xl="12" :lg="24" :md="24" style="margin-bottom: 10px">
       <DepartLeftTree ref="leftTree" @select="onTreeSelect" @rootTreeData="onRootTreeData" />
     </a-col>
@@ -63,11 +63,11 @@
 </style>
 <style lang="less" scoped>
   .ant-tabs {
-    border: 1px solid #4d7ad855 !important;
+    border: 1px solid #44d3ff70 !important;
     border-radius: 2px !important;
-    background-color: #ffffff00 !important;
     -webkit-backdrop-filter: blur(8px) !important;
     backdrop-filter: blur(8px) !important;
-    box-shadow: 0 0 10px #5984e055 inset !important;
+    box-shadow: 0 0 20px #44b4ff33 inset;
+    background-color: #ffffff11 !important;
   }
 </style>

+ 4 - 4
src/views/system/departUser/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <a-row :class="['p-4', `${prefixCls}--box`]" :gutter="10">
+  <a-row :class="['p-4', `${prefixCls}--box`]" :gutter="10" style="margin-top: 10px">
     <a-col :xl="6" :lg="8" :md="10" :sm="24" style="flex: 1">
       <a-card :bordered="false" style="height: 100%">
         <DepartTree @select="onTreeSelect" />
@@ -54,12 +54,12 @@
     background-color: #ffffff00 !important;
   }
   .ant-tabs {
-    border: 1px solid #4d7ad855 !important;
+    border: 1px solid #44d3ff70 !important;
     border-radius: 2px !important;
-    background-color: #ffffff00 !important;
     -webkit-backdrop-filter: blur(8px) !important;
     backdrop-filter: blur(8px) !important;
-    box-shadow: 0 0 10px #5984e055 inset !important;
+    box-shadow: 0 0 20px #44b4ff33 inset;
+    background-color: #ffffff11 !important;
     padding: 10px;
   }
 </style>

+ 31 - 29
src/views/system/dict/index.vue

@@ -1,34 +1,36 @@
 <template>
-  <!--引用表格-->
-  <BasicTable @register="registerTable" :rowSelection="rowSelection">
-    <!--插槽:table标题-->
-    <template #tableTitle>
-      <a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate"> 新增</a-button>
-      <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
-      <j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
-      <a-button type="primary" @click="handlerRefreshCache" preIcon="ant-design:sync-outlined"> 刷新缓存</a-button>
-      <a-button type="primary" @click="openRecycleModal(true)" preIcon="ant-design:hdd-outlined"> 回收站</a-button>
+  <div class="device-manager-box">
+    <!--引用表格-->
+    <BasicTable @register="registerTable" :rowSelection="rowSelection">
+      <!--插槽:table标题-->
+      <template #tableTitle>
+        <a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate"> 新增</a-button>
+        <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
+        <j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
+        <a-button type="primary" @click="handlerRefreshCache" preIcon="ant-design:sync-outlined"> 刷新缓存</a-button>
+        <a-button type="primary" @click="openRecycleModal(true)" preIcon="ant-design:hdd-outlined"> 回收站</a-button>
 
-      <a-dropdown v-if="selectedRowKeys.length > 0">
-        <template #overlay>
-          <a-menu>
-            <a-menu-item key="1" @click="batchHandleDelete">
-              <Icon icon="ant-design:delete-outlined"></Icon>
-              删除
-            </a-menu-item>
-          </a-menu>
-        </template>
-        <a-button
-          >批量操作
-          <Icon icon="ant-design:down-outlined"></Icon>
-        </a-button>
-      </a-dropdown>
-    </template>
-    <!--操作栏-->
-    <template #action="{ record }">
-      <TableAction :actions="getTableAction(record)" />
-    </template>
-  </BasicTable>
+        <a-dropdown v-if="selectedRowKeys.length > 0">
+          <template #overlay>
+            <a-menu>
+              <a-menu-item key="1" @click="batchHandleDelete">
+                <Icon icon="ant-design:delete-outlined" />
+                删除
+              </a-menu-item>
+            </a-menu>
+          </template>
+          <a-button
+            >批量操作
+            <Icon icon="ant-design:down-outlined" />
+          </a-button>
+        </a-dropdown>
+      </template>
+      <!--操作栏-->
+      <template #action="{ record }">
+        <TableAction :actions="getTableAction(record)" />
+      </template>
+    </BasicTable>
+  </div>
   <!--字典弹窗-->
   <DictModal @register="registerModal" @success="handleSuccess" />
   <!--字典配置抽屉-->

+ 2 - 2
src/views/system/menu/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="p-4">
+  <div class="p-4 device-manager-box">
     <BasicTable @register="registerTable" :rowSelection="rowSelection">
       <template #tableTitle>
         <a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate"> 新增菜单</a-button>
@@ -36,7 +36,7 @@
   import { useDrawer } from '/@/components/Drawer';
   import MenuDrawer from './MenuDrawer.vue';
   import DataRuleList from './DataRuleList.vue';
-  import { columns,searchFormSchema } from './menu.data';
+  import { columns, searchFormSchema } from './menu.data';
   import { list, deleteMenu, batchDeleteMenu } from './menu.api';
 
   const checkedKeys = ref<Array<string | number>>([]);

+ 28 - 25
src/views/system/role/index.vue

@@ -1,33 +1,36 @@
 <template>
-  <BasicTable @register="registerTable">
-    <template #tableTitle>
-      <a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate"> 新增</a-button>
-      <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
-      <j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
-      <a-dropdown v-if="selectedRowKeys.length > 0">
-        <template #overlay>
-          <a-menu>
-            <a-menu-item key="1" @click="batchHandleDelete">
-              <Icon icon="ant-design:delete-outlined"></Icon>
-              删除
-            </a-menu-item>
-          </a-menu>
-        </template>
-        <a-button
-          >批量操作
-          <Icon icon="mdi:chevron-down"></Icon>
-        </a-button>
-      </a-dropdown>
-    </template>
-    <template #action="{ record }">
-      <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
-    </template>
-  </BasicTable>
+  <div class="device-manager-box">
+    <BasicTable @register="registerTable">
+      <template #tableTitle>
+        <a-button type="primary" preIcon="ant-design:plus-outlined" @click="handleCreate"> 新增</a-button>
+        <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
+        <j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
+        <a-dropdown v-if="selectedRowKeys.length > 0">
+          <template #overlay>
+            <a-menu>
+              <a-menu-item key="1" @click="batchHandleDelete">
+                <Icon icon="ant-design:delete-outlined" />
+                删除
+              </a-menu-item>
+            </a-menu>
+          </template>
+          <a-button
+            >批量操作
+            <Icon icon="mdi:chevron-down" />
+          </a-button>
+        </a-dropdown>
+      </template>
+      <template #action="{ record }">
+        <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
+      </template>
+    </BasicTable>
+  </div>
+
   <!--角色用户表格-->
   <RoleUserTable @register="roleUserDrawer" />
   <!--角色编辑抽屉-->
   <RoleDrawer @register="registerDrawer" @success="reload" :showFooter="showFooter" />
-  <RoleDesc @register="registerDesc"></RoleDesc>
+  <RoleDesc @register="registerDesc" />
   <!--角色菜单授权抽屉-->
   <RolePermissionDrawer @register="rolePermissionDrawer" />
   <!--角色首页配置-->

+ 1 - 1
src/views/system/user/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div class="device-manager-box">
     <!--引用表格-->
     <BasicTable @register="registerTable" :rowSelection="rowSelection">
       <!--插槽:table标题-->

+ 38 - 1
src/views/vent/deviceManager/comment/NormalTable.vue

@@ -125,7 +125,8 @@
       title: props.title,
       api: props.list,
       columns: props.columns.length > 0 ? (props.columns as any[]) : columnList,
-      size: 'small',
+      // size: 'small',
+      // bordered: false,
       formConfig: {
         // labelWidth: 100,
         labelAlign: 'left',
@@ -139,6 +140,7 @@
         },
         schemas: props.searchFormSchema as any[],
       },
+      striped: true,
       actionColumn: {
         width: 180,
       },
@@ -285,4 +287,39 @@
   // :deep(.jeecg-basic-table-row__striped td){
   //   background-color: transparent;
   // }
+  :deep(.ant-table-cell-row-hover) {
+    background: #264d8833 !important;
+  }
+  :deep(.ant-table-row-selected) {
+    background: #268bc522 !important;
+  }
+  :deep(.ant-table-tbody) {
+    tr.ant-table-row-selected {
+      td {
+        background: #268bc500 !important;
+      }
+    }
+  }
+  :deep(.jeecg-basic-table-row__striped) {
+    // background: #97efff11 !important;
+    td {
+      // background-color: #97efff11 !important;
+      background-color: #268bc522 !important;
+    }
+  }
+  :deep(.ant-table-thead) {
+    // background: linear-gradient(#003f77 0%, #004a86aa 10%) !important; //#003f77, #0a134c
+    background-color: #3d9dd45d !important;
+    & > tr > th,
+    .ant-table-column-title {
+      // color: #70f9fc !important;
+      color: #fff !important;
+      border-color: #91e9fe !important;
+      border-left: none !important;
+      // border-right: none !important;
+      &:last-child {
+        border-right: none !important;
+      }
+    }
+  }
 </style>

+ 18 - 16
src/views/vent/deviceManager/damperTabel/index.vue

@@ -1,20 +1,22 @@
 <template>
-  <NormalTable
-    :columns="columns"
-    :searchFormSchema="searchFormSchema"
-    :list="list"
-    :getImportUrl="getImportUrl"
-    :getExportUrl="getExportUrl"
-    :formSchema="formSchema"
-    :deleteById="deleteById"
-    :batchDelete="batchDeleteById"
-    :saveOrUpdate="saveOrUpdate"
-    :pointList="pointList"
-    designScope="damper-tabel"
-    title="风门列表"
-    :showTab="true"
-    deviceType="gate_normal"
-  />
+  <div class="device-manager-box">
+    <NormalTable
+      :columns="columns"
+      :searchFormSchema="searchFormSchema"
+      :list="list"
+      :getImportUrl="getImportUrl"
+      :getExportUrl="getExportUrl"
+      :formSchema="formSchema"
+      :deleteById="deleteById"
+      :batchDelete="batchDeleteById"
+      :saveOrUpdate="saveOrUpdate"
+      :pointList="pointList"
+      designScope="damper-tabel"
+      title="风门列表"
+      :showTab="true"
+      deviceType="gate_normal"
+    />
+  </div>
 </template>
 
 <script lang="ts" setup>

+ 16 - 14
src/views/vent/deviceManager/deviceColumns/index.vue

@@ -1,18 +1,20 @@
 <template>
-  <NormalTable
-    :columns="columns"
-    :searchFormSchema="searchFormSchema"
-    :list="list"
-    :getImportUrl="getImportUrl"
-    :getExportUrl="getExportUrl"
-    :formSchema="formSchema"
-    :deleteById="deleteById"
-    :batchDelete="batchDeleteById"
-    :saveOrUpdate="saveOrUpdate"
-    designScope="damper-tabel"
-    title="风门列表"
-    :showTab="true"
-  />
+  <div class="device-manager-box">
+    <NormalTable
+      :columns="columns"
+      :searchFormSchema="searchFormSchema"
+      :list="list"
+      :getImportUrl="getImportUrl"
+      :getExportUrl="getExportUrl"
+      :formSchema="formSchema"
+      :deleteById="deleteById"
+      :batchDelete="batchDeleteById"
+      :saveOrUpdate="saveOrUpdate"
+      designScope="damper-tabel"
+      title="风门列表"
+      :showTab="true"
+    />
+  </div>
 </template>
 
 <script lang="ts" name="system-user" setup>

+ 17 - 15
src/views/vent/deviceManager/fanTabel/index.vue

@@ -1,19 +1,21 @@
 <template>
-  <NormalTable
-    :columns="columns"
-    :searchFormSchema="searchFormSchema"
-    :list="list"
-    :getImportUrl="getImportUrl"
-    :getExportUrl="getExportUrl"
-    :formSchema="formSchema"
-    :deleteById="deleteById"
-    :batchDelete="batchDeleteById"
-    :saveOrUpdate="saveOrUpdate"
-    designScope="fan-tabel"
-    title="风机列表"
-    :showTab="true"
-    deviceType="fan_normal"
-  />
+  <div class="device-manager-box">
+    <NormalTable
+      :columns="columns"
+      :searchFormSchema="searchFormSchema"
+      :list="list"
+      :getImportUrl="getImportUrl"
+      :getExportUrl="getExportUrl"
+      :formSchema="formSchema"
+      :deleteById="deleteById"
+      :batchDelete="batchDeleteById"
+      :saveOrUpdate="saveOrUpdate"
+      designScope="fan-tabel"
+      title="风机列表"
+      :showTab="true"
+      deviceType="fan_normal"
+    />
+  </div>
 </template>
 
 <script lang="ts" name="system-user" setup>

+ 15 - 13
src/views/vent/deviceManager/ledTabel/index.vue

@@ -1,17 +1,19 @@
 <template>
-  <NormalTable
-    :columns="columns"
-    :searchFormSchema="searchFormSchema"
-    :list="list"
-    :getImportUrl="getImportUrl"
-    :getExportUrl="getExportUrl"
-    :formSchema="formSchema"
-    :deleteById="deleteById"
-    :batchDelete="batchDeleteById"
-    :saveOrUpdate="saveOrUpdate"
-    designScope="led-tabel"
-    title="LED屏列表"
-  />
+  <div class="device-manager-box">
+    <NormalTable
+      :columns="columns"
+      :searchFormSchema="searchFormSchema"
+      :list="list"
+      :getImportUrl="getImportUrl"
+      :getExportUrl="getExportUrl"
+      :formSchema="formSchema"
+      :deleteById="deleteById"
+      :batchDelete="batchDeleteById"
+      :saveOrUpdate="saveOrUpdate"
+      designScope="led-tabel"
+      title="LED屏列表"
+    />
+  </div>
 </template>
 
 <script lang="ts" name="system-user" setup>

+ 17 - 15
src/views/vent/deviceManager/pointTabel/index.vue

@@ -1,18 +1,20 @@
 <template>
-  <NormalTable
-    :columns="columns"
-    :searchFormSchema="searchFormSchema"
-    :list="list"
-    :getImportUrl="getImportUrl"
-    :getExportUrl="getExportUrl"
-    :formSchema="formSchema"
-    :deleteById="deleteById"
-    :batchDelete="batchDeleteById"
-    :saveOrUpdate="saveOrUpdate"
-    designScope="point-tabel"
-    title="点表列表"
-    :showTab="false"
-  />
+  <div class="device-manager-box">
+    <NormalTable
+      :columns="columns"
+      :searchFormSchema="searchFormSchema"
+      :list="list"
+      :getImportUrl="getImportUrl"
+      :getExportUrl="getExportUrl"
+      :formSchema="formSchema"
+      :deleteById="deleteById"
+      :batchDelete="batchDeleteById"
+      :saveOrUpdate="saveOrUpdate"
+      designScope="point-tabel"
+      title="点表列表"
+      :showTab="false"
+    />
+  </div>
 </template>
 
 <script lang="ts" name="system-user" setup>
@@ -22,4 +24,4 @@
   import { list, getImportUrl, getExportUrl, deleteById, batchDeleteById, saveOrUpdate } from './point.api';
 </script>
 
-<style scoped></style>
+<style scoped lang="less"></style>

+ 15 - 13
src/views/vent/deviceManager/sensorTabel/index.vue

@@ -1,17 +1,19 @@
 <template>
-  <NormalTable
-    :columns="columns"
-    :searchFormSchema="searchFormSchema"
-    :list="list"
-    :getImportUrl="getImportUrl"
-    :getExportUrl="getExportUrl"
-    :formSchema="formSchema"
-    :deleteById="deleteById"
-    :batchDelete="batchDeleteById"
-    :saveOrUpdate="saveOrUpdate"
-    designScope="sensor-tabel"
-    title="传感器列表"
-  />
+  <div class="device-manager-box">
+    <NormalTable
+      :columns="columns"
+      :searchFormSchema="searchFormSchema"
+      :list="list"
+      :getImportUrl="getImportUrl"
+      :getExportUrl="getExportUrl"
+      :formSchema="formSchema"
+      :deleteById="deleteById"
+      :batchDelete="batchDeleteById"
+      :saveOrUpdate="saveOrUpdate"
+      designScope="sensor-tabel"
+      title="传感器列表"
+    />
+  </div>
 </template>
 
 <script lang="ts" name="system-user" setup>

+ 23 - 21
src/views/vent/deviceManager/substationTabel/index.vue

@@ -1,25 +1,27 @@
 <template>
-  <NormalTable
-    ref="normalTabel"
-    :columns="columns"
-    :searchFormSchema="searchFormSchema"
-    :list="list"
-    :getImportUrl="getImportUrl"
-    :getExportUrl="getExportUrl"
-    :formSchema="formSchema"
-    :deleteById="deleteById"
-    :batchDelete="batchDeleteById"
-    :saveOrUpdate="saveOrUpdate"
-    designScope="substation-tabel"
-    title="分站列表"
-    :showTab="false"
-  >
-    <template #filterCell="{ column, record }">
-      <a-tag v-if="column.dataIndex === 'linkstatus'" :color="record.linkstatus == 0 ? '#999' : '#87d068'">{{
-        record.linkstatus == 1 ? '链接' : '断开'
-      }}</a-tag>
-    </template>
-  </NormalTable>
+  <div class="device-manager-box">
+    <NormalTable
+      ref="normalTabel"
+      :columns="columns"
+      :searchFormSchema="searchFormSchema"
+      :list="list"
+      :getImportUrl="getImportUrl"
+      :getExportUrl="getExportUrl"
+      :formSchema="formSchema"
+      :deleteById="deleteById"
+      :batchDelete="batchDeleteById"
+      :saveOrUpdate="saveOrUpdate"
+      designScope="substation-tabel"
+      title="分站列表"
+      :showTab="false"
+    >
+      <template #filterCell="{ column, record }">
+        <a-tag v-if="column.dataIndex === 'linkstatus'" :color="record.linkstatus == 0 ? '#999' : '#87d068'">{{
+          record.linkstatus == 1 ? '链接' : '断开'
+        }}</a-tag>
+      </template>
+    </NormalTable>
+  </div>
 </template>
 
 <script lang="ts" name="system-user" setup>

+ 16 - 14
src/views/vent/deviceManager/tableColumns/index.vue

@@ -1,18 +1,20 @@
 <template>
-  <NormalTable
-    :columns="columns"
-    :searchFormSchema="searchFormSchema"
-    :list="list"
-    :getImportUrl="getImportUrl"
-    :getExportUrl="getExportUrl"
-    :formSchema="formSchema"
-    :deleteById="deleteById"
-    :batchDelete="batchDeleteById"
-    :saveOrUpdate="saveOrUpdate"
-    designScope="tabel-columns"
-    title="字段裂变"
-    :showTab="false"
-  />
+  <div class="device-manager-box">
+    <NormalTable
+      :columns="columns"
+      :searchFormSchema="searchFormSchema"
+      :list="list"
+      :getImportUrl="getImportUrl"
+      :getExportUrl="getExportUrl"
+      :formSchema="formSchema"
+      :deleteById="deleteById"
+      :batchDelete="batchDeleteById"
+      :saveOrUpdate="saveOrUpdate"
+      designScope="tabel-columns"
+      title="字段裂变"
+      :showTab="false"
+    />
+  </div>
 </template>
 
 <script lang="ts" name="system-user" setup>

+ 17 - 15
src/views/vent/deviceManager/windWindowTabel/index.vue

@@ -1,19 +1,21 @@
 <template>
-  <NormalTable
-    :columns="columns"
-    :searchFormSchema="searchFormSchema"
-    :list="list"
-    :getImportUrl="getImportUrl"
-    :getExportUrl="getExportUrl"
-    :formSchema="formSchema"
-    :deleteById="deleteById"
-    :batchDelete="batchDeleteById"
-    :saveOrUpdate="saveOrUpdate"
-    designScope="ventanalyWindow-tabel"
-    title="风窗列表"
-    :showTab="true"
-    deviceType="window_normal"
-  />
+  <div class="device-manager-box">
+    <NormalTable
+      :columns="columns"
+      :searchFormSchema="searchFormSchema"
+      :list="list"
+      :getImportUrl="getImportUrl"
+      :getExportUrl="getExportUrl"
+      :formSchema="formSchema"
+      :deleteById="deleteById"
+      :batchDelete="batchDeleteById"
+      :saveOrUpdate="saveOrUpdate"
+      designScope="ventanalyWindow-tabel"
+      title="风窗列表"
+      :showTab="true"
+      deviceType="window_normal"
+    />
+  </div>
 </template>
 
 <script lang="ts" name="system-user" setup>

+ 17 - 15
src/views/vent/deviceManager/windfindingTabel/index.vue

@@ -1,19 +1,21 @@
 <template>
-  <NormalTable
-    :columns="columns"
-    :searchFormSchema="searchFormSchema"
-    :list="list"
-    :getImportUrl="getImportUrl"
-    :getExportUrl="getExportUrl"
-    :formSchema="formSchema"
-    :deleteById="deleteById"
-    :batchDelete="batchDeleteById"
-    :saveOrUpdate="saveOrUpdate"
-    designScope="windfinding-tabel"
-    title="测风装置列表"
-    :showTab="true"
-    deviceType="windrect_normal"
-  />
+  <div class="device-manager-box">
+    <NormalTable
+      :columns="columns"
+      :searchFormSchema="searchFormSchema"
+      :list="list"
+      :getImportUrl="getImportUrl"
+      :getExportUrl="getExportUrl"
+      :formSchema="formSchema"
+      :deleteById="deleteById"
+      :batchDelete="batchDeleteById"
+      :saveOrUpdate="saveOrUpdate"
+      designScope="windfinding-tabel"
+      title="测风装置列表"
+      :showTab="true"
+      deviceType="windrect_normal"
+    />
+  </div>
 </template>
 
 <script lang="ts" name="system-user" setup>

+ 18 - 16
src/views/vent/deviceManager/workingFace/index.vue

@@ -1,20 +1,22 @@
 <template>
-  <NormalTable
-    :columns="[]"
-    :searchFormSchema="searchFormSchema"
-    :list="list"
-    :getImportUrl="getImportUrl"
-    :getExportUrl="getExportUrl"
-    :formSchema="formSchema"
-    :deleteById="deleteById"
-    :batchDelete="batchDeleteById"
-    :saveOrUpdate="saveOrUpdate"
-    designScope="workingFace-tabel"
-    title="智能管控"
-    :showTab="true"
-    deviceType="managesys"
-    columnsType="managesys_list"
-  />
+  <div class="device-manager-box">
+    <NormalTable
+      :columns="[]"
+      :searchFormSchema="searchFormSchema"
+      :list="list"
+      :getImportUrl="getImportUrl"
+      :getExportUrl="getExportUrl"
+      :formSchema="formSchema"
+      :deleteById="deleteById"
+      :batchDelete="batchDeleteById"
+      :saveOrUpdate="saveOrUpdate"
+      designScope="workingFace-tabel"
+      title="智能管控"
+      :showTab="true"
+      deviceType="managesys"
+      columnsType="managesys_list"
+    />
+  </div>
 </template>
 
 <script lang="ts" name="system-user" setup>

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

@@ -6,6 +6,12 @@
           <template v-if="column.dataIndex === 'isCheck'">
             <a-radio :value="record.deviceID" />
           </template>
+          <a-tag v-if="column.dataIndex === 'warnFlag'" :color="record.warnFlag == 0 ? 'green' : 'red'">{{
+            record.warnFlag == 0 ? '正常' : '报警'
+          }}</a-tag>
+          <a-tag v-if="column.dataIndex === 'netStatus'" :color="record.netStatus == 0 ? 'default' : 'green'">{{
+            record.netStatus == 0 ? '断开' : '连接'
+          }}</a-tag>
         </template>
       </a-table>
     </a-radio-group>
@@ -149,7 +155,7 @@
     return columns;
   }
   const columns = setColumns();
-
+  console.log('[ columns ] >', columns);
   onMounted(() => {
     // 如果是https
     // 反之是websocket

+ 23 - 9
src/views/vent/monitorManager/comment/MonitorTable.vue

@@ -22,6 +22,7 @@
   import { list, deleteUser, batchDeleteUser, getImportUrl, getExportUrl, frozenBatch, syncUser } from '../../../system/user/user.api';
   import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
   import { findIndex } from 'lodash-es';
+  import { computed } from '@vue/reactivity';
   const listApi = '/ventanaly-device/monitor/device';
   const props = defineProps({
     columnsType: {
@@ -41,6 +42,10 @@
     title: {
       type: String,
     },
+    size: {
+      type: String,
+      default: 'small',
+    },
   });
   const emits = defineEmits(['selectRow']);
   const dataTableSource = ref([]);
@@ -56,7 +61,7 @@
       return props.dataSource;
     },
     (newVal, oldVal) => {
-      if (oldVal.length < 1) {
+      if (oldVal.length < 1 && newVal.length > 0) {
         // 第一次
         setSelectedRowKeys([newVal[0].deviceID]);
       }
@@ -70,7 +75,7 @@
   );
 
   const columns = getTableHeaderColumns(props.columnsType);
-
+  console.log('[ columns ] >', columns);
   // 列表页面公共参数、方法
   const { prefixCls, tableContext, doRequest } = useListPage({
     designScope: props.designScope,
@@ -80,13 +85,14 @@
       dataSource: dataTableSource,
       columns: columns,
       rowSelection: { type: 'radio' },
-      size: 'small',
+      size: props.size,
       useSearchForm: false,
       showTableSetting: false,
       showActionColumn: false,
       maxHeight: tableMaxHeight,
       bordered: false,
       rowKey: 'deviceID',
+      striped: true,
       actionColumn: {
         width: 180,
       },
@@ -103,15 +109,20 @@
 
   //注册table数据
   const [registerTable, { reload, setLoading, setSelectedRowKeys }, { rowSelection, selectedRows, selectedRowKeys }] = tableContext;
-  watch(selectedRowKeys, (oldKeys, newKeys) => {
-    const index = findIndex(dataTableSource.value, (data: any) => {
-      return data.deviceID == selectedRowKeys.value[0];
-    });
-    emits('selectRow', selectedRows.value[0], index);
-  });
+  watch(
+    selectedRowKeys,
+    (oldKeys, newKeys) => {
+      const index = findIndex(dataTableSource.value, (data: any) => {
+        return data.deviceID == selectedRowKeys.value[0];
+      });
+      emits('selectRow', selectedRows.value[0], index);
+    },
+    { immediate: false }
+  );
 
   defineExpose({
     doRequest,
+    setSelectedRowKeys,
   });
 
   onMounted(() => {
@@ -129,4 +140,7 @@
   :deep(.jeecg-basic-table .ant-table-wrapper .ant-table-title) {
     min-height: 0;
   }
+  .jeecg-basic-table-row__striped {
+    background: #97efff11 !important;
+  }
 </style>

+ 6 - 4
src/views/vent/monitorManager/fanLocalMonitor/fanLocal.three.ts

@@ -137,11 +137,11 @@ export const addText = (selectData) => {
   }
   const textArr = [
     {
-      text: `煤矿巷道远程风门系统`,
+      text: `煤矿巷道远程局部风机系统`,
       font: 'normal 30px Arial',
       color: '#009900',
       strokeStyle: '#002200',
-      x: 80,
+      x: 50,
       y: 110,
     },
     {
@@ -325,8 +325,8 @@ const initFly = () => {
 
   const downCurve = [
     {
-      path0: new THREE.Vector3(-90.653, -0.388, 3.61),
-      path1: new THREE.Vector3(-85.678, -0.393, 3.275),
+      path0: new THREE.Vector3(-94.84, -0.388, 3.61),
+      path1: new THREE.Vector3(-85.678, -0.393, 3.61),
       isSpread: true,
       spreadDirection: -1, //
     },
@@ -494,5 +494,7 @@ export const destroy = () => {
     model.deleteModal();
     model = null;
     group = null;
+    topSmoke = null;
+    downSmoke = null;
   }
 };

+ 50 - 12
src/views/vent/monitorManager/fanLocalMonitor/index.vue

@@ -135,31 +135,31 @@
       <!-- 调频 -->
       <div class="vent-flex-row input-box" v-if="modalType == 'frequency'">
         <div class="label">运行频率(单位):</div>
-        <a-input-number v-model:value="frequencyVal" :min="0" :max="50" :step="0.1" />
+        <a-input-number size="small" v-model:value="frequencyVal" :min="30" :max="50" :step="0.1" />
       </div>
       <div class="vent-flex-row input-box" v-if="modalType == 'needAir'">
         <div class="label">需风量(单位):</div>
-        <a-input-number v-model:value="frequencyVal" :min="30" :max="50" :step="0.1" />
+        <a-input-number size="small" v-model:value="frequencyVal" :min="30" :max="50" :step="0.1" />
       </div>
       <div class="vent-flex-row input-box" v-if="modalType == 'disAirAlarm'">
         <div class="label">漏风率(%):</div>
-        <a-input-number v-model:value="frequencyVal" :min="0" :max="50" :step="0.1" />
+        <a-input-number size="small" v-model:value="frequencyVal" :min="0" :max="50" :step="0.1" />
       </div>
       <div class="vent-flex-row input-box" v-if="modalType == 'diameter'">
         <div class="label">风筒直径(m):</div>
-        <a-input-number v-model:value="frequencyVal" :min="0" :max="50" :step="0.1" />
+        <a-input-number size="small" v-model:value="frequencyVal" :min="0" :max="50" :step="0.1" />
       </div>
       <div class="vent-flex-row input-box" v-if="modalType == 'len'">
         <div class="label">风筒长度(m):</div>
-        <a-input-number v-model:value="frequencyVal" :min="0" :max="50" :step="0.1" />
+        <a-input-number size="small" v-model:value="frequencyVal" :min="0" :max="50" :step="0.1" />
       </div>
       <div class="vent-flex-row input-box" v-if="modalType == 'windPowerLimit'">
         <div class="label">风电闭锁限值(m³/min):</div>
-        <a-input-number v-model:value="frequencyVal" :min="0" :max="50" :step="0.1" />
+        <a-input-number size="small" v-model:value="frequencyVal" :min="0" :max="50" :step="0.1" />
       </div>
       <div class="vent-flex-row input-box" v-if="modalType == 'gasPowerLimit'">
         <div class="label">瓦斯电闭锁限值(m³/min):</div>
-        <a-input-number v-model:value="frequencyVal" :min="0" :max="50" :step="0.1" />
+        <a-input-number size="small" v-model:value="frequencyVal" :min="0" :max="50" :step="0.1" />
       </div>
       <div v-if="modalType == 'gasAlarm'">
         <div class="vent-flex-row input-box">
@@ -168,21 +168,25 @@
         </div>
         <div class="vent-flex-row input-box">
           <div class="label">传感器值:</div>
-          <a-input-number v-model:value="frequencyVal" :min="0" :max="50" :step="0.1" />
+          <a-input-number size="small" v-model:value="frequencyVal" :min="0" :max="50" :step="0.1" />
         </div>
       </div>
       <div v-if="modalType == 'airVolumeAlarm'">
         <div class="vent-flex-row input-box">
           <div class="label">风量上限(m³/min):</div>
-          <a-input-number v-model:value="modalTypeArr.rightBtnArr[3].min" :min="0" :max="50" :step="0.1" />
+          <a-input-number size="small" v-model:value="modalTypeArr.rightBtnArr[3].min" :min="0" :max="50" :step="0.1" />
         </div>
         <div class="vent-flex-row input-box">
           <div class="label">风量下限(m³/min):</div>
-          <a-input-number v-model:value="modalTypeArr.rightBtnArr[3].max" :min="0" :max="50" :step="0.1" />
+          <a-input-number size="small" v-model:value="modalTypeArr.rightBtnArr[3].max" :min="0" :max="50" :step="0.1" />
         </div>
       </div>
       <!-- 启动或停止 -->
       <div class="" v-if="modalType == 'startSmoke'"> </div>
+      <div class="vent-flex-row input-box">
+        <div class="label">操作密码:</div>
+        <a-input size="small" type="password" v-model:value="passWord" />
+      </div>
     </div>
   </a-modal>
 </template>
@@ -191,13 +195,11 @@
   import '/@/design/vent/modal.less';
   import { ExclamationCircleFilled } from '@ant-design/icons-vue';
   import { onBeforeMount, ref, onMounted, nextTick, toRaw, reactive, onUnmounted } from 'vue';
-  import Bar from '/@/components/chart/Bar.vue';
   import BarSingle from '../../../../components/chart/BarSingle.vue';
   import GroupMonitorTable from '../comment/GroupMonitorTable.vue';
   import HistoryTable from '../comment/HistoryTable.vue';
   import AlarmHistoryTable from '../comment/AlarmHistoryTable.vue';
   import HandlerHistoryTable from '../comment/HandlerHistoryTable.vue';
-  import { initWebSocket, getRecordList } from '/@/hooks/web/useVentWebSocket';
   import { mountedThree, setModelType, destroy, addCssText, addText, playSmoke } from './fanLocal.three';
   import lodash from 'lodash';
   import { getTableList, list } from '/@/views/vent/monitorManager/fanLocalMonitor/fanLocal.api';
@@ -205,6 +207,7 @@
   import { chartsColumns, chartsColumns1 } from './fanLocal.data';
   import { deviceControlApi } from '/@/api/vent/index';
   import LivePlayer from '@liveqing/liveplayer-v3';
+  import { message } from 'ant-design-vue';
 
   const modalTypeArr = reactive({
     leftBtnArr: [
@@ -290,6 +293,7 @@
   const frequencyVal = ref(40); //频率
   const mainWindIsShow1 = ref('stop'); // 1#风机默认启动
   const mainWindIsShow2 = ref('stop'); // 2#风机默认不启动
+  const passWord = ref('');
   // 默认初始是第一行
   const selectRowIndex = ref(0);
   // 设备数据
@@ -405,7 +409,13 @@
       }
     }
   };
+
   const handleOk = (e: MouseEvent) => {
+    if (passWord.value !== '123456') {
+      message.warning('密码不正确,请重新输入');
+      return;
+    }
+
     const handType = modalType.value;
     const frequency = frequencyVal.value;
     const data = {
@@ -445,6 +455,27 @@
       deviceControlApi(data).then((res) => {
         console.log('设备操作结果', res);
       });
+    } else if (handType === 'changeSmoke') {
+      // 一键倒机
+      if (mainWindIsShow1.value === 'open' && mainWindIsShow2.value === 'stop') {
+        playSmoke(handType, 'down', frequency, 'open');
+        data.paramcode = 'fanRun2';
+        deviceControlApi(data).then((res) => {
+          console.log('设备操作结果', res);
+        });
+        mainWindIsShow1.value = 'stop';
+        mainWindIsShow2.value = 'open';
+      } else if (mainWindIsShow2.value === 'open' && mainWindIsShow1.value === 'stop') {
+        playSmoke(handType, 'top', frequency, 'open');
+        data.paramcode = 'fanRun1';
+        deviceControlApi(data).then((res) => {
+          console.log('设备操作结果', res);
+        });
+        mainWindIsShow1.value = 'open';
+        mainWindIsShow2.value = 'stop';
+      } else if (mainWindIsShow1.value === 'stop' && mainWindIsShow2.value === 'stop') {
+        playSmoke(handType, '', frequency, 'stop');
+      }
     }
     modalTitle.value = '';
     modalIsShow.value = false;
@@ -470,6 +501,7 @@
       nextTick(() => {
         getMonitor();
         addCssText();
+
         playSmoke('startSmoke', 'top', frequencyVal.value, 'open');
       });
     });
@@ -497,4 +529,10 @@
     }
     margin-right: 10px;
   }
+  .label {
+    max-width: 220px;
+  }
+  .ant-input {
+    width: 150px;
+  }
 </style>

+ 1 - 3
src/views/vent/monitorManager/gateMonitor/detail.vue

@@ -8,8 +8,6 @@
 <script setup lang="ts">
   import { ref, onMounted, onUnmounted } from 'vue';
   import UseThree from '../../../../hooks/core/threejs/useThree';
-  import * as THREE from 'three';
-  import gsap from 'gsap';
 
   const loading = ref(false);
   let model;
@@ -31,4 +29,4 @@
     }
   });
 </script>
-<style scoped lang="scss"></style>
+<style scoped lang="less"></style>

+ 7 - 4
src/views/vent/monitorManager/gateMonitor/gate.threejs.ts

@@ -504,10 +504,12 @@ export const initOpenState = (selectData) => {
   return new Promise((resolve) => {
     setTimeout(async () => {
       const oldCameraPosition = { x: -1000, y: 100, z: 500 };
-      await animateCamera(oldCameraPosition, oldCameraPosition, { x: 46.257, y: 57.539, z: 94.313 }, { x: -50, y: 0, z: 0 }, model);
+      await animateCamera(oldCameraPosition, oldCameraPosition, { x: 46.257, y: 57.539, z: 94.313 }, { x: -50, y: 0, z: 0 }, model, 0.8);
       resolve(null);
-    }, 300);
-
+    }, 500);
+    if (!selectData) {
+      return;
+    }
     if (selectData.frontGateOpen == 1) {
       clipActionArr.frontDoor.reset();
       clipActionArr.frontDoor.time = 0.5;
@@ -555,7 +557,7 @@ export const mountedThree = (playerVal1, playerVal2) => {
         });
       }
       model.scene?.add(group);
-      model.camera.position.set(-1000, 100, 500);
+      // model.camera.position.set(-1000, 100, 500);
       addLight(model.scene);
       // resetCamera();
       setModalPosition();
@@ -564,6 +566,7 @@ export const mountedThree = (playerVal1, playerVal2) => {
       // startAnimation();
       initAnimation();
       model.animate();
+
       // renderBloomPass = createComposer(model).renderBloomPass;
 
       // const flyLineMesh = flyLine(

+ 180 - 85
src/views/vent/monitorManager/gateMonitor/index.vue

@@ -1,7 +1,7 @@
 <template>
-  <div class="bg" style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; overflow: hidden;">
+  <div class="bg" style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; overflow: hidden">
     <a-spin :spinning="loading" />
-    <div id="damper3D" style="width: 100%; height: 100%;; position: absolute; overflow: hidden;"> </div>
+    <div id="damper3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden"> </div>
     <!-- <div id="damper3DCSS" v-show="!loading" style="width: 100%; height: 100%; top:0; left: 0; position: absolute; overflow: hidden;">
       <div>
         <div ref="elementContent" class="elementContent">
@@ -18,12 +18,17 @@
   <div class="scene-box">
     <div class="top-box">
       <div class="top-center row">
-        <div class="button-box" :class="{'button-disable': backDoorIsOpen}" @click="playAnimation(1)">打开前门</div>
-        <div class="button-box" :class="{'button-disable': backDoorIsOpen}" @click="playAnimation(2)">关闭前门</div>
-        <div class="button-box" :class="{'button-disable': frontDoorIsOpen}" @click="playAnimation(3)">打开后门</div>
-        <div class="button-box" :class="{'button-disable': frontDoorIsOpen}" @click="playAnimation(4)">关闭后门</div>
-        <div class="button-box" :class="{'button-disable': frontDoorIsOpen || backDoorIsOpen}" @click="playAnimation(5)">打开前后门</div>
-        <div class="button-box" :class="{'button-disable': (frontDoorIsOpen && !backDoorIsOpen) || (backDoorIsOpen && !frontDoorIsOpen)}" @click="playAnimation(6)">关闭前后门</div>
+        <div class="button-box" :class="{ 'button-disable': backDoorIsOpen }" @click="playAnimation(1)">打开前门</div>
+        <div class="button-box" :class="{ 'button-disable': backDoorIsOpen }" @click="playAnimation(2)">关闭前门</div>
+        <div class="button-box" :class="{ 'button-disable': frontDoorIsOpen }" @click="playAnimation(3)">打开后门</div>
+        <div class="button-box" :class="{ 'button-disable': frontDoorIsOpen }" @click="playAnimation(4)">关闭后门</div>
+        <div class="button-box" :class="{ 'button-disable': frontDoorIsOpen || backDoorIsOpen }" @click="playAnimation(5)">打开前后门</div>
+        <div
+          class="button-box"
+          :class="{ 'button-disable': (frontDoorIsOpen && !backDoorIsOpen) || (backDoorIsOpen && !frontDoorIsOpen) }"
+          @click="playAnimation(6)"
+          >关闭前后门</div
+        >
         <!-- <div class="button-box" @click="enterMY">漫游</div> -->
       </div>
       <div class="top-right row">
@@ -47,7 +52,6 @@
           </a-radio-group>
         </div>
       </div>
-
     </div>
     <div class="title-text">
       {{ selectData.stationname }}
@@ -55,7 +59,29 @@
     <div class="bottom-tabs-box">
       <a-tabs class="tabs-box" v-model:activeKey="activeKey" @change="tabChange">
         <a-tab-pane key="1" tab="实时监测">
-            <MonitorTable class="monitor-table" columnsType="gate_monitor" :dataSource="dataSource" design-scope="gate-monitor" @selectRow="getSelectRow" title="风门监测" />
+          <MonitorTable
+            class="monitor-table"
+            columnsType="gate_monitor"
+            :dataSource="dataSource"
+            design-scope="gate-monitor"
+            @selectRow="getSelectRow"
+            title="风门监测"
+          >
+            <template #filterCell="{ column, record }">
+              <a-tag v-if="column.dataIndex === 'frontGateOpen'" :color="record.frontGateOpen == 0 ? 'default' : 'processing'">{{
+                record.frontGateOpen == 0 ? '关闭' : '打开'
+              }}</a-tag>
+              <a-tag v-if="column.dataIndex === 'rearGateOpen'" :color="record.rearGateOpen == 0 ? 'default' : 'processing'">{{
+                record.rearGateOpen == 0 ? '关闭' : '打开'
+              }}</a-tag>
+              <a-tag v-if="column.dataIndex === 'warnFlag'" :color="record.warnFlag == 0 ? 'green' : 'red'">{{
+                record.warnFlag == 0 ? '正常' : '报警'
+              }}</a-tag>
+              <a-tag v-if="column.dataIndex === 'netStatus'" :color="record.netStatus == 0 ? 'default' : 'green'">{{
+                record.netStatus == 0 ? '断开' : '连接'
+              }}</a-tag>
+            </template>
+          </MonitorTable>
         </a-tab-pane>
         <a-tab-pane key="2" tab="实时曲线图" force-render>
           <div class="tab-item" v-if="activeKey === '2'">
@@ -72,7 +98,7 @@
         </a-tab-pane>
         <a-tab-pane key="3" tab="历史数据">
           <div class="tab-item">
-            <HistoryTable columns-type="gate_history" device-type="gate" :device-list-api="baseList" designScope="gate-history"/>
+            <HistoryTable columns-type="gate_history" device-type="gate" :device-list-api="baseList" designScope="gate-history" />
           </div>
         </a-tab-pane>
         <a-tab-pane key="4" tab="报警历史">
@@ -88,43 +114,54 @@
       </a-tabs>
     </div>
   </div>
-  <div style=" z-index: -1; position: absolute; top: 50px; right: 10px; width:300px;height:280px;margin:auto" class="palyer1">
+  <div style="z-index: -1; position: absolute; top: 50px; right: 10px; width: 300px; height: 280px; margin: auto" class="palyer1">
     <LivePlayer id="fm-player1" ref="player1" :videoUrl="flvURL1()" muted live loading controls />
-    <LivePlayer id="fm-player2" ref="player2" :videoUrl="flvURL1()" muted live loading controls style="margin-top: 10px"/>
+    <LivePlayer id="fm-player2" ref="player2" :videoUrl="flvURL1()" muted live loading controls style="margin-top: 10px" />
   </div>
+  <!-- <a-modal v-model:visible="modalIsShow" :title="modalTitle" @ok="handleOk">
+    <div class="modal-container">
+      <div class="vent-flex-row">
+        <ExclamationCircleFilled style="color: #ffb700; font-size: 30px" />
+        <div class="warning-text">您是否要进行{{ modalTitle }}操作?</div>
+      </div>
+    </div>
+  </a-modal> -->
+  <HandleModal :modal-is-show="modalIsShow" :modal-title="modalTitle" :modal-type="modalType" @handle-ok="handleOK" @handle-cancel="handleCancel" />
 </template>
 
 <script setup lang="ts">
   import '/@/design/vent/modal.less';
-  import LivePlayer from '@liveqing/liveplayer-v3'
-  import {onBeforeMount, onBeforeUnmount, onUnmounted, onMounted, ref, Ref, reactive, toRaw } from 'vue';
-  import BarAndLine from '../../../../components/chart/BarAndLine.vue';
+  import LivePlayer from '@liveqing/liveplayer-v3';
+  import { onBeforeMount, onBeforeUnmount, onUnmounted, onMounted, ref, reactive, toRaw, nextTick } from 'vue';
   import DeviceEcharts from '../comment/DeviceEcharts.vue';
   import MonitorTable from '../comment/MonitorTable.vue';
   import HistoryTable from '../comment/HistoryTable.vue';
   import AlarmHistoryTable from '../comment/AlarmHistoryTable.vue';
   import HandlerHistoryTable from '../comment/HandlerHistoryTable.vue';
+  import HandleModal from './modal.vue';
   import { initWebSocket, getRecordList } from '/@/hooks/web/useVentWebSocket';
-  import { mountedThree, addFmText, play, destroy, initOpenState} from './gate.threejs'
+  import { mountedThree, addFmText, play, destroy, initOpenState } from './gate.threejs';
   import { deviceControlApi } from '/@/api/vent/index';
   import { message } from 'ant-design-vue';
-  import { list } from "/@/views/vent/monitorManager/windowMonitor/window.api";
-  import { list as baseList } from '../../deviceManager/damperTabel/damper.api'
-  import {chartsColumns} from './gate.data'
-  import lodash from "lodash";
+  import { list } from '/@/views/vent/monitorManager/windowMonitor/window.api';
+  import { list as baseList } from '../../deviceManager/damperTabel/damper.api';
+  import { chartsColumns } from './gate.data';
+  import lodash from 'lodash';
 
-  const player1 = ref(null)
-  const player2 = ref(null)
-  const elementContent = <Ref<HTMLElement>>ref()
-  const activeKey = ref('1')
-  const loading = ref(false);
+  const player1 = ref(null);
+  const player2 = ref(null);
 
+  const activeKey = ref('1');
+  const loading = ref(false);
 
   const frontDoorIsOpen = ref(false); //前门是否开启
   const backDoorIsOpen = ref(false); //后门是否开启
 
+  const modalIsShow = ref<boolean>(false); // 是否显示模态框
+  const modalTitle = ref(''); // 模态框标题显示内容,根据设备操作类型决定
+  const modalType = ref(''); // 模态框内容显示类型,设备操作类型
 
-  const selectRowIndex = ref(0)
+  const selectRowIndex = ref(0);
   const dataSource = ref([]);
   //  webSocket 请求 实时监测数据
   // const dataSource:any = computed(() => {
@@ -137,13 +174,12 @@
   //   return data;
   // });
 
-
   // 设备数据
-  const controlType = ref(1)
+  const controlType = ref(1);
 
   const tabChange = (activeKeyVal) => {
-    activeKey.value = activeKeyVal
-  }
+    activeKey.value = activeKeyVal;
+  };
   const initData = {
     deviceID: '',
     deviceType: '',
@@ -154,7 +190,7 @@
     frontGateOpen: '0',
     rearGateOpen: '0',
     fault: '气源压力超限',
-    autoRoManual: 0
+    autoRoManual: 0,
   };
   // 监测数据
   const selectData = reactive(lodash.cloneDeep(initData));
@@ -165,52 +201,102 @@
     if (Object.prototype.toString.call(timer) === '[object Null]') {
       timer = setTimeout(() => {
         list({ devicetype: 'gate', pagetype: 'normal' }).then((res) => {
-          if(res.msgTxt && res.msgTxt[0]){
+          if (res.msgTxt && res.msgTxt[0]) {
             dataSource.value = res.msgTxt[0].datalist || [];
             dataSource.value.forEach((data: any) => {
               const readData = data.readData;
               data = Object.assign(data, readData);
             });
-            if(dataSource.value.length > selectRowIndex.value) {
+            if (dataSource.value.length > selectRowIndex.value) {
               const data: any = toRaw(dataSource.value[selectRowIndex.value]); //maxarea
               Object.assign(selectData, data);
               addFmText(selectData);
-              if(timer){
+              if (timer) {
                 timer = null;
               }
               getMonitor();
             }
           }
-          
         });
       }, 1000);
     }
   };
 
   // 切换检测数据
-  const getSelectRow = async(selectRow, index) => {
-    loading.value = true
-    selectRowIndex.value = index
-    frontDoorIsOpen.value = selectData.frontGateOpen === '1'
-    backDoorIsOpen.value = selectData.rearGateOpen === '1'
-    await initOpenState(selectData)
-    loading.value = false
-  }
+  const getSelectRow = async (selectRow, index) => {
+    loading.value = true;
+    selectRowIndex.value = index;
+    frontDoorIsOpen.value = selectData.frontGateOpen === '1';
+    backDoorIsOpen.value = selectData.rearGateOpen === '1';
+    await initOpenState(selectData);
+    loading.value = false;
+  };
 
   // 播放动画
   const playAnimation = (handlerState) => {
+    switch (handlerState) {
+      case 1: // 打开前门
+        if (!frontDoorIsOpen.value && !backDoorIsOpen.value) {
+          modalTitle.value = '打开前门';
+          modalType.value = '1';
+          modalIsShow.value = true;
+        }
+        break;
+      case 2: // 关闭前门
+        if (frontDoorIsOpen.value && !backDoorIsOpen.value) {
+          modalTitle.value = '关闭前门';
+          modalType.value = '2';
+          modalIsShow.value = true;
+        }
+        break;
+      case 3: // 打开后门
+        if (!backDoorIsOpen.value && !frontDoorIsOpen.value) {
+          modalTitle.value = '打开后门';
+          modalType.value = '3';
+          modalIsShow.value = true;
+        }
+        break;
+      case 4: // 关闭后门
+        if (backDoorIsOpen.value && !frontDoorIsOpen.value) {
+          modalTitle.value = '关闭后门';
+          modalType.value = '4';
+          modalIsShow.value = true;
+        }
+        break;
+      case 5: // 打开前后门
+        if (!frontDoorIsOpen.value && !backDoorIsOpen.value) {
+          modalTitle.value = '打开前后门';
+          modalType.value = '5';
+          modalIsShow.value = true;
+        }
+        break;
+      case 6: // 关闭前后门
+        if (frontDoorIsOpen.value && backDoorIsOpen.value) {
+          modalTitle.value = '关闭前后门';
+          modalType.value = '6';
+          modalIsShow.value = true;
+        }
+        break;
+    }
+  };
+
+  const handleOK = (passWord, handlerState) => {
+    if (passWord !== '123456') {
+      message.warning('密码不正确,请重新输入');
+      return;
+    }
+
     const data = {
       deviceid: selectData.deviceID,
       devicetype: selectData.deviceType,
       paramcode: '',
       value: null,
-      autoRoManual: selectData.autoRoManual
+      autoRoManual: selectData.autoRoManual,
     };
-
     let handler = () => {};
 
     switch (handlerState) {
-      case 1: // 打开前门
+      case '1': // 打开前门
         if (!frontDoorIsOpen.value && !backDoorIsOpen.value) {
           handler = () => {
             frontDoorIsOpen.value = true;
@@ -218,7 +304,7 @@
           data.paramcode = 'frontGateOpen_S';
         }
         break;
-      case 2: // 关闭前门
+      case '2': // 关闭前门
         if (frontDoorIsOpen.value && !backDoorIsOpen.value) {
           handler = () => {
             frontDoorIsOpen.value = false;
@@ -226,7 +312,7 @@
           data.paramcode = 'frontGateClose_S';
         }
         break;
-      case 3: // 打开后门
+      case '3': // 打开后门
         if (!backDoorIsOpen.value && !frontDoorIsOpen.value) {
           handler = () => {
             backDoorIsOpen.value = true;
@@ -234,7 +320,7 @@
           data.paramcode = 'rearGateOpen_S';
         }
         break;
-      case 4: // 关闭后门
+      case '4': // 关闭后门
         if (backDoorIsOpen.value && !frontDoorIsOpen.value) {
           handler = () => {
             backDoorIsOpen.value = false;
@@ -242,16 +328,16 @@
           data.paramcode = 'rearGateClose_S';
         }
         break;
-      case 5: // 打开前后门
+      case '5': // 打开前后门
         if (!frontDoorIsOpen.value && !backDoorIsOpen.value) {
           handler = () => {
             frontDoorIsOpen.value = true;
-            backDoorIsOpen.value = true
+            backDoorIsOpen.value = true;
           };
           data.paramcode = 'sameTimeOpen';
         }
         break;
-      case 6: // 关闭前后门
+      case '6': // 关闭前后门
         if (frontDoorIsOpen.value && backDoorIsOpen.value) {
           handler = () => {
             frontDoorIsOpen.value = false;
@@ -261,7 +347,6 @@
         }
         break;
     }
-
     if (data.paramcode) {
       deviceControlApi(data)
         .then((res) => {
@@ -269,11 +354,19 @@
           }
         })
         .finally(() => {
+          modalIsShow.value = false;
+          modalTitle.value = '';
+          modalType.value = '';
           handler();
-          play(handlerState)
+          play(Number(handlerState));
         });
     }
   };
+  const handleCancel = () => {
+    modalIsShow.value = false;
+    modalTitle.value = '';
+    modalType.value = '';
+  };
 
   // 远程、就地切换
   const changeType = () => {
@@ -281,61 +374,63 @@
       deviceid: selectData.deviceID,
       devicetype: selectData.deviceType,
       paramcode: 'autoRoManual',
-      value: selectData.autoRoManual
+      value: selectData.autoRoManual,
     };
     deviceControlApi(data).then(() => {
-      message.success('状态切换成功!')
-    })
-  }
+      message.success('状态切换成功!');
+    });
+  };
 
-  const flvURL1 = () =>{
-    return `https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv`
-  }
-  const flvURL2 = () =>{
-    return `https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv`
-  }
+  const flvURL1 = () => {
+    return `https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv`;
+  };
+  const flvURL2 = () => {
+    return `https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv`;
+  };
 
   // 视频播放
   const addPlayVideo = () => {
-    if(player1.value && player2.value && player1.value?.play && player2.value?.play) {
+    if (player1.value && player2.value && player1.value?.play && player2.value?.play) {
       // player1.value.setMuted(false);
       // player2.value.setMuted(false);
       player1.value.play();
       player2.value.play();
-      document.body.removeEventListener('mousedown', addPlayVideo)
+      document.body.removeEventListener('mousedown', addPlayVideo);
     }
-  }
+  };
+
+  const handleOk = (e: MouseEvent) => {
+    //
+  };
 
   onBeforeMount(() => {
     const sendVal = JSON.stringify({ pagetype: 'normal', devicetype: 'gate', orgcode: '', ids: '', systemID: '' });
     initWebSocket(sendVal);
-
   });
 
   onMounted(() => {
-    loading.value = true
-    getMonitor()
+    loading.value = true;
+    getMonitor();
     mountedThree(player1.value, player2.value).then(() => {
-      addFmText(selectData)
-      loading.value = false
-    })
+      nextTick(() => {
+        addFmText(selectData);
+      });
+      loading.value = false;
+    });
     document.body.addEventListener('mousedown', addPlayVideo, false);
   });
-  onBeforeUnmount(() => {
-
-  })
+  onBeforeUnmount(() => {});
   onUnmounted(() => {
-    if(timer) {
-      clearTimeout(timer)
+    if (timer) {
+      clearTimeout(timer);
       timer = undefined;
     }
-    destroy()
-  })
-
+    destroy();
+  });
 </script>
 
-<style  lang="less" scoped>
-  .button-box{
+<style lang="less" scoped>
+  .button-box {
     border: none !important;
     height: 34px !important;
     &:hover {
@@ -349,7 +444,7 @@
       top: 35px !important;
     }
   }
-  :deep(.ant-tabs-tabpane-active){
+  :deep(.ant-tabs-tabpane-active) {
     overflow: auto;
   }
 </style>

+ 64 - 0
src/views/vent/monitorManager/gateMonitor/modal.vue

@@ -0,0 +1,64 @@
+<template>
+  <a-modal v-model:visible="visible" :title="title" @ok="handleOk" @cancel="handleCancel">
+    <div class="modal-container">
+      <div class="vent-flex-row">
+        <ExclamationCircleFilled style="color: #ffb700; font-size: 30px" />
+        <div class="warning-text">您是否要进行{{ title }}操作?</div>
+      </div>
+      <div class="vent-flex-row input-box">
+        <div class="label">操作密码:</div>
+        <a-input size="small" type="password" v-model:value="passWord" />
+      </div>
+    </div>
+  </a-modal>
+</template>
+<script setup lang="ts">
+  import { watch, ref } from 'vue';
+  import { ExclamationCircleFilled } from '@ant-design/icons-vue';
+
+  const props = defineProps({
+    modalIsShow: {
+      type: Boolean,
+      default: false,
+    },
+    modalTitle: {
+      type: String,
+      default: '',
+    },
+    modalType: {
+      type: String,
+      default: '',
+    },
+  });
+
+  const emit = defineEmits(['handleOk', 'handleCancel']);
+
+  const visible = ref<Boolean>(false);
+  const title = ref<String>('');
+  const type = ref<String>('');
+  const passWord = ref('');
+
+  watch([() => props.modalIsShow, () => props.modalTitle, () => props.modalType], ([newVal, newModalTitle, newModalType]) => {
+    visible.value = newVal;
+    if (newModalTitle) title.value = newModalTitle;
+    if (newModalType) type.value = newModalType;
+    passWord.value = '';
+  });
+
+  function handleOk() {
+    //
+    emit('handleOk', passWord.value, type.value);
+  }
+  function handleCancel() {
+    //
+    emit('handleCancel');
+  }
+</script>
+<style scoped lang="less">
+  .label {
+    width: 80px;
+  }
+  .ant-input {
+    width: 150px;
+  }
+</style>

+ 42 - 9
src/views/vent/monitorManager/mainFanMonitor/index.vue

@@ -137,7 +137,7 @@
     <!-- <LivePlayer id="main-player1" ref="player1" :videoUrl="flvURL1()" muted live loading controls /> -->
     <LivePlayer id="main-player1" ref="player1" :videoUrl="flvURL1()" muted loop loading controls />
   </div>
-  <a-modal v-model:visible="modalIsShow" :title="modalTitle" @ok="handleOk">
+  <a-modal v-model:visible="modalIsShow" :title="modalTitle" @ok="handleOk" @cancel="handleCancel">
     <div class="modal-container">
       <div class="vent-flex-row">
         <ExclamationCircleFilled style="color: #ffb700; font-size: 30px" />
@@ -165,6 +165,10 @@
           </a-radio-group>
         </div>
       </div>
+      <div class="vent-flex-row input-box">
+        <div class="label">操作密码:</div>
+        <a-input size="small" type="password" v-model:value="passWord" />
+      </div>
     </div>
   </a-modal>
 </template>
@@ -186,6 +190,7 @@
   import { list, pathList, deviceList, testWind } from './main.api';
   import { list as baseList } from '../../deviceManager/fanTabel/fan.api';
   import { getTableList } from '/@/views/vent/monitorManager/fanLocalMonitor/fanLocal.api';
+  import { message } from 'ant-design-vue';
   const modalTypeArr = reactive({
     centerBtnArr: [
       {
@@ -217,7 +222,7 @@
   const mainWindIsShow2 = ref('stop'); // 2#风机默认不启动
   const frontMonitorIsShow = ref(true); // 存放1#风机临时状态,保存模态框取消时,还需要返回之前的值
   const backMonitorIsShow = ref(false); // 存放2#风机临时状态,保存模态框取消时,还需要返回之前的值
-
+  const passWord = ref('');
   // 默认初始是第一行 (默认n%2==0时是主机,n%2==1时是备机)
   const selectRowIndex = ref(0);
   // 默认数据左边监测的是1#风机
@@ -327,13 +332,14 @@
       loading.value = false;
     });
     const data = dataSource.value[baseDataIndex];
-    mainWindIsShow1.value = 'stop';
+    mainWindIsShow1.value = 'open';
     mainWindIsShow2.value = 'stop';
     if (data['fanStart1'] == 1) {
       mainWindIsShow1.value = 'open';
     } else if (data['fanStart2'] == 1) {
       mainWindIsShow2.value = 'open';
     }
+    play('initiatePlay', 'front', frequencyVal.value, 'open', 'tubPositivePath');
     return;
   };
 
@@ -379,6 +385,11 @@
   };
   // 风机操作
   const handleOk = (e: MouseEvent) => {
+    if (passWord.value !== '123456') {
+      message.warning('密码不正确,请重新输入');
+      return;
+    }
+
     if (selectRowIndex.value % 2 == 0) {
       selectRowIndex.value = selectRowIndex.value + 1;
     } else {
@@ -394,7 +405,7 @@
       } else if (mainWindIsShow2.value === 'open' && mainWindIsShow1.value === 'stop') {
         frontMonitorIsShow.value = false;
         backMonitorIsShow.value = true;
-        play('startSmoke', 'back', frequency, 'open', 'tubInversePath');
+        play('startSmoke', 'back', frequency, 'open', 'tubPositivePath');
         play('startSmoke', 'front', null, 'close', '');
       } else if (mainWindIsShow1.value === 'stop' && mainWindIsShow2.value === 'stop') {
         frontMonitorIsShow.value = false;
@@ -409,17 +420,19 @@
         play('changeDirection', 'back', null, null, 'tubInversePath');
       }
     } else if (modalType.value == 'changeSmoke') {
+      debugger;
       // 不停风倒机的同时要切换当前监测数据
       if (mainWindIsShow1.value == 'open') {
         frontMonitorIsShow.value = false;
         backMonitorIsShow.value = true;
         // 切换到后面那台风,并需要设置后面风机的频率
-        play('changeSmoke', 'back', dataSource.value[selectRowIndex.value + 1]['frequency'], null, 'tubInversePath');
+        // play('changeSmoke', 'back', dataSource.value[selectRowIndex.value + 1]['frequency'], null, 'tubInversePath');
+        play('changeSmoke', 'back', frequency, null, 'tubPositivePath');
       } else if (mainWindIsShow2.value == 'open') {
         frontMonitorIsShow.value = true;
         backMonitorIsShow.value = false;
         // 切换到前面那台风,并需要设置前面风机的频率
-        play('changeSmoke', 'front', dataSource.value[selectRowIndex.value]['frequency'], null, 'tubPositivePath');
+        play('changeSmoke', 'front', frequency, null, 'tubPositivePath');
       }
     } else if (modalType.value == 'frequency') {
       if (mainWindIsShow1.value == 'open') {
@@ -432,6 +445,20 @@
     modalIsShow.value = false;
   };
 
+  // 取消
+  const handleCancel = () => {
+    if (modalType.value == 'startSmoke') {
+      const data = dataSource.value[selectRowIndex.value];
+      mainWindIsShow1.value = 'stop';
+      mainWindIsShow2.value = 'stop';
+      if (data['fanStart1'] == 1) {
+        mainWindIsShow1.value = 'open';
+      } else if (data['fanStart2'] == 1) {
+        mainWindIsShow2.value = 'open';
+      }
+    }
+  };
+
   onBeforeMount(() => {
     // document.body.addEventListener('mousedown', addPlayVideo, true);
     getDeviceBaseList();
@@ -440,10 +467,10 @@
   onMounted(() => {
     loading.value = true;
     mountedThree(player1.value).then(async () => {
-      await setModelType('mainWindRect');
+      // await setModelType('mainWindRect');
       getMonitor();
-      addText('mainWindRect');
-      play('initiatePlay', 'front', frequencyVal.value, 'open', 'tubPositivePath');
+      // addText('mainWindRect');
+      // play('initiatePlay', 'front', frequencyVal.value, 'open', 'tubPositivePath');
     });
   });
 
@@ -762,4 +789,10 @@
     height: 100% !important;
     overflow-y: auto;
   }
+  .label {
+    max-width: 220px;
+  }
+  .ant-input {
+    width: 150px;
+  }
 </style>

+ 2 - 1
src/views/vent/monitorManager/mainFanMonitor/main.threejs.ts

@@ -154,7 +154,8 @@ export const setModelType = (type) => {
           oldCameraPosition,
           { x: 0, y: -100.539, z: 104.313 },
           { x: position.x, y: position.y, z: position.z },
-          model
+          model,
+          0.8
         );
         model.scene.add(mainWindObj.group);
       }, 300);

+ 80 - 11
src/views/vent/monitorManager/mainFanMonitor/mainWind.threejs.ts

@@ -146,6 +146,7 @@ class mainWindRect {
     this.frontSmoke = new SmokePath('/model/img/texture-smoke.png', '#ffffff', 0, 1, 0.7, 300, frontPath);
     this.frontSmoke.setPoints();
     this.frontSmoke.pointsMesh.position.set(0.33, 2.8, 8.04);
+    this.frontSmoke.pointsMesh.name = 'frontSmoke';
     this.group?.add(this.frontSmoke.pointsMesh);
 
     const backSmoke = new THREE.CatmullRomCurve3([
@@ -164,6 +165,7 @@ class mainWindRect {
     this.backSmoke = new SmokePath('/model/img/texture-smoke.png', '#ffffff', 0, 1, 0.7, 300, backSmoke);
     this.backSmoke.setPoints();
     this.backSmoke.pointsMesh.position.set(0.65, 2.77, -7.38);
+    this.backSmoke.pointsMesh.name = 'backSmoke';
     this.group?.add(this.backSmoke.pointsMesh);
   }
 
@@ -218,7 +220,58 @@ class mainWindRect {
   }
 
   async setSmokeDirection(deviceType, smokeDirection) {
-    const _this = this;
+    const windowPositivePath = [
+      {
+        path0: new THREE.Vector3(4.441, 20.267, 3.614),
+        path1: new THREE.Vector3(5.041, 6.806, 3.614),
+        isSpread: true,
+        spreadDirection: -1, //
+      },
+      {
+        path0: new THREE.Vector3(7.441, 0.806, 3.614),
+        path1: new THREE.Vector3(41.583, 1.485, 3.614),
+        isSpread: false,
+        spreadDirection: 0, //
+      },
+      {
+        path0: new THREE.Vector3(41.583, 1.485, 3.614),
+        path1: new THREE.Vector3(42.741, 5.364, 3.614),
+        isSpread: false,
+        spreadDirection: 0,
+      },
+      {
+        path0: new THREE.Vector3(42.741, 5.364, 3.614),
+        path1: new THREE.Vector3(44.741, 17.267, 3.614),
+        isSpread: true,
+        spreadDirection: 1, // 1是由小变大(出),-1是由大变小(进)
+      },
+    ];
+    const windowInversePath = [
+      {
+        path0: new THREE.Vector3(44.741, 17.267, 3.614),
+        path1: new THREE.Vector3(42.741, 5.364, 3.614),
+        isSpread: true,
+        spreadDirection: -1, //
+      },
+      {
+        path0: new THREE.Vector3(42.741, 5.364, 3.614),
+        path1: new THREE.Vector3(41.583, 1.485, 3.614),
+        isSpread: false,
+        spreadDirection: 0, //
+      },
+      {
+        path0: new THREE.Vector3(41.583, 1.485, 3.614),
+        path1: new THREE.Vector3(7.441, 0.806, 3.614),
+        isSpread: false,
+        spreadDirection: 0, // 1是由小变大,-1是由大变小
+      },
+      {
+        path0: new THREE.Vector3(4.441, 17.267, 3.614),
+        path1: new THREE.Vector3(5.041, 6.806, 3.614),
+        isSpread: true,
+        spreadDirection: 1, //
+      },
+    ];
     const tubPositivePath = [
       {
         path0: new THREE.Vector3(7.441, 0.806, 3.614),
@@ -236,7 +289,7 @@ class mainWindRect {
         path0: new THREE.Vector3(42.741, 5.364, 3.614),
         path1: new THREE.Vector3(44.741, 17.267, 3.614),
         isSpread: true,
-        spreadDirection: 1, // 1是由小变大,-1是由大变小
+        spreadDirection: 1, // 1是由小变大(出),-1是由大变小(进)
       },
     ];
     const tubInversePath = [
@@ -259,15 +312,25 @@ class mainWindRect {
         spreadDirection: 0, // 1是由小变大,-1是由大变小
       },
     ];
+    let smoke;
     if (deviceType === 'front') {
-      switch (smokeDirection) {
-        case 'tubPositivePath': // 风筒正
-          _this.frontSmoke.setPath(tubPositivePath);
-          break;
-        case 'tubInversePath': // 风筒反
-          _this.frontSmoke.setPath(tubInversePath);
-          break;
-      }
+      smoke = this.frontSmoke;
+    } else if (deviceType === 'back') {
+      smoke = this.backSmoke;
+    }
+    switch (smokeDirection) {
+      case 'tubPositivePath': // 风筒正
+        smoke.setPath(tubPositivePath);
+        break;
+      case 'tubInversePath': // 风筒反
+        smoke.setPath(tubInversePath);
+        break;
+      case 'windowPositivePath': // 风窗正
+        smoke.setPath(windowPositivePath);
+        break;
+      case 'windowInversePath': // 风窗反
+        smoke.setPath(windowInversePath);
+        break;
     }
   }
 
@@ -308,6 +371,8 @@ class mainWindRect {
       this.startGearAnimation(deviceType, 'frequency', smokeDirection, frequencyVal);
     } else if (controlType === 'initiatePlay') {
       this.openDevice(deviceType, smokeDirection, frequencyVal, 0);
+    } else if (controlType === 'changeSmoke') {
+      //
     }
   }
 
@@ -427,6 +492,7 @@ class mainWindRect {
         repeat: 0,
         overwrite: true,
       });
+
       const clock = new THREE.Clock(); // 时钟
       const h = () => {
         gearObj.gearFrameId = requestAnimationFrame(h);
@@ -456,6 +522,7 @@ class mainWindRect {
       }
     } else if (flag === 'open') {
       gearObj.gear1Direction = gearDirection;
+      gearObj.gear2Direction = -1 * gearDirection;
       gearAnimation();
     } else if (flag === 'close') {
       gsap.to(gearObj, {
@@ -489,11 +556,13 @@ class mainWindRect {
   /* 口上面的气体 */
   setSmokePosition() {
     this.frontSmoke.setPoints();
+    this.frontSmoke.points.name = 'frontSmoke';
     this.group?.add(this.frontSmoke.points);
     this.frontSmoke.points.position.set(-2.51, 2.51, 8.18);
     this.backSmoke.setPoints();
+    this.backSmoke.points.name = 'backSmoke';
     this.group?.add(this.backSmoke.points);
-    // this.backSmoke.points.position.set(47.07, -8.48, -1.83);
+    this.backSmoke.points.position.set(-2.2, 3.13, -7.87);
   }
 
   /** 初始化电机 */

+ 69 - 4
src/views/vent/monitorManager/sensorMonitor/index.vue

@@ -5,7 +5,7 @@
         <div class="box-bg table-box" style="margin-bottom: 10px">
           <label style="color: #fff">设备类型:</label>
           <Select
-            @change="handleChange"
+            @change="handleSensorChange"
             :options="deviceTypeOption"
             :fieldNames="{ label: 'itemText', value: 'itemValue' }"
             v-model:value="deviceKind"
@@ -14,12 +14,24 @@
             :allowClear="true"
           />
           <MonitorTable
+            ref="SensorMonitorRef"
             columnsType="modelsensor_monitor"
             :dataSource="dataSource"
             design-scope="modelsensor_monitor"
             @select-row="getSelectRow"
-            title="风窗监测"
-          />
+            :deviceType="deviceKind"
+            size="''"
+            title="传感器监测"
+          >
+            <template #filterCell="{ column, record }">
+              <a-tag v-if="column.dataIndex === 'warnFlag'" :color="record.warnFlag == 0 ? 'green' : 'red'">{{
+                record.warnFlag == 0 ? '正常' : '报警'
+              }}</a-tag>
+              <a-tag v-if="column.dataIndex === 'netStatus'" :color="record.netStatus == 0 ? 'default' : 'green'">{{
+                record.netStatus == 0 ? '断开' : '连接'
+              }}</a-tag>
+            </template>
+          </MonitorTable>
         </div>
 
         <div class="charts-box box-bg">
@@ -79,7 +91,7 @@
   import '/@/design/vent/modal.less';
   import BarAndLine from '/@/components/chart/BarAndLine.vue';
   import { Select } from 'ant-design-vue';
-  import { onBeforeMount, ref, onMounted, onUnmounted, toRaw, reactive } from 'vue';
+  import { onBeforeMount, ref, onMounted, onUnmounted, toRaw, reactive, nextTick } from 'vue';
   import MonitorTable from '../comment/MonitorTable.vue';
   import HistoryTable from '../comment/HistoryTable.vue';
   import AlarmHistoryTable from '../comment/AlarmHistoryTable.vue';
@@ -88,6 +100,7 @@
   import { list as baseList } from '../../deviceManager/sensorTabel/sensor.api';
   import { deviceList } from '../../deviceManager/comment/pointTabel/point.api';
 
+  const SensorMonitorRef = ref();
   const deviceBaseList = ref([]);
   const activeKey = ref('1');
   const deviceKind = ref(null);
@@ -254,6 +267,20 @@
 
     console.log('[ type ] >', type, chartsColumns.value);
   }
+
+  function handleSensorChange(type) {
+    setTimeout(() => {
+      handleChange(type);
+      if (timer) {
+        clearTimeout(timer);
+        timer = null;
+      }
+      dataSource.value = [];
+      detailDataSource.value = [];
+      getMonitor();
+    }, 50);
+  }
+
   function refreshEchatrs() {
     timer = null;
     getMonitor();
@@ -319,6 +346,7 @@
       -webkit-backdrop-filter: blur(8px);
       backdrop-filter: blur(8px);
       box-shadow: 0 0 10px #5984e055 inset;
+      background-color: #00b3ff12;
     }
     .charts-box {
       height: calc(40vh - 80px);
@@ -364,5 +392,42 @@
     .ant-picker-separator {
       color: #fff !important;
     }
+    .ant-table-cell-row-hover {
+      background: #264d8833 !important;
+    }
+    .ant-table-row-selected {
+      background: #264d8888 !important;
+      td {
+        background-color: #00000000 !important;
+      }
+    }
+    .ant-table-thead {
+      background: linear-gradient(#004a8655 0%, #004a86aa 10%) !important;
+
+      & > tr > th,
+      .ant-table-column-title {
+        // color: #70f9fc !important;
+        border-color: #91e9fe !important;
+        border-left: none !important;
+        border-right: none !important;
+        padding: 7px;
+      }
+    }
+
+    .ant-table-tbody {
+      tr > td {
+        padding: 12px;
+      }
+    }
+    .ant-table-tbody > tr:hover.ant-table-row > td {
+      background-color: #264d8855 !important;
+    }
+
+    .jeecg-basic-table-row__striped {
+      // background: #97efff11 !important;
+      td {
+        background-color: #97efff11 !important;
+      }
+    }
   }
 </style>

+ 44 - 8
src/views/vent/monitorManager/windowMonitor/index.vue

@@ -18,10 +18,10 @@
   <div class="scene-box">
     <div class="top-box">
       <div class="top-center row">
-        <div class="input-box">
+        <!-- <div class="input-box">
           <span class="input-title">风窗面积:</span>
           <a-input-number size="small" placeholder="0" :min="0" :max="90" :step="1" v-model:value="windowAngle" />
-        </div>
+        </div> -->
         <div class="button-box" @click="setArea(1)">设定前窗面积</div>
         <div class="button-box" @click="setArea(2)">设定后窗面积</div>
         <div class="button-box" @click="setArea(2)" style="display: none">设定风窗面积</div>
@@ -60,7 +60,16 @@
             @selectRow="getSelectRow"
             design-scope="window-monitor"
             title="风窗监测"
-          />
+          >
+            <template #filterCell="{ column, record }">
+              <a-tag v-if="column.dataIndex === 'warnFlag'" :color="record.warnFlag == 0 ? 'green' : 'red'">{{
+                record.warnFlag == 0 ? '正常' : '报警'
+              }}</a-tag>
+              <a-tag v-if="column.dataIndex === 'netStatus'" :color="record.netStatus == 0 ? 'default' : 'green'">{{
+                record.netStatus == 0 ? '断开' : '连接'
+              }}</a-tag>
+            </template>
+          </MonitorTable>
         </a-tab-pane>
         <a-tab-pane key="2" tab="实时曲线图" force-render>
           <div class="tab-item" v-if="activeKey === '2'">
@@ -97,16 +106,19 @@
     <LivePlayer id="fc-player1" ref="player1" :videoUrl="flvURL1()" muted live loading controls />
     <LivePlayer id="fc-player2" ref="player2" :videoUrl="flvURL1()" muted live loading controls style="margin-top: 10px" />
   </div>
+  <HandleModal :modal-is-show="modalIsShow" :modal-title="modalTitle" :modal-type="modalType" @handle-ok="handleOK" @handle-cancel="handleCancel" />
 </template>
 
 <script setup lang="ts">
   import '/@/design/vent/modal.less';
+  import { message } from 'ant-design-vue';
   import DeviceEcharts from '../comment/DeviceEcharts.vue';
   import { onBeforeMount, ref, onMounted, onUnmounted, reactive, toRaw } from 'vue';
   import MonitorTable from '../comment/MonitorTable.vue';
   import HistoryTable from '../comment/HistoryTable.vue';
   import AlarmHistoryTable from '../comment/AlarmHistoryTable.vue';
   import HandlerHistoryTable from '../comment/HandlerHistoryTable.vue';
+  import HandleModal from './modal.vue';
   import { initWebSocket, getRecordList } from '/@/hooks/web/useVentWebSocket';
   import { mountedThree, destroy, addFmText, play, setModelType } from './window.threejs';
   import { list, getTableList } from './window.api';
@@ -119,6 +131,10 @@
   const player1 = ref(null);
   const player2 = ref(null);
 
+  const modalIsShow = ref<boolean>(false); // 是否显示模态框
+  const modalTitle = ref(''); // 模态框标题显示内容,根据设备操作类型决定
+  const modalType = ref(''); // 模态框内容显示类型,设备操作类型
+
   const deviceBaseList = ref([]);
   const activeKey = ref('1');
   const loading = ref(false);
@@ -251,16 +267,36 @@
 
   // 设置风窗面积
   const setArea = (flag) => {
+    modalTitle.value = flag === 1 ? '设定前窗面积' : '设定后窗面积';
+    modalType.value = flag;
+    modalIsShow.value = true;
+  };
+
+  const handleOK = (passWord, handlerState, windowAngle) => {
+    windowAngle.value = windowAngle;
+    if (passWord !== '123456') {
+      message.warning('密码不正确,请重新输入');
+      return;
+    }
     const data = {
       deviceid: selectData.deviceID,
       devicetype: selectData.deviceType,
-      paramcode: flag === 1 ? 'frontSetValue' : 'rearSetValue',
+      paramcode: handlerState == 1 ? 'frontSetValue' : 'rearSetValue',
       value: windowAngle.value,
     };
-    deviceControlApi(data).then((res) => {
-      if (res.success) {
-      }
-    });
+    deviceControlApi(data)
+      .then((res) => {
+        if (res.success) {
+        }
+      })
+      .finally(() => {
+        handleCancel();
+      });
+  };
+  const handleCancel = () => {
+    modalIsShow.value = false;
+    modalTitle.value = '';
+    modalType.value = '';
   };
 
   const addPlayVideo = () => {

+ 71 - 0
src/views/vent/monitorManager/windowMonitor/modal.vue

@@ -0,0 +1,71 @@
+<template>
+  <a-modal v-model:visible="visible" :title="title" @ok="handleOk" @cancel="handleCancel">
+    <div class="modal-container">
+      <div class="vent-flex-row">
+        <ExclamationCircleFilled style="color: #ffb700; font-size: 30px" />
+        <div class="warning-text">您是否要进行{{ title }}操作?</div>
+      </div>
+      <div class="vent-flex-row input-box">
+        <div class="label">风窗面积:</div>
+        <a-input-number size="small" placeholder="0" :min="0" :max="90" :step="1" v-model:value="area" />
+      </div>
+      <div class="vent-flex-row input-box">
+        <div class="label">操作密码:</div>
+        <a-input size="small" type="password" v-model:value="passWord" />
+      </div>
+    </div>
+  </a-modal>
+</template>
+<script setup lang="ts">
+  import { watch, ref } from 'vue';
+  import { ExclamationCircleFilled } from '@ant-design/icons-vue';
+
+  const props = defineProps({
+    modalIsShow: {
+      type: Boolean,
+      default: false,
+    },
+    modalTitle: {
+      type: String,
+      default: '',
+    },
+    modalType: {
+      type: String,
+      default: '',
+    },
+  });
+
+  const emit = defineEmits(['handleOk', 'handleCancel']);
+
+  const visible = ref<Boolean>(false);
+  const title = ref<String>('');
+  const type = ref<String>('');
+  const passWord = ref('');
+  const area = ref(0);
+
+  watch([() => props.modalIsShow, () => props.modalTitle, () => props.modalType], ([newVal, newModalTitle, newModalType]) => {
+    visible.value = newVal;
+    if (newModalTitle) title.value = newModalTitle;
+    if (newModalType) type.value = newModalType;
+    passWord.value = '';
+    area.value = 0;
+  });
+
+  function handleOk() {
+    //
+    emit('handleOk', passWord.value, type.value, area.value);
+  }
+  function handleCancel() {
+    //
+    emit('handleCancel');
+  }
+</script>
+<style scoped lang="less">
+  .label {
+    width: 80px;
+  }
+  .ant-input,
+  .ant-input-number {
+    width: 150px;
+  }
+</style>

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

@@ -18,8 +18,8 @@
   <div class="scene-box">
     <div class="top-box">
       <div class="top-center row">
-        <div class="button-box" @click="start(0)">复位</div>
-        <div class="button-box" @click="testPlay()">自测动画</div>
+        <!-- <div class="button-box" @click="start(0)">复位</div> -->
+        <!-- <div class="button-box" @click="testPlay()">自测动画</div> -->
         <div class="button-box" @click="testPlay('up')">上</div>
         <div class="button-box" @click="testPlay('center')">中</div>
         <div class="button-box" @click="testPlay('down')">下</div>

+ 3 - 3
src/views/vent/monitorManager/windrectMonitor/longmen.threejs.ts

@@ -291,14 +291,14 @@ class lmWindRect {
       case 'up':
         gsap.to(cfTanTou['position'], {
           y: 0,
-          duration: Math.abs(cfTanTou['position']['y'] - 0) / 14,
+          duration: Math.abs(cfTanTou['position']['y'] - 0),
           ease: 'easeQutQuad',
           overwrite: true,
         });
         break;
       case 'center':
         gsap.to(cfTanTou['position'], {
-          y: -7,
+          y: -0.28,
           duration: Math.abs(cfTanTou['position']['y'] + 7) / 14,
           ease: 'easeQutQuad',
           overwrite: true,
@@ -306,7 +306,7 @@ class lmWindRect {
         break;
       case 'down':
         gsap.to(cfTanTou['position'], {
-          y: -14,
+          y: -0.52,
           duration: Math.abs(cfTanTou['position']['y'] + 14) / 14,
           ease: 'easeQutCubic',
           overwrite: true,

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

@@ -163,7 +163,8 @@ export const setModelType = (type) => {
           oldCameraPosition,
           { x: 46.257, y: 57.539, z: 94.313 },
           { x: position.x, y: position.y, z: position.z },
-          model
+          model,
+          0.8
         );
       }, 300);
     } else if (windRectType === 'zdWindRect') {
@@ -185,7 +186,8 @@ export const setModelType = (type) => {
           oldCameraPosition,
           { x: 66.257, y: 57.539, z: 104.313 },
           { x: position.x, y: position.y, z: position.z },
-          model
+          model,
+          0.8
         );
       }, 300);
     } else if (windRectType === 'dsWindRect') {
@@ -207,7 +209,8 @@ export const setModelType = (type) => {
           oldCameraPosition,
           { x: 46.257, y: 57.539, z: 104.313 },
           { x: position.x, y: position.y, z: position.z },
-          model
+          model,
+          0.8
         );
       }, 300);
     }