@sl-material/sl-import 1.0.0-beta0 → 1.0.0-beta11

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/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, atau",
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, or",
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,170 @@ 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
+ }
2959
3123
  const generateId = () => {
2960
3124
  return `file_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
2961
3125
  };
@@ -2963,13 +3127,11 @@ class ImportDialogUploader {
2963
3127
  constructor(config, callbacks = {}) {
2964
3128
  __publicField(this, "config");
2965
3129
  __publicField(this, "callbacks");
2966
- __publicField(this, "resumable");
2967
- // Resumable实例
2968
- __publicField(this, "currentFileItem", null);
2969
- // 当前上传的文件项
2970
- // Promise resolve/reject 函数存储
2971
- __publicField(this, "uploadCompleteResolve");
2972
- __publicField(this, "uploadCompleteReject");
3130
+ // 分片上传器实例
3131
+ __publicField(this, "chunkedUploader", null);
3132
+ // 并发上传队列
3133
+ __publicField(this, "uploadQueue", []);
3134
+ __publicField(this, "activeUploads", 0);
2973
3135
  // 上传状态
2974
3136
  __publicField(this, "uploadFileList", []);
2975
3137
  //上传文件列表
@@ -2981,6 +3143,32 @@ class ImportDialogUploader {
2981
3143
  __publicField(this, "uploadMessageType", "info");
2982
3144
  this.config = config;
2983
3145
  this.callbacks = callbacks;
3146
+ this.initUploaders();
3147
+ }
3148
+ /**
3149
+ * 初始化上传器
3150
+ */
3151
+ initUploaders() {
3152
+ const uploadConfig = this.config.uploadConfig;
3153
+ if ((uploadConfig == null ? void 0 : uploadConfig.chunkedUpload) && !this.config.multiple) {
3154
+ this.chunkedUploader = new ChunkedUploader(uploadConfig.chunkedUpload, {
3155
+ onProgress: (fileItem, progress) => {
3156
+ var _a, _b, _c, _d;
3157
+ (_b = (_a = this.callbacks).onUploadProgress) == null ? void 0 : _b.call(_a, fileItem, progress);
3158
+ (_d = (_c = this.callbacks).onUpdate) == null ? void 0 : _d.call(_c);
3159
+ },
3160
+ onUpdate: () => {
3161
+ var _a, _b;
3162
+ return (_b = (_a = this.callbacks).onUpdate) == null ? void 0 : _b.call(_a);
3163
+ }
3164
+ });
3165
+ }
3166
+ }
3167
+ /**
3168
+ * 获取并发限制数
3169
+ */
3170
+ get concurrentLimit() {
3171
+ return this.config.concurrentLimit ?? 3;
2984
3172
  }
2985
3173
  /**
2986
3174
  * 判断是否应该使用分片上传
@@ -2990,15 +3178,9 @@ class ImportDialogUploader {
2990
3178
  const uploadConfig = this.config.uploadConfig;
2991
3179
  return !!((uploadConfig == null ? void 0 : uploadConfig.chunkedUpload) && !this.config.multiple);
2992
3180
  }
2993
- /**
2994
- * 获取分片上传配置
2995
- */
2996
- getChunkedUploadConfig() {
2997
- var _a;
2998
- return ((_a = this.config.uploadConfig) == null ? void 0 : _a.chunkedUpload) || null;
2999
- }
3000
3181
  updateConfig(config) {
3001
3182
  this.config = { ...this.config, ...config };
3183
+ this.initUploaders();
3002
3184
  }
3003
3185
  updateCallbacks(callbacks) {
3004
3186
  this.callbacks = { ...this.callbacks, ...callbacks };
@@ -3011,15 +3193,14 @@ class ImportDialogUploader {
3011
3193
  this.isUploading = false;
3012
3194
  this.uploadMessage = "";
3013
3195
  this.uploadMessageType = "info";
3014
- this.currentFileItem = null;
3015
- this.uploadCompleteResolve = void 0;
3016
- this.uploadCompleteReject = void 0;
3196
+ this.uploadQueue = [];
3197
+ this.activeUploads = 0;
3017
3198
  }
3018
3199
  /**
3019
3200
  * 文件上传之前的校验 选择文件时调用
3020
3201
  */
3021
3202
  beforeUpload(files) {
3022
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
3203
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
3023
3204
  const fileArray = Array.isArray(files) ? files : [files];
3024
3205
  if (!fileArray.length) {
3025
3206
  (_b = (_a = this.callbacks).onMessage) == null ? void 0 : _b.call(_a, "请选择文件", "warning");
@@ -3065,12 +3246,69 @@ class ImportDialogUploader {
3065
3246
  }
3066
3247
  (_h = (_g = this.callbacks).onUpdate) == null ? void 0 : _h.call(_g);
3067
3248
  (_j = (_i = this.callbacks).onFileChange) == null ? void 0 : _j.call(_i, this.uploadFileList);
3068
- const autoUpload = ((_k = this.config.uploadConfig) == null ? void 0 : _k.autoUpload) != null ? this.config.uploadConfig.autoUpload : false;
3069
- if (autoUpload) {
3070
- this.startUploadFiles();
3071
- }
3249
+ this.processFilesWithCustomUpload();
3072
3250
  return true;
3073
3251
  }
3252
+ /**
3253
+ * 使用 customUpload 预处理文件
3254
+ * 在选择文件后立即调用,用于二次加工参数或自定义校验
3255
+ */
3256
+ async processFilesWithCustomUpload() {
3257
+ const pendingFiles = this.uploadFileList.filter(
3258
+ (f) => f.status === "pending"
3259
+ );
3260
+ for (const fileItem of pendingFiles) {
3261
+ await this.processFileWithCustomUpload(fileItem);
3262
+ }
3263
+ }
3264
+ /**
3265
+ * 单个文件的预处理
3266
+ */
3267
+ async processFileWithCustomUpload(fileItem) {
3268
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
3269
+ const customUpload = (_a = this.config.uploadConfig) == null ? void 0 : _a.customUpload;
3270
+ if (!customUpload) {
3271
+ fileItem.status = "success";
3272
+ fileItem.progress = 100;
3273
+ fileItem.response = fileItem.file;
3274
+ (_c = (_b = this.callbacks).onUpdate) == null ? void 0 : _c.call(_b);
3275
+ return;
3276
+ }
3277
+ fileItem.status = "uploading";
3278
+ fileItem.progress = 0;
3279
+ this.isUploading = true;
3280
+ (_e = (_d = this.callbacks).onUpdate) == null ? void 0 : _e.call(_d);
3281
+ try {
3282
+ const context = {
3283
+ fileList: [...this.uploadFileList],
3284
+ removeFile: (index) => {
3285
+ this.removeFile(index);
3286
+ }
3287
+ };
3288
+ fileItem.response = await customUpload(
3289
+ fileItem.file,
3290
+ context,
3291
+ (progress) => {
3292
+ var _a2, _b2, _c2, _d2;
3293
+ fileItem.progress = progress;
3294
+ (_b2 = (_a2 = this.callbacks).onUploadProgress) == null ? void 0 : _b2.call(_a2, fileItem, progress);
3295
+ (_d2 = (_c2 = this.callbacks).onUpdate) == null ? void 0 : _d2.call(_c2);
3296
+ }
3297
+ );
3298
+ fileItem.status = "success";
3299
+ fileItem.progress = 100;
3300
+ (_g = (_f = this.callbacks).onUploadSuccess) == null ? void 0 : _g.call(_f, fileItem, fileItem.response);
3301
+ } catch (error) {
3302
+ fileItem.status = "error";
3303
+ fileItem.errorMessage = error instanceof Error ? error.message : "处理失败";
3304
+ (_i = (_h = this.callbacks).onUploadError) == null ? void 0 : _i.call(_h, fileItem, error);
3305
+ }
3306
+ this.isUploading = this.uploadFileList.some(
3307
+ (f) => f.status === "uploading"
3308
+ );
3309
+ (_k = (_j = this.callbacks).onUpdate) == null ? void 0 : _k.call(_j);
3310
+ this.updateOverallProgress();
3311
+ }
3074
3312
  /**
3075
3313
  * 删除文件
3076
3314
  */
@@ -3096,16 +3334,34 @@ class ImportDialogUploader {
3096
3334
  (_f = (_e = this.callbacks).onUpdate) == null ? void 0 : _f.call(_e);
3097
3335
  return true;
3098
3336
  }
3099
- async startUploadFiles() {
3100
- const pendingFiles = this.uploadFileList.filter(
3101
- (f) => f.status === "pending"
3337
+ /**
3338
+ * 将文件加入上传队列并启动处理
3339
+ */
3340
+ enqueueUpload(fileItems) {
3341
+ const newItems = fileItems.filter(
3342
+ (item) => !this.uploadQueue.some((q) => q.id === item.id)
3102
3343
  );
3103
- for (const fileItem of pendingFiles) {
3104
- await this.uploadSingleFile(fileItem);
3344
+ this.uploadQueue.push(...newItems);
3345
+ this.processUploadQueue();
3346
+ }
3347
+ /**
3348
+ * 处理上传队列(支持并发)
3349
+ */
3350
+ processUploadQueue() {
3351
+ while (this.uploadQueue.length > 0 && this.activeUploads < this.concurrentLimit) {
3352
+ const fileItem = this.uploadQueue.shift();
3353
+ if (fileItem.status !== "pending") {
3354
+ continue;
3355
+ }
3356
+ this.activeUploads++;
3357
+ this.uploadSingleFile(fileItem).finally(() => {
3358
+ this.activeUploads--;
3359
+ this.processUploadQueue();
3360
+ });
3105
3361
  }
3106
3362
  }
3107
3363
  /**
3108
- * 单个文件上传
3364
+ * 单个文件分片上传
3109
3365
  * @param fileItem
3110
3366
  */
3111
3367
  async uploadSingleFile(fileItem) {
@@ -3115,11 +3371,7 @@ class ImportDialogUploader {
3115
3371
  this.isUploading = true;
3116
3372
  (_b = (_a = this.callbacks).onUpdate) == null ? void 0 : _b.call(_a);
3117
3373
  try {
3118
- if (this.shouldUseChunkedUpload()) {
3119
- await this.uploadFileChunked(fileItem);
3120
- } else {
3121
- await this.uploadFileSimple(fileItem);
3122
- }
3374
+ fileItem.response = await this.uploadFileChunked(fileItem);
3123
3375
  fileItem.status = "success";
3124
3376
  fileItem.progress = 100;
3125
3377
  (_d = (_c = this.callbacks).onUploadSuccess) == null ? void 0 : _d.call(_c, fileItem, fileItem.response);
@@ -3134,201 +3386,58 @@ class ImportDialogUploader {
3134
3386
  (_h = (_g = this.callbacks).onUpdate) == null ? void 0 : _h.call(_g);
3135
3387
  this.updateOverallProgress();
3136
3388
  }
3137
- /**
3138
- * 普通上传(非分片)
3139
- */
3140
- async uploadFileSimple(fileItem) {
3141
- var _a;
3142
- const customUpload = (_a = this.config.uploadConfig) == null ? void 0 : _a.customUpload;
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;
3152
- }
3153
- }
3154
3389
  /**
3155
3390
  * 分片上传
3156
- * 业务侧只需提供:initUpload, getResumableConfig, mergeChunks
3157
3391
  */
3158
3392
  async uploadFileChunked(fileItem) {
3159
- const chunkedConfig = this.getChunkedUploadConfig();
3160
- if (!chunkedConfig) {
3393
+ if (!this.chunkedUploader) {
3161
3394
  throw new Error("分片上传需要配置 chunkedUpload");
3162
3395
  }
3163
- try {
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();
3396
+ return await this.chunkedUploader.upload(fileItem);
3211
3397
  }
3212
3398
  /**
3213
- * 绑定Resumable事件监听器
3399
+ * 手动触发分片上传(仅用于分片上传场景)
3214
3400
  */
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;
3401
+ async startUpload() {
3402
+ if (this.shouldUseChunkedUpload()) {
3403
+ await this.startChunkedUploadFiles();
3293
3404
  }
3294
- (_b = (_a = this.callbacks).onUpdate) == null ? void 0 : _b.call(_a);
3295
3405
  }
3296
3406
  /**
3297
- * 手动触发上传(用于autoUpload=false的场景)
3407
+ * 启动分片上传
3298
3408
  */
3299
- async startUpload() {
3300
- await this.startUploadFiles();
3409
+ async startChunkedUploadFiles() {
3410
+ const pendingFiles = this.uploadFileList.filter(
3411
+ (f) => f.status === "pending"
3412
+ );
3413
+ this.enqueueUpload(pendingFiles);
3301
3414
  }
3302
3415
  /**
3303
- * 暂停上传
3416
+ * 暂停上传(仅分片上传支持)
3304
3417
  */
3305
3418
  pauseUpload() {
3306
- if (this.resumable) {
3307
- this.resumable.pause();
3308
- }
3419
+ var _a;
3420
+ (_a = this.chunkedUploader) == null ? void 0 : _a.pause();
3309
3421
  }
3310
3422
  /**
3311
- * 恢复上传
3423
+ * 恢复上传(仅分片上传支持)
3312
3424
  */
3313
3425
  resumeUpload() {
3314
- if (this.resumable) {
3315
- this.resumable.upload();
3316
- }
3426
+ var _a;
3427
+ (_a = this.chunkedUploader) == null ? void 0 : _a.resume();
3317
3428
  }
3318
3429
  /**
3319
3430
  * 取消上传
3320
3431
  */
3321
3432
  cancelUpload() {
3322
- var _a, _b;
3323
- if (this.resumable) {
3324
- this.resumable.cancel();
3325
- this.resumable = null;
3326
- }
3327
- this.currentFileItem = null;
3433
+ var _a, _b, _c;
3434
+ (_a = this.chunkedUploader) == null ? void 0 : _a.cancel();
3435
+ this.uploadQueue = [];
3436
+ this.activeUploads = 0;
3328
3437
  this.isUploading = false;
3329
3438
  this.uploadMessage = "上传已取消";
3330
3439
  this.uploadMessageType = "info";
3331
- (_b = (_a = this.callbacks).onUpdate) == null ? void 0 : _b.call(_a);
3440
+ (_c = (_b = this.callbacks).onUpdate) == null ? void 0 : _c.call(_b);
3332
3441
  }
3333
3442
  updateOverallProgress() {
3334
3443
  if (this.uploadFileList.length === 0) {
@@ -3870,6 +3979,7 @@ const _ImportDialog = class _ImportDialog {
3870
3979
  * @returns
3871
3980
  */
3872
3981
  async handleConfirm() {
3982
+ var _a, _b, _c, _d;
3873
3983
  if (this.uploader.uploadFileList.length === 0) {
3874
3984
  this.showMessage(t("fileTypeError"), "warning");
3875
3985
  return;
@@ -3879,13 +3989,20 @@ const _ImportDialog = class _ImportDialog {
3879
3989
  return;
3880
3990
  }
3881
3991
  if (this.uploader.hasPendingFiles()) {
3882
- this.confirmLoading = true;
3883
- this.updateModal();
3992
+ const confirmLoadingEnabled2 = ((_a = this.modalOptions.uploadConfig) == null ? void 0 : _a.confirmLoading) != null ? this.modalOptions.uploadConfig.confirmLoading : true;
3993
+ if (confirmLoadingEnabled2) {
3994
+ this.confirmLoading = true;
3995
+ this.updateModal();
3996
+ }
3884
3997
  try {
3885
3998
  await this.uploader.startUpload();
3886
3999
  } catch (error) {
3887
4000
  console.error("[ImportDialog] 上传失败:", error);
3888
4001
  this.showMessage("上传失败,请重试", "error");
4002
+ if (confirmLoadingEnabled2) {
4003
+ this.confirmLoading = false;
4004
+ this.updateModal();
4005
+ }
3889
4006
  return;
3890
4007
  }
3891
4008
  }
@@ -3896,14 +4013,20 @@ const _ImportDialog = class _ImportDialog {
3896
4013
  `有 ${failedFiles.length} 个文件上传失败,请重新上传`,
3897
4014
  "warning"
3898
4015
  );
3899
- this.confirmLoading = false;
3900
- this.updateModal();
4016
+ const confirmLoadingEnabled2 = ((_b = this.modalOptions.uploadConfig) == null ? void 0 : _b.confirmLoading) != null ? this.modalOptions.uploadConfig.confirmLoading : true;
4017
+ if (confirmLoadingEnabled2) {
4018
+ this.confirmLoading = false;
4019
+ this.updateModal();
4020
+ }
3901
4021
  return;
3902
4022
  }
3903
4023
  if (!this.uploader.hasAllFilesUploaded()) {
3904
4024
  this.showMessage("请等待所有文件上传完成", "warning");
3905
- this.confirmLoading = false;
3906
- this.updateModal();
4025
+ const confirmLoadingEnabled2 = ((_c = this.modalOptions.uploadConfig) == null ? void 0 : _c.confirmLoading) != null ? this.modalOptions.uploadConfig.confirmLoading : true;
4026
+ if (confirmLoadingEnabled2) {
4027
+ this.confirmLoading = false;
4028
+ this.updateModal();
4029
+ }
3907
4030
  return;
3908
4031
  }
3909
4032
  const uploadResponses = this.uploader.uploadFileList.map(
@@ -3915,6 +4038,11 @@ const _ImportDialog = class _ImportDialog {
3915
4038
  activeTab: this.currentConfig.tabs[this.activeTabIndex],
3916
4039
  activeTabIndex: this.activeTabIndex
3917
4040
  };
4041
+ const confirmLoadingEnabled = ((_d = this.modalOptions.uploadConfig) == null ? void 0 : _d.confirmLoading) != null ? this.modalOptions.uploadConfig.confirmLoading : true;
4042
+ if (confirmLoadingEnabled) {
4043
+ this.confirmLoading = true;
4044
+ this.updateModal();
4045
+ }
3918
4046
  try {
3919
4047
  if (this.modalOptions.onBeforeConfirm) {
3920
4048
  await this.modalOptions.onBeforeConfirm(submitData);
@@ -3928,8 +4056,10 @@ const _ImportDialog = class _ImportDialog {
3928
4056
  }
3929
4057
  }
3930
4058
  } finally {
3931
- this.confirmLoading = false;
3932
- this.updateModal();
4059
+ if (confirmLoadingEnabled) {
4060
+ this.confirmLoading = false;
4061
+ this.updateModal();
4062
+ }
3933
4063
  }
3934
4064
  }
3935
4065
  showMessage(message, type) {