3 Commits 57caa2e971 ... c54145eba0

Author SHA1 Message Date
  hongrunxia c54145eba0 1 1 week ago
  hongrunxia f71eafdf2a Merge branch 'master' of http://182.92.126.35:3000/hrx/mky-vent-base 1 week ago
  hongrunxia 1af07b8214 1. 提交为文件 1 week ago

+ 8 - 7
src/hooks/system/useCamera.ts

@@ -17,7 +17,7 @@ export function useCamera() {
   let webRtcServer = <any[]>[];
   const playerList = <any[]>[];
   const playerDoms = <(HTMLVideoElement | undefined | null)[]>[];
-  const videoParentDomList: (HTMLElement | [string, { name: string; addr: string; cameraRate: number }])[] = [];
+  const videoParentDomList: (HTMLElement | [string, { name: string; addr: string; cameraRate: number; devicekind: string }])[] = [];
 
   async function getCamera(deviceid, parentPlayerDom?, devKind?) {
     removeCamera();
@@ -62,7 +62,7 @@ export function useCamera() {
           try {
             const data = await cameraAddr({ cameraCode: item['addr'], videoType });
             if (data && data['url']) {
-              cameraAddrs.push({ name: item['name'], addr: data['url'], cameraRate: item['cameraRate'] });
+              cameraAddrs.push({ name: item['name'], addr: data['url'], cameraRate: item['cameraRate'], devicekind: item['devicekind'] });
             }
             // // 从海康平台接口获取视频流测试
             // cameraAddrs.push({
@@ -73,7 +73,7 @@ export function useCamera() {
         } else if (item['devicekind'] == 'toHKR') {
           cameraNames.push({ name: item['name'], cameraRate: item['cameraRate'] });
         } else {
-          cameraAddrs.push({ name: item['name'], addr: item['addr'], cameraRate: item['cameraRate'] });
+          cameraAddrs.push({ name: item['name'], addr: item['addr'], cameraRate: item['cameraRate'], devicekind: item['devicekind'] });
         }
       }
     }
@@ -107,8 +107,8 @@ export function useCamera() {
       const playCamrea = () => {
         if (cameraAddrs.length > 0) {
           const promiseList: Promise<any>[] = [];
-
-          cameraAddrs.forEach(async (cameraUrl: { name: string; addr: string; cameraRate: number }, index) => {
+          debugger;
+          cameraAddrs.forEach(async (cameraUrl: { name: string; addr: string; cameraRate: number; devicekind: string }, index) => {
             const promise = new Promise(async (childResolve) => {
               let cameraNameDom: null | HTMLElement = null;
               console.log('摄像头地址--------->', cameraUrl, cameraUrl.addr.startsWith('rtsp://'), livePlayerDiv);
@@ -203,7 +203,7 @@ export function useCamera() {
           if (videoParent[1] && videoParent[1].addr) {
             const fileExtension = videoParent[1].addr.split('.').pop();
             let player;
-            if (fileExtension === 'flv') {
+            if (fileExtension === 'flv' || videoParent[1].devicekind == 'flv') {
               player = new Player({
                 lang: 'zh',
                 id: videoParent[0],
@@ -239,9 +239,10 @@ export function useCamera() {
                   maxJumpDistance: 10,
                 },
               });
+
               playerList.push(player);
             }
-            if (fileExtension === 'm3u8') {
+            if (fileExtension === 'm3u8' || videoParent[1].devicekind == 'm3u8') {
               let player;
               if (document.createElement('video').canPlayType('application/vnd.apple.mpegurl')) {
                 // 原生支持 hls 播放

+ 471 - 0
src/views/vent/monitorManager/comment/FanDeviceEcharts.vue

@@ -0,0 +1,471 @@
+<template>
+  <div class="charts-container">
+    <a-select ref="select" v-model:value="chartsType" size="small" style="position: absolute; z-index: 99; top: 2px; left: 2px; width: 98px">
+      <a-select-option value="listMonitor">实时监测</a-select-option>
+      <a-select-option value="detail">详情监测</a-select-option>
+      <a-select-option value="history">历史记录</a-select-option>
+    </a-select>
+
+    <div class="charts-box" v-if="chartsType === 'listMonitor'" style="position: absolute; top: 20px">
+      <div class="echarts-group">
+        <BarAndLine
+          class="echarts-item"
+          :chartsColumnsType="chartsColumnsType"
+          :xAxisPropType="xAxisPropType"
+          :dataSource="dataSource"
+          height="100%"
+          chartsType="listMonitor"
+          :option="echartsOption"
+          :chartsColumns="fan1ChartsColumns"
+          style="border-right: 1px solid #fff"
+        />
+        <BarAndLine
+          class="echarts-item"
+          :chartsColumnsType="chartsColumnsType"
+          :xAxisPropType="xAxisPropType"
+          :dataSource="dataSource"
+          height="100%"
+          chartsType="listMonitor"
+          :option="echartsOption"
+          :chartsColumns="fan2ChartsColumns"
+        />
+      </div>
+    </div>
+    <div class="charts-box" v-else-if="chartsType === 'detail' && deviceListApi">
+      <Select
+        :options="options"
+        :fieldNames="{ label: 'strname', value: 'deviceID' }"
+        v-model:value="deviceId"
+        placeholder="请选择查看的设备"
+        size="small"
+        style="position: absolute; z-index: 99; left: 102px; width: 150px; top: 2px"
+      />
+      <div class="echarts-group">
+        <BarAndLine
+          class="echarts-item"
+          :chartsColumnsType="chartsColumnsType"
+          :xAxisPropType="resultXAxisPropType"
+          :dataSource="detailDataSource"
+          height="100%"
+          :option="echartsOption2"
+          chartsType="detail"
+          :chartsColumns="fan1ChartsColumns"
+          style="border-right: 1px solid #fff"
+        />
+        <BarAndLine
+          class="echarts-item"
+          :chartsColumnsType="chartsColumnsType"
+          :xAxisPropType="resultXAxisPropType"
+          :dataSource="detailDataSource"
+          height="100%"
+          :option="echartsOption2"
+          chartsType="detail"
+          :chartsColumns="fan2ChartsColumns"
+        />
+      </div>
+    </div>
+    <div class="charts-box" v-else-if="chartsType === 'history'">
+      <Select
+        :options="options"
+        :fieldNames="{ label: 'strname', value: 'deviceID' }"
+        v-model:value="deviceId"
+        placeholder="请选择查看的设备"
+        size="small"
+        style="position: absolute; z-index: 99; left: 102px; width: 150px; top: 2px"
+      />
+      <template v-if="globalConfig.History_Type == 'vent'">
+        <a-date-picker
+          v-model:value="historyParams.ttime_begin"
+          valueFormat="YYYY-MM-DD HH:mm:ss"
+          placeholder="请选择开始日期"
+          size="small"
+          :showTime="true"
+          style="position: absolute; z-index: 99; left: 254px; width: 170px; top: 2px"
+        />
+        <a-date-picker
+          v-model:value="historyParams.ttime_end"
+          valueFormat="YYYY-MM-DD HH:mm:ss"
+          placeholder="请选择结束日期"
+          size="small"
+          :showTime="true"
+          style="position: absolute; z-index: 99; left: 426px; width: 170px; top: 2px"
+        />
+        <a-select
+          ref="select"
+          v-model:value="historyParams.skip"
+          placeholder="请选择间隔时间"
+          size="small"
+          style="position: absolute; z-index: 99; top: 2px; left: 598px; width: 150px"
+        >
+          <a-select-option value="1">1秒</a-select-option>
+          <a-select-option value="2">5秒</a-select-option>
+          <a-select-option value="3">10秒</a-select-option>
+          <a-select-option value="4">30分钟</a-select-option>
+          <a-select-option value="5">1分钟</a-select-option>
+          <a-select-option value="6">10分钟</a-select-option>
+          <a-select-option value="7">30分钟</a-select-option>
+          <a-select-option value="8">1小时</a-select-option>
+        </a-select>
+      </template>
+      <template v-else>
+        <a-date-picker
+          v-model:value="historyParams.startTime"
+          valueFormat="YYYY-MM-DD HH:mm:ss"
+          placeholder="开始时间"
+          size="small"
+          :showTime="true"
+          style="position: absolute; z-index: 99; left: 254px; width: 170px; top: 2px"
+        />
+        <a-date-picker
+          v-model:value="historyParams.endTime"
+          valueFormat="YYYY-MM-DD HH:mm:ss"
+          placeholder="结束时间"
+          size="small"
+          :showTime="true"
+          style="position: absolute; z-index: 99; left: 426px; width: 170px; top: 2px"
+        />
+        <a-select
+          ref="select"
+          v-model:value="historyParams.interval"
+          placeholder="请选择间隔时间"
+          size="small"
+          style="position: absolute; z-index: 99; top: 2px; left: 598px; width: 150px"
+        >
+          <a-select-option value="1s">1秒</a-select-option>
+          <a-select-option value="5s">5秒</a-select-option>
+          <a-select-option value="10s">10秒</a-select-option>
+          <a-select-option value="30s">30秒</a-select-option>
+          <a-select-option value="1m">1分钟</a-select-option>
+          <a-select-option value="10m">5分钟</a-select-option>
+          <a-select-option value="30m">10分钟</a-select-option>
+          <a-select-option value="1h">1小时</a-select-option>
+        </a-select>
+      </template>
+      <Pagination
+        size="small"
+        v-model:current="currentPage"
+        v-model:page-size="pageSize"
+        :total="total"
+        :show-total="(total) => `共 ${total} 条`"
+        style="position: absolute; z-index: 99; top: 2px; right: 30px"
+      />
+      <div class="echarts-group">
+        <BarAndLine
+          class="echarts-item"
+          :chartsColumnsType="chartsColumnsType"
+          :xAxisPropType="resultXAxisPropType"
+          :dataSource="resultDataSource"
+          height="100%"
+          :option="echartsOption1"
+          chartsType="history"
+          style="margin-top: 20px; border-right: 1px solid #fff"
+          :chartsColumns="fan1ChartsColumns"
+        />
+        <BarAndLine
+          class="echarts-item"
+          :chartsColumnsType="chartsColumnsType"
+          :xAxisPropType="resultXAxisPropType"
+          :dataSource="resultDataSource"
+          height="100%"
+          :option="echartsOption1"
+          chartsType="history"
+          style="margin-top: 20px"
+          :chartsColumns="fan2ChartsColumns"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts">
+  import { ref, defineComponent, watch, reactive, onMounted, watchEffect, inject } from 'vue';
+  import BarAndLine from '/@/components/chart/BarAndLine.vue';
+  import dayjs from 'dayjs';
+  import { defHttp } from '/@/utils/http/axios';
+  import { Select, Pagination } from 'ant-design-vue';
+
+  export default defineComponent({
+    name: 'DeviceEcharts',
+    components: { BarAndLine, Select, Pagination },
+    props: {
+      fan1ChartsColumns: {
+        type: Array,
+        default: () => [],
+      },
+      fan2ChartsColumns: {
+        type: Array,
+        default: () => [],
+      },
+      chartsColumnsHistory: {
+        type: Array,
+        default: () => [],
+      },
+      chartsColumnsType: {
+        type: String,
+        required: true,
+      },
+      dataSource: {
+        type: Array,
+        default: () => [],
+      },
+      deviceListApi: {
+        type: Function,
+        required: true,
+      },
+      deviceType: {
+        type: String,
+        required: true,
+      },
+      option: {
+        type: Object,
+        default: () => ({}),
+      },
+      xAxisPropType: {
+        type: String,
+        required: true,
+      },
+    },
+    setup(props) {
+      const globalConfig = inject('globalConfig');
+      let historyList;
+      if (globalConfig.History_Type == 'vent') {
+        historyList = (params) => defHttp.get({ url: '/safety/ventanalyMonitorData/listdays', params });
+      } else {
+        historyList = (params) => defHttp.post({ url: '/monitor/history/getHistoryData', params });
+      }
+      const chartsType = ref('history');
+      const deviceId = ref('');
+      const options = ref([]);
+      const historyParams = reactive({
+        ttime_begin: dayjs().startOf('date').format('YYYY-MM-DD HH:mm:ss'),
+        ttime_end: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+        skip: '8',
+        startTime: dayjs().startOf('date').format('YYYY-MM-DD HH:mm:ss'),
+        endTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
+        interval: '1h',
+      });
+      const resultXAxisPropType = ref('');
+      const resultDataSource = ref<any[]>([]);
+      const detailDataSource = ref<any[]>([]);
+      const currentPage = ref<number>(1);
+      const pageSize = ref<number>(20);
+      const total = ref(0);
+
+      const echartsOption = {
+        grid: {
+          top: '50px',
+          left: '10px',
+          right: props.fan1ChartsColumns.length * 15 + 'px',
+          bottom: '15px',
+          containLabel: true,
+        },
+        toolbox: {
+          feature: {},
+        },
+        xAxis: {
+          axisLabel: {
+            interval: 0,
+          },
+        },
+      };
+      const echartsOption1 = {
+        grid: {
+          top: '60px',
+          left: '10px',
+          right: props.fan1ChartsColumns.length * 15 + 'px',
+          bottom: '35px',
+          containLabel: true,
+        },
+        toolbox: {
+          feature: {},
+        },
+        legend: {
+          top: 40,
+        },
+        xAxis: {
+          interval: 0,
+        },
+      };
+      const echartsOption2 = {
+        grid: {
+          top: '70px',
+          left: '10px',
+          right: props.fan1ChartsColumns.length * 15 + 'px',
+          bottom: '5px',
+          containLabel: true,
+        },
+        toolbox: {
+          feature: {},
+        },
+      };
+
+      const onChange = (pageNumber: number) => {
+        console.log('Page: ', pageNumber);
+      };
+
+      watch(
+        [chartsType, deviceId, historyParams, pageSize, currentPage],
+        async (
+          [newChartsType, newDeviceId, newHistoryParams, newPageSize, newCurrentPage],
+          [oldChartsType, oldDeviceId, oldHistoryParams, oldPageSize, oldCurrentPage]
+        ) => {
+          console.log('[ historyParams ] >', historyParams.ttime, dayjs(historyParams.ttime).format('HH:mm:ss'));
+          if (newChartsType === 'listMonitor') {
+            // 实时监测所有
+            resultDataSource.value = props.dataSource;
+          } else if (newChartsType === 'history') {
+            resultDataSource.value = [];
+            // 历史
+            if (newChartsType !== oldChartsType || newDeviceId !== oldDeviceId) {
+              currentPage.value = 1;
+            }
+            const device = options.value.find((device) => device['deviceID'] === newDeviceId);
+            if (device) {
+              let res;
+              if (globalConfig.History_Type == 'vent') {
+                resultXAxisPropType.value = 'ttime';
+
+                const datas = await historyList({
+                  ttime_begin: newHistoryParams.ttime_begin,
+                  ttime_end: newHistoryParams.ttime_end,
+                  strtype: device.deviceType,
+                  gdeviceid: newDeviceId,
+                  skip: historyParams.skip,
+                  pageSize: pageSize.value,
+                  pageNo: currentPage.value,
+                  column: 'createTime',
+                });
+                res = datas['datalist']['records'];
+                if (res && res.length > 0) {
+                  resultDataSource.value = res.map((item) => Object.assign(item, item.readData));
+                } else {
+                  resultDataSource.value = [];
+                }
+                total.value = datas['datalist'].total;
+              } else {
+                resultXAxisPropType.value = 'time';
+                res = await historyList({
+                  pageSize: pageSize.value,
+                  pageNum: currentPage.value,
+                  startTime: newHistoryParams.ttime_begin,
+                  endTime: newHistoryParams.ttime_end,
+                  deviceId: newDeviceId,
+                  strtype: device.deviceType,
+                  interval: historyParams.interval,
+                  column: 'createTime',
+                });
+                if (res && res.records && res.records.length > 0) {
+                  resultDataSource.value = res.records.map((item) => Object.assign(item, item.readData));
+                } else {
+                  resultDataSource.value = [];
+                }
+                total.value = res.total;
+              }
+            }
+          } else if (newChartsType === 'detail') {
+            // 设备详情
+            resultXAxisPropType.value = 'readTime';
+            if (newDeviceId !== oldDeviceId) {
+              detailDataSource.value = [];
+            }
+          }
+        }
+      );
+      watchEffect(() => {
+        if (chartsType.value === 'detail') {
+          const currentData = props.dataSource.find((item: any) => item.deviceID === deviceId.value);
+          if (currentData) {
+            const isHas = detailDataSource.value.find((item) => item[resultXAxisPropType.value] === currentData[resultXAxisPropType.value]);
+            if (!isHas) {
+              if (detailDataSource.value.length < 15) {
+                detailDataSource.value.push(currentData);
+              } else {
+                detailDataSource.value.shift();
+                detailDataSource.value.push(currentData);
+              }
+            }
+          }
+        }
+      });
+
+      onMounted(async () => {
+        const res = await props.deviceListApi();
+        // debugger;
+        if (res['msgTxt'] && res['msgTxt'][0] && res['msgTxt'][0]['datalist']) {
+          options.value = res['msgTxt'][0]['datalist'];
+          deviceId.value = options.value[0]['deviceID'];
+        }
+      });
+
+      return {
+        chartsType,
+        deviceId,
+        resultDataSource,
+        historyParams,
+        options,
+        resultXAxisPropType,
+        detailDataSource,
+        currentPage,
+        pageSize,
+        total,
+        echartsOption,
+        echartsOption1,
+        echartsOption2,
+        onChange,
+        globalConfig,
+      };
+    },
+  });
+</script>
+<style lang="less">
+  :deep(.vent-select-dropdown) {
+    color: #000 !important;
+    .vent-select-item {
+      color: #000 !important;
+    }
+  }
+</style>
+<style lang="less" scoped>
+  @import '/@/design/vent/color.less';
+  .charts-container {
+    position: relative;
+    height: 100%;
+    .charts-box {
+      width: 100%;
+      height: 100%;
+      position: absolute;
+      bottom: 0;
+      top: 0px;
+      .echarts-group {
+        height: 100%;
+        display: flex;
+        :deep(div) {
+          border-right: 1px solid #ffffff22 !important;
+        }
+      }
+    }
+
+    .@{ventSpace}-picker,
+    .@{ventSpace}-select-selector {
+      background: #00000017 !important;
+      border: 1px solid @vent-form-item-boder !important;
+      input,
+      .@{ventSpace}-select-selection-item,
+      .@{ventSpace}-picker-suffix {
+        color: #fff !important;
+      }
+      .@{ventSpace}-select-selection-placeholder {
+        color: #b7b7b7 !important;
+      }
+    }
+    .@{ventSpace}-select-arrow,
+    .@{ventSpace}-picker-separator {
+      color: #fff !important;
+    }
+  }
+  :deep(.@{ventSpace}-select-dropdown) {
+    color: #000 !important;
+    .@{ventSpace}-select-item {
+      color: #000 !important;
+    }
+  }
+</style>

+ 1 - 0
src/views/vent/monitorManager/deviceMonitor/components/device/device.data.ts

@@ -50,6 +50,7 @@ export function getMonitorComponent() {
   // sysOrgCode = 'sdmtjtbdmk';
   let FiberModal;
   switch (sysOrgCode) {
+    case 'sdmtjtcctmk': // 寸草塔
     case 'sdmtjthlgmk': //哈拉沟
       FiberModal = defineAsyncComponent(() => import('./modal/fiber.modal.hlg.vue'));
       break;