Task.vue 4.81 KB
<script lang="ts" setup>
  import { ReloadOutlined } from '@ant-design/icons-vue';
  import { Button, List, Tooltip } from 'ant-design-vue';
  import { TaskCard } from '/@/views/task/center/components/TaskCard';
  import { reactive, ref, unref } from 'vue';
  import { PageWrapper } from '/@/components/Page';
  import { BasicForm, useForm } from '/@/components/Form';
  import { formSchemas } from '/@/views/task/center/config';
  import { getTaskCenterList } from '/@/api/task';
  import { onMounted } from 'vue';
  import { getBoundingClientRect } from '/@/utils/domUtils';
  import { TaskRecordType } from '/@/api/task/model';
  import { RunTaskModal } from '/@/views/task/center/components/RunTaskModal';
  import { useModal } from '/@/components/Modal';

  const props = defineProps<{
    tbDeviceId: string;
  }>();

  const listElRef = ref<Nullable<ComponentElRef>>(null);

  const [registerRunTaskModal, { openModal }] = useModal();

  const [registerForm, { getFieldsValue }] = useForm({
    schemas: formSchemas,
    baseColProps: { span: 8 },
    compact: true,
    showAdvancedButton: true,
    labelWidth: 100,
    submitFunc: async () => {
      getDataSource();
    },
  });

  const paginationChange = (page: number, pageSize: number) => {
    pagination.current = page - 1 * pageSize > pagination.total ? 1 : page;
    pagination.pageSize = pageSize;
    getDataSource();
  };

  const pagination = reactive({
    current: 1,
    pageSize: 10,
    total: 0,
    showQuickJumper: true,
    size: 'small',
    showTotal: (total: number) => `共 ${total} 条数据`,
    onChange: paginationChange,
    onShowSizeChange: paginationChange,
  });

  const dataSource = ref<TaskRecordType[]>([]);
  const loading = ref(false);

  const getDataSource = async () => {
    try {
      loading.value = true;
      const params = getFieldsValue() || {};
      const { items, total } = await getTaskCenterList({
        page: pagination.current,
        pageSize: pagination.pageSize,
        tbDeviceId: props.tbDeviceId,
        ...params,
      });
      pagination.total = total;
      dataSource.value = items;
    } catch (error) {
      throw error;
    } finally {
      loading.value = false;
    }
  };

  const reload = () => getDataSource();

  const setListHeight = () => {
    const clientHeight = document.documentElement.clientHeight;
    const rect = getBoundingClientRect(unref(listElRef)!.$el!) as DOMRect;
    // margin-top 24 height 24
    const paginationHeight = 24 + 24 + 8;
    // list pading top 8 maring-top 8 extra slot 56
    const listContainerMarginBottom = 8 + 8 + 72;
    const listContainerHeight =
      clientHeight - rect.top - paginationHeight - listContainerMarginBottom;
    const listContainerEl = (unref(listElRef)!.$el as HTMLElement).querySelector(
      '.ant-spin-container'
    ) as HTMLElement;
    listContainerEl &&
      (listContainerEl.style.height = listContainerHeight + 'px') &&
      (listContainerEl.style.overflowY = 'auto') &&
      (listContainerEl.style.overflowX = 'hidden');
  };

  const handleRunTask = (record: TaskRecordType) => {
    openModal(true, record);
  };

  onMounted(() => {
    setListHeight();
    getDataSource();
  });
</script>

<template>
  <PageWrapper
    class="bg-neutral-100 dark:text-gray-300 dark:bg-dark-700 device-task-list-container"
  >
    <section
      class="form-container bg-light-50 px-4 pt-4 mt-4 x dark:text-gray-300 dark:bg-dark-900"
    >
      <BasicForm @register="registerForm" />
    </section>
    <section class="bg-light-50 my-4 p-4 x dark:text-gray-300 dark:bg-dark-900">
      <List
        ref="listElRef"
        :dataSource="dataSource"
        :pagination="pagination"
        :grid="{ gutter: 16, xs: 1, sm: 1, md: 1, lg: 2, xl: 2, xxl: 3, column: 3 }"
        :loading="loading"
      >
        <template #header>
          <section class="flex justify-between gap-4 min-h-12 items-center">
            <div class="text-lg font-semibold">
              <span>任务列表</span>
            </div>
            <Tooltip title="刷新">
              <Button type="primary" @click="getDataSource">
                <ReloadOutlined :spin="loading" />
              </Button>
            </Tooltip>
          </section>
        </template>
        <template #renderItem="{ item }">
          <List.Item :key="item.id">
            <TaskCard
              :record="item"
              :reload="reload"
              :tbDeviceId="tbDeviceId"
              :deviceTaskCardMode="true"
              @runTask="handleRunTask"
            />
          </List.Item>
        </template>
      </List>
      <RunTaskModal :reload="reload" @register="registerRunTaskModal" />
    </section>
  </PageWrapper>
</template>

<style lang="less" scoped>
  .device-task-list-container {
    :deep(.ant-list-header) {
      border: none;
    }

    :deep(.ant-card-body) {
      padding: 16px 24px;
    }
  }
</style>