huangxw 6 kuukautta sitten
vanhempi
säilyke
60c236d4e2
1 muutettua tiedostoa jossa 178 lisäystä ja 168 poistoa
  1. 178 168
      src/components/FileUpload/index.vue

+ 178 - 168
src/components/FileUpload/index.vue

@@ -52,22 +52,22 @@ import { fileExt } from '@/utils/ruoyi';
 import { ImageViewer } from '@/views/models';
 
 const props = defineProps({
-  modelValue: [String, Object, Array],
-  // 数量限制
-  limit: propTypes.number.def(1),
-  // 大小限制(MB)
-  fileSize: propTypes.number.def(5),
-  // 文件类型, 例如['png', 'jpg', 'jpeg', 'bmp']
-  fileType: propTypes.array.def(['doc', 'xls', 'ppt', 'txt', 'pdf']),
-  // 是否显示提示
-  isShowTip: propTypes.bool.def(true),
-  tipText: propTypes.string.def(''),
-  span: propTypes.number.def(24),
-  multiple: propTypes.bool.def(true),
-  white: propTypes.bool.def(false),
-  // 上传数据格式
-  format: propTypes.string.def('id'),
-  btnText: propTypes.string.def('上传文件')
+    modelValue: [String, Object, Array],
+    // 数量限制
+    limit: propTypes.number.def(1),
+    // 大小限制(MB)
+    fileSize: propTypes.number.def(5),
+    // 文件类型, 例如['png', 'jpg', 'jpeg', 'bmp']
+    fileType: propTypes.array.def(['doc', 'xls', 'ppt', 'txt', 'pdf', 'xlsx', 'docx', 'pptx', 'DOCX', 'DOC', 'PPTX', 'PPT']),
+    // 是否显示提示
+    isShowTip: propTypes.bool.def(true),
+    tipText: propTypes.string.def(''),
+    span: propTypes.number.def(24),
+    multiple: propTypes.bool.def(true),
+    white: propTypes.bool.def(false),
+    // 上传数据格式
+    format: propTypes.string.def('id'),
+    btnText: propTypes.string.def('上传文件')
 });
 const loading = ref(false);
 const lookIndex = ref(0);
@@ -86,208 +86,218 @@ const showTip = computed(() => props.isShowTip && (props.fileType || props.fileS
 
 const fileUploadRef = ref<ElUploadInstance>();
 const progressList = ref<any>([]);
+const formatValue = ref(props.format);
 watch(
-  () => props.modelValue,
-  async (val: any) => {
-      if (val) {
-          let temp = 1;
-          // 首先将值转为数组
-          let list = [];
-           if (props.format === 'array' && Array.isArray(val)) {
-              list = val;
-           } else if (props.format === 'object') {
-              list = [{
-                    name: val.fileName,
-                    url: val.url,
-                    fileSize: val.fileSize,
-                    fileType: val.fileType,
-                    ossId: val.ossId
-              }];
-          } else {
-              const res = await listByIds(val as string);
-              list = res.data.map((oss) => {
-                  const data = { name: oss.originalName, url: oss.url, ossId: oss.ossId };
-                  return data;
-              });
-          }
-          // 然后将数组转为对象数组
-          fileList.value = list.map((item) => {
-              item = { name: item.fileName ? item.fileName : item.name, url: item.url, fileSize: item.fileSize, fileType: item.fileType };
-              item.uid = item.uid || new Date().getTime() + temp++;
-              return item;
-          });
-      } else {
-          fileList.value = [];
-          return [];
-      }
-  },
-  { deep: true, immediate: true }
+    () => props.modelValue,
+    async (val: any) => {
+        if (val) {
+            let temp = 1;
+            // 首先将值转为数组
+            let list = [];
+            if (props.format === 'array' || Array.isArray(val)) {
+                formatValue.value = 'object';
+                list = val;
+            } else if (props.format === 'object' || typeof val === 'object') {
+                formatValue.value = 'object';
+                list = [
+                    {
+                        name: val.fileName,
+                        url: val.url,
+                        fileSize: val.fileSize,
+                        fileType: val.fileType,
+                        ossId: val.ossId
+                    }
+                ];
+            } else {
+                // 是否http开头
+                formatValue.value = 'id';
+                const res = await listByIds(val as string);
+                list = res.data.map((oss) => {
+                    const data = { name: oss.originalName, url: oss.url, ossId: oss.ossId };
+                    return data;
+                });
+            }
+            // 然后将数组转为对象数组
+            fileList.value = list.map((item) => {
+                item = { name: item.fileName ? item.fileName : item.name, url: item.url, fileSize: item.fileSize, fileType: item.fileType };
+                item.uid = item.uid || new Date().getTime() + temp++;
+                return item;
+            });
+        } else {
+            fileList.value = [];
+            return [];
+        }
+    },
+    { deep: true, immediate: true }
 );
 
 // 上传前校检格式和大小
 const handleBeforeUpload = (file: any) => {
-  // 校检文件类型
-  if (props.fileType.length) {
-      loading.value = true;
-      const fileName = file.name.split('.');
-      const fileExt = fileName[fileName.length - 1];
-      const isTypeOk = props.fileType.indexOf(fileExt) >= 0;
-      if (!isTypeOk) {
-          proxy?.$modal.msgError(`文件格式不正确, 请上传${props.fileType.join('/')}格式文件!`);
-          loading.value = false;
-          return false;
-      }
-  }
-  // 校检文件大小
-  if (props.fileSize) {
-      const isLt = file.size / 1024 / 1024 < props.fileSize;
-      if (!isLt) {
-          loading.value = false;
-          proxy?.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
-          return false;
-      }
-  }
-  number.value++;
-  return true;
+    // 校检文件类型
+    if (props.fileType.length) {
+        loading.value = true;
+        const fileName = file.name.split('.');
+        const fileExt = fileName[fileName.length - 1];
+        const isTypeOk = props.fileType.indexOf(fileExt) >= 0;
+        if (!isTypeOk) {
+            proxy?.$modal.msgError(`文件格式不正确, 请上传${props.fileType.join('/')}格式文件!`);
+            loading.value = false;
+            return false;
+        }
+    }
+    // 校检文件大小
+    if (props.fileSize) {
+        const isLt = file.size / 1024 / 1024 < props.fileSize;
+        if (!isLt) {
+            loading.value = false;
+            proxy?.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
+            return false;
+        }
+    }
+    number.value++;
+    return true;
 };
 
 // 文件个数超出
 const handleExceed = () => {
-  proxy?.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
+    proxy?.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
 };
 
 // 上传失败
 const handleUploadError = () => {
-  loading.value = false;
-  proxy?.$modal.msgError('上传文件失败');
+    loading.value = false;
+    proxy?.$modal.msgError('上传文件失败');
 };
 
 // 上传成功回调
 const handleUploadSuccess = (res: any, file: UploadFile) => {
-  loading.value = false;
-  if (res.code === 200) {
-      uploadList.value.push({
-          name: res.data.fileName,
-          url: res.data.url,
-          ossId: res.data.ossId,
-          fileSize: file?.raw.size,
-          fileType: file?.raw.type
-      });
-      uploadedSuccessfully();
-  } else {
-      number.value--;
-      proxy?.$modal.msgError(res.msg);
-      fileUploadRef.value?.handleRemove(file);
-      uploadedSuccessfully();
-  }
+    loading.value = false;
+    if (res.code === 200) {
+        uploadList.value.push({
+            name: res.data.fileName,
+            url: res.data.url,
+            ossId: res.data.ossId,
+            fileSize: file?.raw.size,
+            fileType: file?.raw.type
+        });
+        uploadedSuccessfully();
+    } else {
+        number.value--;
+        proxy?.$modal.msgError(res.msg);
+        fileUploadRef.value?.handleRemove(file);
+        uploadedSuccessfully();
+    }
 };
 
 // 上传结束处理
 const uploadedSuccessfully = () => {
-  if (number.value > 0 && uploadList.value.length === number.value) {
-      fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value);
-      uploadList.value = [];
-      number.value = 0;
-      const valuef = fileList.value.map(({ name, url, fileType, fileSize, ossId }) => ({ fileName: name, url, fileSize, fileType, ossId }));
-      if (props.format === 'id') {
-         emit('change', listToString(valuef));
-         emit('update:modelValue', listToString(valuef));
-      } else if (props.format === 'object') {
-          emit('change', valuef[0])
-          emit('update:modelValue', valuef[0]);
-      } else {
-          emit('change', valuef)
-          emit('update:modelValue', valuef);
-      }
-  }
+    if (number.value > 0 && uploadList.value.length === number.value) {
+        fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value);
+        uploadList.value = [];
+        number.value = 0;
+        const valuef = fileList.value.map(({ name, url, fileType, fileSize, ossId }) => ({ fileName: name, url, fileSize, fileType, ossId }));
+        if (formatValue.value === 'id') {
+            emit('change', listToString(valuef));
+            emit('update:modelValue', listToString(valuef));
+        } else if (formatValue.value === 'object') {
+            emit('change', valuef[0]);
+            emit('update:modelValue', valuef[0]);
+        } else {
+            emit('change', valuef);
+            emit('update:modelValue', valuef);
+        }
+    }
 };
 const handleOnProgress = (event: any, file: any, list: any) => {
-  const progress = Math.round((event.loaded / event.total) * 100);
-  fileList.value = [...list];
+    const progress = Math.round((event.loaded / event.total) * 100);
+    fileList.value = [...list];
 };
 // 删除文件
 const handleDelete = (index: number) => {
-  fileUploadRef.value?.abort(fileList.value[index]);
-  fileList.value.splice(index, 1);
-  const valuef = fileList.value.map(({ name, url, fileType, fileSize }) => ({ fileName: name, url, fileSize, fileType }));
-  if (props.format === 'object') {
-      emit('change', null)
-      emit('update:modelValue', null);
-  } else {
-      emit('change', valuef)
-      emit('update:modelValue', valuef);
-  }
-  loading.value = false;
+    fileUploadRef.value?.abort(fileList.value[index]);
+    fileList.value.splice(index, 1);
+    const valuef = fileList.value.map(({ name, url, fileType, fileSize }) => ({ fileName: name, url, fileSize, fileType }));
+    if (formatValue.value === 'id') {
+        emit('change', listToString(valuef));
+        emit('update:modelValue', listToString(valuef));
+    } else if (formatValue.value === 'object') {
+        emit('change', null);
+        emit('update:modelValue', null);
+    } else {
+        emit('change', valuef);
+        emit('update:modelValue', valuef);
+    }
+    loading.value = false;
 };
 // 获取文件名称
 const getFileName = (name: string) => {
-  // 如果是url那么取最后的名字 如果不是直接返回
-  if (name.lastIndexOf('/') > -1) {
-      return name.slice(name.lastIndexOf('/') + 1);
-  } else {
-      return name;
-  }
+    // 如果是url那么取最后的名字 如果不是直接返回
+    if (name.lastIndexOf('/') > -1) {
+        return name.slice(name.lastIndexOf('/') + 1);
+    } else {
+        return name;
+    }
 };
 
 // 对象转成指定字符串分隔
 const listToString = (list: any[], separator?: string) => {
-  let strs = '';
-  separator = separator || ',';
-  list.forEach((item) => {
-      if (item.ossId) {
-          strs += item.ossId + separator;
-      }
-  });
-  return strs != '' ? strs.substring(0, strs.length - 1) : '';
+    let strs = '';
+    separator = separator || ',';
+    list.forEach((item) => {
+        if (item.ossId) {
+            strs += item.ossId + separator;
+        }
+    });
+    return strs != '' ? strs.substring(0, strs.length - 1) : '';
 };
 </script>
 
 <style scoped lang="scss">
 .btn-file {
-  width: 90px;
-  height: 40px;
-  line-height: 40px;
-  border-radius: 8px;
-  color: #666;
-  text-align: center;
-  background-color: #f7f7f7;
+    width: 90px;
+    height: 40px;
+    line-height: 40px;
+    border-radius: 8px;
+    color: #666;
+    text-align: center;
+    background-color: #f7f7f7;
 }
 .upload-list-img {
-  background-color: #f7f7f7;
-  border-radius: 8px;
+    background-color: #f7f7f7;
+    border-radius: 8px;
 
-  &.mt10 {
-      margin-top: 10px;
-  }
+    &.mt10 {
+        margin-top: 10px;
+    }
 }
 .right-item {
-  padding: 10px 16px;
-  cursor: pointer;
-  &:hover {
-      color: var(--el-color-primary);
-  }
+    padding: 10px 16px;
+    cursor: pointer;
+    &:hover {
+        color: var(--el-color-primary);
+    }
 }
 .delete-item {
-  width: 40px;
-  cursor: pointer;
+    width: 40px;
+    cursor: pointer;
 }
 .upload-file-list.white {
-  .btn-file {
-      background-color: #fff;
-  }
-  .upload-list-img {
-      background-color: #fff;
-  }
+    .btn-file {
+        background-color: #fff;
+    }
+    .upload-list-img {
+        background-color: #fff;
+    }
 }
 .right-wrap {
-  padding: 6px 10px;
-  box-sizing: border-box;
+    padding: 6px 10px;
+    box-sizing: border-box;
 }
 .progress {
-  position: absolute;
-  left: 0;
-  bottom: 0;
-  height: 1px;
-  background-color: var(--el-color-primary);
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    height: 1px;
+    background-color: var(--el-color-primary);
 }
 </style>