query-table.vue 4.24 KB
<template>
  <filter-search v-show="hasSearch" :loading="loading" :model="filter" @search="onSearch" @reset="onReset">
    <filter-search-item field="name" label="操作人">
      <a-input v-model="filter.userNickName" allow-clear placeholder="请输入" />
    </filter-search-item>
    <filter-search-item field="guard" label="操作平台">
      <a-select v-model="filter.guard" :options="guardOption" allow-clear placeholder="请选择" @change="() => (filter.path = '')" />
    </filter-search-item>
    <filter-search-item field="name" label="操作模块">
      <permission-select v-model="filter.path" :guard="filter.guard" allow-clear allow-search />
    </filter-search-item>
    <filter-search-item field="createBetween" label="操作时间">
      <a-range-picker v-model="filter.createBetween" show-time :time-picker-props="{ defaultValue: ['00:00:00', '23:59:59'] }" />
    </filter-search-item>
  </filter-search>
  <filter-table ref="tableRef" :loading="loading" :on-query="onQuery">
    <user-table-column title="操作人" data-index="user_id" user="user" show-href :width="160" />
    <filter-table-column title="操作平台" data-index="guard" :width="100">
      <template #default="{ record }">
        {{ guardOption.find((item) => item.value === record.guard)?.label || '未知' }}
      </template>
    </filter-table-column>
    <filter-table-column :width="180" data-index="path" title="操作模块">
      <template #default="{ record }">
        {{
          record.path
            ?.map((item: string) => findPermissionLabel(record.guard, item))
            .filter((item: string) => item !== '')
            .join('/')
        }}
      </template>
    </filter-table-column>
    <filter-table-column :width="100" data-index="action" title="操作类型" />
    <filter-table-column :width="460" data-index="content" title="操作内容" />
    <filter-table-column :width="170" data-index="created_at" title="操作时间" />
  </filter-table>
</template>

<script lang="ts" setup>
  import { AnyObject, QueryForParams } from '@/types/global';
  import useLoading from '@/hooks/loading';
  import { computed, onMounted, ref } from 'vue';
  import { useAppStore } from '@/store';
  import { storeToRefs } from 'pinia';
  import { SystemPermission } from '@/types/system-permission';
  import UserTableColumn from '@/components/filter/user-table-column.vue';
  import useOperationLog from '@/http/log';

  type propType = { filter?: AnyObject; hasSearch?: boolean; showGuard?: boolean };

  const props = withDefaults(defineProps<propType>(), { filter: undefined, hasSearch: true, showGuard: true });

  const appStore = useAppStore();
  const { permissions } = storeToRefs(appStore);

  const { loading, setLoading } = useLoading(false);
  const filter = ref<QueryForParams>({ userNickName: '', guard: '', path: [], createBetween: [] });
  const tableRef = ref();

  const guardOption = [
    { value: 'Admin', label: '运营管理平台' },
    { value: 'Manage', label: '厂牌管理平台' },
  ];

  const systemPermission = computed((): SystemPermission[] => {
    return [
      { guard: 'Admin', name: 'dashboard', label: '信息概览' } as SystemPermission,
      { guard: 'Manage', name: 'dashboard', label: '信息概览' } as SystemPermission,
      ...(permissions?.value ?? []),
    ];
  });

  const findPermissionLabel = (guard: 'Admin' | 'Manage', name: string) => {
    return systemPermission.value?.find((item) => item.guard === guard && item.name === name)?.label || '';
  };

  const onQuery = async (params: AnyObject) => {
    setLoading(true);

    return useOperationLog
      .get({
        ...filter.value,
        ...props.filter,
        setWith: ['user:id,nick_name,real_name,identity'],
        ...params,
        sortBy: 'id',
        sortType: 'desc',
      })
      .finally(() => {
        setLoading(false);
      });
  };

  const onSearch = () => {
    tableRef.value?.onPageChange(1);
  };

  const onReset = () => {
    filter.value = { userNickName: '', guard: '', path: [], createBetween: [] };
    onSearch();
  };

  onMounted(() => {
    onReset();
  });
</script>

<style lang="less" scoped>
  :deep(.arco-table-cell) {
    padding: 5px 8px !important;

    & > .arco-table-td-content .arco-btn-size-small {
      padding: 5px !important;
    }
  }
</style>