Ver código fonte

[Feat 0000]操作历史嵌套表格开发

bobo04052021@163.com 1 mês atrás
pai
commit
e020e8c580
1 arquivos alterados com 260 adições e 193 exclusões
  1. 260 193
      src/views/vent/monitorManager/comment/HandlerHistoryTable.vue

+ 260 - 193
src/views/vent/monitorManager/comment/HandlerHistoryTable.vue

@@ -1,218 +1,285 @@
 <template>
   <div class="handler-history-table">
-    <BasicTable ref="handlerHistory" @register="registerTable" />
+    <BasicTable ref="handlerHistory" @register="registerTable">
+      <template #expandedRowRender="{ record }">
+        <a-table
+          size="small"
+          :columns="innerColumns"
+          :data-source="innerDataMap[record.groupcode] || []"
+          :pagination="false"
+          :loading="innerLoadingMap[record.groupcode]"
+          row-key="id"
+        >
+          <template #bodyCell="{ column }"> </template>
+        </a-table>
+      </template>
+    </BasicTable>
   </div>
 </template>
 
 <script lang="ts" name="system-user" setup>
-  //ts语法
-  import { watch, ref } 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';
+//ts语法
+import { watch, ref, reactive } 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';
 
-  const list = (params) => defHttp.get({ url: '/safety/ventanalyDevicesetLog/list', params });
+const list = (params) => defHttp.get({ url: '/safety/ventanalyDevicesetLog/list', params });
+const getDevicesetLog = (params) => defHttp.post({ url: '/ventanaly-device/safety/ventanalyDevicesetLog/queryByGroupCode', params });
+const props = defineProps({
+  columnsType: {
+    type: String,
+    required: true,
+  },
+  deviceType: {
+    type: String,
+    required: true,
+  },
+  deviceListApi: {
+    type: Function,
+    required: false,
+  },
+  designScope: {
+    type: String,
+  },
+  sysId: {
+    type: String,
+  },
+  deviceId: {
+    type: String,
+    default: '',
+  },
+  scroll: {
+    type: Object,
+    default: { y: 0 },
+  },
+});
 
-  const props = defineProps({
-    columnsType: {
-      type: String,
-      required: true,
-    },
-    deviceType: {
-      type: String,
-      required: true,
-    },
-    deviceListApi: {
-      type: Function,
-      required: false,
-    },
-    designScope: {
-      type: String,
-    },
-    sysId: {
-      type: String,
-    },
-    deviceId: {
-      type: String,
-      default: '',
-    },
-    scroll: {
-      type: Object,
-      default: { y: 0 },
-    },
-  });
+const handlerHistory = ref();
+const columns = ref([]);
+const tableScroll = props.scroll.y ? ref({ y: props.scroll.y - 100 }) : ref({});
+const innerColumns = ref([
+  {
+    title: '设备名称',
+    dataIndex: 'devicename',
+    key: 'devicename',
+  },
+  {
+    title: '用户',
+    dataIndex: 'realname',
+    key: 'realname',
+  },
+  {
+    title: '操作记录',
+    dataIndex: 'strremark',
+    key: 'strremark',
+  },
 
-  const handlerHistory = ref();
-  const columns = ref([]);
-  const tableScroll = props.scroll.y ? ref({ y: props.scroll.y - 100 }) : ref({});
+  {
+    title: 'IP',
+    dataIndex: 'ip',
+    key: 'ip',
+  },
+  {
+    title: '操作时间',
+    dataIndex: 'createTime',
+    key: 'createTime',
+  },
+]);
+// 展开行相关
+const expandedRowKeys = ref<string[]>([]);
+const innerDataMap = reactive<Record<string, any[]>>({});
+const innerLoadingMap = reactive<Record<string, boolean>>({});
 
-  watch(
-    () => {
-      return props.columnsType;
-    },
-    (newVal) => {
-      const column = getTableHeaderColumns(newVal);
-      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 (handlerHistory.value) reload();
-    },
-    {
-      immediate: true,
+// 展开/收起事件
+const onExpand = async (expanded: boolean, record: Recordable) => {
+  if (!expanded) return;
+  const key = record.groupcode;
+  if (innerDataMap[key]) return;
+  innerLoadingMap[key] = true;
+  try {
+    const res = await getDevicesetLog({ groupCode: key });
+    innerDataMap[key] = res.records || res || [];
+  } catch (e) {
+    console.error('获取子数据失败:', e);
+    innerDataMap[key] = [];
+  } finally {
+    innerLoadingMap[key] = false;
+  }
+};
+watch(
+  () => {
+    return props.columnsType;
+  },
+  (newVal) => {
+    const column = getTableHeaderColumns(newVal);
+    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 (handlerHistory.value) reload();
+  },
+  {
+    immediate: true,
+  }
+);
 
-  watch(
-    () => props.scroll.y,
-    (newVal) => {
-      if (newVal) {
-        tableScroll.value = { y: newVal - 100 };
-      } else {
-        tableScroll.value = {};
-      }
+watch(
+  () => props.scroll.y,
+  (newVal) => {
+    if (newVal) {
+      tableScroll.value = { y: newVal - 100 };
+    } else {
+      tableScroll.value = {};
     }
-  );
-
-  // 列表页面公共参数、方法
-  const { tableContext } = useListPage({
-    tableProps: {
-      api: list,
-      columns: columns,
-      canResize: true,
-      showTableSetting: false,
-      showActionColumn: false,
-      showIndexColumn: true,
-      bordered: false,
-      size: 'small',
-      scroll: tableScroll,
-      formConfig: {
-        labelAlign: 'left',
-        showAdvancedButton: false,
-        baseColProps: {
-          // offset: 0.5,
-          xs: 24,
-          sm: 24,
-          md: 24,
-          lg: 9,
-          xl: 7,
-          xxl: 4,
+  }
+);
+const onExpandedRowsChange = (keys: string[]) => {
+  expandedRowKeys.value = keys;
+};
+// 列表页面公共参数、方法
+const { tableContext } = useListPage({
+  tableProps: {
+    api: list,
+    columns: columns,
+    canResize: true,
+    showTableSetting: false,
+    showActionColumn: false,
+    showIndexColumn: true,
+    bordered: false,
+    size: 'small',
+    scroll: tableScroll,
+    formConfig: {
+      labelAlign: 'left',
+      showAdvancedButton: false,
+      baseColProps: {
+        // offset: 0.5,
+        xs: 24,
+        sm: 24,
+        md: 24,
+        lg: 9,
+        xl: 7,
+        xxl: 4,
+      },
+      schemas: [
+        {
+          field: 'createTime_begin',
+          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,
+          },
         },
-        schemas: [
-          {
-            field: 'createTime_begin',
-            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,
-            },
+        {
+          field: 'createTime_end',
+          label: '结束时间',
+          component: 'DatePicker',
+          defaultValue: dayjs(),
+          required: true,
+          componentProps: {
+            showTime: true,
+            valueFormat: 'YYYY-MM-DD HH:mm:ss',
+            getPopupContainer: getAutoScrollContainer,
           },
-          {
-            field: 'createTime_end',
-            label: '结束时间',
-            component: 'DatePicker',
-            defaultValue: dayjs(),
-            required: true,
-            componentProps: {
-              showTime: true,
-              valueFormat: 'YYYY-MM-DD HH:mm:ss',
-              getPopupContainer: getAutoScrollContainer,
-            },
-            colProps: {
-              span: 4,
-            },
+          colProps: {
+            span: 4,
           },
-          // {
-          //   label: '查询设备',
-          //   field: 'gdeviceid',
-          //   component: 'ApiSelect',
-          //   componentProps: {
-          //     api: props.deviceListApi,
-          //     resultField: 'records',
-          //     labelField: 'strname',
-          //     valueField: 'id',
-          //   },
-          // },
-        ],
-      },
-      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;
-        }
-        if (props.deviceId) {
-          params.deviceid = props.deviceId;
-        }
-      },
+        },
+        // {
+        //   label: '查询设备',
+        //   field: 'gdeviceid',
+        //   component: 'ApiSelect',
+        //   componentProps: {
+        //     api: props.deviceListApi,
+        //     resultField: 'records',
+        //     labelField: 'strname',
+        //     valueField: 'id',
+        //   },
+        // },
+      ],
+    },
+    fetchSetting: {
+      listField: 'records',
     },
-  });
-  //注册table数据
-  const [registerTable, { reload, setLoading }] = tableContext;
-  defineExpose({ setLoading });
+    pagination: {
+      current: 1,
+      pageSize: 10,
+      pageSizeOptions: ['10', '30', '50', '100'],
+    },
+    expandedRowKeys: expandedRowKeys,
+    onExpand: onExpand,
+    onExpandedRowsChange: onExpandedRowsChange,
+    beforeFetch(params) {
+      params.devicetype = props.deviceType + '*';
+      if (props.sysId) {
+        params.sysId = props.sysId;
+      }
+      if (props.deviceId) {
+        params.deviceid = props.deviceId;
+      }
+    },
+  },
+});
+
+//注册table数据
+const [registerTable, { reload, setLoading }] = tableContext;
+defineExpose({ setLoading });
 </script>
 
 <style scoped lang="less">
-  @ventSpace: zxm;
+@ventSpace: zxm;
 
-  // :deep(.@{ventSpace}-table-body) {
-  //   height: auto !important;
-  // }
-  :deep(.zxm-picker) {
-    height: 30px !important;
-  }
-  .handler-history-table {
-    width: 100%;
-    :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;
-          height: 100%;
-          background: #00000017;
-          border: 1px solid #b7b7b7;
-          input,
-          .@{ventSpace}-select-selection-item,
-          .@{ventSpace}-picker-suffix {
-            color: #fff;
-          }
-          .@{ventSpace}-select-selection-placeholder {
-            color: #ffffffaa;
-          }
+// :deep(.@{ventSpace}-table-body) {
+//   height: auto !important;
+// }
+:deep(.zxm-picker) {
+  height: 30px !important;
+}
+.handler-history-table {
+  width: 100%;
+  :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;
+        height: 100%;
+        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;
-      }
+    }
+    .@{ventSpace}-table-title {
+      min-height: 0 !important;
     }
   }
-</style>
+}
+</style>