| | |
| | | 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;"> |
| | |
| | | <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> |
| | |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | limit: { |
| | | type: Number, |
| | | default: undefined, |
| | | }, |
| | | replaceOnExceed: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | autoUpload: { |
| | | type: Boolean, |
| | | default: true, |
| | |
| | | showFileList: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | disabled: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | buttonText: { |
| | | type: String, |
| | |
| | | type: Function, |
| | | default: null, |
| | | }, |
| | | onView: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | }); |
| | | |
| | | const emit = defineEmits([ |
| | |
| | | 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) => { |
| | |
| | | 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); |
| | | }; |