index.vue 8.99 KB
<script setup lang="ts">
  import { List, Card, Button, PaginationProps, Tooltip } from 'ant-design-vue';
  import { ReloadOutlined } from '@ant-design/icons-vue';
  import { onMounted, reactive, ref, unref } from 'vue';
  import { OrganizationIdTree, useResetOrganizationTree } from '../common/organizationIdTree';
  import { deleteBigScreenenter, getPage } from '/@/api/bigscreen/center/bigscreenCenter';
  import { BigScreenCenterItemsModel } from '/@/api/bigscreen/center/model/bigscreenCenterModel';
  import { PageWrapper } from '/@/components/Page';
  import { BasicForm, useForm } from '/@/components/Form';
  import { ConfigurationPermission, searchFormSchema } from './config';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { Authority } from '/@/components/Authority';
  import ConfigurationCenterDrawer from './BigScreenDrawer.vue';
  import { useDrawer } from '/@/components/Drawer';
  import { getBoundingClientRect } from '/@/utils/domUtils';
  import configurationSrc from '/@/assets/icons/configuration.svg';
  import { cloneDeep } from 'lodash';
  import { useGlobSetting } from '/@/hooks/setting';
  import { AuthIcon, CardLayoutButton } from '/@/components/Widget';
  import AuthDropDown from '/@/components/Widget/AuthDropDown.vue';

  const listColumn = ref(5);

  const { createMessage } = useMessage();

  const organizationId = ref<Nullable<number>>(null);

  const pagination = reactive<PaginationProps>({
    size: 'small',
    showTotal: (total: number) => `共 ${total} 条数据`,
    current: 1,
    pageSize: unref(listColumn) * 2,
    onChange: (page: number) => {
      pagination.current = page;
      getListData();
    },
  });

  const loading = ref(false);

  const dataSource = ref<BigScreenCenterItemsModel[]>([]);

  const [registerForm, { getFieldsValue }] = useForm({
    schemas: searchFormSchema,
    showAdvancedButton: true,
    labelWidth: 100,
    compact: true,
    resetFunc: () => {
      resetFn();
      organizationId.value = null;
      return getListData();
    },
    submitFunc: async () => {
      const value = getFieldsValue();
      getListData(value);
    },
  });

  async function getListData(value: Recordable = {}) {
    try {
      loading.value = true;
      const pageSize = unref(listColumn) * 2;
      const { items, total } = await getPage({
        organizationId: unref(organizationId),
        ...value,
        page: pagination.current!,
        pageSize,
      });

      dataSource.value = items;
      Object.assign(pagination, { total, pageSize });
    } catch (error) {
    } finally {
      loading.value = false;
    }
  }

  onMounted(() => {
    getListData();
  });

  const searchInfo = reactive<Recordable>({});
  const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
  const handleSelect = (orgId: number) => {
    organizationId.value = orgId;
    getListData();
  };

  const [registerDrawer, { openDrawer }] = useDrawer();

  const handleCreateOrUpdate = (record?: BigScreenCenterItemsModel) => {
    if (record) {
      openDrawer(true, {
        isUpdate: true,
        record: cloneDeep(record),
      });
    } else {
      openDrawer(true, {
        isUpdate: false,
      });
    }
  };

  const { largeDesignerPrefix } = useGlobSetting();

  const handlePreview = (record: BigScreenCenterItemsModel) => {
    window.open(`${largeDesignerPrefix}/${record.id}`);
  };

  const handleDesign = (record: BigScreenCenterItemsModel) => {
    window.open(`${largeDesignerPrefix}/${record.id}`);
  };

  const handleDelete = async (record: BigScreenCenterItemsModel) => {
    try {
      await deleteBigScreenenter([record.id]);
      createMessage.success('删除成功');
      await getListData();
    } catch (error) {}
  };

  const handleCardLayoutChange = () => {
    pagination.current = 1;
    getListData();
  };

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

  onMounted(() => {
    const clientHeight = document.documentElement.clientHeight;
    const rect = getBoundingClientRect(unref(listEl)!.$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 + 56;
    const listContainerHeight =
      clientHeight - rect.top - paginationHeight - listContainerMarginBottom;
    const listContainerEl = (unref(listEl)!.$el as HTMLElement).querySelector(
      '.ant-spin-container'
    ) as HTMLElement;
    listContainerEl &&
      (listContainerEl.style.height = listContainerHeight + 'px') &&
      (listContainerEl.style.overflowY = 'auto') &&
      (listContainerEl.style.overflowX = 'hidden');
  });
</script>

<template>
  <PageWrapper dense contentFullHeight contentClass="flex">
    <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" />
    <section class="flex-auto p-4 w-3/4 xl:w-4/5 w-full configuration-list">
      <div class="flex-auto w-full bg-light-50 dark:bg-dark-900 p-4">
        <BasicForm @register="registerForm" />
      </div>
      <List
        ref="listEl"
        :loading="loading"
        class="flex-auto bg-light-50 dark:bg-dark-900 !p-2 !mt-4"
        position="bottom"
        :pagination="pagination"
        :data-source="dataSource"
        :grid="{ gutter: 4, column: listColumn }"
      >
        <template #header>
          <div class="flex gap-3 justify-end">
            <Authority :value="ConfigurationPermission.CREATE">
              <Button type="primary" @click="handleCreateOrUpdate()">新增大屏</Button>
            </Authority>
            <CardLayoutButton v-model:value="listColumn" @change="handleCardLayoutChange" />
            <Tooltip title="刷新">
              <Button type="primary" @click="getListData">
                <ReloadOutlined @click="getListData" />
              </Button>
            </Tooltip>
          </div>
        </template>
        <template #renderItem="{ item }">
          <List.Item>
            <Card hoverable>
              <template #cover>
                <div class="h-full w-full !flex justify-center items-center text-center p-1">
                  <img
                    class="w-full h-36"
                    alt="example"
                    :src="item.thumbnail || configurationSrc"
                    @click="handlePreview(item)"
                  />
                </div>
              </template>
              <template class="ant-card-actions" #actions>
                <Tooltip title="预览">
                  <AuthIcon
                    class="!text-lg"
                    icon="ant-design:eye-outlined"
                    @click="handlePreview(item)"
                  />
                </Tooltip>
                <Tooltip title="设计">
                  <AuthIcon
                    class="!text-lg"
                    icon="ant-design:edit-outlined"
                    @click="handleDesign(item)"
                  />
                </Tooltip>
                <AuthDropDown
                  :dropMenuList="[
                    {
                      text: '编辑',
                      auth: ConfigurationPermission.UPDATE,
                      icon: 'clarity:note-edit-line',
                      event: '',
                      onClick: handleCreateOrUpdate.bind(null, item),
                    },
                    {
                      text: '删除',
                      auth: ConfigurationPermission.DELETE,
                      icon: 'ant-design:delete-outlined',
                      event: '',
                      popconfirm: {
                        title: '是否确认删除操作?',
                        onConfirm: handleDelete.bind(null, item),
                      },
                    },
                  ]"
                  :trigger="['hover']"
                />
              </template>
              <Card.Meta>
                <template #title>
                  <span class="truncate">{{ item.name }}</span>
                </template>
                <template #description>
                  <div class="truncate h-11">
                    <div class="truncate">{{ item.organizationDTO.name }}</div>
                    <div class="truncate">{{ item.remark || '' }} </div>
                  </div>
                </template>
              </Card.Meta>
            </Card>
          </List.Item>
        </template>
      </List>
    </section>
    <ConfigurationCenterDrawer @register="registerDrawer" @success="getListData" />
  </PageWrapper>
</template>

<style lang="less" scoped>
  .configuration-list:deep(.ant-list-header) {
    border-bottom: none !important;
  }

  .configuration-list:deep(.ant-list-pagination) {
    height: 24px;
  }

  .configuration-list:deep(.ant-card-body) {
    padding: 16px !important;
  }

  .configuration-list:deep(.ant-list-empty-text) {
    @apply w-full h-full flex justify-center items-center;
  }
</style>