浏览代码

百度网盘的上传实时进度更新

onecold 8 月之前
父节点
当前提交
21774e40ac
共有 2 个文件被更改,包括 93 次插入27 次删除
  1. 92 21
      entry/src/main/ets/common/util/RemoteDriveManager.ets
  2. 1 6
      entry/src/main/ets/pages/UploadMusicPage.ets

+ 92 - 21
entry/src/main/ets/common/util/RemoteDriveManager.ets

@@ -50,6 +50,19 @@ interface TaskBaiduUploadResult {
   songId?: string;
   uploadId?: string;
   progress?: number;
+  currentPart?: number;
+  totalParts?: number;
+}
+
+// TaskPool进度消息接口
+interface BaiduUploadProgressMessage {
+  type: 'progress';
+  progress: number;
+  currentPart?: number;
+  totalParts?: number;
+  stage: 'md5' | 'upload' | 'create';
+  uploadedSize?: number;
+  totalSize?: number;
 }
 
 /**
@@ -81,7 +94,7 @@ async function executeBaiduUpload(params: TaskBaiduUploadParams): Promise<TaskBa
     const PART_SIZE = 4 * 1024 * 1024; // 4MB分片大小
     const totalParts = Math.ceil(fileSize / PART_SIZE);
 
-    // 3. 计算分片MD5列表
+    // 3. 计算分片MD5列表(占总进度的10%)
     const blockMd5List: string[] = [];
     for (let i = 0; i < totalParts; i++) {
       const start = i * PART_SIZE;
@@ -89,6 +102,19 @@ async function executeBaiduUpload(params: TaskBaiduUploadParams): Promise<TaskBa
       const partData = fileData.slice(start, end);
       const md5 = await simpleCalculateMD5(partData);
       blockMd5List.push(md5);
+
+      // 发送MD5计算进度
+      const md5Progress = ((i + 1) / totalParts) * 10;
+      const progressMessage: BaiduUploadProgressMessage = {
+        type: 'progress',
+        progress: md5Progress,
+        currentPart: i + 1,
+        totalParts: totalParts,
+        stage: 'md5',
+        uploadedSize: Math.floor(fileSize * md5Progress / 100),
+        totalSize: fileSize
+      };
+      taskpool.Task.sendData(progressMessage);
     }
 
     // 4. 预上传(第一阶段)
@@ -110,14 +136,17 @@ async function executeBaiduUpload(params: TaskBaiduUploadParams): Promise<TaskBa
     }
     console.info(`heanup 预上传成功,uploadid: ${JSON.stringify(precreateResponse)}`);
     const uploadServer = await simpleLocateUploadServer(accessToken, remotePath, precreateResponse.uploadid!);
-    // 5. 分片上传
+    // 5. 分片上传(占总进度的80%)
     const partsToUpload = precreateResponse.block_list || [];
     Logger.info(`heanup 预上传返回block_list: ${JSON.stringify(partsToUpload)}, errno: ${precreateResponse.errno}`);
 
     // 如果block_list为空,说明所有分片都已存在,直接跳过分片上传
-
     Logger.info( `heanup 需要上传的分片列表: ${JSON.stringify(partsToUpload)}, 总计${partsToUpload.length}个分片`);
 
+    const baseProgress = 10; // MD5计算已完成
+    const uploadProgressRange = 80; // 上传进度范围
+    const uploadedParts = new Set<number>();
+
     for (let i = 0; i < partsToUpload.length; i++) {
       const partSeq = partsToUpload[i];
       const start = partSeq * PART_SIZE;
@@ -127,10 +156,35 @@ async function executeBaiduUpload(params: TaskBaiduUploadParams): Promise<TaskBa
       Logger.info( `heanup 开始上传分片${partSeq}, 大小: ${partData.byteLength}字节`);
       await simpleUploadFilePart(uploadServer, accessToken, remotePath, precreateResponse.uploadid!, partSeq, partData);
       Logger.info(`heanup 分片${partSeq}上传完成`);
+
+      // 记录已上传的分片并发送进度
+      uploadedParts.add(partSeq);
+      const uploadProgress = (uploadedParts.size / partsToUpload.length) * uploadProgressRange;
+      const totalProgress = baseProgress + uploadProgress;
+
+      const progressMessage: BaiduUploadProgressMessage = {
+        type: 'progress',
+        progress: totalProgress,
+        currentPart: uploadedParts.size,
+        totalParts: partsToUpload.length,
+        stage: 'upload',
+        uploadedSize: Math.floor(fileSize * totalProgress / 100),
+        totalSize: fileSize
+      };
+      taskpool.Task.sendData(progressMessage);
     }
 
 
-    // 6. 创建文件(第三阶段)
+    // 6. 创建文件(第三阶段,占总进度的10%)
+    const createFileProgressMessage: BaiduUploadProgressMessage = {
+      type: 'progress',
+      progress: 90,
+      stage: 'create',
+      uploadedSize: Math.floor(fileSize * 0.9),
+      totalSize: fileSize
+    };
+    taskpool.Task.sendData(createFileProgressMessage);
+
     const createFileRequest: TaskCreateFileRequest = {
       path: remotePath,
       size: fileSize,
@@ -143,6 +197,16 @@ async function executeBaiduUpload(params: TaskBaiduUploadParams): Promise<TaskBa
       throw new Error('创建文件失败:未获取到文件路径');
     }
 
+    // 发送完成进度
+    const finalProgressMessage: BaiduUploadProgressMessage = {
+      type: 'progress',
+      progress: 100,
+      stage: 'create',
+      uploadedSize: fileSize,
+      totalSize: fileSize
+    };
+    taskpool.Task.sendData(finalProgressMessage);
+
     return {
       success: true,
       filePath: filePath,
@@ -2815,23 +2879,30 @@ export class RemoteDriveManager {
       Logger.info(TAG, `最终远程路径: ${remotePath}`);
       Logger.info(TAG, '------------------------------');
 
-      // 使用TaskPool执行上传任务
-      const taskId = `baidu-upload-${song.id || Date.now()}`;
+      // 转换路径为百度网盘要求的格式
+      const baiduRemotePath = convertToBaiduPath(remotePath);
+      Logger.info(TAG, `原始路径: ${remotePath}, 转换后路径: ${baiduRemotePath}`);
+
+      // 使用TaskPool执行上传任务(支持进度消息)
       Logger.info(TAG, '创建TaskPool上传任务...');
+      const taskParams: TaskBaiduUploadParams = {
+        filePath: song.filePath,
+        accessToken: accessToken,
+        remotePath: baiduRemotePath,
+        songName: song.name,
+        songId: song.id || `file-${Date.now()}`
+      };
 
-    // 转换路径为百度网盘要求的格式
-    const baiduRemotePath = convertToBaiduPath(remotePath);
-    Logger.info(TAG, `原始路径: ${remotePath}, 转换后路径: ${baiduRemotePath}`);
+      const uploadTask: taskpool.Task = new taskpool.Task(executeBaiduUpload, taskParams);
 
-    const taskParams: TaskBaiduUploadParams = {
-      filePath: song.filePath,
-      accessToken: accessToken,
-      remotePath: baiduRemotePath,
-      songName: song.name,
-      songId: song.id || `file-${Date.now()}`
-    };
-
-    const uploadTask: taskpool.Task = new taskpool.Task(executeBaiduUpload, taskParams);
+      // 设置进度消息接收器
+      uploadTask.onReceiveData((progressData: BaiduUploadProgressMessage) => {
+        // 更新上传进度
+        this.uploadReceivedSize = progressData.uploadedSize || 0;
+        this.uploadTotalSize = progressData.totalSize || 0;
+        Logger.info(TAG, `百度网盘上传进度: ${progressData.progress.toFixed(1)}% (${progressData.currentPart || 0}/${progressData.totalParts || 0} ${progressData.stage})`);
+        this.notifyObservers(RemoteDriveManagerStates.UploadProgress);
+      });
 
       // 提交任务到TaskPool
       Logger.info(TAG, '提交上传任务到TaskPool...');
@@ -2849,9 +2920,8 @@ export class RemoteDriveManager {
 
       Logger.info(TAG, '========== 百度网盘上传任务成功 ==========');
       Logger.info(TAG, `文件名: ${song.name}`);
-      Logger.info(TAG, `文件路径: ${result.filePath || song.filePath}`);
-      Logger.info(TAG, `目标路径: ${result.remotePath || remotePath}`);
-      Logger.info(TAG, `UploadId: ${result.uploadId || 'unknown'}`);
+      Logger.info(TAG, `文件路径: ${song.filePath}`);
+      Logger.info(TAG, `目标路径: ${remotePath}`);
       Logger.info(TAG, `耗时: ${duration} 秒`);
       Logger.info(TAG, '====================================');
 
@@ -2884,6 +2954,7 @@ export class RemoteDriveManager {
 
   
     
+  
   /**
    * 获取错误类型
    * @param error 错误对象

+ 1 - 6
entry/src/main/ets/pages/UploadMusicPage.ets

@@ -1008,12 +1008,7 @@ export struct UploadMusicPage {
     try {
       Logger.info(TAG, '开始上传任务');
 
-      // 显示处理提示
-      promptAction.showToast({
-        message: '正在处理文件...',
-        duration: 2000
-      });
-
+      this.handleCurrentTaskChanged()
       // 构建VideoItem列表
       const songs: VideoItem[] = [];
       let totalFiles = 0;