|
@@ -1,31 +1,28 @@
|
|
|
<template>
|
|
|
- <div class="file-upload">
|
|
|
- <el-upload
|
|
|
- ref="uploadRef"
|
|
|
- :action="uploadUrl"
|
|
|
- :headers="headers"
|
|
|
- :data="uploadDataDict"
|
|
|
- :show-file-list="false"
|
|
|
- :auto-upload="autoUpload"
|
|
|
- :http-request="customRequest"
|
|
|
- :disabled="disabled"
|
|
|
- :before-upload="handleBeforeUpload"
|
|
|
- :accept="accept"
|
|
|
- :multiple="multiple"
|
|
|
- :on-exceed="handleExceededSize"
|
|
|
- @change="handleFileChange"
|
|
|
- @error="handleError"
|
|
|
- @success="handleSuccess"
|
|
|
- >
|
|
|
- <template #trigger>
|
|
|
- <el-button type="primary" :disabled="loading">{{ btnText }}</el-button>
|
|
|
- </template>
|
|
|
- </el-upload>
|
|
|
- </div>
|
|
|
+ <el-upload
|
|
|
+ ref="uploadRef"
|
|
|
+ :action="uploadUrl"
|
|
|
+ :headers="headers"
|
|
|
+ :data="uploadDataDict"
|
|
|
+ :show-file-list="false"
|
|
|
+ :http-request="customRequest"
|
|
|
+ :disabled="disabled"
|
|
|
+ :before-upload="handleBeforeUpload"
|
|
|
+ :accept="accept"
|
|
|
+ :multiple="multiple"
|
|
|
+ :on-exceed="handleExceededSize"
|
|
|
+ @change="handleFileChange"
|
|
|
+ @error="handleError"
|
|
|
+ @success="handleSuccess"
|
|
|
+ >
|
|
|
+ <template #trigger>
|
|
|
+ <el-button type="primary" :disabled="loading">{{ btnText }}</el-button>
|
|
|
+ </template>
|
|
|
+ </el-upload>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
- import { ref } from 'vue';
|
|
|
+ import { ref, computed } from 'vue';
|
|
|
import { fileMD5 } from '@/utils/md5';
|
|
|
import { ElMessage } from 'element-plus';
|
|
|
import type {
|
|
@@ -50,7 +47,7 @@
|
|
|
autoUpload?: boolean;
|
|
|
disabled?: boolean;
|
|
|
btnText?: string;
|
|
|
- accept?: string;
|
|
|
+ format?: string[];
|
|
|
multiple?: boolean;
|
|
|
}>(),
|
|
|
{
|
|
@@ -58,12 +55,12 @@
|
|
|
uploadData: () => {
|
|
|
return {};
|
|
|
},
|
|
|
+ format: () => ['xls', 'xlsx'],
|
|
|
maxSize: 20 * 1024 * 1024,
|
|
|
uploadFileAlias: 'file',
|
|
|
autoUpload: true,
|
|
|
disabled: false,
|
|
|
btnText: '选择',
|
|
|
- accept: '.xls,.xlsx',
|
|
|
multiple: false,
|
|
|
}
|
|
|
);
|
|
@@ -73,6 +70,7 @@
|
|
|
'uploadError',
|
|
|
'uploadSuccess',
|
|
|
'validError',
|
|
|
+ 'fileReady',
|
|
|
]);
|
|
|
|
|
|
const uploadRef = ref();
|
|
@@ -82,6 +80,15 @@
|
|
|
const result = ref({ success: true, message: '' });
|
|
|
const loading = ref(false);
|
|
|
|
|
|
+ const accept = computed(() => {
|
|
|
+ return props.format.map((el) => `.${el}`).join();
|
|
|
+ });
|
|
|
+
|
|
|
+ function checkFileFormat(fileType: string) {
|
|
|
+ const fileFormat = fileType.split('.').pop()?.toLocaleLowerCase();
|
|
|
+ return props.format.some((item) => item.toLocaleLowerCase() === fileFormat);
|
|
|
+ }
|
|
|
+
|
|
|
function handleFileChange(uploadFile: UploadFile, uploadFiles: UploadFiles) {
|
|
|
if (props.autoUpload || !uploadFiles.length) return;
|
|
|
// Element Plus's status: ready, uploading, success, fail
|
|
@@ -90,35 +97,38 @@
|
|
|
canUpload.value = uploadFiles[0]?.status === 'ready';
|
|
|
}
|
|
|
|
|
|
- async function handleBeforeUpload(rawFile: UploadRawFile) {
|
|
|
+ async function handleBeforeUpload(file: UploadRawFile) {
|
|
|
uploadDataDict.value = {
|
|
|
...props.uploadData,
|
|
|
- filename: rawFile.name,
|
|
|
+ filename: file.name,
|
|
|
};
|
|
|
|
|
|
- if (rawFile.size > props.maxSize) {
|
|
|
- // Element Plus uses on-exceed for this, but we can also check here
|
|
|
- // For consistency with original logic, we call handleExceededSize and reject
|
|
|
- // However, on-exceed will also be triggered if :limit is set for file count, not size directly.
|
|
|
- // Here, we manually trigger the message and prevent upload.
|
|
|
- const content = `文件大小不能超过${Math.floor(
|
|
|
- props.maxSize / 1024 / 1024
|
|
|
- )}MB`;
|
|
|
- ElMessage.error(content);
|
|
|
- result.value = {
|
|
|
- success: false,
|
|
|
- message: content,
|
|
|
- };
|
|
|
- emit('validError', result.value);
|
|
|
- return Promise.reject(new Error(content));
|
|
|
+ if (file.size > props.maxSize) {
|
|
|
+ handleExceededSize();
|
|
|
+ return Promise.reject(result.value);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!checkFileFormat(file.name)) {
|
|
|
+ handleFormatError();
|
|
|
+ return Promise.reject(result.value);
|
|
|
}
|
|
|
|
|
|
- const md5 = await fileMD5(rawFile);
|
|
|
+ const md5 = await fileMD5(file);
|
|
|
headers.value.md5 = md5;
|
|
|
|
|
|
- if (props.autoUpload) loading.value = true;
|
|
|
+ if (!props.autoUpload) {
|
|
|
+ console.log('111');
|
|
|
|
|
|
- return true;
|
|
|
+ emit('fileReady', {
|
|
|
+ md5,
|
|
|
+ filename: file.name,
|
|
|
+ file,
|
|
|
+ });
|
|
|
+ return Promise.reject();
|
|
|
+ }
|
|
|
+
|
|
|
+ loading.value = true;
|
|
|
+ return Promise.resolve();
|
|
|
}
|
|
|
|
|
|
function customRequest(options: UploadRequestOptions) {
|
|
@@ -168,13 +178,8 @@
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- function handleExceededSize(files: File[]) {
|
|
|
- // This function is now primarily called by el-upload's on-exceed prop
|
|
|
- // The before-upload also has a check, this is a fallback or for multiple files if `limit` (count) is exceeded.
|
|
|
- const file = files[0]; // Assuming single file upload context for this message
|
|
|
- const content = `文件 ${file.name} 大小超过限制 (${Math.floor(
|
|
|
- props.maxSize / 1024 / 1024
|
|
|
- )}MB)`;
|
|
|
+ function handleFormatError() {
|
|
|
+ const content = `只支持文件格式为${props.format.join('/')}`;
|
|
|
result.value = {
|
|
|
success: false,
|
|
|
message: content,
|
|
@@ -183,24 +188,16 @@
|
|
|
ElMessage.error(content);
|
|
|
emit('validError', result.value);
|
|
|
}
|
|
|
-</script>
|
|
|
-
|
|
|
-<style lang="scss">
|
|
|
- .file-upload {
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- align-items: center;
|
|
|
- width: 100%;
|
|
|
- .arco-upload-hide {
|
|
|
- display: inline-block;
|
|
|
- }
|
|
|
- .el-input__wrapper {
|
|
|
- flex-grow: 2;
|
|
|
- margin-right: 10px;
|
|
|
- }
|
|
|
- .arco-upload {
|
|
|
- flex-grow: 0;
|
|
|
- flex-shrink: 0;
|
|
|
- }
|
|
|
+ function handleExceededSize() {
|
|
|
+ const content = `文件大小不能超过${Math.floor(
|
|
|
+ props.maxSize / (1024 * 1024)
|
|
|
+ )}M`;
|
|
|
+ result.value = {
|
|
|
+ success: false,
|
|
|
+ message: content,
|
|
|
+ };
|
|
|
+ loading.value = false;
|
|
|
+ ElMessage.error(content);
|
|
|
+ emit('validError', result.value);
|
|
|
}
|
|
|
-</style>
|
|
|
+</script>
|