Jelajahi Sumber

fix: 【公共】附件上传组件修改

hanxiaohui 2 bulan lalu
induk
melakukan
78ff5406a5
1 mengubah file dengan 216 tambahan dan 202 penghapusan
  1. 216 202
      src/components/support/file-upload/index.vue

+ 216 - 202
src/components/support/file-upload/index.vue

@@ -7,10 +7,21 @@
 -->
 <template>
   <div class="clearfix">
-    <a-upload multiple :accept="props.accept" :before-upload="beforeUpload" :customRequest="customRequest"
-      :file-list="fileList" :headers="{ 'x-access-token': useUserStore().getToken }" :list-type="listType"
-      @change="handleChange" @preview="handlePreview" @remove="handleRemove" :showUploadList="showUploadList" :disabled="disabled">
-      <div v-if="fileList.length < props.maxUploadSize">
+    <a-upload
+      multiple
+      :accept="props.accept"
+      :before-upload="beforeUpload"
+      :customRequest="customRequest"
+      :file-list="fileList"
+      :headers="{ 'x-access-token': useUserStore().getToken }"
+      :list-type="listType"
+      @change="handleChange"
+      @preview="handlePreview"
+      @remove="handleRemove"
+      :showUploadList="showUploadList"
+      :disabled="disabled"
+    >
+      <div v-if="fileList.length < props.maxUploadSize && !slot.customUploadBtnSlot">
         <template v-if="listType === 'picture-card'">
           <PlusOutlined />
           <div class="ant-upload-text">
@@ -19,11 +30,12 @@
         </template>
         <template v-if="listType === 'text'">
           <a-button :type="btnType">
-            <upload-outlined v-if="btnIcon"/>
+            <upload-outlined v-if="btnIcon" />
             {{ buttonText }}
           </a-button>
         </template>
       </div>
+      <slot name="customUploadBtnSlot"></slot>
     </a-upload>
     <a-modal :footer="null" :open="previewVisible" @cancel="handleCancel">
       <img :src="previewUrl" alt="example" style="width: 100%" />
@@ -31,218 +43,220 @@
   </div>
 </template>
 <script setup>
-import { computed, ref, watch } from 'vue';
-import { Modal } from 'ant-design-vue';
-import { fileApi } from '/src/api/support/file-api';
-import { useUserStore } from '/@/store/modules/system/user';
-import { SmartLoading } from '/@/components/framework/smart-loading';
-import { FILE_FOLDER_TYPE_ENUM } from '/@/constants/support/file-const';
-import { smartSentry } from '/@/lib/smart-sentry';
-const props = defineProps({
-  value: String,
-  buttonText: {
-    type: String,
-    default: '点击上传附件',
-  },
-  showUploadBtn: {
-    type: Boolean,
-    default: true,
-  },
-  defaultFileList: {
-    type: Array,
-    default: () => [],
-  },
-  multiple: {
-    type: Boolean,
-    default: false,
-  },
-  // 最多上传文件数量
-  maxUploadSize: {
-    type: Number,
-    default: 10,
-  },
-  maxSize: {
-    type: Number,
-    default: 500,
-  },
-  // 上传的文件类型
-  accept: {
-    type: String,
-    default: '',
-  },
-  // 文件上传类型
-  folder: {
-    type: Number,
-    default: FILE_FOLDER_TYPE_ENUM.COMMON.value,
-  },
-  // 上传列表的内建样式,支持三种基本样式 text, picture 和 picture-card
-  listType: {
-    type: String,
-    default: 'picture-card',
-  },
-  // 上传按钮样式
-  btnType: {
-    type: String,
-    default: 'default',
-  },
-  // 是否显示上传按钮图标
-  btnIcon: {
-    type: Boolean,
-    default: true,
-  },
-  //是否显示上传列表
-  showUploadList:{
-    type: Boolean,
-    default: true,
-  },
-  //是否上传后清空文件列表
-  uploadAterClear:{
-    type: Boolean,
-    default: false,
-  },
-  //是否禁用上传
-  disabled:{
-    type: Boolean,
-    default: false,
-  }
-});
-
-// 图片类型的后缀名
-const imgFileType = ['jpg', 'jpeg', 'png', 'gif'];
-
-// 重新修改图片展示字段
-const files = computed(() => {
-  let res = [];
-  if (props.defaultFileList && props.defaultFileList.length > 0) {
-    props.defaultFileList.forEach((element) => {
-      element.url = element.fileUrl;
-      element.name = element.fileName;
-      res.push(element);
-    });
+  import { computed, ref, useSlots, watch } from 'vue';
+  import { Modal } from 'ant-design-vue';
+  import { fileApi } from '/src/api/support/file-api';
+  import { useUserStore } from '/@/store/modules/system/user';
+  import { SmartLoading } from '/@/components/framework/smart-loading';
+  import { FILE_FOLDER_TYPE_ENUM } from '/@/constants/support/file-const';
+  import { smartSentry } from '/@/lib/smart-sentry';
+  const props = defineProps({
+    value: String,
+    buttonText: {
+      type: String,
+      default: '点击上传附件',
+    },
+    showUploadBtn: {
+      type: Boolean,
+      default: true,
+    },
+    defaultFileList: {
+      type: Array,
+      default: () => [],
+    },
+    multiple: {
+      type: Boolean,
+      default: false,
+    },
+    // 最多上传文件数量
+    maxUploadSize: {
+      type: Number,
+      default: 10,
+    },
+    maxSize: {
+      type: Number,
+      default: 500,
+    },
+    // 上传的文件类型
+    accept: {
+      type: String,
+      default: '',
+    },
+    // 文件上传类型
+    folder: {
+      type: Number,
+      default: FILE_FOLDER_TYPE_ENUM.COMMON.value,
+    },
+    // 上传列表的内建样式,支持三种基本样式 text, picture 和 picture-card
+    listType: {
+      type: String,
+      default: 'picture-card',
+    },
+    // 上传按钮样式
+    btnType: {
+      type: String,
+      default: 'default',
+    },
+    // 是否显示上传按钮图标
+    btnIcon: {
+      type: Boolean,
+      default: true,
+    },
+    //是否显示上传列表
+    showUploadList: {
+      type: Boolean,
+      default: true,
+    },
+    //是否上传后清空文件列表
+    uploadAterClear: {
+      type: Boolean,
+      default: false,
+    },
+    //是否禁用上传
+    disabled: {
+      type: Boolean,
+      default: false,
+    },
+  });
+
+  const slot = useSlots();
+
+  // 图片类型的后缀名
+  const imgFileType = ['jpg', 'jpeg', 'png', 'gif'];
+
+  // 重新修改图片展示字段
+  const files = computed(() => {
+    let res = [];
+    if (props.defaultFileList && props.defaultFileList.length > 0) {
+      props.defaultFileList.forEach((element) => {
+        element.url = element.fileUrl;
+        element.name = element.fileName;
+        res.push(element);
+      });
+      return res;
+    }
     return res;
-  }
-  return res;
-});
-// -------------------- 逻辑 --------------------
-
-const previewVisible = ref(false);
-const fileList = ref([]);
-const previewUrl = ref('');
-
-watch(
-  files,
-  (value) => {
-    fileList.value = value;
-  },
-  {
-    immediate: true,
-  }
-);
-
-const emit = defineEmits(['update:value', 'change']);
-const customRequest = async (options) => {
-  SmartLoading.show();
-  try {
-    // console.log(options);
-    const formData = new FormData();
-    formData.append('file', options.file);
-    // console.log(formData)
-    let res = await fileApi.uploadFile(formData, props.folder);
-    // console.log(res)
-    let file = res.data;
-    file.url = file.fileUrl;
-    file.name = file.fileName;
-    if (props.uploadAterClear) {
-      fileList.value = []
+  });
+  // -------------------- 逻辑 --------------------
+
+  const previewVisible = ref(false);
+  const fileList = ref([]);
+  const previewUrl = ref('');
+
+  watch(
+    files,
+    (value) => {
+      fileList.value = value;
+    },
+    {
+      immediate: true,
     }
-    fileList.value.push(file);
-    emit('change', fileList.value);
-  } catch (e) {
-    smartSentry.captureError(e);
-  } finally {
-    SmartLoading.hide();
-  }
-};
-
-function handleChange(info) {
-  // console.log(info)
-  let fileStatus = info.file.status;
-  let file = info.file;
-  if (fileStatus === 'removed') {
-    let index = fileList.value.findIndex((e) => e.fileId === file.fileId);
-    if (index !== -1) {
-      fileList.value.splice(index, 1);
+  );
+
+  const emit = defineEmits(['update:value', 'change']);
+  const customRequest = async (options) => {
+    SmartLoading.show();
+    try {
+      // console.log(options);
+      const formData = new FormData();
+      formData.append('file', options.file);
+      // console.log(formData)
+      let res = await fileApi.uploadFile(formData, props.folder);
+      // console.log(res)
+      let file = res.data;
+      file.url = file.fileUrl;
+      file.name = file.fileName;
+      if (props.uploadAterClear) {
+        fileList.value = [];
+      }
+      fileList.value.push(file);
       emit('change', fileList.value);
+    } catch (e) {
+      smartSentry.captureError(e);
+    } finally {
+      SmartLoading.hide();
     }
-  }
-}
+  };
 
-function handleRemove(file) {
-  // console.log(fileList.value);
-}
+  function handleChange(info) {
+    // console.log(info)
+    let fileStatus = info.file.status;
+    let file = info.file;
+    if (fileStatus === 'removed') {
+      let index = fileList.value.findIndex((e) => e.fileId === file.fileId);
+      if (index !== -1) {
+        fileList.value.splice(index, 1);
+        emit('change', fileList.value);
+      }
+    }
+  }
 
-function beforeUpload(file, files) {
-  if (fileList.value.length + files.length > props.maxUploadSize) {
-    showErrorMsgOnce(`最多支持上传 ${props.maxUploadSize} 个文件哦!`);
-    return false;
+  function handleRemove(file) {
+    // console.log(fileList.value);
   }
 
-  if (props.accept) {
-    const suffixIndex = file.name.lastIndexOf('.');
-    const fileSuffix = file.name.substring(suffixIndex <= -1 ? 0 : suffixIndex);
-    if (props.accept.indexOf(fileSuffix) === -1) {
-      showErrorMsgOnce(`只支持上传 ${props.accept.replaceAll(',', ' ')} 格式的文件`);
+  function beforeUpload(file, files) {
+    if (fileList.value.length + files.length > props.maxUploadSize) {
+      showErrorMsgOnce(`最多支持上传 ${props.maxUploadSize} 个文件哦!`);
       return false;
     }
-  }
 
-  const isLimitSize = file.size / 1024 / 1024 < props.maxSize;
-  if (!isLimitSize) {
-    showErrorMsgOnce(`单个文件大小必须小于 ${props.maxSize} Mb`);
-  }
-  return isLimitSize;
-}
-
-const showErrorModalFlag = ref(true);
-const showErrorMsgOnce = (content) => {
-  if (showErrorModalFlag.value) {
-    Modal.error({
-      title: '提示',
-      content: content,
-      okType: 'danger',
-      centered: true,
-      onOk() {
-        showErrorModalFlag.value = true;
-      },
-    });
-    showErrorModalFlag.value = false;
+    if (props.accept) {
+      const suffixIndex = file.name.lastIndexOf('.');
+      const fileSuffix = file.name.substring(suffixIndex <= -1 ? 0 : suffixIndex);
+      if (props.accept.indexOf(fileSuffix) === -1) {
+        showErrorMsgOnce(`只支持上传 ${props.accept.replaceAll(',', ' ')} 格式的文件`);
+        return false;
+      }
+    }
+
+    const isLimitSize = file.size / 1024 / 1024 < props.maxSize;
+    if (!isLimitSize) {
+      showErrorMsgOnce(`单个文件大小必须小于 ${props.maxSize} Mb`);
+    }
+    return isLimitSize;
   }
-};
-
-function handleCancel() {
-  previewVisible.value = false;
-}
-
-const handlePreview = async (file) => {
-  if (imgFileType.some((e) => e === file.fileType)) {
-    previewUrl.value = file.url || file.preview;
-    previewVisible.value = true;
-  } else {
-    fileApi.downLoadFile(file.fileKey);
+
+  const showErrorModalFlag = ref(true);
+  const showErrorMsgOnce = (content) => {
+    if (showErrorModalFlag.value) {
+      Modal.error({
+        title: '提示',
+        content: content,
+        okType: 'danger',
+        centered: true,
+        onOk() {
+          showErrorModalFlag.value = true;
+        },
+      });
+      showErrorModalFlag.value = false;
+    }
+  };
+
+  function handleCancel() {
+    previewVisible.value = false;
   }
-};
 
-// ------------------------ 清空 上传 ------------------------
-function clear() {
-  fileList.value = [];
-}
+  const handlePreview = async (file) => {
+    if (imgFileType.some((e) => e === file.fileType)) {
+      previewUrl.value = file.url || file.preview;
+      previewVisible.value = true;
+    } else {
+      fileApi.downLoadFile(file.fileKey);
+    }
+  };
+
+  // ------------------------ 清空 上传 ------------------------
+  function clear() {
+    fileList.value = [];
+  }
 
-defineExpose({
-  clear,
-});
+  defineExpose({
+    clear,
+  });
 </script>
 <style lang="less" scoped>
-:deep(.ant-upload-picture-card-wrapper) {
-  display: flex;
-}
+  :deep(.ant-upload-picture-card-wrapper) {
+    display: flex;
+  }
 </style>