@idooel/components 0.0.2-beta.8 → 0.0.2-beta.9

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idooel/components",
3
- "version": "0.0.2-beta.8",
3
+ "version": "0.0.2-beta.9",
4
4
  "description": "",
5
5
  "private": false,
6
6
  "main": "dist/@idooel/components.umd.js",
@@ -266,7 +266,19 @@ export default {
266
266
 
267
267
  // ==================== 文件状态 ====================
268
268
  uploadingFiles() {
269
- return this.files.filter(file => file.progress !== undefined && !file.success)
269
+ // 筛选条件:有进度信息 (未成功 成功但还没有fileID的切片上传文件)
270
+ // 这样可以确保切片上传完成但异步保存未完成的文件继续显示,避免闪烁
271
+ return this.files.filter(file => {
272
+ if (file.progress === undefined) return false
273
+ if (!file.success) return true
274
+
275
+ // 检查文件是否已经有 fileID(可能在 file.fileID 或 file.response.data.fileID)
276
+ const hasFileID = file.fileID || (file.response && file.response.data && file.response.data.fileID)
277
+
278
+ // 切片上传成功但还没有完成异步保存(没有fileID)的文件继续显示
279
+ // 普通上传成功且已有 fileID 的文件不显示(会在 completedFiles 中显示)
280
+ return file.success && !hasFileID
281
+ })
270
282
  },
271
283
 
272
284
  completedFiles() {
@@ -316,7 +328,22 @@ export default {
316
328
  */
317
329
  removeFromArrays(file, arrays, key = 'fileID') {
318
330
  return arrays.map(arr =>
319
- arr.filter(item => item[key] !== file[key] && item.id !== file.id)
331
+ arr.filter(item => {
332
+ // 如果 fileID 都存在且相等,则移除
333
+ if (item[key] && file[key] && item[key] === file[key]) {
334
+ return false
335
+ }
336
+ // 如果 id 都存在且相等,则移除
337
+ if (item.id && file.id && item.id === file.id) {
338
+ return false
339
+ }
340
+ // 如果文件名相同,也考虑移除(额外的安全检查)
341
+ if (item.name && file.name && item.name === file.name && item[key] === file[key]) {
342
+ return false
343
+ }
344
+ // 否则保留
345
+ return true
346
+ })
320
347
  )
321
348
  },
322
349
 
@@ -384,15 +411,37 @@ export default {
384
411
  console.log('fetchFileWithFileId error:', error)
385
412
  }
386
413
  },
414
+
415
+ /**
416
+ * 调用服务器删除文件 API
417
+ */
418
+ async deleteFiles (ids) {
419
+ if (!ids) {
420
+ console.warn('No fileID provided for deletion')
421
+ return
422
+ }
423
+
424
+ if (type.isArray(ids)) {
425
+ ids = ids.join(',')
426
+ }
427
+
428
+ try {
429
+ await net.remove(`/api-file/workbench/file?ids=${ids}`)
430
+ console.log('File deleted from server:', ids)
431
+ } catch (error) {
432
+ console.error('Failed to delete file from server:', error)
433
+ throw error // 重新抛出错误,让调用方处理
434
+ }
435
+ },
387
436
 
388
437
  /**
389
438
  * 处理文件删除
390
439
  */
391
- handleClickDelete(file) {
392
- const { fileID } = file
393
- console.log('Deleting file:', { name: file.name, fileID })
440
+ async handleClickDelete(file) {
441
+ const { fileID, name } = file
442
+ console.log('Deleting file:', { name, fileID })
394
443
 
395
- // 从上传组件中移除文件
444
+ // 先从上传组件中移除文件
396
445
  if (this.$refs[this.uploadRef]) {
397
446
  this.$refs[this.uploadRef].remove(file)
398
447
  }
@@ -402,6 +451,17 @@ export default {
402
451
 
403
452
  console.log('After deletion - files:', this.files.length, 'buildedFiles:', this.buildedFiles.length)
404
453
 
454
+ // 如果有 fileID,调用服务器删除 API
455
+ if (fileID) {
456
+ try {
457
+ await this.deleteFiles(fileID)
458
+ } catch (error) {
459
+ console.error('Failed to delete file from server:', error)
460
+ // 可以选择提示用户或回滚操作
461
+ // 这里仅记录错误,不影响前端显示
462
+ }
463
+ }
464
+
405
465
  // 多文件模式下,如果删除最后一个文件,重置 groupId
406
466
  if (this.multiple && this.buildedFiles.length === 0) {
407
467
  this.groupId = null
@@ -454,6 +514,17 @@ export default {
454
514
  } else {
455
515
  // 单文件模式:只保留最新的文件
456
516
  this.buildedFiles = newBuildedFiles
517
+
518
+ // 从 files 数组中移除已完成的文件(普通上传),避免重复显示
519
+ if (newBuildedFiles.length > 0 && newBuildedFiles[0].fileID) {
520
+ this.$nextTick(() => {
521
+ this.files = this.files.filter(file => {
522
+ const fileID = file.fileID || (file.response && file.response.data && file.response.data.fileID)
523
+ return fileID !== newBuildedFiles[0].fileID
524
+ })
525
+ console.log('Removed completed file from upload list (single mode)')
526
+ })
527
+ }
457
528
  }
458
529
 
459
530
  this.logFileStatus()
@@ -479,6 +550,16 @@ export default {
479
550
  if (trulyNewFiles.length > 0) {
480
551
  this.buildedFiles = [...this.buildedFiles, ...trulyNewFiles]
481
552
  console.log('Added new files, total buildedFiles:', this.buildedFiles.length)
553
+
554
+ // 从 files 数组中移除已完成的文件(普通上传),避免重复显示
555
+ this.$nextTick(() => {
556
+ const completedFileIDs = new Set(trulyNewFiles.map(f => f.fileID))
557
+ this.files = this.files.filter(file => {
558
+ const fileID = file.fileID || (file.response && file.response.data && file.response.data.fileID)
559
+ return !completedFileIDs.has(fileID)
560
+ })
561
+ console.log('Removed completed files from upload list')
562
+ })
482
563
  }
483
564
 
484
565
  // 更新现有文件的状态(包括新添加的文件)
@@ -508,8 +589,10 @@ export default {
508
589
 
509
590
  /**
510
591
  * 异步保存文件到服务器
592
+ * @param {FormData} payloads - 上传参数
593
+ * @param {Object} uploadingFile - 正在上传的文件对象(可选)
511
594
  */
512
- async saveToServerAsyncPage(payloads = {}) {
595
+ async saveToServerAsyncPage(payloads = {}, uploadingFile = null) {
513
596
  try {
514
597
  const response = await net.post('zuul/api-file/workbench/file/temp/saveToServerAsyncPage', payloads, {
515
598
  headers: {
@@ -520,6 +603,68 @@ export default {
520
603
  const { data } = response
521
604
  if (data !== 'saveToServerAsyncPage') {
522
605
  clearInterval(this.saveToServerAsyncPageTimer)
606
+ console.log('Chunk upload async save completed, file data:', data)
607
+
608
+ const { fileID, groupID, name } = data
609
+
610
+ // 根据上传模式处理文件信息
611
+ if (this.multiple) {
612
+ // 多文件模式:更新 groupID 并追加文件到列表
613
+ if (groupID) {
614
+ this.groupId = groupID
615
+ console.log('Updated groupId from server:', groupID)
616
+ }
617
+
618
+ // 检查文件是否已存在,避免重复添加
619
+ const fileExists = this.buildedFiles.some(file => file.fileID === fileID)
620
+ if (!fileExists && fileID) {
621
+ // 将服务器返回的完整文件信息追加到文件列表
622
+ // 添加必要的显示属性
623
+ const fileData = {
624
+ ...data,
625
+ success: true // 标记为上传成功
626
+ }
627
+
628
+ // 先添加到已完成列表
629
+ this.buildedFiles.push(fileData)
630
+ console.log('File added to list:', name, 'Total files:', this.buildedFiles.length)
631
+
632
+ // 使用 nextTick 确保视图更新后再移除上传列表中的文件,避免闪烁
633
+ this.$nextTick(() => {
634
+ // 从上传列表中精确移除对应的文件
635
+ if (uploadingFile) {
636
+ // 如果有文件对象引用,直接移除该文件
637
+ this.files = this.files.filter(file => file.id !== uploadingFile.id)
638
+ console.log('Removed uploading file by id:', uploadingFile.id)
639
+ } else {
640
+ // 否则根据文件名移除
641
+ this.files = this.files.filter(file => file.name !== name)
642
+ console.log('Removed uploading file by name:', name)
643
+ }
644
+ })
645
+
646
+ // 触发 change 事件通知父组件
647
+ this.$emit('change', this.fileIds)
648
+ this.$emit('on-success', this.fileResponseData)
649
+ } else {
650
+ console.log('File already exists or invalid fileID, skip adding')
651
+ }
652
+ } else {
653
+ // 单文件模式:替换文件列表
654
+ if (fileID) {
655
+ const fileData = {
656
+ ...data,
657
+ success: true // 标记为上传成功
658
+ }
659
+ this.buildedFiles = [fileData]
660
+ this.files = [] // 清空上传列表
661
+ console.log('Single file updated:', name)
662
+
663
+ // 触发 change 事件通知父组件更新 value
664
+ this.$emit('change', fileID)
665
+ this.$emit('on-success', data)
666
+ }
667
+ }
523
668
  }
524
669
  } catch (error) {
525
670
  console.error('saveToServerAsyncPage error:', error)
@@ -634,7 +779,7 @@ export default {
634
779
 
635
780
  if (chunk && success && !active) {
636
781
  console.log('chunk end')
637
- this.handleChunkComplete(response)
782
+ this.handleChunkComplete(response, newFile)
638
783
  }
639
784
  },
640
785
 
@@ -676,20 +821,30 @@ export default {
676
821
 
677
822
  /**
678
823
  * 处理分片上传完成
824
+ * @param {Object} response - 上传响应
825
+ * @param {Object} uploadingFile - 正在上传的文件对象(可选)
679
826
  */
680
- handleChunkComplete(response) {
827
+ handleChunkComplete(response, uploadingFile = null) {
681
828
  const { data: { file, type } } = response
682
829
  const payloads = {
683
830
  filePath: file.match(/\/cw(.*)/) ? file.match(/\/cw(.*)/)[0] : void 0,
684
831
  asyncID: uuidv4(),
832
+ groupID: this.groupId,
685
833
  isDeleteOrigin: false,
686
834
  toImage: type === 'pdf',
687
835
  unzip: type === 'zip',
688
836
  _csrf: localStorage.getItem('token')
689
837
  }
838
+
839
+ const formData = new FormData()
840
+
841
+ Object.keys(payloads).forEach(key => {
842
+ formData.append(key, payloads[key])
843
+ })
690
844
 
845
+ // 将上传文件对象传递给异步保存方法
691
846
  this.saveToServerAsyncPageTimer = setInterval(() => {
692
- this.saveToServerAsyncPage(payloads)
847
+ this.saveToServerAsyncPage(formData, uploadingFile)
693
848
  }, CONSTANTS.SAVE_INTERVAL)
694
849
  },
695
850