@sl-material/sl-import 1.0.0 → 1.1.0-beta1
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/package.json +1 -1
- package/sl-import.cjs.js +1 -1
- package/sl-import.es.js +126 -85
- package/sl-import.umd.umd.js +81 -31
package/sl-import.es.js
CHANGED
|
@@ -1388,7 +1388,6 @@ function getImportDialogStyles() {
|
|
|
1388
1388
|
overflow-y: hidden;
|
|
1389
1389
|
padding: 0px 0px 12px 0px;
|
|
1390
1390
|
scrollbar-width: thin;
|
|
1391
|
-
// scrollbar-color: #d9d9d9 transparent;
|
|
1392
1391
|
}
|
|
1393
1392
|
|
|
1394
1393
|
.import-dialog-vanilla-file-list::-webkit-scrollbar {
|
|
@@ -1428,22 +1427,10 @@ function getImportDialogStyles() {
|
|
|
1428
1427
|
width:100%;
|
|
1429
1428
|
}
|
|
1430
1429
|
|
|
1431
|
-
// .import-dialog-vanilla-file-item:hover {
|
|
1432
|
-
// background: #FFF7E6;
|
|
1433
|
-
// }
|
|
1434
|
-
|
|
1435
|
-
// .import-dialog-vanilla-file-item.status-success {
|
|
1436
|
-
// background: #FFFBF0;
|
|
1437
|
-
// }
|
|
1438
|
-
|
|
1439
1430
|
.import-dialog-vanilla-file-item.status-error {
|
|
1440
|
-
background:
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
.import-dialog-vanilla-file-item.status-uploading {
|
|
1444
|
-
background: #FFFBF0;
|
|
1431
|
+
background: var(--sl-color-danger-light-9);
|
|
1432
|
+
border:1px solid var(--sl-color-error);
|
|
1445
1433
|
}
|
|
1446
|
-
|
|
1447
1434
|
.import-dialog-vanilla-file-icon {
|
|
1448
1435
|
width: 18px;
|
|
1449
1436
|
height: 18px;
|
|
@@ -1479,19 +1466,64 @@ function getImportDialogStyles() {
|
|
|
1479
1466
|
align-items: center;
|
|
1480
1467
|
gap: 4px;
|
|
1481
1468
|
font-size: 12px;
|
|
1482
|
-
color: var(--sl-text-color-
|
|
1469
|
+
color: var(--sl-text-color-thridary);
|
|
1483
1470
|
}
|
|
1484
1471
|
|
|
1485
|
-
.import-dialog-vanilla-file-progress-text {
|
|
1486
|
-
font-size: 12px;
|
|
1487
|
-
color: #1890FF;
|
|
1488
|
-
}
|
|
1489
1472
|
|
|
1490
1473
|
.import-dialog-vanilla-file-error-text {
|
|
1491
1474
|
font-size: 12px;
|
|
1492
1475
|
color: var(--sl-color-error);
|
|
1493
1476
|
}
|
|
1494
1477
|
|
|
1478
|
+
/* 上传中状态的 loading 图标 */
|
|
1479
|
+
.import-dialog-vanilla-file-loading-icon {
|
|
1480
|
+
position: absolute;
|
|
1481
|
+
top: 8px;
|
|
1482
|
+
left: 8px;
|
|
1483
|
+
width: 32px;
|
|
1484
|
+
height: 32px;
|
|
1485
|
+
display: flex;
|
|
1486
|
+
align-items: center;
|
|
1487
|
+
justify-content: center;
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
.loading-spinner {
|
|
1491
|
+
width: 24px;
|
|
1492
|
+
height: 24px;
|
|
1493
|
+
border-radius: 50%;
|
|
1494
|
+
background: conic-gradient(from 0deg at 50% 50%, rgba(24, 144, 255, 0.1) 0%, #1890ff 75%, rgba(24, 144, 255, 0) 100%);
|
|
1495
|
+
animation: spin 1s linear infinite;
|
|
1496
|
+
display: flex;
|
|
1497
|
+
align-items: center;
|
|
1498
|
+
justify-content: center;
|
|
1499
|
+
position: relative;
|
|
1500
|
+
opacity: 0;
|
|
1501
|
+
transition: opacity 0.3s ease;
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
.loading-spinner::before {
|
|
1505
|
+
content: '';
|
|
1506
|
+
width: 18px;
|
|
1507
|
+
height: 18px;
|
|
1508
|
+
border-radius: 50%;
|
|
1509
|
+
background-color: #fff;
|
|
1510
|
+
position: absolute;
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
.loading-spinner.active {
|
|
1514
|
+
opacity: 1;
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
@keyframes spin {
|
|
1518
|
+
0% { transform: rotate(0deg); }
|
|
1519
|
+
100% { transform: rotate(360deg); }
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
/* 上传中状态的文件信息向右偏移 */
|
|
1523
|
+
.import-dialog-vanilla-file-item.status-uploading .import-dialog-vanilla-file-info {
|
|
1524
|
+
margin-left: 32px;
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1495
1527
|
/* 删除按钮 - 默认隐藏,hover时显示 */
|
|
1496
1528
|
.import-dialog-vanilla-file-remove-btn {
|
|
1497
1529
|
position: absolute;
|
|
@@ -2816,10 +2848,31 @@ class ImportDialogRenderer {
|
|
|
2816
2848
|
if (isError) {
|
|
2817
2849
|
metaContent = `<span class="import-dialog-vanilla-file-error-text">${t("uploadFailed")}</span>`;
|
|
2818
2850
|
} else if (isUploading) {
|
|
2819
|
-
metaContent = `<span
|
|
2851
|
+
metaContent = `<span>${t("uploading")}...</span><span>·</span><span>${fileSize}</span>`;
|
|
2820
2852
|
} else {
|
|
2821
2853
|
metaContent = `<span>${fileExt}</span><span>·</span><span>${fileSize}</span>`;
|
|
2822
2854
|
}
|
|
2855
|
+
if (isUploading) {
|
|
2856
|
+
return `
|
|
2857
|
+
<div class="import-dialog-vanilla-file-item ${statusClass} ${widthClass}" data-file-id="${fileItem.id}">
|
|
2858
|
+
<div class="import-dialog-vanilla-file-loading-icon">
|
|
2859
|
+
<div class="loading-spinner active"></div>
|
|
2860
|
+
</div>
|
|
2861
|
+
<div class="import-dialog-vanilla-file-remove-btn" data-file-index="${index}" title="删除">
|
|
2862
|
+
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2863
|
+
<circle cx="8" cy="8" r="8" fill="rgba(0,0,0)"/>
|
|
2864
|
+
<path d="M5 5L11 11M11 5L5 11" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
|
|
2865
|
+
</svg>
|
|
2866
|
+
</div>
|
|
2867
|
+
<div class="import-dialog-vanilla-file-info">
|
|
2868
|
+
<div class="import-dialog-vanilla-file-name" title="${fileItem.name}">${fileItem.name}</div>
|
|
2869
|
+
<div class="import-dialog-vanilla-file-meta">
|
|
2870
|
+
${metaContent}
|
|
2871
|
+
</div>
|
|
2872
|
+
</div>
|
|
2873
|
+
</div>
|
|
2874
|
+
`;
|
|
2875
|
+
}
|
|
2823
2876
|
return `
|
|
2824
2877
|
<div class="import-dialog-vanilla-file-item ${statusClass} ${widthClass}" data-file-id="${fileItem.id}">
|
|
2825
2878
|
<div class="import-dialog-vanilla-file-icon">
|
|
@@ -2918,6 +2971,7 @@ class ChunkedUploader {
|
|
|
2918
2971
|
fileItem.file.name,
|
|
2919
2972
|
fileItem.file.size
|
|
2920
2973
|
);
|
|
2974
|
+
console.info("upload>>>分片结果", initResult);
|
|
2921
2975
|
fileItem.uploadSessionId = initResult.uploadSessionId;
|
|
2922
2976
|
this.currentFileItem = fileItem;
|
|
2923
2977
|
this.initResumable(initResult);
|
|
@@ -2941,6 +2995,7 @@ class ChunkedUploader {
|
|
|
2941
2995
|
* 初始化Resumable实例
|
|
2942
2996
|
*/
|
|
2943
2997
|
initResumable(initResult) {
|
|
2998
|
+
console.log("[分片上传] 初始化分片上传...", initResult);
|
|
2944
2999
|
if (this.resumable) {
|
|
2945
3000
|
this.resumable.cancel();
|
|
2946
3001
|
}
|
|
@@ -2959,6 +3014,7 @@ class ChunkedUploader {
|
|
|
2959
3014
|
forceChunkSize: true
|
|
2960
3015
|
};
|
|
2961
3016
|
const finalConfig = { ...defaultConfig, ...customConfig };
|
|
3017
|
+
console.info("finalConfig>>>分片上传配置", finalConfig);
|
|
2962
3018
|
this.resumable = new Resumable(finalConfig);
|
|
2963
3019
|
this.bindResumableEvents();
|
|
2964
3020
|
}
|
|
@@ -2969,6 +3025,7 @@ class ChunkedUploader {
|
|
|
2969
3025
|
this.resumable.on("progress", () => {
|
|
2970
3026
|
var _a, _b, _c, _d;
|
|
2971
3027
|
const progress = Math.floor(this.resumable.progress() * 100);
|
|
3028
|
+
console.log(`[Resumable分片上传] 进度: ${progress}%`);
|
|
2972
3029
|
if (this.currentFileItem) {
|
|
2973
3030
|
this.currentFileItem.progress = Math.min(progress, 90);
|
|
2974
3031
|
(_b = (_a = this.callbacks).onProgress) == null ? void 0 : _b.call(
|
|
@@ -2980,6 +3037,7 @@ class ChunkedUploader {
|
|
|
2980
3037
|
(_d = (_c = this.callbacks).onUpdate) == null ? void 0 : _d.call(_c);
|
|
2981
3038
|
});
|
|
2982
3039
|
this.resumable.on("fileSuccess", () => {
|
|
3040
|
+
console.log("[Resumable分片上传] 文件上传成功");
|
|
2983
3041
|
this.handleResumableComplete();
|
|
2984
3042
|
});
|
|
2985
3043
|
this.resumable.on("error", (message) => {
|
|
@@ -2987,6 +3045,7 @@ class ChunkedUploader {
|
|
|
2987
3045
|
this.handleResumableError(message);
|
|
2988
3046
|
});
|
|
2989
3047
|
this.resumable.on("fileAdded", () => {
|
|
3048
|
+
console.info("fileAdded>>>开始上传");
|
|
2990
3049
|
this.resumable.upload();
|
|
2991
3050
|
});
|
|
2992
3051
|
}
|
|
@@ -3005,6 +3064,7 @@ class ChunkedUploader {
|
|
|
3005
3064
|
this.currentFileItem.progress = 100;
|
|
3006
3065
|
}
|
|
3007
3066
|
this.uploadCompleteResolve(mergeResult);
|
|
3067
|
+
console.log("合并分片成功>>>uploadCompleteResolve", mergeResult);
|
|
3008
3068
|
this.cleanup();
|
|
3009
3069
|
} catch (error) {
|
|
3010
3070
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
@@ -3070,9 +3130,6 @@ class ImportDialogUploader {
|
|
|
3070
3130
|
__publicField(this, "callbacks");
|
|
3071
3131
|
// 分片上传器实例
|
|
3072
3132
|
__publicField(this, "chunkedUploader", null);
|
|
3073
|
-
// 并发上传队列
|
|
3074
|
-
__publicField(this, "uploadQueue", []);
|
|
3075
|
-
__publicField(this, "activeUploads", 0);
|
|
3076
3133
|
// 上传状态
|
|
3077
3134
|
__publicField(this, "uploadFileList", []);
|
|
3078
3135
|
//上传文件列表
|
|
@@ -3105,12 +3162,6 @@ class ImportDialogUploader {
|
|
|
3105
3162
|
});
|
|
3106
3163
|
}
|
|
3107
3164
|
}
|
|
3108
|
-
/**
|
|
3109
|
-
* 获取并发限制数
|
|
3110
|
-
*/
|
|
3111
|
-
get concurrentLimit() {
|
|
3112
|
-
return this.config.concurrentLimit != null ? this.config.concurrentLimit : 3;
|
|
3113
|
-
}
|
|
3114
3165
|
/**
|
|
3115
3166
|
* 判断是否应该使用分片上传
|
|
3116
3167
|
* 条件:配置了chunkedUpload 且 是单文件模式
|
|
@@ -3134,14 +3185,12 @@ class ImportDialogUploader {
|
|
|
3134
3185
|
this.isUploading = false;
|
|
3135
3186
|
this.uploadMessage = "";
|
|
3136
3187
|
this.uploadMessageType = "info";
|
|
3137
|
-
this.uploadQueue = [];
|
|
3138
|
-
this.activeUploads = 0;
|
|
3139
3188
|
}
|
|
3140
3189
|
/**
|
|
3141
3190
|
* 文件上传之前的校验 选择文件时调用
|
|
3142
3191
|
*/
|
|
3143
3192
|
beforeUpload(files) {
|
|
3144
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
3193
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
3145
3194
|
const fileArray = Array.isArray(files) ? files : [files];
|
|
3146
3195
|
if (!fileArray.length) {
|
|
3147
3196
|
(_b = (_a = this.callbacks).onMessage) == null ? void 0 : _b.call(_a, "请选择文件", "warning");
|
|
@@ -3187,9 +3236,27 @@ class ImportDialogUploader {
|
|
|
3187
3236
|
}
|
|
3188
3237
|
(_h = (_g = this.callbacks).onUpdate) == null ? void 0 : _h.call(_g);
|
|
3189
3238
|
(_j = (_i = this.callbacks).onFileChange) == null ? void 0 : _j.call(_i, this.uploadFileList);
|
|
3190
|
-
this.
|
|
3239
|
+
if (this.shouldUseChunkedUpload()) {
|
|
3240
|
+
if (((_k = this.config.uploadConfig) == null ? void 0 : _k.autoUpload) !== false) {
|
|
3241
|
+
this.processChunkedUpload();
|
|
3242
|
+
}
|
|
3243
|
+
} else {
|
|
3244
|
+
this.processFilesWithCustomUpload();
|
|
3245
|
+
}
|
|
3191
3246
|
return true;
|
|
3192
3247
|
}
|
|
3248
|
+
/**
|
|
3249
|
+
* 处理分片上传
|
|
3250
|
+
* 仅在配置了 chunkedUpload 时调用
|
|
3251
|
+
*/
|
|
3252
|
+
async processChunkedUpload() {
|
|
3253
|
+
const pendingFiles = this.uploadFileList.filter(
|
|
3254
|
+
(f) => f.status === "pending"
|
|
3255
|
+
);
|
|
3256
|
+
for (const fileItem of pendingFiles) {
|
|
3257
|
+
await this.uploadSingleFile(fileItem);
|
|
3258
|
+
}
|
|
3259
|
+
}
|
|
3193
3260
|
/**
|
|
3194
3261
|
* 使用 customUpload 预处理文件
|
|
3195
3262
|
* 仅在配置了 customUpload 时才调用
|
|
@@ -3268,12 +3335,6 @@ class ImportDialogUploader {
|
|
|
3268
3335
|
(_c = (_b = this.callbacks).onMessage) == null ? void 0 : _c.call(_b, "文件正在上传中,无法删除", "warning");
|
|
3269
3336
|
return false;
|
|
3270
3337
|
}
|
|
3271
|
-
const queueIndex = this.uploadQueue.findIndex(
|
|
3272
|
-
(q) => q.id === fileItem.id
|
|
3273
|
-
);
|
|
3274
|
-
if (queueIndex !== -1) {
|
|
3275
|
-
this.uploadQueue.splice(queueIndex, 1);
|
|
3276
|
-
}
|
|
3277
3338
|
this.uploadFileList.splice(index, 1);
|
|
3278
3339
|
this.fileList.splice(index, 1);
|
|
3279
3340
|
} else {
|
|
@@ -3286,7 +3347,6 @@ class ImportDialogUploader {
|
|
|
3286
3347
|
return false;
|
|
3287
3348
|
}
|
|
3288
3349
|
}
|
|
3289
|
-
this.uploadQueue = [];
|
|
3290
3350
|
this.uploadFileList = [];
|
|
3291
3351
|
this.fileList = [];
|
|
3292
3352
|
}
|
|
@@ -3300,38 +3360,12 @@ class ImportDialogUploader {
|
|
|
3300
3360
|
(_i = (_h = this.callbacks).onUpdate) == null ? void 0 : _i.call(_h);
|
|
3301
3361
|
return true;
|
|
3302
3362
|
}
|
|
3303
|
-
/**
|
|
3304
|
-
* 将文件加入上传队列并启动处理
|
|
3305
|
-
*/
|
|
3306
|
-
enqueueUpload(fileItems) {
|
|
3307
|
-
const newItems = fileItems.filter(
|
|
3308
|
-
(item) => !this.uploadQueue.some((q) => q.id === item.id)
|
|
3309
|
-
);
|
|
3310
|
-
this.uploadQueue.push(...newItems);
|
|
3311
|
-
this.processUploadQueue();
|
|
3312
|
-
}
|
|
3313
|
-
/**
|
|
3314
|
-
* 处理上传队列(支持并发)
|
|
3315
|
-
*/
|
|
3316
|
-
processUploadQueue() {
|
|
3317
|
-
while (this.uploadQueue.length > 0 && this.activeUploads < this.concurrentLimit) {
|
|
3318
|
-
const fileItem = this.uploadQueue.shift();
|
|
3319
|
-
if (fileItem.status !== "pending") {
|
|
3320
|
-
continue;
|
|
3321
|
-
}
|
|
3322
|
-
this.activeUploads++;
|
|
3323
|
-
this.uploadSingleFile(fileItem).finally(() => {
|
|
3324
|
-
this.activeUploads--;
|
|
3325
|
-
this.processUploadQueue();
|
|
3326
|
-
});
|
|
3327
|
-
}
|
|
3328
|
-
}
|
|
3329
3363
|
/**
|
|
3330
3364
|
* 单个文件分片上传
|
|
3331
3365
|
* @param fileItem
|
|
3332
3366
|
*/
|
|
3333
3367
|
async uploadSingleFile(fileItem) {
|
|
3334
|
-
var _a, _b, _c, _d, _e, _f
|
|
3368
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3335
3369
|
fileItem.status = "uploading";
|
|
3336
3370
|
fileItem.progress = 0;
|
|
3337
3371
|
this.isUploading = true;
|
|
@@ -3341,16 +3375,13 @@ class ImportDialogUploader {
|
|
|
3341
3375
|
fileItem.status = "success";
|
|
3342
3376
|
fileItem.progress = 100;
|
|
3343
3377
|
(_d = (_c = this.callbacks).onUploadSuccess) == null ? void 0 : _d.call(_c, fileItem, fileItem.response);
|
|
3378
|
+
return fileItem.response;
|
|
3344
3379
|
} catch (error) {
|
|
3345
3380
|
fileItem.status = "error";
|
|
3346
3381
|
fileItem.errorMessage = error instanceof Error ? error.message : "上传失败";
|
|
3347
3382
|
(_f = (_e = this.callbacks).onUploadError) == null ? void 0 : _f.call(_e, fileItem, error);
|
|
3383
|
+
throw error;
|
|
3348
3384
|
}
|
|
3349
|
-
this.isUploading = this.uploadFileList.some(
|
|
3350
|
-
(f) => f.status === "uploading"
|
|
3351
|
-
);
|
|
3352
|
-
(_h = (_g = this.callbacks).onUpdate) == null ? void 0 : _h.call(_g);
|
|
3353
|
-
this.updateOverallProgress();
|
|
3354
3385
|
}
|
|
3355
3386
|
/**
|
|
3356
3387
|
* 分片上传
|
|
@@ -3362,21 +3393,32 @@ class ImportDialogUploader {
|
|
|
3362
3393
|
return await this.chunkedUploader.upload(fileItem);
|
|
3363
3394
|
}
|
|
3364
3395
|
/**
|
|
3365
|
-
*
|
|
3396
|
+
* 手动触发上传(用于延迟上传场景)
|
|
3397
|
+
* 分片上传:直接调用 uploadSingleFile 并等待完成
|
|
3398
|
+
* 普通上传:已在选择文件时通过 customUpload 处理完成
|
|
3366
3399
|
*/
|
|
3367
3400
|
async startUpload() {
|
|
3368
|
-
if (this.shouldUseChunkedUpload()) {
|
|
3369
|
-
|
|
3401
|
+
if (!this.shouldUseChunkedUpload()) {
|
|
3402
|
+
return;
|
|
3370
3403
|
}
|
|
3371
|
-
}
|
|
3372
|
-
/**
|
|
3373
|
-
* 启动分片上传
|
|
3374
|
-
*/
|
|
3375
|
-
async startChunkedUploadFiles() {
|
|
3376
3404
|
const pendingFiles = this.uploadFileList.filter(
|
|
3377
3405
|
(f) => f.status === "pending"
|
|
3378
3406
|
);
|
|
3379
|
-
|
|
3407
|
+
if (pendingFiles.length === 0) {
|
|
3408
|
+
return;
|
|
3409
|
+
}
|
|
3410
|
+
const results = [];
|
|
3411
|
+
for (const fileItem of pendingFiles) {
|
|
3412
|
+
try {
|
|
3413
|
+
const result = await this.uploadSingleFile(fileItem);
|
|
3414
|
+
if (result) {
|
|
3415
|
+
results.push(result);
|
|
3416
|
+
}
|
|
3417
|
+
} catch (error) {
|
|
3418
|
+
console.error(`文件 ${fileItem.file.name} 上传失败:`, error);
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3421
|
+
return results;
|
|
3380
3422
|
}
|
|
3381
3423
|
/**
|
|
3382
3424
|
* 暂停上传(仅分片上传支持)
|
|
@@ -3398,8 +3440,6 @@ class ImportDialogUploader {
|
|
|
3398
3440
|
cancelUpload() {
|
|
3399
3441
|
var _a, _b, _c;
|
|
3400
3442
|
(_a = this.chunkedUploader) == null ? void 0 : _a.cancel();
|
|
3401
|
-
this.uploadQueue = [];
|
|
3402
|
-
this.activeUploads = 0;
|
|
3403
3443
|
this.isUploading = false;
|
|
3404
3444
|
this.uploadMessage = "上传已取消";
|
|
3405
3445
|
this.uploadMessageType = "info";
|
|
@@ -3969,7 +4009,8 @@ const _ImportDialog = class _ImportDialog {
|
|
|
3969
4009
|
this.updateModal();
|
|
3970
4010
|
}
|
|
3971
4011
|
try {
|
|
3972
|
-
await this.uploader.startUpload();
|
|
4012
|
+
const chunkResult = await this.uploader.startUpload();
|
|
4013
|
+
console.log("[分片上传] 分片上传结果:", chunkResult);
|
|
3973
4014
|
} catch (error) {
|
|
3974
4015
|
console.error("[ImportDialog] 上传失败:", error);
|
|
3975
4016
|
this.showMessage("上传失败,请重试", "error");
|