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

[Feat 0000] 新增通风小调度功能

hongrunxia 3 недель назад
Родитель
Сommit
8fba35c072

+ 270 - 271
src/views/vent/monitorManager/safetyMonitor/AlarmHistoryTable.vue

@@ -9,317 +9,316 @@
 </template>
 
 <script lang="ts" name="system-user" setup>
-//ts语法
-import { watch, ref, defineExpose, inject, onMounted } from 'vue';
-import { BasicTable } from '/@/components/Table';
-import { useListPage } from '/@/hooks/system/useListPage';
-import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
-import { defHttp } from '/@/utils/http/axios';
-import dayjs from 'dayjs';
-import { getAutoScrollContainer } from '/@/utils/common/compUtils';
-import { safetyDeviceList, safetyList } from './safety.api';
+  //ts语法
+  import { watch, ref, defineExpose, inject, onMounted } from 'vue';
+  import { BasicTable } from '/@/components/Table';
+  import { useListPage } from '/@/hooks/system/useListPage';
+  import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
+  import { defHttp } from '/@/utils/http/axios';
+  import dayjs from 'dayjs';
+  import { getAutoScrollContainer } from '/@/utils/common/compUtils';
+  import { safetyDeviceList, safetyList } from './safety.api';
 
-const props = defineProps({
-  columnsType: {
-    type: String,
-    required: true,
-  },
-  columns: {
-    type: Array,
-    // required: true,
-    default: () => [],
-  },
-  deviceType: {
-    type: String,
-    required: true,
-  },
-  deviceListApi: {
-    type: Function,
-  },
-  designScope: {
-    type: String,
-  },
-  sysId: {
-    type: String,
-  },
-  scroll: {
-    type: Object,
-    default: { y: 0 },
-  },
-  list: {
-    type: Function,
-    default: (params) => defHttp.get({ url: '/safety/ventanalyAlarmLog/list', params }),
-  },
-});
-
-const getDeviceListApi = (params) => defHttp.post({ url: '/monitor/device', params });
-const globalConfig = inject('globalConfig');
-const alarmHistory = ref();
-const columns = ref([]);
-const deviceOptions = ref([]);
-const dataTypeName = ref('');
+  const props = defineProps({
+    columnsType: {
+      type: String,
+      required: true,
+    },
+    columns: {
+      type: Array,
+      // required: true,
+      default: () => [],
+    },
+    deviceType: {
+      type: String,
+      required: true,
+    },
+    deviceListApi: {
+      type: Function,
+    },
+    designScope: {
+      type: String,
+    },
+    sysId: {
+      type: String,
+    },
+    scroll: {
+      type: Object,
+      default: { y: 0 },
+    },
+    list: {
+      type: Function,
+      default: (params) => defHttp.get({ url: '/safety/ventanalyAlarmLog/list', params }),
+    },
+  });
 
-const tableScroll = props.scroll.y ? ref({ y: props.scroll.y - 100 }) : ref({});
+  const getDeviceListApi = (params) => defHttp.post({ url: '/monitor/device', params });
+  const globalConfig = inject('globalConfig');
+  const alarmHistory = ref();
+  const columns = ref([]);
+  const deviceOptions = ref([]);
+  const dataTypeName = ref('');
 
-async function getDeviceList() {
-  let result;
-  const res = await getDeviceListApi({ devicetype: props.deviceType, filterParams: { dataTypeName: dataTypeName.value }, pageSize: 10000 });
-  if (res['records'] && res['records'].length > 0) {
-    result = res['records'];
-  } else if (res['msgTxt'] && res['msgTxt'][0] && res['msgTxt'][0]['datalist']) {
-    result = res['msgTxt'][0]['datalist'];
-  }
-  if (result && result.length > 0) {
-    deviceOptions.value = [];
-    deviceOptions.value = result.map((item, index) => {
-      return {
-        label: item['strinstallpos'],
-        value: item['id'] || item['deviceID'],
-        strtype: item['strtype'] || item['deviceType'],
-        strinstallpos: item['strinstallpos'],
-        devicekind: item['devicekind'],
-        stationtype: item['stationtype'],
-      };
-    });
-  } else {
-    deviceOptions.value = [];
-  }
-  await getForm().setFieldsValue({ deviceId: deviceOptions.value[0] ? deviceOptions.value[0]['value'] : '' });
-}
+  const tableScroll = props.scroll.y ? ref({ y: props.scroll.y - 100 }) : ref({});
 
-watch(
-  () => {
-    return props.columnsType;
-  },
-  async (newVal) => {
-    if (!newVal) return;
-    let column;
-    column = getTableHeaderColumns('safetymonitor_warning');
-    if (!column || column.length < 1) {
-      column = getTableHeaderColumns(newVal + '_history');
+  async function getDeviceList() {
+    let result;
+    const res = await getDeviceListApi({ devicetype: props.deviceType, filterParams: { dataTypeName: dataTypeName.value }, pageSize: 10000 });
+    if (res['records'] && res['records'].length > 0) {
+      result = res['records'];
+    } else if (res['msgTxt'] && res['msgTxt'][0] && res['msgTxt'][0]['datalist']) {
+      result = res['msgTxt'][0]['datalist'];
     }
-    if (column && column.length < 1) {
-      const arr = newVal.split('_');
-      const columnKey = arr.reduce((prev, cur, index) => {
-        if (index !== arr.length - 2) {
-          return prev + '_' + cur;
-        } else {
-          return prev;
-        }
+    if (result && result.length > 0) {
+      deviceOptions.value = [];
+      deviceOptions.value = result.map((item, index) => {
+        return {
+          label: item['strinstallpos'],
+          value: item['id'] || item['deviceID'],
+          strtype: item['strtype'] || item['deviceType'],
+          strinstallpos: item['strinstallpos'],
+          devicekind: item['devicekind'],
+          stationtype: item['stationtype'],
+        };
       });
-      columns.value = getTableHeaderColumns(arr[0] + '_history');
     } else {
-      columns.value = column;
+      deviceOptions.value = [];
     }
-    if (alarmHistory.value) reload();
-  },
-  {
-    immediate: true,
+    await getForm().setFieldsValue({ deviceId: deviceOptions.value[0] ? deviceOptions.value[0]['value'] : '' });
   }
-);
 
-watch(
-  () => props.deviceType,
-  async () => {
-    if (alarmHistory.value) getForm().resetFields();
-    await getDeviceList();
-  }
-);
+  watch(
+    () => {
+      return props.columnsType;
+    },
+    async (newVal) => {
+      if (!newVal) return;
+      let column;
+      column = getTableHeaderColumns('safetymonitor_warning');
+      if (!column || column.length < 1) {
+        column = getTableHeaderColumns(newVal + '_history');
+      }
+      if (column && column.length < 1) {
+        const arr = newVal.split('_');
+        const columnKey = arr.reduce((prev, cur, index) => {
+          if (index !== arr.length - 2) {
+            return prev + '_' + cur;
+          } else {
+            return prev;
+          }
+        });
+        columns.value = getTableHeaderColumns(arr[0] + '_history');
+      } else {
+        columns.value = column;
+      }
+      if (alarmHistory.value) reload();
+    },
+    {
+      immediate: true,
+    }
+  );
 
-watch(
-  () => props.scroll.y,
-  (newVal) => {
-    if (newVal) {
-      tableScroll.value = { y: newVal - 100 };
-    } else {
-      tableScroll.value = {};
+  watch(
+    () => props.deviceType,
+    async () => {
+      if (alarmHistory.value) getForm().resetFields();
+      await getDeviceList();
     }
-  }
-);
+  );
 
-// 列表页面公共参数、方法
-const { tableContext, onExportXls } = useListPage({
-  tableProps: {
-    api: safetyList,
-    columns: props.columnsType ? columns : (props.columns as any[]),
-    canResize: false,
-    showTableSetting: false,
-    showActionColumn: false,
-    bordered: false,
-    showIndexColumn: true,
-    size: 'small',
-    scroll: tableScroll,
-    formConfig: {
-      labelAlign: 'left',
-      showAdvancedButton: false,
-      // autoAdvancedCol: 2,
-      actionColOptions: {
+  watch(
+    () => props.scroll.y,
+    (newVal) => {
+      if (newVal) {
+        tableScroll.value = { y: newVal - 100 };
+      } else {
+        tableScroll.value = {};
+      }
+    }
+  );
 
-        xs: 4, // <576px
-        sm: 14, // ≥576px
-        md: 4, // ≥768px
-        lg: 4, // ≥992px
-        xl: 4, // ≥1200px
-        xxl: 4, // ≥1600px
+  // 列表页面公共参数、方法
+  const { tableContext, onExportXls } = useListPage({
+    tableProps: {
+      api: safetyList,
+      columns: props.columnsType ? columns : (props.columns as any[]),
+      canResize: false,
+      showTableSetting: false,
+      showActionColumn: false,
+      bordered: false,
+      showIndexColumn: true,
+      size: 'small',
+      scroll: tableScroll,
+      formConfig: {
+        labelAlign: 'left',
+        showAdvancedButton: false,
+        // autoAdvancedCol: 2,
+        actionColOptions: {
+          xs: 4, // <576px
+          sm: 14, // ≥576px
+          md: 4, // ≥768px
+          lg: 4, // ≥992px
+          xl: 4, // ≥1200px
+          xxl: 4, // ≥1600px
 
-        style: { textAlign: 'left' },
-      },
-      schemas: [
-        {
-          field: 'startTime',
-          label: '开始时间',
-          component: 'DatePicker',
-          defaultValue: dayjs().add(-30, 'day').format('YYYY-MM-DD HH:mm:ss'),
-          required: true,
-          componentProps: {
-            showTime: true,
-            valueFormat: 'YYYY-MM-DD HH:mm:ss',
-            getPopupContainer: getAutoScrollContainer,
-          },
-          colProps: {
-            span: 4,
-          },
+          style: { textAlign: 'left' },
         },
-        {
-          field: 'endTime',
-          label: '结束时间',
-          component: 'DatePicker',
-          defaultValue: dayjs(),
-          required: true,
-          componentProps: {
-            showTime: true,
-            valueFormat: 'YYYY-MM-DD HH:mm:ss',
-            getPopupContainer: getAutoScrollContainer,
-          },
-          colProps: {
-            span: 4,
-          },
-        },
-        {
-          label: '设备类型',
-          field: 'dataTypeName',
-          component: 'ApiSelect',
-          componentProps: {
-            api: safetyDeviceList.bind(null, { devicetype: 'safetymonitor', code: 'dataTypeName' }),
-            labelField: 'name',
-            valueField: 'code',
-            onChange: async (e, option) => {
-              console.log('1111', e, option);
-              dataTypeName.value = e;
-              await getDeviceList();
+        schemas: [
+          {
+            field: 'startTime',
+            label: '开始时间',
+            component: 'DatePicker',
+            defaultValue: dayjs().add(-30, 'day').format('YYYY-MM-DD HH:mm:ss'),
+            required: true,
+            componentProps: {
+              showTime: true,
+              valueFormat: 'YYYY-MM-DD HH:mm:ss',
+              getPopupContainer: getAutoScrollContainer,
             },
-          },
-          colProps: {
-            span: 4,
-          },
-        },
-        {
-          label: '查询设备',
-          field: 'deviceId',
-          component: 'Select',
-          defaultValue: deviceOptions.value[0] ? deviceOptions.value[0]['value'] : '',
-          componentProps: {
-            showSearch: true,
-            filterOption: (input: string, option: any) => {
-              return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
+            colProps: {
+              span: 4,
             },
-            options: deviceOptions,
           },
-          colProps: {
-            span: 4,
+          {
+            field: 'endTime',
+            label: '结束时间',
+            component: 'DatePicker',
+            defaultValue: dayjs(),
+            required: true,
+            componentProps: {
+              showTime: true,
+              valueFormat: 'YYYY-MM-DD HH:mm:ss',
+              getPopupContainer: getAutoScrollContainer,
+            },
+            colProps: {
+              span: 4,
+            },
           },
-        },
-        {
-          label: '是否解决',
-          field: 'isok',
-          component: 'Select',
-          componentProps: {
-            options: [
-              {
-                label: '未解决',
-                value: '0',
+          {
+            label: '设备类型',
+            field: 'dataTypeName',
+            component: 'ApiSelect',
+            componentProps: {
+              api: safetyDeviceList.bind(null, { devicetype: 'safetymonitor', code: 'dataTypeName' }),
+              labelField: 'name',
+              valueField: 'code',
+              onChange: async (e, option) => {
+                console.log('1111', e, option);
+                dataTypeName.value = e;
+                await getDeviceList();
               },
-              {
-                label: '已解决',
-                value: '1',
+            },
+            colProps: {
+              span: 4,
+            },
+          },
+          {
+            label: '查询设备',
+            field: 'deviceId',
+            component: 'Select',
+            defaultValue: deviceOptions.value[0] ? deviceOptions.value[0]['value'] : '',
+            componentProps: {
+              showSearch: true,
+              filterOption: (input: string, option: any) => {
+                return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
               },
-            ],
+              options: deviceOptions,
+            },
+            colProps: {
+              span: 4,
+            },
           },
-          colProps: { span: 4 },
-        },
-      ],
-    },
-    fetchSetting: {
-      listField: 'records',
+          {
+            label: '是否解决',
+            field: 'isok',
+            component: 'Select',
+            componentProps: {
+              options: [
+                {
+                  label: '未解决',
+                  value: '0',
+                },
+                {
+                  label: '已解决',
+                  value: '1',
+                },
+              ],
+            },
+            colProps: { span: 4 },
+          },
+        ],
+      },
+      fetchSetting: {
+        listField: 'records',
+      },
+      pagination: {
+        current: 1,
+        pageSize: 10,
+        pageSizeOptions: ['10', '30', '50', '100'],
+      },
+      // beforeFetch(params) {
+      //   params.devicetype = props.deviceType + '*';
+      //   if (props.sysId) {
+      //     params.sysId = props.sysId;
+      //   }
+      // },
     },
-    pagination: {
-      current: 1,
-      pageSize: 10,
-      pageSizeOptions: ['10', '30', '50', '100'],
+    exportConfig: {
+      name: '预警历史列表',
+      url: '/safety/ventanalyAlarmLog/exportXls',
     },
-    // beforeFetch(params) {
-    //   params.devicetype = props.deviceType + '*';
-    //   if (props.sysId) {
-    //     params.sysId = props.sysId;
-    //   }
-    // },
-  },
-  exportConfig: {
-    name: '预警历史列表',
-    url: '/safety/ventanalyAlarmLog/exportXls',
-  },
-});
-//注册table数据
-const [registerTable, { reload, setLoading, getForm }] = tableContext;
+  });
+  //注册table数据
+  const [registerTable, { reload, setLoading, getForm }] = tableContext;
 
-onMounted(async () => {
-  await getDeviceList();
-});
+  onMounted(async () => {
+    await getDeviceList();
+  });
 
-defineExpose({ setLoading });
+  defineExpose({ setLoading });
 </script>
 
 <style scoped lang="less">
-@ventSpace: zxm;
+  @ventSpace: zxm;
 
-:deep(.ventSpace-table-body) {
-  height: auto !important;
-}
+  :deep(.ventSpace-table-body) {
+    height: auto !important;
+  }
 
-:deep(.zxm-picker) {
-  height: 30px !important;
-}
+  :deep(.zxm-picker) {
+    height: 30px !important;
+  }
 
-.alarm-history-table {
-  width: 100%;
+  .alarm-history-table {
+    width: 100%;
 
-  :deep(.jeecg-basic-table-form-container) {
-    .@{ventSpace}-form {
-      padding: 0 !important;
-      border: none !important;
-      margin-bottom: 0 !important;
+    :deep(.jeecg-basic-table-form-container) {
+      .@{ventSpace}-form {
+        padding: 0 !important;
+        border: none !important;
+        margin-bottom: 0 !important;
 
-      .@{ventSpace}-picker,
-      .@{ventSpace}-select-selector {
-        width: 100% !important;
-        background: #00000017;
-        border: 1px solid #b7b7b7;
+        .@{ventSpace}-picker,
+        .@{ventSpace}-select-selector {
+          width: 100% !important;
+          background: #00000017;
+          border: 1px solid #b7b7b7;
 
-        input,
-        .@{ventSpace}-select-selection-item,
-        .@{ventSpace}-picker-suffix {
-          color: #fff;
-        }
+          input,
+          .@{ventSpace}-select-selection-item,
+          .@{ventSpace}-picker-suffix {
+            color: #fff;
+          }
 
-        .@{ventSpace}-select-selection-placeholder {
-          color: #ffffffaa;
+          .@{ventSpace}-select-selection-placeholder {
+            color: #ffffffaa;
+          }
         }
       }
-    }
 
-    .@{ventSpace}-table-title {
-      min-height: 0 !important;
+      .@{ventSpace}-table-title {
+        min-height: 0 !important;
+      }
     }
   }
-}
 </style>

+ 263 - 0
src/views/vent/monitorManager/safetySensorMonitor/AlarmHistoryTable.vue

@@ -0,0 +1,263 @@
+<template>
+  <div class="alarm-history-table">
+    <BasicTable ref="alarmHistory" @register="registerTable">
+      <template #form-onExportXls>
+        <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls()"> 导出</a-button>
+      </template>
+
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.dict">
+          <!-- 除了 101(蓝色预警)其他都是红色字体 -->
+          <span v-if="column.dataIndex === 'nwartype'" :class="{ 'color-#ff3823': ['102', '103', '104', '201', '1001'].includes(record.nwartype) }">
+            {{ render.renderDictText(record.nwartype, 'leveltype') || '-' }}
+          </span>
+          <span v-else>
+            {{ render.renderDictText(record[column.dataIndex], column.dict) || '-' }}
+          </span>
+        </template>
+      </template>
+      <template #action="{ record }">
+        <a @click="openHistoryCurve(record)">预警分析</a>
+      </template>
+    </BasicTable>
+  </div>
+</template>
+
+<script lang="ts" name="SafetyAlarm" setup>
+  //ts语法
+  import { watch, ref, defineExpose, inject, onMounted } from 'vue';
+  import { BasicTable } from '/@/components/Table';
+  import { useListPage } from '/@/hooks/system/useListPage';
+  import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
+  import { defHttp } from '/@/utils/http/axios';
+  import dayjs from 'dayjs';
+  import { getAutoScrollContainer } from '/@/utils/common/compUtils';
+  import { render } from '/@/utils/common/renderUtils';
+  import { useModal } from '/@/components/Modal';
+  import { message } from 'ant-design-vue';
+
+  const props = defineProps({
+    columnsType: {
+      type: String,
+      required: true,
+    },
+    columns: {
+      type: Array,
+      // required: true,
+      default: () => [],
+    },
+    deviceType: {
+      type: String,
+      required: true,
+    },
+    deviceListApi: {
+      type: Function,
+    },
+    designScope: {
+      type: String,
+    },
+    sysId: {
+      type: String,
+    },
+    deviceId: {
+      type: String,
+      default: '',
+    },
+    scroll: {
+      type: Object,
+      default: { y: 0 },
+    },
+    deviceTypeOption: {
+      type: Array,
+      default: () => [],
+    },
+    list: {
+      type: Function,
+      default: (params) => defHttp.post({ url: '/monitor/history/getAlarmHistoryData', params }),
+    },
+  });
+  const alarmHistory = ref();
+  const columns = ref([]);
+  const deviceOptions = ref<any>([]);
+
+  const tableScroll = props.scroll.y ? ref({ y: props.scroll.y - 100 }) : ref({});
+
+  watch(
+    () => {
+      return props.columnsType;
+    },
+    async (newVal) => {
+      if (!newVal) return;
+
+      const column = getTableHeaderColumns(newVal + '_history');
+      if (column && column.length < 1) {
+        const arr = newVal.split('_');
+        const columnKey = arr.reduce((prev, cur, index) => {
+          if (index !== arr.length - 2) {
+            return prev + '_' + cur;
+          } else {
+            return prev;
+          }
+        });
+        columns.value = getTableHeaderColumns(arr[0] + '_history');
+      } else {
+        columns.value = column;
+      }
+      if (alarmHistory.value) reload();
+    },
+    {
+      immediate: true,
+    }
+  );
+
+  watch(
+    () => props.scroll.y,
+    (newVal) => {
+      if (newVal) {
+        tableScroll.value = { y: newVal - 100 };
+      } else {
+        tableScroll.value = {};
+      }
+    }
+  );
+
+  // 列表页面公共参数、方法
+  const { tableContext, onExportXls } = useListPage({
+    tableProps: {
+      api: props.list,
+      columns: props.columnsType ? columns : (props.columns as any[]),
+      canResize: true,
+      showTableSetting: false,
+      showActionColumn: true,
+      bordered: false,
+      size: 'small',
+      scroll: tableScroll,
+      showIndexColumn: true,
+      formConfig: {
+        labelAlign: 'left',
+        showAdvancedButton: false,
+        // autoAdvancedCol: 2,
+        schemas: [
+          {
+            field: 'time',
+            label: '查询时间',
+            component: 'DatePicker',
+            defaultValue: dayjs().format('YYYY-MM-DD'),
+            required: true,
+            componentProps: {
+              showTime: true,
+              valueFormat: 'YYYY-MM-DD',
+              getPopupContainer: getAutoScrollContainer,
+            },
+            colProps: {
+              span: 4,
+            },
+          },
+          {
+            label: '设备类型',
+            field: 'deviceid',
+            component: 'Select',
+            defaultValue: props.deviceTypeOption && props.deviceTypeOption.length > 0 ? props.deviceTypeOption[0]['value'] : '',
+            componentProps: {
+              options: props.deviceTypeOption,
+            },
+            colProps: {
+              span: 4,
+            },
+          },
+          // {
+          //   label: '查询设备',
+          //   field: 'deviceid',
+          //   component: 'Select',
+          //   defaultValue: '',
+          //   componentProps: {
+          //     showSearch: true,
+          //     filterOption: (input: string, option: any) => {
+          //       return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
+          //     },
+          //     options: props.deviceTypeOption,
+          //   },
+          //   colProps: {
+          //     span: 4,
+          //   },
+          // },
+        ],
+        // fieldMapToTime: [['createTime', ['createTime_begin', 'createTime_end'], '']],
+      },
+      fetchSetting: {
+        listField: 'records',
+      },
+      pagination: {
+        current: 1,
+        pageSize: 10,
+        pageSizeOptions: ['10', '30', '50', '100'],
+      },
+      beforeFetch(params) {
+        params.devicetype = props.deviceType + '*';
+        if (props.sysId) {
+          params.sysId = props.sysId;
+        }
+      },
+    },
+    exportConfig: {
+      name: '预警历史列表',
+      url: '/safety/ventanalyAlarmLog/exportXls',
+    },
+  });
+  //注册table数据
+  const [registerTable, { reload, setLoading }] = tableContext;
+
+  const [{ openModal }] = useModal();
+
+  function openHistoryCurve(record) {
+    if (['net'].includes(record.valuecode)) return message.info('该报警字段不支持历史曲线展示');
+    openModal(true, {
+      data: record,
+      device: deviceOptions.value[0],
+    });
+  }
+
+  onMounted(async () => {});
+
+  defineExpose({ setLoading });
+</script>
+
+<style scoped lang="less">
+  @ventSpace: zxm;
+
+  :deep(.ventSpace-table-body) {
+    height: auto !important;
+  }
+  :deep(.zxm-picker) {
+    height: 30px !important;
+  }
+  .alarm-history-table {
+    width: 100%;
+    padding-top: 10px;
+    height: 770px;
+    :deep(.jeecg-basic-table-form-container) {
+      .@{ventSpace}-form {
+        padding: 0 !important;
+        border: none !important;
+        margin-bottom: 0 !important;
+        .@{ventSpace}-picker,
+        .@{ventSpace}-select-selector {
+          width: 100% !important;
+          background: #00000017;
+          border: 1px solid #b7b7b7;
+          input,
+          .@{ventSpace}-select-selection-item,
+          .@{ventSpace}-picker-suffix {
+            color: #fff;
+          }
+          .@{ventSpace}-select-selection-placeholder {
+            color: #ffffffaa;
+          }
+        }
+      }
+      .@{ventSpace}-table-title {
+        min-height: 0 !important;
+      }
+    }
+  }
+</style>

+ 422 - 0
src/views/vent/monitorManager/safetySensorMonitor/index.vue

@@ -0,0 +1,422 @@
+<template>
+  <div class="sensor-container">
+    <a-spin :spinning="loading">
+      <a-tabs class="tabs-box" type="card" v-model:activeKey="activeKey" @change="tabChange">
+        <a-tab-pane key="1" tab="实时监测">
+          <div class="box-bg table-box" style="margin-bottom: 10px">
+            <div>
+              <label style="color: var(--vent-font-color)">设备类型:</label>
+              <Select
+                @change="handleSensorChange"
+                :options="deviceTypeOption"
+                :fieldNames="{ label: 'label', value: 'value' }"
+                v-model:value="deviceKind"
+                style="width: 200px; margin-bottom: 5px; color: black"
+                placeholder="请选择设备类型"
+                :allowClear="true"
+              />
+              <!--hnjmypmk 崖坪 特有 -->
+              <template v-if="deviceKind === 'modelsensor_multi' && sysOrgCode === 'hnjmypmk'">
+                <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXlsFn"> 导出</a-button>
+              </template>
+              <MonitorTable
+                ref="SensorMonitorRef"
+                :is-show-select="true"
+                :columnsType="deviceKind + '_monitor'"
+                :dataSource="dataSource"
+                design-scope="modelsensor_monitor"
+                @select-row="getSelectRow"
+                :deviceType="deviceKind"
+                :scroll="{ y: chartsColumns.length > 0 ? 600 : 600 }"
+                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>
+        </a-tab-pane>
+        <!-- <a-tab-pane key="2" tab="历史数据">
+          <div class="tab-item table-box box-bg padding-0" v-if="activeKey == '2'">
+            <HistoryTable
+              :columns-type="deviceKind"
+              :device-type="deviceKind"
+              :device-list-api="list.bind(null, { devicetype: selectData.deviceType })"
+              @change="historyDataSourceChange"
+              designScope="modelsensor-history"
+              :scroll="{ y: chartsColumns.length > 0 ? 400 : 600 }"
+            />
+            <div class="charts-box" v-if="chartsColumns.length > 0">
+              <BarAndLine
+                :chartsColumnsType="selectData.deviceType"
+                xAxisPropType="ttime"
+                :dataSource="historyDataSource"
+                height="300px"
+                :chartsColumns="chartsColumns"
+                chartsType="history"
+                :option="echartsOption1"
+                @refresh="refreshEchatrs"
+              />
+            </div>
+          </div>
+        </a-tab-pane> -->
+        <a-tab-pane key="3" tab="报警历史">
+          <div class="tab-item box-bg" v-if="activeKey == '3'">
+            <SafetyAlarm columns-type="alarm" device-type="modelsensor" designScope="alarm-history" :device-type-option="deviceTypeOption" />
+          </div>
+        </a-tab-pane>
+        <!-- <a-tab-pane key="4" tab="报警分析">
+          <div class="tab-item box-bg" v-if="activeKey == '4'">
+            <warnAnalysis device-type="modelsensor" />
+          </div>
+        </a-tab-pane> -->
+        <!-- <a-tab-pane key="4" tab="操作历史">
+          <div class="tab-item box-bg">
+            <HandlerHistoryTable columns-type="operator_history" device-type="modelsensor" designScope="alarm-history" />
+          </div>
+        </a-tab-pane> -->
+      </a-tabs>
+    </a-spin>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import BarAndLine from '/@/components/chart/BarAndLine.vue';
+  import { Select } from 'ant-design-vue';
+  import { onBeforeMount, ref, onMounted, onUnmounted, toRaw, reactive, nextTick, unref } from 'vue';
+  import MonitorTable from '../comment/MonitorTable.vue';
+  // import HistoryTable from '../comment/HistoryTable.vue';
+  import SafetyAlarm from './AlarmHistoryTable.vue';
+  // import warnAnalysis from '../comment/warnAnalysis.vue';
+  import { list, getTableList } from './sensor.api';
+  // import { deviceList } from '../../deviceManager/comment/pointTabel/point.api';
+  import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
+  import { cloneDeep } from 'lodash-es';
+  import { useMethods } from '/@/hooks/system/useMethods';
+  import { useGlobSetting } from '/@/hooks/setting';
+  import { useRouter } from 'vue-router';
+  import { getDictItemsByCode } from '/@/utils/dict';
+
+  const router = useRouter();
+  const { sysOrgCode } = useGlobSetting();
+  const { exportXlsPostBlob } = useMethods();
+  const SensorMonitorRef = ref();
+  const deviceBaseList = ref([]);
+  const activeKey = ref('1');
+  const deviceKind = ref('');
+  const deviceTypeOption = ref([]);
+  // 默认初始是第一行
+  const selectRowIndex = ref(0);
+  const dataSource = ref([]);
+  const detailDataSource = ref<any[]>([]);
+  const historyDataSource = ref<any[]>([]);
+  const chartsColumns = ref<any[]>([]);
+  const loading = ref(true);
+
+  const selectData = reactive({
+    strname: '',
+    deviceType: '',
+    deviceID: '',
+  });
+
+  const tabChange = (activeKeyVal) => {
+    activeKey.value = activeKeyVal;
+    detailDataSource.value = [];
+    if (activeKeyVal == 1) {
+      nextTick(() => {
+        SensorMonitorRef.value.setSelectedRowKeys([selectData.deviceID]);
+      });
+    }
+  };
+
+  // https获取监测数据
+  let timer: null | NodeJS.Timeout = null;
+  const getMonitor = (flag?) => {
+    if (Object.prototype.toString.call(timer) === '[object Null]') {
+      timer = setTimeout(
+        async () => {
+          await getDataSource(deviceKind.value);
+          if (timer) {
+            timer = null;
+          }
+          getMonitor();
+        },
+        flag ? 0 : 1000
+      );
+    }
+  };
+
+  const getDataSource = async (devicetype) => {
+    const type = devicetype ? devicetype : 'modelsensor';
+    const res = await list({ devicetype: type, pagetype: 'normal' });
+    dataSource.value = res.msgTxt[0].datalist || [];
+    dataSource.value.map((data: any) => {
+      const readData = data.readData;
+      data = Object.assign(data, readData);
+      return data;
+    });
+    const data: any = toRaw(dataSource.value[selectRowIndex.value]); //maxarea
+    Object.assign(selectData, data);
+
+    // if (chartsColumns.value.length <= 0 && selectData.deviceType) {
+    //   handleChange(selectData.deviceType);
+    // }
+
+    // 如果当前为监测tab
+    if (activeKey.value === '1') {
+      // const isHas = detailDataSource.value.find((item) => item['readTime'] === selectData['readTime']);
+      // // 获取选中数据
+      // if (!isHas) {
+      //   if (detailDataSource.value.length < 15) {
+      //     detailDataSource.value.push({ ...selectData });
+      //   } else {
+      //     detailDataSource.value.shift();
+      //     detailDataSource.value.push({ ...selectData });
+      //   }
+      // }
+      const dataList = cloneDeep(detailDataSource.value);
+      if (dataList.length < 15) {
+        dataList.push({ ...selectData });
+      } else {
+        dataList.shift();
+        dataList.push({ ...selectData });
+      }
+      detailDataSource.value = dataList;
+    }
+
+    if (loading.value) {
+      loading.value = false;
+    }
+    return data;
+  };
+
+  const getSelectRow = (selectRow, index) => {
+    if (!selectRow) return;
+    selectRowIndex.value = index;
+    const baseData: any = deviceBaseList.value.find((baseData: any) => baseData.id === selectRow.deviceID);
+    Object.assign(selectData, selectRow, baseData);
+    if (selectData.deviceType) {
+      // if (timer) {
+      //   clearTimeout(timer);
+      //   timer = undefined;
+      // }
+      if (activeKey.value === '1') detailDataSource.value = [];
+      if (activeKey.value === '2') historyDataSource.value = [];
+      handleChange(selectData.deviceType);
+    }
+  };
+
+  // 获取设备基本信息列表
+  const getDeviceBaseList = () => {
+    getTableList({ pageSize: 1000 }).then((res) => {
+      deviceBaseList.value = res.records;
+    });
+  };
+
+  function handleChange(type) {
+    chartsColumns.value = getTableHeaderColumns(type + '_chart');
+    console.log('[ type ] >', type, chartsColumns.value);
+  }
+
+  function handleSensorChange(type) {
+    loading.value = true;
+    handleChange(type);
+    timer = null;
+    dataSource.value = [];
+    detailDataSource.value = [];
+  }
+
+  function refreshEchatrs() {
+    timer = null;
+    // getMonitor(true);
+    console.log('echarts 刷新');
+  }
+
+  function onExportXlsFn() {
+    // 判断时间间隔和查询时间区间,数据量下载大时进行提示
+    const url = '/ventanaly-device/safety/reportInfo/expComReportByParam';
+    return exportXlsPostBlob('多参数报表', url, {
+      deviceKind: deviceKind.value.split('_')[0],
+      deviceType: deviceKind.value,
+      tempName: 'dcsbb',
+    });
+  }
+
+  onBeforeMount(() => {
+    getDeviceBaseList();
+  });
+
+  onMounted(async () => {
+    let dictName = 'modelsensorkind';
+    // const route = unref(router.currentRoute);
+    // if (route.name) {
+    //   const nameStrList = route.name.split('-');
+    //   if (nameStrList.length > 0 && nameStrList[nameStrList.length - 1] !== 'sensorMonitor') {
+    //     dictName = nameStrList[nameStrList.length - 1];
+    //   }
+    // }
+    const res = getDictItemsByCode(dictName);
+    deviceTypeOption.value = res;
+    deviceKind.value = deviceTypeOption.value[0]['value'];
+    handleChange(deviceKind.value);
+    await getMonitor(true);
+  });
+  onUnmounted(() => {
+    if (timer) {
+      clearTimeout(timer);
+      timer = undefined;
+    }
+  });
+</script>
+<style lang="less" scoped>
+  @import '/@/design/theme.less';
+  @import '/@/design/vent/modal.less';
+  .padding-0 {
+    padding: 10px 0 !important;
+  }
+  .sensor-container {
+    height: 100%;
+    position: relative;
+    // top: 65px;
+    padding: 10px;
+    z-index: 999;
+    // max-height: calc(100vh - 150px);
+    .@{ventSpace}-tabs {
+      max-height: calc(100% - 100px);
+      .tab-item {
+        max-height: calc(100% - 170px);
+        overflow-y: auto;
+      }
+    }
+    .title-text {
+      position: absolute;
+      top: -24px;
+      left: 0;
+      width: 100%;
+      text-align: center;
+      color: var(--vent-font-color);
+    }
+    .table-box {
+      // height: calc(60% - 150px);
+      height: 780px;
+      padding: 20px 10px;
+      overflow-y: auto;
+    }
+
+    .box-bg {
+      // border: 1px solid #4d7ad855;
+      // border-radius: 2px;
+      // // background-color: #001d3055;
+      // -webkit-backdrop-filter: blur(8px);
+      // backdrop-filter: blur(8px);
+      // box-shadow: 0 0 10px #5984e055 inset;
+      // background-color: #00b3ff12;
+      padding-bottom: 10px;
+      border: 1px solid #44d3ff70;
+      border-radius: 2px;
+      -webkit-backdrop-filter: blur(8px);
+      box-shadow: 0 0 20px #44b4ff33 inset;
+      background-color: #ffffff11;
+      overflow-y: auto;
+    }
+    .table-box-content {
+      height: 430px;
+      background-color: #ffffff03;
+      border-bottom: 1px solid #44d3ff70;
+    }
+    .charts-box {
+      height: 300px;
+      padding: 5px 10px;
+      margin-top: 10px;
+    }
+  }
+  :deep(.@{ventSpace}-tabs-tabpane-active) {
+    height: 100%;
+  }
+  :deep(.@{ventSpace}-tabs-card) {
+    .@{ventSpace}-tabs-tab {
+      background: var(--vent-device-manager-control-btn-hover);
+      border-color: #74e9fe;
+      border-radius: 0%;
+      &:hover {
+        color: #64d5ff;
+      }
+    }
+    .@{ventSpace}-tabs-tab.@{ventSpace}-tabs-tab-active .@{ventSpace}-tabs-tab-btn {
+      color: aqua;
+    }
+    .@{ventSpace}-tabs-nav::before {
+      border-color: #74e9fe;
+    }
+    .@{ventSpace}-picker,
+    .@{ventSpace}-select-selector {
+      width: 100%;
+      background: #00000017 !important;
+      border: 1px solid @vent-form-item-border !important;
+      input,
+      .@{ventSpace}-select-selection-item,
+      .@{ventSpace}-picker-suffix {
+        color: #fff !important;
+      }
+      .@{ventSpace}-select-selection-placeholder {
+        color: #b7b7b7 !important;
+      }
+    }
+    .@{ventSpace}-pagination-next,
+    .action,
+    .@{ventSpace}-select-arrow,
+    .@{ventSpace}-picker-separator {
+      color: var(--vent-font-color) !important;
+    }
+    .@{ventSpace}-table-cell-row-hover {
+      background: #264d8833 !important;
+    }
+    .@{ventSpace}-table-row-selected {
+      background: #00c0a311 !important;
+      td {
+        background-color: #00000000 !important;
+      }
+    }
+    .@{ventSpace}-table-thead {
+      // background: linear-gradient(#004a8655 0%, #004a86aa 10%) !important;
+      background: #3d9dd45d !important;
+
+      & > tr > th,
+      .@{ventSpace}-table-column-title {
+        // color: #70f9fc !important;
+        border-color: var(--vent-base-border) !important;
+        border-left: none !important;
+        border-right: none !important;
+        padding: 7px;
+      }
+    }
+
+    .@{ventSpace}-table-tbody {
+      tr > td {
+        padding: 12px;
+      }
+    }
+    .@{ventSpace}-table-tbody > tr:hover.@{ventSpace}-table-row > td {
+      background-color: #26648855 !important;
+    }
+
+    .jeecg-basic-table-row__striped {
+      // background: #97efff11 !important;
+      td {
+        background-color: #97efff11 !important;
+      }
+    }
+    :deep(.vent-form) {
+      .@{ventSpace}-select-dropdown {
+        color: #000000 !important;
+      }
+    }
+  }
+</style>

+ 20 - 0
src/views/vent/monitorManager/safetySensorMonitor/sensor.api.ts

@@ -0,0 +1,20 @@
+import { defHttp } from '/@/utils/http/axios';
+
+enum Api {
+  list = '/monitor/device',
+  baseList = '/safety/ventanalyWindow/list',
+  safetyList = '/monitor/history/getAlarmHistoryData',
+}
+/**
+ * 列表接口
+ * @param params
+ */
+export const list = (params) => defHttp.post({ url: Api.list, params });
+
+/**
+ * 保存或者更新用户
+ * @param params
+ */
+export const getTableList = (params) => defHttp.get({ url: Api.baseList, params });
+
+export const safetyList = (params) => defHttp.post({ url: Api.safetyList, params });

+ 0 - 0
src/views/vent/monitorManager/safetySensorMonitor/sensor.data.ts