@sl-material/sl-import 1.0.0-beta0 → 1.0.0-beta10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -8
- package/index.d.ts +13 -1
- package/package.json +1 -1
- package/sl-import.cjs.js +1 -1
- package/sl-import.es.js +340 -196
- package/sl-import.umd.umd.js +32 -32
package/sl-import.es.js
CHANGED
|
@@ -2192,7 +2192,7 @@ const zhCN = {
|
|
|
2192
2192
|
selectDate: "选择日期",
|
|
2193
2193
|
// 上传部分
|
|
2194
2194
|
uploadTitle: "3.上传文件",
|
|
2195
|
-
dragFileHere: "
|
|
2195
|
+
dragFileHere: "将文件拖到此处,",
|
|
2196
2196
|
or: "或",
|
|
2197
2197
|
uploadLinkText: "点击上传",
|
|
2198
2198
|
uploadHint: "文件仅支持扩展名:.xls,.xlsx",
|
|
@@ -2278,7 +2278,7 @@ const zhTW = {
|
|
|
2278
2278
|
selectDate: "選擇日期",
|
|
2279
2279
|
// 上傳部分
|
|
2280
2280
|
uploadTitle: "3.上傳檔案",
|
|
2281
|
-
dragFileHere: "
|
|
2281
|
+
dragFileHere: "將檔案拖到此處,",
|
|
2282
2282
|
or: "或",
|
|
2283
2283
|
uploadLinkText: "點擊上傳",
|
|
2284
2284
|
uploadHint: "檔案僅支援副檔名:.xls,.xlsx",
|
|
@@ -2364,7 +2364,7 @@ const ja = {
|
|
|
2364
2364
|
selectDate: "日付を選択",
|
|
2365
2365
|
// アップロード部分
|
|
2366
2366
|
uploadTitle: "3.ファイルをアップロード",
|
|
2367
|
-
dragFileHere: "
|
|
2367
|
+
dragFileHere: "ファイルをここにドラッグ、",
|
|
2368
2368
|
or: "または",
|
|
2369
2369
|
uploadLinkText: "クリックしてアップロード",
|
|
2370
2370
|
uploadHint: "ファイルは拡張子のみサポート:.xls,.xlsx",
|
|
@@ -2450,7 +2450,7 @@ const id = {
|
|
|
2450
2450
|
selectDate: "Pilih Tanggal",
|
|
2451
2451
|
// Bagian unggah
|
|
2452
2452
|
uploadTitle: "3. Unggah File",
|
|
2453
|
-
dragFileHere: "Seret file di sini,
|
|
2453
|
+
dragFileHere: "Seret file di sini, ",
|
|
2454
2454
|
or: "atau",
|
|
2455
2455
|
uploadLinkText: "klik untuk mengunggah",
|
|
2456
2456
|
uploadHint: "Hanya mendukung ekstensi file: .xls,.xlsx",
|
|
@@ -2536,7 +2536,7 @@ const enUS = {
|
|
|
2536
2536
|
selectDate: "Select Date",
|
|
2537
2537
|
// 上传部分
|
|
2538
2538
|
uploadTitle: "3. Upload File",
|
|
2539
|
-
dragFileHere: "Drag files here,
|
|
2539
|
+
dragFileHere: "Drag files here, ",
|
|
2540
2540
|
or: "or",
|
|
2541
2541
|
uploadLinkText: "click to upload",
|
|
2542
2542
|
uploadHint: "Supports batch import, file size not exceeding 10MB",
|
|
@@ -2956,6 +2956,214 @@ class ImportDialogRenderer {
|
|
|
2956
2956
|
`;
|
|
2957
2957
|
}
|
|
2958
2958
|
}
|
|
2959
|
+
class ChunkedUploader {
|
|
2960
|
+
constructor(chunkedConfig, callbacks = {}) {
|
|
2961
|
+
__publicField(this, "resumable");
|
|
2962
|
+
__publicField(this, "currentFileItem", null);
|
|
2963
|
+
__publicField(this, "chunkedConfig");
|
|
2964
|
+
__publicField(this, "callbacks");
|
|
2965
|
+
// Promise resolve/reject 函数存储
|
|
2966
|
+
__publicField(this, "uploadCompleteResolve");
|
|
2967
|
+
__publicField(this, "uploadCompleteReject");
|
|
2968
|
+
this.chunkedConfig = chunkedConfig;
|
|
2969
|
+
this.callbacks = callbacks;
|
|
2970
|
+
}
|
|
2971
|
+
/**
|
|
2972
|
+
* 上传单个文件(分片方式)
|
|
2973
|
+
*/
|
|
2974
|
+
async upload(fileItem) {
|
|
2975
|
+
try {
|
|
2976
|
+
const initResult = await this.chunkedConfig.initUpload(
|
|
2977
|
+
fileItem.file.name,
|
|
2978
|
+
fileItem.file.size
|
|
2979
|
+
);
|
|
2980
|
+
fileItem.uploadSessionId = initResult.uploadSessionId;
|
|
2981
|
+
this.currentFileItem = fileItem;
|
|
2982
|
+
this.initResumable(initResult);
|
|
2983
|
+
this.resumable.addFile(fileItem.file);
|
|
2984
|
+
return await this.waitForUploadComplete();
|
|
2985
|
+
} catch (error) {
|
|
2986
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
2987
|
+
throw err;
|
|
2988
|
+
}
|
|
2989
|
+
}
|
|
2990
|
+
/**
|
|
2991
|
+
* 等待上传完成
|
|
2992
|
+
*/
|
|
2993
|
+
waitForUploadComplete() {
|
|
2994
|
+
return new Promise((resolve, reject) => {
|
|
2995
|
+
this.uploadCompleteResolve = resolve;
|
|
2996
|
+
this.uploadCompleteReject = reject;
|
|
2997
|
+
});
|
|
2998
|
+
}
|
|
2999
|
+
/**
|
|
3000
|
+
* 初始化Resumable实例
|
|
3001
|
+
*/
|
|
3002
|
+
initResumable(initResult) {
|
|
3003
|
+
if (this.resumable) {
|
|
3004
|
+
this.resumable.cancel();
|
|
3005
|
+
}
|
|
3006
|
+
const customConfig = this.chunkedConfig.getResumableConfig(initResult);
|
|
3007
|
+
const defaultConfig = {
|
|
3008
|
+
chunkSize: initResult.partSize,
|
|
3009
|
+
simultaneousUploads: 3,
|
|
3010
|
+
testChunks: false,
|
|
3011
|
+
method: "multipart",
|
|
3012
|
+
chunkNumberParameterName: "partNumber",
|
|
3013
|
+
totalChunksParameterName: "totalParts",
|
|
3014
|
+
fileParameterName: "file",
|
|
3015
|
+
withCredentials: true,
|
|
3016
|
+
maxChunkRetries: 3,
|
|
3017
|
+
chunkRetryInterval: 1e3,
|
|
3018
|
+
forceChunkSize: true
|
|
3019
|
+
};
|
|
3020
|
+
const finalConfig = { ...defaultConfig, ...customConfig };
|
|
3021
|
+
this.resumable = new Resumable(finalConfig);
|
|
3022
|
+
this.bindResumableEvents();
|
|
3023
|
+
}
|
|
3024
|
+
/**
|
|
3025
|
+
* 绑定Resumable事件监听器
|
|
3026
|
+
*/
|
|
3027
|
+
bindResumableEvents() {
|
|
3028
|
+
this.resumable.on("progress", () => {
|
|
3029
|
+
var _a, _b, _c, _d;
|
|
3030
|
+
const progress = Math.floor(this.resumable.progress() * 100);
|
|
3031
|
+
if (this.currentFileItem) {
|
|
3032
|
+
this.currentFileItem.progress = Math.min(progress, 90);
|
|
3033
|
+
(_b = (_a = this.callbacks).onProgress) == null ? void 0 : _b.call(
|
|
3034
|
+
_a,
|
|
3035
|
+
this.currentFileItem,
|
|
3036
|
+
this.currentFileItem.progress
|
|
3037
|
+
);
|
|
3038
|
+
}
|
|
3039
|
+
(_d = (_c = this.callbacks).onUpdate) == null ? void 0 : _d.call(_c);
|
|
3040
|
+
});
|
|
3041
|
+
this.resumable.on("fileSuccess", () => {
|
|
3042
|
+
this.handleResumableComplete();
|
|
3043
|
+
});
|
|
3044
|
+
this.resumable.on("error", (message) => {
|
|
3045
|
+
console.error("[ChunkedUploader] 上传错误:", message);
|
|
3046
|
+
this.handleResumableError(message);
|
|
3047
|
+
});
|
|
3048
|
+
this.resumable.on("fileAdded", () => {
|
|
3049
|
+
this.resumable.upload();
|
|
3050
|
+
});
|
|
3051
|
+
}
|
|
3052
|
+
/**
|
|
3053
|
+
* 处理Resumable上传完成
|
|
3054
|
+
*/
|
|
3055
|
+
async handleResumableComplete() {
|
|
3056
|
+
if (!this.currentFileItem || !this.uploadCompleteResolve || !this.uploadCompleteReject) {
|
|
3057
|
+
return;
|
|
3058
|
+
}
|
|
3059
|
+
try {
|
|
3060
|
+
const mergeResult = await this.chunkedConfig.mergeChunks(
|
|
3061
|
+
this.currentFileItem.uploadSessionId
|
|
3062
|
+
);
|
|
3063
|
+
if (this.currentFileItem) {
|
|
3064
|
+
this.currentFileItem.progress = 100;
|
|
3065
|
+
}
|
|
3066
|
+
this.uploadCompleteResolve(mergeResult);
|
|
3067
|
+
this.cleanup();
|
|
3068
|
+
} catch (error) {
|
|
3069
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
3070
|
+
this.handleResumableError(err.message);
|
|
3071
|
+
}
|
|
3072
|
+
}
|
|
3073
|
+
/**
|
|
3074
|
+
* 处理Resumable上传错误
|
|
3075
|
+
*/
|
|
3076
|
+
handleResumableError(message) {
|
|
3077
|
+
var _a, _b;
|
|
3078
|
+
if (this.currentFileItem) {
|
|
3079
|
+
this.currentFileItem.status = "error";
|
|
3080
|
+
this.currentFileItem.errorMessage = message;
|
|
3081
|
+
}
|
|
3082
|
+
if (this.uploadCompleteReject) {
|
|
3083
|
+
this.uploadCompleteReject(new Error(message));
|
|
3084
|
+
this.cleanup();
|
|
3085
|
+
}
|
|
3086
|
+
(_b = (_a = this.callbacks).onUpdate) == null ? void 0 : _b.call(_a);
|
|
3087
|
+
}
|
|
3088
|
+
/**
|
|
3089
|
+
* 清理状态
|
|
3090
|
+
*/
|
|
3091
|
+
cleanup() {
|
|
3092
|
+
this.uploadCompleteResolve = void 0;
|
|
3093
|
+
this.uploadCompleteReject = void 0;
|
|
3094
|
+
}
|
|
3095
|
+
/**
|
|
3096
|
+
* 暂停上传
|
|
3097
|
+
*/
|
|
3098
|
+
pause() {
|
|
3099
|
+
if (this.resumable) {
|
|
3100
|
+
this.resumable.pause();
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
/**
|
|
3104
|
+
* 恢复上传
|
|
3105
|
+
*/
|
|
3106
|
+
resume() {
|
|
3107
|
+
if (this.resumable) {
|
|
3108
|
+
this.resumable.upload();
|
|
3109
|
+
}
|
|
3110
|
+
}
|
|
3111
|
+
/**
|
|
3112
|
+
* 取消上传
|
|
3113
|
+
*/
|
|
3114
|
+
cancel() {
|
|
3115
|
+
if (this.resumable) {
|
|
3116
|
+
this.resumable.cancel();
|
|
3117
|
+
this.resumable = null;
|
|
3118
|
+
}
|
|
3119
|
+
this.currentFileItem = null;
|
|
3120
|
+
this.cleanup();
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
class SimpleUploader {
|
|
3124
|
+
constructor(options, callbacks = {}) {
|
|
3125
|
+
__publicField(this, "customUpload");
|
|
3126
|
+
__publicField(this, "callbacks");
|
|
3127
|
+
__publicField(this, "getFileList");
|
|
3128
|
+
__publicField(this, "removeFile");
|
|
3129
|
+
this.customUpload = options.customUpload;
|
|
3130
|
+
this.getFileList = options.getFileList;
|
|
3131
|
+
this.removeFile = options.removeFile;
|
|
3132
|
+
this.callbacks = callbacks;
|
|
3133
|
+
}
|
|
3134
|
+
/**
|
|
3135
|
+
* 更新自定义上传函数
|
|
3136
|
+
*/
|
|
3137
|
+
updateCustomUpload(customUpload) {
|
|
3138
|
+
this.customUpload = customUpload;
|
|
3139
|
+
}
|
|
3140
|
+
/**
|
|
3141
|
+
* 上传单个文件
|
|
3142
|
+
*/
|
|
3143
|
+
async upload(fileItem) {
|
|
3144
|
+
if (this.customUpload) {
|
|
3145
|
+
const context = {
|
|
3146
|
+
fileList: [...this.getFileList()],
|
|
3147
|
+
removeFile: (index) => {
|
|
3148
|
+
this.removeFile(index);
|
|
3149
|
+
}
|
|
3150
|
+
};
|
|
3151
|
+
const response = await this.customUpload(
|
|
3152
|
+
fileItem.file,
|
|
3153
|
+
context,
|
|
3154
|
+
(progress) => {
|
|
3155
|
+
var _a, _b, _c, _d;
|
|
3156
|
+
fileItem.progress = progress;
|
|
3157
|
+
(_b = (_a = this.callbacks).onProgress) == null ? void 0 : _b.call(_a, fileItem, progress);
|
|
3158
|
+
(_d = (_c = this.callbacks).onUpdate) == null ? void 0 : _d.call(_c);
|
|
3159
|
+
}
|
|
3160
|
+
);
|
|
3161
|
+
return response;
|
|
3162
|
+
} else {
|
|
3163
|
+
return fileItem.file;
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
}
|
|
2959
3167
|
const generateId = () => {
|
|
2960
3168
|
return `file_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
2961
3169
|
};
|
|
@@ -2963,13 +3171,12 @@ class ImportDialogUploader {
|
|
|
2963
3171
|
constructor(config, callbacks = {}) {
|
|
2964
3172
|
__publicField(this, "config");
|
|
2965
3173
|
__publicField(this, "callbacks");
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
__publicField(this, "
|
|
2969
|
-
//
|
|
2970
|
-
|
|
2971
|
-
__publicField(this, "
|
|
2972
|
-
__publicField(this, "uploadCompleteReject");
|
|
3174
|
+
// 上传器实例
|
|
3175
|
+
__publicField(this, "chunkedUploader", null);
|
|
3176
|
+
__publicField(this, "simpleUploader", null);
|
|
3177
|
+
// 并发上传队列
|
|
3178
|
+
__publicField(this, "uploadQueue", []);
|
|
3179
|
+
__publicField(this, "activeUploads", 0);
|
|
2973
3180
|
// 上传状态
|
|
2974
3181
|
__publicField(this, "uploadFileList", []);
|
|
2975
3182
|
//上传文件列表
|
|
@@ -2981,6 +3188,50 @@ class ImportDialogUploader {
|
|
|
2981
3188
|
__publicField(this, "uploadMessageType", "info");
|
|
2982
3189
|
this.config = config;
|
|
2983
3190
|
this.callbacks = callbacks;
|
|
3191
|
+
this.initUploaders();
|
|
3192
|
+
}
|
|
3193
|
+
/**
|
|
3194
|
+
* 初始化上传器
|
|
3195
|
+
*/
|
|
3196
|
+
initUploaders() {
|
|
3197
|
+
const uploadConfig = this.config.uploadConfig;
|
|
3198
|
+
if ((uploadConfig == null ? void 0 : uploadConfig.chunkedUpload) && !this.config.multiple) {
|
|
3199
|
+
this.chunkedUploader = new ChunkedUploader(uploadConfig.chunkedUpload, {
|
|
3200
|
+
onProgress: (fileItem, progress) => {
|
|
3201
|
+
var _a, _b, _c, _d;
|
|
3202
|
+
(_b = (_a = this.callbacks).onUploadProgress) == null ? void 0 : _b.call(_a, fileItem, progress);
|
|
3203
|
+
(_d = (_c = this.callbacks).onUpdate) == null ? void 0 : _d.call(_c);
|
|
3204
|
+
},
|
|
3205
|
+
onUpdate: () => {
|
|
3206
|
+
var _a, _b;
|
|
3207
|
+
return (_b = (_a = this.callbacks).onUpdate) == null ? void 0 : _b.call(_a);
|
|
3208
|
+
}
|
|
3209
|
+
});
|
|
3210
|
+
}
|
|
3211
|
+
this.simpleUploader = new SimpleUploader(
|
|
3212
|
+
{
|
|
3213
|
+
customUpload: uploadConfig == null ? void 0 : uploadConfig.customUpload,
|
|
3214
|
+
getFileList: () => this.uploadFileList,
|
|
3215
|
+
removeFile: (index) => this.removeFile(index)
|
|
3216
|
+
},
|
|
3217
|
+
{
|
|
3218
|
+
onProgress: (fileItem, progress) => {
|
|
3219
|
+
var _a, _b, _c, _d;
|
|
3220
|
+
(_b = (_a = this.callbacks).onUploadProgress) == null ? void 0 : _b.call(_a, fileItem, progress);
|
|
3221
|
+
(_d = (_c = this.callbacks).onUpdate) == null ? void 0 : _d.call(_c);
|
|
3222
|
+
},
|
|
3223
|
+
onUpdate: () => {
|
|
3224
|
+
var _a, _b;
|
|
3225
|
+
return (_b = (_a = this.callbacks).onUpdate) == null ? void 0 : _b.call(_a);
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
);
|
|
3229
|
+
}
|
|
3230
|
+
/**
|
|
3231
|
+
* 获取并发限制数
|
|
3232
|
+
*/
|
|
3233
|
+
get concurrentLimit() {
|
|
3234
|
+
return this.config.concurrentLimit ?? 3;
|
|
2984
3235
|
}
|
|
2985
3236
|
/**
|
|
2986
3237
|
* 判断是否应该使用分片上传
|
|
@@ -2990,15 +3241,9 @@ class ImportDialogUploader {
|
|
|
2990
3241
|
const uploadConfig = this.config.uploadConfig;
|
|
2991
3242
|
return !!((uploadConfig == null ? void 0 : uploadConfig.chunkedUpload) && !this.config.multiple);
|
|
2992
3243
|
}
|
|
2993
|
-
/**
|
|
2994
|
-
* 获取分片上传配置
|
|
2995
|
-
*/
|
|
2996
|
-
getChunkedUploadConfig() {
|
|
2997
|
-
var _a;
|
|
2998
|
-
return ((_a = this.config.uploadConfig) == null ? void 0 : _a.chunkedUpload) || null;
|
|
2999
|
-
}
|
|
3000
3244
|
updateConfig(config) {
|
|
3001
3245
|
this.config = { ...this.config, ...config };
|
|
3246
|
+
this.initUploaders();
|
|
3002
3247
|
}
|
|
3003
3248
|
updateCallbacks(callbacks) {
|
|
3004
3249
|
this.callbacks = { ...this.callbacks, ...callbacks };
|
|
@@ -3011,9 +3256,8 @@ class ImportDialogUploader {
|
|
|
3011
3256
|
this.isUploading = false;
|
|
3012
3257
|
this.uploadMessage = "";
|
|
3013
3258
|
this.uploadMessageType = "info";
|
|
3014
|
-
this.
|
|
3015
|
-
this.
|
|
3016
|
-
this.uploadCompleteReject = void 0;
|
|
3259
|
+
this.uploadQueue = [];
|
|
3260
|
+
this.activeUploads = 0;
|
|
3017
3261
|
}
|
|
3018
3262
|
/**
|
|
3019
3263
|
* 文件上传之前的校验 选择文件时调用
|
|
@@ -3096,13 +3340,37 @@ class ImportDialogUploader {
|
|
|
3096
3340
|
(_f = (_e = this.callbacks).onUpdate) == null ? void 0 : _f.call(_e);
|
|
3097
3341
|
return true;
|
|
3098
3342
|
}
|
|
3343
|
+
/**
|
|
3344
|
+
* 将文件加入上传队列并启动处理
|
|
3345
|
+
*/
|
|
3346
|
+
enqueueUpload(fileItems) {
|
|
3347
|
+
const newItems = fileItems.filter(
|
|
3348
|
+
(item) => !this.uploadQueue.some((q) => q.id === item.id)
|
|
3349
|
+
);
|
|
3350
|
+
this.uploadQueue.push(...newItems);
|
|
3351
|
+
this.processUploadQueue();
|
|
3352
|
+
}
|
|
3353
|
+
/**
|
|
3354
|
+
* 处理上传队列(支持并发)
|
|
3355
|
+
*/
|
|
3356
|
+
processUploadQueue() {
|
|
3357
|
+
while (this.uploadQueue.length > 0 && this.activeUploads < this.concurrentLimit) {
|
|
3358
|
+
const fileItem = this.uploadQueue.shift();
|
|
3359
|
+
if (fileItem.status !== "pending") {
|
|
3360
|
+
continue;
|
|
3361
|
+
}
|
|
3362
|
+
this.activeUploads++;
|
|
3363
|
+
this.uploadSingleFile(fileItem).finally(() => {
|
|
3364
|
+
this.activeUploads--;
|
|
3365
|
+
this.processUploadQueue();
|
|
3366
|
+
});
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3099
3369
|
async startUploadFiles() {
|
|
3100
3370
|
const pendingFiles = this.uploadFileList.filter(
|
|
3101
3371
|
(f) => f.status === "pending"
|
|
3102
3372
|
);
|
|
3103
|
-
|
|
3104
|
-
await this.uploadSingleFile(fileItem);
|
|
3105
|
-
}
|
|
3373
|
+
this.enqueueUpload(pendingFiles);
|
|
3106
3374
|
}
|
|
3107
3375
|
/**
|
|
3108
3376
|
* 单个文件上传
|
|
@@ -3116,9 +3384,9 @@ class ImportDialogUploader {
|
|
|
3116
3384
|
(_b = (_a = this.callbacks).onUpdate) == null ? void 0 : _b.call(_a);
|
|
3117
3385
|
try {
|
|
3118
3386
|
if (this.shouldUseChunkedUpload()) {
|
|
3119
|
-
await this.uploadFileChunked(fileItem);
|
|
3387
|
+
fileItem.response = await this.uploadFileChunked(fileItem);
|
|
3120
3388
|
} else {
|
|
3121
|
-
await this.uploadFileSimple(fileItem);
|
|
3389
|
+
fileItem.response = await this.uploadFileSimple(fileItem);
|
|
3122
3390
|
}
|
|
3123
3391
|
fileItem.status = "success";
|
|
3124
3392
|
fileItem.progress = 100;
|
|
@@ -3138,160 +3406,19 @@ class ImportDialogUploader {
|
|
|
3138
3406
|
* 普通上传(非分片)
|
|
3139
3407
|
*/
|
|
3140
3408
|
async uploadFileSimple(fileItem) {
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
if (customUpload) {
|
|
3144
|
-
fileItem.response = await customUpload(fileItem.file, (progress) => {
|
|
3145
|
-
var _a2, _b, _c, _d;
|
|
3146
|
-
fileItem.progress = progress;
|
|
3147
|
-
(_b = (_a2 = this.callbacks).onUploadProgress) == null ? void 0 : _b.call(_a2, fileItem, progress);
|
|
3148
|
-
(_d = (_c = this.callbacks).onUpdate) == null ? void 0 : _d.call(_c);
|
|
3149
|
-
});
|
|
3150
|
-
} else {
|
|
3151
|
-
fileItem.response = fileItem.file;
|
|
3409
|
+
if (!this.simpleUploader) {
|
|
3410
|
+
throw new Error("SimpleUploader 未初始化");
|
|
3152
3411
|
}
|
|
3412
|
+
return await this.simpleUploader.upload(fileItem);
|
|
3153
3413
|
}
|
|
3154
3414
|
/**
|
|
3155
3415
|
* 分片上传
|
|
3156
|
-
* 业务侧只需提供:initUpload, getResumableConfig, mergeChunks
|
|
3157
3416
|
*/
|
|
3158
3417
|
async uploadFileChunked(fileItem) {
|
|
3159
|
-
|
|
3160
|
-
if (!chunkedConfig) {
|
|
3418
|
+
if (!this.chunkedUploader) {
|
|
3161
3419
|
throw new Error("分片上传需要配置 chunkedUpload");
|
|
3162
3420
|
}
|
|
3163
|
-
|
|
3164
|
-
const initResult = await chunkedConfig.initUpload(
|
|
3165
|
-
fileItem.file.name,
|
|
3166
|
-
fileItem.file.size
|
|
3167
|
-
);
|
|
3168
|
-
fileItem.uploadSessionId = initResult.uploadSessionId;
|
|
3169
|
-
this.currentFileItem = fileItem;
|
|
3170
|
-
this.initResumable(chunkedConfig, initResult);
|
|
3171
|
-
this.resumable.addFile(fileItem.file);
|
|
3172
|
-
fileItem.response = await this.waitForUploadComplete();
|
|
3173
|
-
} catch (error) {
|
|
3174
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
3175
|
-
throw err;
|
|
3176
|
-
}
|
|
3177
|
-
}
|
|
3178
|
-
/**
|
|
3179
|
-
* 等待上传完成
|
|
3180
|
-
*/
|
|
3181
|
-
waitForUploadComplete() {
|
|
3182
|
-
return new Promise((resolve, reject) => {
|
|
3183
|
-
this.uploadCompleteResolve = resolve;
|
|
3184
|
-
this.uploadCompleteReject = reject;
|
|
3185
|
-
});
|
|
3186
|
-
}
|
|
3187
|
-
/**
|
|
3188
|
-
* 初始化Resumable实例
|
|
3189
|
-
*/
|
|
3190
|
-
initResumable(chunkedConfig, initResult) {
|
|
3191
|
-
if (this.resumable) {
|
|
3192
|
-
this.resumable.cancel();
|
|
3193
|
-
}
|
|
3194
|
-
const customConfig = chunkedConfig.getResumableConfig(initResult);
|
|
3195
|
-
const defaultConfig = {
|
|
3196
|
-
chunkSize: initResult.partSize,
|
|
3197
|
-
simultaneousUploads: 3,
|
|
3198
|
-
testChunks: false,
|
|
3199
|
-
method: "multipart",
|
|
3200
|
-
chunkNumberParameterName: "partNumber",
|
|
3201
|
-
totalChunksParameterName: "totalParts",
|
|
3202
|
-
fileParameterName: "file",
|
|
3203
|
-
withCredentials: true,
|
|
3204
|
-
maxChunkRetries: 3,
|
|
3205
|
-
chunkRetryInterval: 1e3,
|
|
3206
|
-
forceChunkSize: true
|
|
3207
|
-
};
|
|
3208
|
-
const finalConfig = { ...defaultConfig, ...customConfig };
|
|
3209
|
-
this.resumable = new Resumable(finalConfig);
|
|
3210
|
-
this.bindResumableEvents();
|
|
3211
|
-
}
|
|
3212
|
-
/**
|
|
3213
|
-
* 绑定Resumable事件监听器
|
|
3214
|
-
*/
|
|
3215
|
-
bindResumableEvents() {
|
|
3216
|
-
this.resumable.on("progress", () => {
|
|
3217
|
-
var _a, _b, _c, _d;
|
|
3218
|
-
const progress = Math.floor(this.resumable.progress() * 100);
|
|
3219
|
-
this.uploadProgress = progress;
|
|
3220
|
-
this.uploadMessage = `正在上传 (${progress}%)...`;
|
|
3221
|
-
if (this.currentFileItem) {
|
|
3222
|
-
this.currentFileItem.progress = Math.min(progress, 90);
|
|
3223
|
-
(_b = (_a = this.callbacks).onUploadProgress) == null ? void 0 : _b.call(
|
|
3224
|
-
_a,
|
|
3225
|
-
this.currentFileItem,
|
|
3226
|
-
this.currentFileItem.progress
|
|
3227
|
-
);
|
|
3228
|
-
}
|
|
3229
|
-
(_d = (_c = this.callbacks).onUpdate) == null ? void 0 : _d.call(_c);
|
|
3230
|
-
});
|
|
3231
|
-
this.resumable.on("fileSuccess", () => {
|
|
3232
|
-
this.handleResumableComplete();
|
|
3233
|
-
});
|
|
3234
|
-
this.resumable.on("error", (message) => {
|
|
3235
|
-
console.error("[Resumable分片上传] 上传错误:", message);
|
|
3236
|
-
this.handleResumableError(message);
|
|
3237
|
-
});
|
|
3238
|
-
this.resumable.on("fileAdded", () => {
|
|
3239
|
-
this.resumable.upload();
|
|
3240
|
-
});
|
|
3241
|
-
this.resumable.on("pause", () => {
|
|
3242
|
-
this.uploadMessage = "上传已暂停";
|
|
3243
|
-
});
|
|
3244
|
-
}
|
|
3245
|
-
/**
|
|
3246
|
-
* 处理Resumable上传完成
|
|
3247
|
-
*/
|
|
3248
|
-
async handleResumableComplete() {
|
|
3249
|
-
var _a;
|
|
3250
|
-
if (!this.currentFileItem || !this.uploadCompleteResolve || !this.uploadCompleteReject) {
|
|
3251
|
-
return;
|
|
3252
|
-
}
|
|
3253
|
-
try {
|
|
3254
|
-
const chunkedConfig = this.getChunkedUploadConfig();
|
|
3255
|
-
if (!chunkedConfig) {
|
|
3256
|
-
throw new Error("分片上传配置缺失");
|
|
3257
|
-
}
|
|
3258
|
-
const mergeResult = await chunkedConfig.mergeChunks(
|
|
3259
|
-
this.currentFileItem.uploadSessionId
|
|
3260
|
-
);
|
|
3261
|
-
if (this.currentFileItem) {
|
|
3262
|
-
this.currentFileItem.progress = 100;
|
|
3263
|
-
}
|
|
3264
|
-
this.uploadMessage = "上传完成";
|
|
3265
|
-
this.uploadMessageType = "success";
|
|
3266
|
-
this.uploadCompleteResolve(mergeResult);
|
|
3267
|
-
this.uploadCompleteResolve = void 0;
|
|
3268
|
-
this.uploadCompleteReject = void 0;
|
|
3269
|
-
} catch (error) {
|
|
3270
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
3271
|
-
this.handleResumableError(err.message);
|
|
3272
|
-
(_a = this.uploadCompleteReject) == null ? void 0 : _a.call(this, error);
|
|
3273
|
-
this.uploadCompleteResolve = void 0;
|
|
3274
|
-
this.uploadCompleteReject = void 0;
|
|
3275
|
-
}
|
|
3276
|
-
}
|
|
3277
|
-
/**
|
|
3278
|
-
* 处理Resumable上传错误
|
|
3279
|
-
*/
|
|
3280
|
-
handleResumableError(message) {
|
|
3281
|
-
var _a, _b;
|
|
3282
|
-
if (this.currentFileItem) {
|
|
3283
|
-
this.currentFileItem.status = "error";
|
|
3284
|
-
this.currentFileItem.errorMessage = message;
|
|
3285
|
-
}
|
|
3286
|
-
this.uploadMessage = message || "上传失败";
|
|
3287
|
-
this.uploadMessageType = "error";
|
|
3288
|
-
this.isUploading = false;
|
|
3289
|
-
if (this.uploadCompleteReject) {
|
|
3290
|
-
this.uploadCompleteReject(new Error(message));
|
|
3291
|
-
this.uploadCompleteResolve = void 0;
|
|
3292
|
-
this.uploadCompleteReject = void 0;
|
|
3293
|
-
}
|
|
3294
|
-
(_b = (_a = this.callbacks).onUpdate) == null ? void 0 : _b.call(_a);
|
|
3421
|
+
return await this.chunkedUploader.upload(fileItem);
|
|
3295
3422
|
}
|
|
3296
3423
|
/**
|
|
3297
3424
|
* 手动触发上传(用于autoUpload=false的场景)
|
|
@@ -3300,35 +3427,31 @@ class ImportDialogUploader {
|
|
|
3300
3427
|
await this.startUploadFiles();
|
|
3301
3428
|
}
|
|
3302
3429
|
/**
|
|
3303
|
-
*
|
|
3430
|
+
* 暂停上传(仅分片上传支持)
|
|
3304
3431
|
*/
|
|
3305
3432
|
pauseUpload() {
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
}
|
|
3433
|
+
var _a;
|
|
3434
|
+
(_a = this.chunkedUploader) == null ? void 0 : _a.pause();
|
|
3309
3435
|
}
|
|
3310
3436
|
/**
|
|
3311
|
-
*
|
|
3437
|
+
* 恢复上传(仅分片上传支持)
|
|
3312
3438
|
*/
|
|
3313
3439
|
resumeUpload() {
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
}
|
|
3440
|
+
var _a;
|
|
3441
|
+
(_a = this.chunkedUploader) == null ? void 0 : _a.resume();
|
|
3317
3442
|
}
|
|
3318
3443
|
/**
|
|
3319
3444
|
* 取消上传
|
|
3320
3445
|
*/
|
|
3321
3446
|
cancelUpload() {
|
|
3322
|
-
var _a, _b;
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
}
|
|
3327
|
-
this.currentFileItem = null;
|
|
3447
|
+
var _a, _b, _c;
|
|
3448
|
+
(_a = this.chunkedUploader) == null ? void 0 : _a.cancel();
|
|
3449
|
+
this.uploadQueue = [];
|
|
3450
|
+
this.activeUploads = 0;
|
|
3328
3451
|
this.isUploading = false;
|
|
3329
3452
|
this.uploadMessage = "上传已取消";
|
|
3330
3453
|
this.uploadMessageType = "info";
|
|
3331
|
-
(
|
|
3454
|
+
(_c = (_b = this.callbacks).onUpdate) == null ? void 0 : _c.call(_b);
|
|
3332
3455
|
}
|
|
3333
3456
|
updateOverallProgress() {
|
|
3334
3457
|
if (this.uploadFileList.length === 0) {
|
|
@@ -3870,6 +3993,7 @@ const _ImportDialog = class _ImportDialog {
|
|
|
3870
3993
|
* @returns
|
|
3871
3994
|
*/
|
|
3872
3995
|
async handleConfirm() {
|
|
3996
|
+
var _a, _b, _c, _d;
|
|
3873
3997
|
if (this.uploader.uploadFileList.length === 0) {
|
|
3874
3998
|
this.showMessage(t("fileTypeError"), "warning");
|
|
3875
3999
|
return;
|
|
@@ -3879,13 +4003,20 @@ const _ImportDialog = class _ImportDialog {
|
|
|
3879
4003
|
return;
|
|
3880
4004
|
}
|
|
3881
4005
|
if (this.uploader.hasPendingFiles()) {
|
|
3882
|
-
this.confirmLoading
|
|
3883
|
-
|
|
4006
|
+
const confirmLoadingEnabled2 = ((_a = this.modalOptions.uploadConfig) == null ? void 0 : _a.confirmLoading) != null ? this.modalOptions.uploadConfig.confirmLoading : true;
|
|
4007
|
+
if (confirmLoadingEnabled2) {
|
|
4008
|
+
this.confirmLoading = true;
|
|
4009
|
+
this.updateModal();
|
|
4010
|
+
}
|
|
3884
4011
|
try {
|
|
3885
4012
|
await this.uploader.startUpload();
|
|
3886
4013
|
} catch (error) {
|
|
3887
4014
|
console.error("[ImportDialog] 上传失败:", error);
|
|
3888
4015
|
this.showMessage("上传失败,请重试", "error");
|
|
4016
|
+
if (confirmLoadingEnabled2) {
|
|
4017
|
+
this.confirmLoading = false;
|
|
4018
|
+
this.updateModal();
|
|
4019
|
+
}
|
|
3889
4020
|
return;
|
|
3890
4021
|
}
|
|
3891
4022
|
}
|
|
@@ -3896,14 +4027,20 @@ const _ImportDialog = class _ImportDialog {
|
|
|
3896
4027
|
`有 ${failedFiles.length} 个文件上传失败,请重新上传`,
|
|
3897
4028
|
"warning"
|
|
3898
4029
|
);
|
|
3899
|
-
this.confirmLoading
|
|
3900
|
-
|
|
4030
|
+
const confirmLoadingEnabled2 = ((_b = this.modalOptions.uploadConfig) == null ? void 0 : _b.confirmLoading) != null ? this.modalOptions.uploadConfig.confirmLoading : true;
|
|
4031
|
+
if (confirmLoadingEnabled2) {
|
|
4032
|
+
this.confirmLoading = false;
|
|
4033
|
+
this.updateModal();
|
|
4034
|
+
}
|
|
3901
4035
|
return;
|
|
3902
4036
|
}
|
|
3903
4037
|
if (!this.uploader.hasAllFilesUploaded()) {
|
|
3904
4038
|
this.showMessage("请等待所有文件上传完成", "warning");
|
|
3905
|
-
this.confirmLoading
|
|
3906
|
-
|
|
4039
|
+
const confirmLoadingEnabled2 = ((_c = this.modalOptions.uploadConfig) == null ? void 0 : _c.confirmLoading) != null ? this.modalOptions.uploadConfig.confirmLoading : true;
|
|
4040
|
+
if (confirmLoadingEnabled2) {
|
|
4041
|
+
this.confirmLoading = false;
|
|
4042
|
+
this.updateModal();
|
|
4043
|
+
}
|
|
3907
4044
|
return;
|
|
3908
4045
|
}
|
|
3909
4046
|
const uploadResponses = this.uploader.uploadFileList.map(
|
|
@@ -3915,6 +4052,11 @@ const _ImportDialog = class _ImportDialog {
|
|
|
3915
4052
|
activeTab: this.currentConfig.tabs[this.activeTabIndex],
|
|
3916
4053
|
activeTabIndex: this.activeTabIndex
|
|
3917
4054
|
};
|
|
4055
|
+
const confirmLoadingEnabled = ((_d = this.modalOptions.uploadConfig) == null ? void 0 : _d.confirmLoading) != null ? this.modalOptions.uploadConfig.confirmLoading : true;
|
|
4056
|
+
if (confirmLoadingEnabled) {
|
|
4057
|
+
this.confirmLoading = true;
|
|
4058
|
+
this.updateModal();
|
|
4059
|
+
}
|
|
3918
4060
|
try {
|
|
3919
4061
|
if (this.modalOptions.onBeforeConfirm) {
|
|
3920
4062
|
await this.modalOptions.onBeforeConfirm(submitData);
|
|
@@ -3928,8 +4070,10 @@ const _ImportDialog = class _ImportDialog {
|
|
|
3928
4070
|
}
|
|
3929
4071
|
}
|
|
3930
4072
|
} finally {
|
|
3931
|
-
|
|
3932
|
-
|
|
4073
|
+
if (confirmLoadingEnabled) {
|
|
4074
|
+
this.confirmLoading = false;
|
|
4075
|
+
this.updateModal();
|
|
4076
|
+
}
|
|
3933
4077
|
}
|
|
3934
4078
|
}
|
|
3935
4079
|
showMessage(message, type) {
|