1
- import { computed } from 'vue' ;
2
1
import { useRoute } from 'vue-router' ;
2
+ import { computed , ref , watch } from 'vue' ;
3
3
import { useWebSocket } from '@vueuse/core' ;
4
4
import { createDiscreteApi , darkTheme } from 'naive-ui' ;
5
5
import { useFileManageStore } from '@/store/modules/fileManage.ts' ;
@@ -14,6 +14,8 @@ import type { RouteRecordNameGeneric } from 'vue-router';
14
14
import type { ConfigProviderProps , UploadFileInfo } from 'naive-ui'
15
15
import type { MessageApiInjection } from 'naive-ui/es/message/src/MessageProvider' ;
16
16
import type { IFileManage , IFileManageConnectData , IFileManageSftpFileItem } from '@/hooks/interface' ;
17
+ import { message } from '@/languages/modules' ;
18
+ import { PercentFilled } from '@vicons/material' ;
17
19
18
20
export enum MessageType {
19
21
CONNECT = 'CONNECT' ,
@@ -227,23 +229,14 @@ const initSocketEvent = (socket: WebSocket, t: any) => {
227
229
mittBus . emit ( 'reload-table' ) ;
228
230
}
229
231
230
- if ( message . cmd === 'upload' && message . data ! == 'ok' ) {
232
+ if ( message . cmd === 'upload' && message . data = == 'ok' ) {
231
233
fileManageStore . setReceived ( true ) ;
232
234
233
- socket . send (
234
- JSON . stringify ( {
235
- cmd : 'upload' ,
236
- type : 'SFTP_DATA' ,
237
- id : message . id ,
238
- raw : '' ,
239
- data : JSON . stringify ( {
240
- offSet : 0 ,
241
- merge : true ,
242
- size : 0 ,
243
- path : message . data
244
- } )
245
- } )
246
- ) ;
235
+ globalTipsMessage . success ( t ( 'UploadSuccess' ) ) ;
236
+ }
237
+
238
+ if ( message . cmd === 'upload' && message . data !== 'ok' ) {
239
+ fileManageStore . setReceived ( true ) ;
247
240
}
248
241
249
242
if ( message . cmd === 'download' && message . data ) {
@@ -272,7 +265,16 @@ const initSocketEvent = (socket: WebSocket, t: any) => {
272
265
}
273
266
274
267
case MessageType . SFTP_BINARY : {
275
- receivedBuffers . push ( message . raw ) ;
268
+ const binaryString = atob ( message . raw ) ;
269
+ const len = binaryString . length ;
270
+ const bytes = new Uint8Array ( len ) ;
271
+
272
+
273
+ for ( let i = 0 ; i < len ; i ++ ) {
274
+ bytes [ i ] = binaryString . charCodeAt ( i ) ;
275
+ }
276
+
277
+ receivedBuffers . push ( bytes ) ;
276
278
277
279
break ;
278
280
}
@@ -425,7 +427,7 @@ const generateUploadChunks = async (
425
427
socket : WebSocket ,
426
428
fileInfo : UploadFileInfo ,
427
429
CHUNK_SIZE : number ,
428
- sentChunks : number
430
+ sentChunks : Ref < number >
429
431
) => {
430
432
const fileManageStore = useFileManageStore ( ) ;
431
433
@@ -448,13 +450,13 @@ const generateUploadChunks = async (
448
450
const arrayBuffer : ArrayBuffer = await sliceChunk . arrayBuffer ( ) ;
449
451
const base64String : string = arrayBufferToBase64 ( arrayBuffer ) ;
450
452
451
- sendData . offSet = sentChunks * CHUNK_SIZE ;
453
+ sendData . offSet = sentChunks . value * CHUNK_SIZE ;
452
454
sendBody . raw = base64String ;
453
455
sendBody . data = JSON . stringify ( sendData ) ;
454
456
455
457
socket . send ( JSON . stringify ( sendBody ) ) ;
456
458
457
- sentChunks ++ ;
459
+ sentChunks . value ++
458
460
459
461
return new Promise < boolean > ( resolve => {
460
462
const interval = setInterval ( ( ) => {
@@ -469,55 +471,93 @@ const generateUploadChunks = async (
469
471
/**
470
472
* @description 上传文件
471
473
*/
472
- const handleFileUpload = (
474
+ const handleFileUpload = async (
473
475
socket : WebSocket ,
474
- fileList : Ref < Array < UploadFileInfo > > ,
475
- onProgress : any ,
476
+ uploadFileList : Ref < Array < UploadFileInfo > > ,
477
+ _onProgress : any ,
476
478
onFinish : ( ) => void ,
477
- onError : ( ) => void
479
+ onError : ( ) => void ,
480
+ t : any
478
481
) => {
482
+ const maxSliceCount = 100 ;
483
+ const maxChunkSize = 1024 * 1024 * 10 ;
479
484
const fileManageStore = useFileManageStore ( ) ;
480
- let CHUNK_SIZE = 1024 * 1024 * 3 ;
481
-
482
- fileList . value . forEach ( async ( fileInfo : UploadFileInfo ) => {
483
- if ( fileInfo . file ) {
484
- let sliceCount = Math . ceil ( fileInfo . file ?. size / CHUNK_SIZE ) ;
485
- let sliceChunks = [ ] ;
486
-
487
- for ( let i = 0 ; i < sliceCount ; i ++ ) {
488
- sliceChunks . push ( fileInfo . file . slice ( i * CHUNK_SIZE , ( i + 1 ) * CHUNK_SIZE ) ) ;
485
+ const loadingMessage = globalTipsMessage . loading ( '上传进度: 0%' , { duration : 1000000000 } ) ;
486
+ const fileInfo = uploadFileList . value [ 0 ] ;
487
+
488
+ let sliceChunks = [ ] ;
489
+ let CHUNK_SIZE = 1024 * 1024 * 5 ;
490
+ let sentChunks = ref ( 0 ) ;
491
+
492
+ const unwatch = watch (
493
+ ( ) => sentChunks . value ,
494
+ ( newValue ) => {
495
+ const percent = ( newValue / sliceChunks . length ) * 100 ;
496
+
497
+ console . log (
498
+ '%c DEBUG[ percent ]:' ,
499
+ 'font-size:13px; background: #1ab394; color:#fff;' ,
500
+ percent
501
+ ) ;
502
+
503
+ loadingMessage . content = `上传进度: ${ Math . floor ( percent ) } %` ;
504
+
505
+ if ( percent >= 100 ) {
506
+ onFinish ( ) ;
507
+ loadingMessage . destroy ( ) ;
508
+ mittBus . emit ( 'reload-table' ) ;
509
+ unwatch ( ) ;
489
510
}
511
+ }
512
+ ) ;
490
513
491
- let sentChunks = 0 ;
492
-
493
- try {
494
- for ( const sliceChunk of sliceChunks ) {
495
- fileManageStore . setReceived ( false ) ;
496
- await generateUploadChunks ( sliceChunk , socket , fileInfo , CHUNK_SIZE , sentChunks ) ;
497
-
498
- sentChunks ++ ;
499
-
500
- const percent = ( sentChunks / sliceChunks . length ) * 100 ;
514
+ if ( fileInfo && fileInfo . file ) {
515
+ let sliceCount = Math . ceil ( fileInfo . file ?. size / CHUNK_SIZE ) ;
516
+
517
+ // 如果切片数量大于最大切片数量,那么调大切片大小
518
+ if ( sliceCount > maxSliceCount ) {
519
+ sliceCount = maxSliceCount ;
520
+ CHUNK_SIZE = Math . ceil ( fileInfo . file ?. size / maxSliceCount ) ;
521
+ }
501
522
502
- console . log (
503
- '%c DEBUG[ percent ]:' ,
504
- 'font-size:13px; background: #1ab394; color:#fff;' ,
505
- percent
506
- ) ;
523
+ // 如果切片大小大于最大切片大小,那么依然调整切片数量
524
+ if ( CHUNK_SIZE > maxChunkSize ) {
525
+ CHUNK_SIZE = maxChunkSize ;
526
+ sliceCount = Math . ceil ( fileInfo . file ?. size / CHUNK_SIZE ) ;
527
+ }
507
528
508
- onProgress ( { percent } ) ;
529
+ for ( let i = 0 ; i < sliceCount ; i ++ ) {
530
+ sliceChunks . push ( fileInfo . file . slice ( i * CHUNK_SIZE , ( i + 1 ) * CHUNK_SIZE ) ) ;
531
+ }
509
532
510
- if ( percent === 100 ) {
511
- onFinish ( ) ;
533
+ try {
534
+ for ( const sliceChunk of sliceChunks ) {
535
+ fileManageStore . setReceived ( false ) ;
512
536
513
- mittBus . emit ( 'reload-table' ) ;
514
- }
515
- }
516
- } catch ( e ) {
517
- onError ( ) ;
537
+ await generateUploadChunks ( sliceChunk , socket , fileInfo , CHUNK_SIZE , sentChunks ) ;
518
538
}
539
+
540
+ // 结束 chunk 发送 merge: true
541
+ socket . send (
542
+ JSON . stringify ( {
543
+ cmd : 'upload' ,
544
+ type : 'SFTP_DATA' ,
545
+ id : fileManageStore . messageId ,
546
+ raw : '' ,
547
+ data : JSON . stringify ( {
548
+ offSet : 0 ,
549
+ merge : true ,
550
+ size : 0 ,
551
+ path : `${ fileManageStore . currentPath } /${ fileInfo . name } `
552
+ } )
553
+ } )
554
+ ) ;
555
+
556
+ } catch ( e ) {
557
+ loadingMessage . destroy ( ) ;
558
+ onError ( ) ;
519
559
}
520
- } ) ;
560
+ }
521
561
} ;
522
562
523
563
/**
@@ -532,17 +572,17 @@ export const useFileManage = (token: string, t: any) => {
532
572
mittBus . on (
533
573
'file-upload' ,
534
574
( {
535
- fileList ,
575
+ uploadFileList ,
536
576
onFinish,
537
577
onError,
538
578
onProgress
539
579
} : {
540
- fileList : Ref < Array < UploadFileInfo > > ;
580
+ uploadFileList : Ref < Array < UploadFileInfo > > ;
541
581
onFinish : ( ) => void ;
542
582
onError : ( ) => void ;
543
583
onProgress : ( e : { percent : number } ) => void ;
544
584
} ) => {
545
- handleFileUpload ( < WebSocket > socket , fileList , onProgress , onFinish , onError ) ;
585
+ handleFileUpload ( < WebSocket > socket , uploadFileList , onProgress , onFinish , onError , t ) ;
546
586
}
547
587
) ;
548
588
0 commit comments