|
|
@@ -1,6 +1,7 @@
|
|
|
<template>
|
|
|
<div class="upload-file">
|
|
|
<el-upload
|
|
|
+ ref="upload"
|
|
|
class="upload-demo"
|
|
|
action="#"
|
|
|
:disabled="disabled || loading"
|
|
|
@@ -39,10 +40,7 @@
|
|
|
class="progress-item"
|
|
|
>
|
|
|
<div class="file-name">{{ fileNameMap[fileId] }}</div>
|
|
|
- <el-progress
|
|
|
- :percentage="progress"
|
|
|
- :stroke-width="6"
|
|
|
- ></el-progress>
|
|
|
+ <el-progress :percentage="progress" :stroke-width="6"></el-progress>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -89,6 +87,11 @@
|
|
|
disabled: {
|
|
|
default: false,
|
|
|
type: Boolean
|
|
|
+ },
|
|
|
+ // 上传前拦截钩子:返回 false 取消上传;返回 Promise<boolean> 异步判断(resolve(false) 取消)
|
|
|
+ beforeUploadFile: {
|
|
|
+ type: Function,
|
|
|
+ default: null
|
|
|
}
|
|
|
},
|
|
|
data() {
|
|
|
@@ -221,46 +224,91 @@
|
|
|
|
|
|
if (this.limit > 0 && this.fileList.length === this.limit) {
|
|
|
this.$message.error(`最多上传 ${this.limit}个文件`);
|
|
|
+ this._removeCanceledFile(file);
|
|
|
return false;
|
|
|
}
|
|
|
+ // 父组件可在上传前异步拦截(如查重)
|
|
|
+ if (this.beforeUploadFile) {
|
|
|
+ const result = this.beforeUploadFile(file);
|
|
|
+ if (result === false) {
|
|
|
+ this._removeCanceledFile(file);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (result && typeof result.then === 'function') {
|
|
|
+ return result.then((allowed) => {
|
|
|
+ if (allowed === false) {
|
|
|
+ this._removeCanceledFile(file);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return this._doUpload(file);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return this._doUpload(file);
|
|
|
+ },
|
|
|
+ // 取消上传时清理进度条;file-list 由 el-upload 自己从内部 uploadFiles 移除
|
|
|
+ _removeCanceledFile(file) {
|
|
|
+ const fileId = file.uid;
|
|
|
+ if (
|
|
|
+ fileId !== undefined &&
|
|
|
+ this.fileProgressMap[fileId] !== undefined
|
|
|
+ ) {
|
|
|
+ this.$delete(this.fileProgressMap, fileId);
|
|
|
+ this.$delete(this.fileNameMap, fileId);
|
|
|
+ if (Object.keys(this.fileProgressMap).length === 0) {
|
|
|
+ this.loading = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // el-upload 的 handleStart 在 beforeUpload 之前就把文件塞进 uploadFiles,
|
|
|
+ // 即便 beforeUpload 返回 false 也不会自动清掉;这里手动清掉,否则 display 还会显示
|
|
|
+ const upload = this.$refs.upload;
|
|
|
+ if (upload && Array.isArray(upload.uploadFiles)) {
|
|
|
+ const idx = upload.uploadFiles.findIndex((f) => f.uid === fileId);
|
|
|
+ if (idx !== -1) {
|
|
|
+ upload.uploadFiles.splice(idx, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async _doUpload(file) {
|
|
|
const fileId = file.uid || Date.now();
|
|
|
this.loading = true;
|
|
|
this.$set(this.fileProgressMap, fileId, 0);
|
|
|
this.$set(this.fileNameMap, fileId, file.name);
|
|
|
- return uploadFileNew(
|
|
|
- {
|
|
|
- module: this.module,
|
|
|
- multiPartFile: file
|
|
|
- },
|
|
|
- {
|
|
|
- onUploadProgress: (progressEvent) => {
|
|
|
- if (progressEvent.total) {
|
|
|
- this.$set(
|
|
|
- this.fileProgressMap,
|
|
|
- fileId,
|
|
|
- Math.round((progressEvent.loaded * 100) / progressEvent.total)
|
|
|
- );
|
|
|
+ try {
|
|
|
+ const res = await uploadFileNew(
|
|
|
+ {
|
|
|
+ module: this.module,
|
|
|
+ multiPartFile: file
|
|
|
+ },
|
|
|
+ {
|
|
|
+ onUploadProgress: (progressEvent) => {
|
|
|
+ if (progressEvent.total) {
|
|
|
+ this.$set(
|
|
|
+ this.fileProgressMap,
|
|
|
+ fileId,
|
|
|
+ Math.round(
|
|
|
+ (progressEvent.loaded * 100) / progressEvent.total
|
|
|
+ )
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ );
|
|
|
+ if (res.data) {
|
|
|
+ this.$emit('input', [
|
|
|
+ ...(this.value || []),
|
|
|
+ { ...file, url: res.data.storePath, ...res.data }
|
|
|
+ ]);
|
|
|
}
|
|
|
- )
|
|
|
- .then((res) => {
|
|
|
- if (res.data) {
|
|
|
- this.$emit('input', [
|
|
|
- ...(this.value || []),
|
|
|
- { ...file, url: res.data.storePath, ...res.data }
|
|
|
- ]);
|
|
|
- }
|
|
|
- this.$emit('fileChange', res.data);
|
|
|
- return res.data;
|
|
|
- })
|
|
|
- .finally(() => {
|
|
|
- this.$delete(this.fileProgressMap, fileId);
|
|
|
- this.$delete(this.fileNameMap, fileId);
|
|
|
- if (Object.keys(this.fileProgressMap).length === 0) {
|
|
|
- this.loading = false;
|
|
|
- }
|
|
|
- });
|
|
|
+ this.$emit('fileChange', res.data);
|
|
|
+ return res.data;
|
|
|
+ } finally {
|
|
|
+ this.$delete(this.fileProgressMap, fileId);
|
|
|
+ this.$delete(this.fileNameMap, fileId);
|
|
|
+ if (Object.keys(this.fileProgressMap).length === 0) {
|
|
|
+ this.loading = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
},
|
|
|
handlRequest() {
|
|
|
return Promise.resolve();
|