张诺
6 小时以前 5cfebd7e46c0c53f79b5fb4a917e926194ab4398
src/components/Upload/ActionFileUpload.vue
@@ -7,14 +7,17 @@
    ref="fileUploadRef"
    :auto-upload="autoUpload"
    :headers="headers"
    :limit="limit"
    :disabled="disabled"
    :before-upload="handleBeforeUpload"
    :on-exceed="handleExceed"
    :on-error="handleUploadError"
    :on-success="handleUploadSuccess"
    :on-remove="handleRemove"
    :on-preview="handlePreview"
    :show-file-list="showFileList"
  >
    <el-button type="primary">{{ buttonText }}</el-button>
    <el-button v-if="!disabled" type="primary">{{ buttonText }}</el-button>
    <template #file="{ file }">
      <div style="display:flex; align-items:center; gap: 10px; width: 100%;">
        <span style="flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
@@ -23,7 +26,7 @@
        <div style="display:flex; align-items:center; gap: 6px;">
          <el-button link type="success" :icon="Download" @click="handleDownload(file)" />
          <el-button link type="primary" :icon="View" @click="handlePreview(file)" />
          <el-button link type="danger" :icon="Delete" @click="triggerRemoveFile(file)" />
          <el-button link type="danger" :icon="Delete" @click="triggerRemoveFile(file)" v-if="onView" />
        </div>
      </div>
    </template>
@@ -60,6 +63,14 @@
    type: Boolean,
    default: true,
  },
  limit: {
    type: Number,
    default: undefined,
  },
  replaceOnExceed: {
    type: Boolean,
    default: false,
  },
  autoUpload: {
    type: Boolean,
    default: true,
@@ -67,6 +78,10 @@
  showFileList: {
    type: Boolean,
    default: true,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  buttonText: {
    type: String,
@@ -100,6 +115,10 @@
    type: Function,
    default: null,
  },
  onView: {
    type: Boolean,
    default: true,
  },
});
const emit = defineEmits([
@@ -118,8 +137,27 @@
  set: (val) => emit("update:fileList", val),
});
const resolveUrl = (url) => {
  const u = String(url || "");
  if (!u) return "";
  if (/^(https?:)?\/\//i.test(u)) return u;
  if (/^(blob:|data:)/i.test(u)) return u;
  const baseUrl = import.meta.env.VITE_APP_BASE_API || "";
  if (!baseUrl) return u;
  if (u.startsWith("/")) return baseUrl + u;
  return baseUrl + "/" + u;
};
const getFileUrl = (file) => {
  return file?.url || file?.response?.data?.tempPath || file?.response?.data?.url || "";
  const respData = file?.response?.data;
  const rawUrl =
    file?.url ||
    (Array.isArray(respData) ? respData?.[0]?.fileUrl : undefined) ||
    respData?.fileUrl ||
    respData?.tempPath ||
    respData?.url ||
    "";
  return resolveUrl(rawUrl);
};
const triggerRemoveFile = (file) => {
@@ -138,7 +176,31 @@
  emit("error", ...args);
};
const handleExceed = (files) => {
  if (!props.replaceOnExceed) return;
  if (props.limit !== 1) return;
  const file = files?.[0];
  if (!file) return;
  fileUploadRef.value?.clearFiles?.();
  innerFileList.value = [];
  fileUploadRef.value?.handleStart?.(file);
  if (props.autoUpload) {
    fileUploadRef.value?.submit?.();
  }
};
const handleUploadSuccess = (...args) => {
  const [response, uploadFile, uploadFiles] = args;
  if (uploadFile && !uploadFile.url) {
    const rawUrl = response?.data?.tempPath || response?.data?.url || response?.url || "";
    const resolvedUrl = resolveUrl(rawUrl);
    if (resolvedUrl) {
      uploadFile.url = resolvedUrl;
    }
  }
  if (props.limit === 1 && Array.isArray(uploadFiles) && uploadFiles.length) {
    innerFileList.value = [uploadFiles[uploadFiles.length - 1]];
  }
  props.onSuccess?.(...args);
  emit("success", ...args);
};