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

[Feat 0000] 添加一个三道沟的可配置首页

houzekong 1 день назад
Родитель
Сommit
a0b0aa3c26

+ 66 - 55
src/views/vent/home/configurable/configurable.api.ts

@@ -29,62 +29,73 @@ export const list = (params) => {
     );
   }
   return (cache.get(key) as Promise<any>).then((res) => {
-    res.fanmain.forEach((e) => {
-      if (e.readData.Fan2StartStatus === '1') {
-        e.current = '二号';
-        e.readData.FanFreqHz = e.readData.Fan2FreqHz;
-      } else {
-        e.current = '一号';
-        e.readData.FanFreqHz = e.readData.Fan1FreqHz;
-      }
-    });
-    res.fanlocal.forEach((e) => {
-      e.chartData = [
-        {
-          x: '吸风量',
-          yRealtime: e.readData.windQuantity1,
-          yMock: floor(parseFloat(e.inletAirVolume_merge) * random(0.98, 1, false), 2),
-          y: e.inletAirVolume_merge,
-        },
-        {
-          x: '供风量',
-          yRealtime: e.readData.windQuantity2,
-          yMock: floor(parseFloat(e.ductOutletAirVolume_merge) * random(0.98, 1, false), 2),
-          y: e.ductOutletAirVolume_merge,
-        },
-      ];
-      if (e.readData.Fan2StartStatus === '1') {
-        e.current = '二号';
-        e.readData.FanfHz = e.readData.Fan2fHz;
-      } else {
-        e.current = '一号';
-        e.readData.FanfHz = e.readData.Fan1fHz;
-      }
-    });
-    res.sys_majorpath.forEach((e) => {
-      const { drag_1, drag_2, drag_3, drag_total } = e.majorpath;
-      const { fy_merge = { value: '1' } } = e.readData;
-      const drag_merge = parseInt(fy_merge.value);
-      // const m3_merge = parseInt(retM3_merge.value);
+    if (res.fanmain) {
+      // 处理频率字段,为了兼容旧版保留,现配置项已支持一级动态字段
+      res.fanmain.forEach((e) => {
+        if (e.readData.Fan2StartStatus === '1') {
+          e.current = '二号';
+          e.readData.FanFreqHz = e.readData.Fan2FreqHz;
+        } else {
+          e.current = '一号';
+          e.readData.FanFreqHz = e.readData.Fan1FreqHz;
+        }
+      });
+    }
+    if (res.fanlocal) {
+      res.fanlocal.forEach((e) => {
+        e.chartData = [
+          {
+            x: '吸风量',
+            yRealtime: e.readData.windQuantity1,
+            yMock: floor(parseFloat(e.inletAirVolume_merge) * random(0.98, 1, false), 2),
+            y: e.inletAirVolume_merge,
+          },
+          {
+            x: '供风量',
+            yRealtime: e.readData.windQuantity2,
+            yMock: floor(parseFloat(e.ductOutletAirVolume_merge) * random(0.98, 1, false), 2),
+            y: e.ductOutletAirVolume_merge,
+          },
+        ];
+        if (e.readData.Fan2StartStatus === '1') {
+          e.current = '二号';
+          e.readData.FanfHz = e.readData.Fan2fHz;
+        } else {
+          e.current = '一号';
+          e.readData.FanfHz = e.readData.Fan1fHz;
+        }
+      });
+    }
+    if (res.sys_majorpath) {
+      res.sys_majorpath.forEach((e) => {
+        const { drag_1, drag_2, drag_3, drag_total } = e.majorpath;
+        const { fy_merge = { value: '1' } } = e.readData;
+        const drag_merge = parseInt(fy_merge.value);
+        // const m3_merge = parseInt(retM3_merge.value);
 
-      e.piechart = [
-        { val: drag_1, valMock: floor((drag_1 / drag_total) * drag_merge), label: '进风区(Pa)' },
-        { val: drag_2, valMock: floor((drag_2 / drag_total) * drag_merge), label: '用风区(Pa)' },
-        { val: drag_3, valMock: floor((drag_3 / drag_total) * drag_merge), label: '回风区(Pa)' },
-      ];
-      e.readData.dengjikong_merge = get(res, 'midinfo[0].sysinfo.equalarea');
-      e.readData.fy_merge_int = drag_merge;
-      // e.dengjikong_merge = floor((1.19 * (m3_merge / 60)) / Math.sqrt(drag_merge), 2);
-    });
-    res.sys_surface_caimei.forEach((e) => {
-      if (isArray(e.history)) {
-        e.history = slice(e.history, e.history.length - 30, e.history.length);
-      }
-      if (isArray(e.history_report)) {
-        e.history_report = slice(e.history_report, e.history_report.length - 30, e.history_report.length);
-      }
-    });
-    res.device_arr = Object.values(res.device);
+        e.piechart = [
+          { val: drag_1, valMock: floor((drag_1 / drag_total) * drag_merge), label: '进风区(Pa)' },
+          { val: drag_2, valMock: floor((drag_2 / drag_total) * drag_merge), label: '用风区(Pa)' },
+          { val: drag_3, valMock: floor((drag_3 / drag_total) * drag_merge), label: '回风区(Pa)' },
+        ];
+        e.readData.dengjikong_merge = get(res, 'midinfo[0].sysinfo.equalarea');
+        e.readData.fy_merge_int = drag_merge;
+        // e.dengjikong_merge = floor((1.19 * (m3_merge / 60)) / Math.sqrt(drag_merge), 2);
+      });
+    }
+    if (res.sys_surface_caimei) {
+      res.sys_surface_caimei.forEach((e) => {
+        if (isArray(e.history)) {
+          e.history = slice(e.history, e.history.length - 30, e.history.length);
+        }
+        if (isArray(e.history_report)) {
+          e.history_report = slice(e.history_report, e.history_report.length - 30, e.history_report.length);
+        }
+      });
+    }
+    if (res.device_arr) {
+      res.device_arr = Object.values(res.device);
+    }
 
     return res;
   });

+ 304 - 0
src/views/vent/home/configurable/ventSDG.vue

@@ -0,0 +1,304 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <div class="company-home">
+    <div style="width: 100%; height: 100%; position: absolute; left: 0; top: 0; z-index: 0">
+      <VentModal />
+    </div>
+    <!-- 如果是有 deviceType、type 等 query,认为是详情页,不需要展示普通模块,只需要模型 -->
+    <template v-if="!route.query.deviceType">
+      <div v-if="!route.query.embed" class="top-bg">
+        <div class="main-title">{{ mainTitle }}</div>
+      </div>
+      <a class="ant-dropdown-link module-dropdown" @click.prevent="showBar = !showBar">
+        全矿井通风检测
+        <CaretDownOutlined />
+      </a>
+      <MonitorBar v-if="showBar" class="module-monitor-bar" :is-data-real-time="isDataRealTime" :data="data" />
+      <!-- <a-dropdown class="module-dropdown" :class="{ 'module-dropdown-original': isOriginal }" :trigger="['click']" placement="bottomRight">
+        <template #overlay>
+        </template>
+      </a-dropdown> -->
+
+      <!-- 采用定位方式以避免出现各个模块隐藏时其他模块下移的问题 -->
+      <template v-if="isOriginal">
+        <ModuleOriginal
+          v-for="cfg in configs"
+          :key="cfg.deviceType"
+          :show-style="cfg.showStyle"
+          :module-data="cfg.moduleData"
+          :module-name="cfg.moduleName"
+          :device-type="cfg.deviceType"
+          :data="data"
+          :visible="true"
+        />
+      </template>
+      <template v-else-if="isCommon">
+        <ModuleCommon
+          v-for="cfg in configs"
+          :key="cfg.deviceType"
+          :show-style="cfg.showStyle"
+          :module-data="cfg.moduleData"
+          :module-name="cfg.moduleName"
+          :device-type="cfg.deviceType"
+          :data="data"
+          :visible="true"
+        />
+      </template>
+      <template v-else>
+        <!-- 下面是正常展示的各新版模块 -->
+        <ModuleEnhanced
+          v-for="cfg in enhancedConfigs"
+          :key="cfg.deviceType"
+          :visible="cfg.visible"
+          :show-style="cfg.showStyle"
+          :module-data="cfg.moduleData"
+          :module-name="cfg.moduleName"
+          :device-type="cfg.deviceType"
+          :data="data"
+          @close="cfg.visible = false"
+        />
+        <!-- 下面是用于呼出已隐藏的模块的按钮 -->
+        <div class="pos-absolute top-70px left-460px z-3">
+          <div v-for="(item, i) in hiddenList" :key="`vvhchg${i}`">
+            <AButton class="module-trigger-button" @click="item.visible = true">{{ item.moduleName }}</AButton>
+          </div>
+        </div>
+      </template>
+      <div
+        v-if="sysDataType === 'all'"
+        :class="{ 'realtime-mode': isDataRealTime }"
+        alt="切换数据模式"
+        class="switch-button report-mode right-525px"
+        @click="switchDataMode"
+      ></div>
+      <div class="switch-button icon-goto right-475px" @click="goMicroApp()"></div>
+    </template>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { onMounted, onUnmounted, ref, watch } from 'vue';
+  // import { CaretDownOutlined } from '@ant-design/icons-vue';
+  import MonitorBar from './components/MonitorBar.vue';
+  import { useInitConfigs, useInitPage } from './hooks/useInit';
+  import ModuleEnhanced from './components/ModuleEnhanced.vue';
+  import ModuleOriginal from './components/ModuleOriginal.vue';
+  import ModuleCommon from './components/ModuleCommon.vue';
+  // import { useRoute } from 'vue-router';
+  import VentModal from '/@/components/vent/micro/ventModal.vue';
+  import { list } from './configurable.api';
+  import { useRoute, useRouter } from 'vue-router';
+  import { useGlobSetting } from '/@/hooks/setting';
+  // import { testConfigVent, testConfigVentRealtime } from './configurable.data';
+
+  const { sysDataType = 'monitor', title = '智能通风管控系统' } = useGlobSetting();
+  const { configs, isOriginal, isCommon, fetchConfigs } = useInitConfigs();
+  const { mainTitle, enhancedConfigs, hiddenList, data, updateData, updateEnhancedConfigs } = useInitPage(title);
+  const route = useRoute();
+  const router = useRouter();
+  const isDataRealTime = ref(sysDataType === 'monitor');
+  const showBar = ref(true);
+  let interval: number | undefined;
+
+  function switchDataMode() {
+    isDataRealTime.value = !isDataRealTime.value;
+    refresh();
+  }
+
+  function refresh() {
+    fetchConfigs(isDataRealTime.value ? 'vent_realtime' : 'vent').then(() => {
+      // configs.value = isDataRealTime.value ? testConfigVentRealtime : testConfigVent;
+      updateEnhancedConfigs(configs.value);
+
+      // 测风装置	windrect
+      // 自动风窗	window
+      // 自动风门	gate
+      // 传感器	modelsensor
+      // 局部通风机	fanlocal
+      // 主通风机	fanmain
+      // 密闭	obfurage
+      // 安全监控	safetymonitor
+      // 光纤测温	fiber
+      // 束管监测	bundletube
+      // 制氮	nitrogen
+      // 制浆	pulping
+      // 喷淋	spray
+      // 喷粉	dustdev
+      // 喷雾设备	atomizing
+      // 除尘风机	dedustefan
+      // 粉尘传感器	dustsensor
+      // 转载点	transferpoint
+      // 瓦斯抽采泵	pump
+      // 粉尘	dusting
+      // 瓦斯监测	gasmonitor
+      // 球阀	ballvalve
+      // 压风机	forcFan
+      // 瓦斯巡检	gaspatrol
+      // 防火门	firedoor
+      // 隔爆设施	explosionProof
+      // 瓦斯管道阀门	gasvalve
+      list({
+        types: configs.value
+          .filter((e) => e.deviceType)
+          .map((e) => e.deviceType)
+          .join(','),
+      }).then(updateData);
+    });
+  }
+
+  function initInterval() {
+    setInterval(() => {
+      list({}).then(updateData);
+    }, 60000);
+  }
+
+  function goMicroApp() {
+    router.push({
+      path: route.path,
+      query: {
+        ...route.query,
+        type: 'model3D',
+        deviceType: 'model3D',
+      },
+    });
+  }
+
+  watch(
+    () => route.query,
+    () => {
+      if (route.query.deviceType) {
+        // 仅需要展示子应用,模拟 unmounted
+        clearInterval(interval);
+      } else {
+        // 模拟 mounted
+        refresh();
+        initInterval();
+      }
+    }
+  );
+
+  onMounted(() => {
+    refresh();
+    initInterval();
+  });
+
+  onUnmounted(() => {
+    clearInterval(interval);
+  });
+</script>
+<style lang="less" scoped>
+  @import '/@/design/theme.less';
+
+  @font-face {
+    font-family: 'douyuFont';
+    src: url('/@/assets/font/douyuFont.otf');
+  }
+
+  @{theme-deepblue} {
+    .company-home {
+      --image-modal-top: url('/@/assets/images/themify/deepblue/vent/home/modal-top.png');
+    }
+  }
+
+  .company-home {
+    --image-modal-top: url('/@/assets/images/vent/home/modal-top.png');
+    --image-monitor-realtime: url('/@/assets/images/company/monitor-realtime.png');
+    --image-monitor-doc: url('/@/assets/images/company/monitor-doc.png');
+    --image-monitor-goto: url('/@/assets/images/company/monitor-goto.png');
+
+    width: 100%;
+    height: 100%;
+    color: @white;
+    position: relative;
+    // background: url('@/assets/images/home-container/configurable/firehome/bg.png') no-repeat center;
+
+    .top-bg {
+      width: 100%;
+      height: 56px;
+      background: var(--image-modal-top) no-repeat center;
+      position: absolute;
+      z-index: 1;
+      .main-title {
+        height: 56px;
+        font-family: 'douyuFont';
+        font-size: 20px;
+        letter-spacing: 2px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+
+    // .module-left {
+    //   position: absolute;
+    //   width: 450px;
+    //   height: 280px;
+    //   left: 0;
+    // }
+    // .module-right {
+    //   position: absolute;
+    //   width: 450px;
+    //   height: 280px;
+    //   right: 0;
+    // }
+    // .module-bottom {
+    //   position: absolute;
+    //   width: 1000px;
+    //   height: 280px;
+    // }
+    .module-dropdown {
+      padding: 5px;
+      background-image: @vent-configurable-dropdown;
+      border-bottom: 2px solid @vent-configurable-home-light-border;
+      color: @vent-font-color;
+      position: absolute;
+      top: 60px;
+      right: 480px;
+    }
+    .module-dropdown-original {
+      padding: 10px;
+      background-image: @vent-configurable-dropdown;
+      border-bottom: 2px solid @vent-configurable-home-light-border;
+      color: @vent-font-color;
+      position: absolute;
+      top: 70px;
+      right: 460px;
+    }
+    .module-trigger-button {
+      color: @vent-font-color;
+      background-image: @vent-configurable-dropdown;
+      border: none;
+      border-bottom: 2px solid @vent-configurable-home-light-border;
+    }
+
+    .switch-button {
+      width: 34px;
+      height: 34px;
+      position: absolute;
+      // right: 5px;
+      bottom: 300px;
+      z-index: 5;
+      background-repeat: no-repeat;
+      background-size: 100% 100%;
+    }
+    .report-mode {
+      background-image: var(--image-monitor-doc);
+    }
+    .realtime-mode {
+      background-image: var(--image-monitor-realtime);
+    }
+    .icon-goto {
+      background-image: var(--image-monitor-goto);
+    }
+
+    .module-monitor-bar {
+      position: absolute;
+      top: 100px;
+      width: 1000px;
+      height: 200px;
+      left: calc(50% - 500px);
+    }
+  }
+  :deep(.loading-box) {
+    position: unset;
+  }
+</style>