Browse Source

[Wip 0000] 公用历史数据组件开发

houzekong 9 months ago
parent
commit
93dcf4fc9e

+ 136 - 0
src/views/vent/comment/history/HistoryTable.vue

@@ -0,0 +1,136 @@
+<template>
+  <BasicTable ref="historyTable" @register="register" :data-source="data">
+    <template #bodyCell="{ 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' ? '#f00' : 'green'">
+        {{ record.netStatus == '0' ? '断开' : '连接' }}
+      </a-tag>
+    </template>
+    <template #form-submitBefore>
+      <a-button type="primary" preIcon="ant-design:search-outlined" @click="search">查询</a-button>
+    </template>
+  </BasicTable>
+</template>
+
+<script lang="ts" setup>
+  import { onMounted, ref, shallowRef } from 'vue';
+  import { BasicColumn, BasicTableProps, PaginationProps, FormProps, FormSchema, BasicTable } from '/@/components/Table';
+  import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
+  import { defaultFormProps, defaultPaginationProps, getDefaultSchemas, defaultTableProps } from './history.data';
+  import { getDeviceList, list } from './history.api';
+  import { useListPage } from '/@/hooks/system/useListPage';
+
+  const props = withDefaults(
+    defineProps<{
+      /** 表格项配置,默认由deviceCode获取且联动dictCode,可以覆写,覆写后将不支持联动,参考BaiscTable */
+      columns?: BasicColumn[];
+      /** 表格操作项配置,默认为空,可以覆写 */
+      actionColumns?: BasicColumn;
+      /** 查询表单项配置,默认联动dictCode,可以覆写,覆写后将不支持联动,提供formProps时此项无效,参考BaiscTable */
+      schemas?: FormSchema[];
+      /** 表格分页配置,可以覆写,参考BaiscTable */
+      pagination?: PaginationProps;
+      /** 设备编码,该编码用于从字段/点表配置中读出表头,示例:forcFan */
+      deviceCode: string;
+      /** 字典编码,该编码用于从字典配置中读出设备项,示例:forcFan_dict */
+      dictCode: string;
+      /** 表格配置,参考BaiscTable,该值会与默认的配置进行浅合并,这里提供的任何配置都是优先的 */
+      tableProps?: BasicTableProps;
+      /** 查询表单配置,参考BaiscTable */
+      formProps?: FormProps;
+    }>(),
+    {
+      deviceCode: '',
+      dictCode: '',
+    }
+  );
+
+  // 初始化表格,将默认配置与props提供的配置合并
+  const defaultSchemas = getDefaultSchemas(props.dictCode);
+  const defaultColumns = getTableHeaderColumns(props.deviceCode.concat('_history'));
+
+  const { tableContext } = useListPage({
+    tableProps: {
+      ...defaultTableProps,
+      columns: props.columns || defaultColumns,
+      actionColumn: props.actionColumns,
+      showActionColumn: Boolean(props.actionColumns),
+      formConfig: props.formProps || {
+        ...defaultFormProps,
+        schemas: props.schemas || defaultSchemas,
+      },
+      pagination: props.pagination || defaultPaginationProps,
+      ...props.tableProps,
+    },
+  });
+  const [register, { getForm, setLoading, setColumns, getPaginationRef, setPagination }] = tableContext;
+
+  // 表格数据相关
+  const data = shallowRef([]);
+
+  // 搜索
+  async function search() {
+    const form = getForm();
+    await form.validate();
+    await fetchData(form.getFieldsValue());
+  }
+
+  // 分站类型,不同的分站类型对应不同的方式获取历史数据
+  const deviceInfo = ref({});
+
+  // 获取设备列表信息,初始化一些信息
+  async function fetchDevice() {
+    const results = await getDeviceList({ devicetype: props.deviceCode, pageSize: 10000 });
+
+    const id = results[0].id || results[0].deviceID;
+    deviceInfo.value = results[0];
+    await getForm().setFieldsValue({ gdeviceid: id });
+  }
+
+  // 核心,获取表格的数据
+  function fetchData(formData: Record<string, unknown>) {
+    setLoading(true);
+
+    const pagination = getPaginationRef() as PaginationProps;
+    list(
+      props.deviceCode,
+      deviceInfo,
+      {
+        ...formData,
+        pageNo: pagination.current,
+        pageSize: pagination.pageSize,
+        column: 'createTime',
+        strtype: props.deviceCode + '*',
+        isEmployee: props.deviceCode.startsWith('vehicle') ? false : true,
+      },
+      pagination
+    )
+      .then(({ records, total, current }) => {
+        // 表格的列需要默认情况下需要和设备列表联动
+        defaultColumns.forEach((col) => {
+          col.dataIndex = `${formData.deviceid}${col.dataIndex}`;
+        });
+        setColumns(defaultColumns);
+
+        setPagination({
+          current,
+          total,
+        });
+        data.value = records;
+      })
+      .finally(() => {
+        setLoading(false);
+      });
+  }
+
+  onMounted(() => {
+    fetchDevice();
+    search();
+  });
+</script>
+
+<style scoped lang="less">
+  @import '/@/design/vent/color.less';
+</style>

+ 6 - 0
src/views/vent/comment/history/TestPage.vue

@@ -0,0 +1,6 @@
+<template>
+  <HistoryTable class="w-100% h-100% mt-100px" device-code="forcFan" dict-code="forcFan_dict" />
+</template>
+<script lang="ts" setup>
+  import HistoryTable from './HistoryTable.vue';
+</script>

+ 61 - 0
src/views/vent/comment/history/history.api.ts

@@ -0,0 +1,61 @@
+import { PaginationProps } from '/@/components/Table';
+import { defHttp } from '/@/utils/http/axios';
+
+enum Api {
+  listdays = '/safety/ventanalyMonitorData/listdays',
+  getDeviceList = '/ventanaly-device/monitor/device',
+  getHistoryData = '/ventanaly-device/history/getHistoryData',
+}
+/**
+ * 列表接口
+ * @param params
+ */
+export const list = (deviceCode: string, deviceInfo: any, formData: any, pagination: PaginationProps) => {
+  if (deviceInfo.stationType === 'redis') {
+    return defHttp.post({
+      url: Api.getHistoryData,
+      params: {
+        pageNum: pagination.current,
+        pageSize: pagination.pageSize,
+        column: 'createTime',
+        startTime: formData.ttime_begin,
+        endTime: formData.ttime_end,
+        deviceId: formData.gdeviceid,
+        strtype: deviceCode + '*',
+        interval: formData.skip || '1h',
+        isEmployee: deviceCode.startsWith('vehicle') ? false : true,
+      },
+    });
+  } else {
+    return defHttp
+      .get({
+        url: Api.listdays,
+        params: {
+          pageNo: pagination.current,
+          pageSize: pagination.pageSize,
+          column: 'createTime',
+          strtype: deviceInfo.strtype || deviceCode.concat('*'),
+          ...formData,
+        },
+      })
+      .then((r) => {
+        if (r.datalist) return r.datalist;
+        return { total: 0, records: [] };
+      });
+  }
+};
+
+/**
+ * 根据设备编码获取设备列表
+ * @param params
+ */
+export const getDeviceList = (params) =>
+  defHttp.post({ url: Api.getDeviceList, params }).then((r) => {
+    if (r.records && r.records.length) {
+      return r.records;
+    }
+    if (r.msgTxt && r.msgTxt.length) {
+      return r.msgTxt[0].datalist;
+    }
+    return [];
+  });

+ 134 - 0
src/views/vent/comment/history/history.data.ts

@@ -0,0 +1,134 @@
+import dayjs from 'dayjs';
+import { BasicTableProps, PaginationProps, FormProps, FormSchema } from '/@/components/Table';
+// import { getAutoScrollContainer } from '/@/utils/common/compUtils';
+
+/** 默认的查询表单项props */
+export const getDefaultSchemas: (dictCode: string) => FormSchema[] = (dictCode: string) => [
+  {
+    field: 'ttime_begin',
+    label: '开始时间',
+    component: 'DatePicker',
+    defaultValue: dayjs().startOf('date'),
+    required: true,
+    componentProps: {
+      showTime: true,
+      valueFormat: 'YYYY-MM-DD HH:mm:ss',
+      // getPopupContainer: getAutoScrollContainer,
+    },
+    colProps: {
+      span: 4,
+    },
+  },
+  {
+    field: 'ttime_end',
+    label: '结束时间',
+    component: 'DatePicker',
+    defaultValue: dayjs(),
+    required: true,
+    componentProps: {
+      showTime: true,
+      valueFormat: 'YYYY-MM-DD HH:mm:ss',
+      // getPopupContainer: getAutoScrollContainer,
+    },
+    colProps: {
+      span: 4,
+    },
+  },
+  {
+    label: '查询设备',
+    field: 'gdeviceid',
+    component: 'Input',
+    required: true,
+    // componentProps: {
+    //   onChange: (e, option) => {
+    //     nextTick(async () => {
+    //       await getDataSource();
+    //     });
+    //   },
+    // },
+    colProps: {
+      span: 4,
+    },
+  },
+  {
+    label: '子设备',
+    field: 'deviceNum',
+    component: 'JDictSelectTag',
+    componentProps: {
+      dictCode,
+      placeholder: '请选择',
+    },
+    colProps: {
+      span: 4,
+    },
+  },
+  {
+    label: '间隔时间',
+    field: 'skip',
+    component: 'Select',
+    defaultValue: '8',
+    componentProps: {
+      options: [
+        {
+          label: '1秒',
+          value: '1s',
+        },
+        {
+          label: '5秒',
+          value: '5s',
+        },
+        {
+          label: '10秒',
+          value: '10s',
+        },
+        {
+          label: '30秒',
+          value: '30s',
+        },
+        {
+          label: '1分钟',
+          value: '1m',
+        },
+        {
+          label: '10分钟',
+          value: '10m',
+        },
+        {
+          label: '30分钟',
+          value: '30m',
+        },
+        {
+          label: '1小时',
+          value: '1h',
+        },
+      ],
+    },
+    colProps: {
+      span: 4,
+    },
+  },
+];
+
+/** 默认的表格props,参考 BasicTable 组件 */
+export const defaultTableProps: BasicTableProps = {
+  columns: [],
+  bordered: false,
+  size: 'small',
+  showIndexColumn: true,
+};
+
+/** 默认的查询表单props,参考 BasicForm 组件 */
+export const defaultFormProps: FormProps = {
+  labelAlign: 'left',
+  showAdvancedButton: false,
+  showSubmitButton: false,
+  showResetButton: true,
+};
+
+/** 默认的表格分页props,参考 BasicTable 组件 */
+export const defaultPaginationProps: PaginationProps = {
+  current: 1,
+  pageSize: 10,
+  pageSizeOptions: ['10', '30', '50', '100'],
+  showQuickJumper: false,
+};