SelectImport.vue 5.89 KB
<template>
  <BasicModal
    title="导入物模型"
    :maskClosable="false"
    destroyOnClose
    v-bind="$attrs"
    width="25rem"
    @register="register"
    @cancel="handleCancel"
    :showOkBtn="false"
  >
    <div class="w-full h-full" ref="loadingRef">
      <div class="flex justify-end">
        <Button @click="handleTemplateDownload" type="link">excel模板下载</Button>
      </div>
      <div class="flex justify-evenly items-center h-50 !w-full">
        <Upload
          accept=".json,"
          :show-upload-list="false"
          :customRequest="handleImportModel"
          class="flex justify-center items-center"
        >
          <div class="flex flex-col justify-center items-center">
            <Tooltip>
              <template #title>使用从物模型TSL导出的JSON进行导入</template>
              <img :src="JSONImage" alt="avatar" class="w-20 h-20" />
            </Tooltip>
          </div>
        </Upload>
        <Upload
          accept=".csv,.xls,.xlsx"
          :show-upload-list="false"
          :customRequest="handleCSVImport"
          class="flex justify-center items-center"
        >
          <div class="flex flex-col justify-center items-center">
            <Tooltip>
              <template #title>请使用excel模板编辑之后在进行导入</template>
              <img :src="CSVImage" alt="avatar" class="w-20 h-20" />
            </Tooltip>
          </div>
        </Upload>
      </div>
    </div>
  </BasicModal>
</template>
<script lang="ts" setup>
  import { ref, unref } from 'vue';
  import { Upload, Tooltip, Button } from 'ant-design-vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { DeviceRecord } from '/@/api/device/model/deviceModel';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { isObject, isString } from '/@/utils/is';
  import {
    importCsvCategory,
    importModelCategory,
    importModelOfMatter,
    importCsvDeviceProfileId,
    excelExport,
  } from '/@/api/device/modelOfMatter';
  // import XLSX, { CellObject } from 'xlsx';
  import { useLoading } from '/@/components/Loading';
  import JSONImage from '/@/assets/svg/JSON.svg';
  import CSVImage from '/@/assets/svg/excel.svg';

  const emits = defineEmits(['register', 'handleImportCSV', 'handleReload']);

  defineProps<{
    record: DeviceRecord;
  }>();

  const { createMessage } = useMessage();
  const loadingRef = ref();
  const [openLoading, closeLoading] = useLoading({
    target: loadingRef,
    props: {
      tip: '加载中',
      absolute: true,
    },
  });

  const isEmptyObject = (value: any) => isObject(value) && !Object.keys(value).length;

  const ImportInfo = ref<{ id?: string; isCateGory?: string | Boolean }>({});

  const [register, { closeModal }] = useModalInner(async (data) => {
    ImportInfo.value = data;
  });
  // 导入loading
  const importLoading = ref(false);

  const paseJSON = (string: string) => {
    let data = null;
    let flag = false;
    try {
      if (!isString(string)) return { flag: false, data };
      data = JSON.parse(string);
      flag = true;
      if (!isObject(data)) flag = false;
    } catch (error) {}
    return { flag, data };
  };

  // JSON导入
  const handleImportModel = async (data: { file: File }) => {
    const fileReader = new FileReader();
    const { isCateGory, id } = unref(ImportInfo);

    fileReader.onload = async () => {
      const { flag, data } = paseJSON(fileReader.result as string);
      if (!flag) {
        createMessage.warning('JSON解析失败,请导入正确的JSON');
        return;
      }
      openLoading();
      try {
        importLoading.value = true;

        Object.keys(data || {}).forEach((key) => {
          const value = (data || {})[key];
          if (value && isEmptyObject(value)) {
            (data || {})[key] = [];
          }
        });

        const result = isCateGory
          ? await importModelCategory({
              categoryId: id,
              data: data!,
              functionType: 'all',
            })
          : await importModelOfMatter({
              tkDeviceProfileId: id,
              data: data!,
              functionType: 'all',
            });

        result
          ? createMessage.success('导入成功~')
          : createMessage.error('JSON解析失败,请导入正确的JSON');

        result && emits('handleReload');
      } catch (error) {
        throw error;
      } finally {
        importLoading.value = false;
        closeLoading();
        closeModal();
      }
    };

    fileReader.readAsText(data.file, 'utf-8');
  };

  // CSV导入
  const handleCSVImport = async ({ file }) => {
    const { isCateGory, id } = unref(ImportInfo);

    try {
      openLoading();
      const formData = new FormData();
      formData.set('file', file);
      const flag = isCateGory
        ? await importCsvCategory({ categoryId: id, deviceProfileId: undefined, file: formData })
        : await importCsvDeviceProfileId({
            categoryId: undefined,
            deviceProfileId: id,
            file: formData,
          });
      flag && createMessage.info(flag?.message);
    } catch (msg) {
      // eslint-disable-next-line no-console
      console.log(msg, 'msg');
    } finally {
      closeLoading();
      closeModal();
      emits('handleReload');
    }
  };

  const downloadFile = (data: Blob, fileName: string, ext: string) => {
    const objectURL = URL.createObjectURL(data);
    const element = document.createElement('a');
    element.href = objectURL;
    element.download = `${fileName}.${ext}`;
    element.style.display = 'none';
    document.body.appendChild(element);
    element.click();
    element.remove();
    URL.revokeObjectURL(objectURL);
  };

  // 模板下载
  const handleTemplateDownload = async () => {
    const res = await excelExport();
    downloadFile(res, '物模型属性导入模板', 'xls');
  };

  const handleCancel = () => {
    closeModal();
  };
</script>

<style lang="less" scope></style>