|
96 | 96 | e.preventDefault(); |
97 | 97 | e.stopPropagation(); |
98 | 98 |
|
99 | | - // 移除拖拽样式 |
100 | | - if (e.currentTarget) { |
101 | | - e.currentTarget.classList.remove('drag-over'); |
| 99 | + // 移除拖拽样式(安全地处理) |
| 100 | + try { |
| 101 | + const target = e.currentTarget || e.target; |
| 102 | + if (target && target.classList && typeof target.classList.remove === 'function') { |
| 103 | + target.classList.remove('drag-over'); |
| 104 | + } |
| 105 | + } catch (error) { |
| 106 | + // 忽略样式移除错误 |
102 | 107 | } |
103 | 108 | } |
104 | 109 |
|
|
161 | 166 | e.stopPropagation(); |
162 | 167 | e.stopImmediatePropagation(); |
163 | 168 |
|
164 | | - // 移除拖拽样式 |
165 | | - if (e.currentTarget) { |
166 | | - e.currentTarget.classList.remove('drag-over'); |
| 169 | + // 移除拖拽样式(安全地处理) |
| 170 | + try { |
| 171 | + const target = e.currentTarget || e.target; |
| 172 | + if (target && target.classList && typeof target.classList.remove === 'function') { |
| 173 | + target.classList.remove('drag-over'); |
| 174 | + } |
| 175 | + } catch (error) { |
| 176 | + // 忽略样式移除错误 |
| 177 | + console.warn('[文件夹上传] 移除拖拽样式时出错:', error); |
167 | 178 | } |
168 | 179 |
|
169 | 180 | // 处理文件夹上传 |
|
193 | 204 | e.stopPropagation(); |
194 | 205 | e.stopImmediatePropagation(); |
195 | 206 |
|
196 | | - // 移除拖拽样式 |
197 | | - if (e.currentTarget) { |
198 | | - e.currentTarget.classList.remove('drag-over'); |
| 207 | + // 移除拖拽样式(安全地处理) |
| 208 | + try { |
| 209 | + const target = e.currentTarget || e.target; |
| 210 | + if (target && target.classList && typeof target.classList.remove === 'function') { |
| 211 | + target.classList.remove('drag-over'); |
| 212 | + } |
| 213 | + } catch (error) { |
| 214 | + // 忽略样式移除错误 |
| 215 | + console.warn('[文件夹上传] 移除拖拽样式时出错:', error); |
199 | 216 | } |
200 | 217 |
|
201 | 218 | // 使用我们的上传逻辑处理大文件 |
|
553 | 570 | const CHUNK_SIZE = 20 * 1024 * 1024; // 20MB |
554 | 571 | const totalChunks = Math.ceil(file.size / CHUNK_SIZE); |
555 | 572 | const fileSizeMB = (file.size / 1024 / 1024).toFixed(2); |
| 573 | + const fileSizeGB = (file.size / 1024 / 1024 / 1024).toFixed(2); |
556 | 574 | const baseUrl = window.location.origin; |
557 | 575 |
|
558 | 576 | // 调试信息:检查文件大小和分块数量 |
559 | | - console.log(`[文件夹上传] 文件: ${relativePath}, 大小: ${fileSizeMB}MB, 分块数: ${totalChunks}`); |
| 577 | + console.group(`[文件夹上传] 开始分块上传`); |
| 578 | + console.log(`文件: ${relativePath}`); |
| 579 | + console.log(`大小: ${fileSizeMB}MB (${fileSizeGB}GB)`); |
| 580 | + console.log(`分块数: ${totalChunks} (每块 ${CHUNK_SIZE / 1024 / 1024}MB)`); |
| 581 | + console.log(`限制: 最大 200 个分块 (4GB)`); |
560 | 582 |
|
561 | 583 | // 前端检查:如果分块数超过200,提前提示 |
562 | 584 | if (totalChunks > 200) { |
563 | 585 | const maxSizeGB = (200 * 20 / 1024).toFixed(1); |
564 | | - throw new Error(`文件过大: ${fileSizeMB}MB (${totalChunks}个分块),超过最大限制 ${maxSizeGB}GB (200个分块)`); |
| 586 | + const errorMsg = `文件过大: ${fileSizeMB}MB (${totalChunks}个分块),超过最大限制 ${maxSizeGB}GB (200个分块)`; |
| 587 | + console.error(`[文件夹上传] ${errorMsg}`); |
| 588 | + console.groupEnd(); |
| 589 | + throw new Error(errorMsg); |
565 | 590 | } |
566 | 591 |
|
567 | 592 | try { |
568 | 593 | // 1. 初始化分块上传 |
| 594 | + console.log(`[文件夹上传] 步骤 1/3: 初始化分块上传...`); |
569 | 595 | const initFormData = new FormData(); |
570 | 596 | initFormData.append('originalFileName', relativePath); |
571 | 597 | initFormData.append('originalFileType', file.type || 'application/octet-stream'); |
|
576 | 602 | if (config && config.uploadChannel) { |
577 | 603 | initUrl.searchParams.set('uploadChannel', config.uploadChannel); |
578 | 604 | } |
| 605 | + |
| 606 | + // 添加认证参数 |
| 607 | + const currentUrl = new URL(window.location.href); |
| 608 | + const authCode = currentUrl.searchParams.get('authCode'); |
| 609 | + if (authCode) { |
| 610 | + initUrl.searchParams.set('authCode', authCode); |
| 611 | + } |
| 612 | + |
| 613 | + console.log(`[文件夹上传] 初始化请求 URL: ${initUrl.toString()}`); |
| 614 | + console.log(`[文件夹上传] 请求头:`, getUploadHeaders()); |
579 | 615 |
|
580 | 616 | const initResponse = await fetch(initUrl.toString(), { |
581 | 617 | method: 'POST', |
582 | 618 | body: initFormData, |
583 | 619 | headers: getUploadHeaders() |
584 | 620 | }); |
585 | 621 |
|
| 622 | + console.log(`[文件夹上传] 初始化响应状态: ${initResponse.status} ${initResponse.statusText}`); |
| 623 | + |
586 | 624 | if (!initResponse.ok) { |
587 | 625 | const errorText = await initResponse.text(); |
588 | | - throw new Error(`初始化分块上传失败: ${errorText}`); |
| 626 | + console.error(`[文件夹上传] 初始化失败响应:`, errorText); |
| 627 | + console.groupEnd(); |
| 628 | + throw new Error(`初始化分块上传失败 (${initResponse.status}): ${errorText}`); |
589 | 629 | } |
590 | 630 |
|
591 | 631 | const initResult = await initResponse.json(); |
| 632 | + console.log(`[文件夹上传] 初始化结果:`, initResult); |
592 | 633 | const uploadId = initResult.uploadId; |
593 | 634 |
|
594 | 635 | if (!uploadId) { |
| 636 | + console.error(`[文件夹上传] 初始化失败: 未返回 uploadId`); |
| 637 | + console.groupEnd(); |
595 | 638 | throw new Error('初始化分块上传失败: 未返回 uploadId'); |
596 | 639 | } |
597 | 640 |
|
| 641 | + console.log(`[文件夹上传] 步骤 2/3: 上传分块 (uploadId: ${uploadId})...`); |
| 642 | + |
598 | 643 | // 2. 上传所有分块 |
599 | 644 | const uploadPromises = []; |
600 | 645 | let completedChunks = 0; |
|
647 | 692 | } |
648 | 693 |
|
649 | 694 | // 等待所有分块上传完成 |
| 695 | + console.log(`[文件夹上传] 所有分块上传完成 (${totalChunks}/${totalChunks})`); |
650 | 696 | await Promise.all(uploadPromises); |
651 | 697 |
|
652 | 698 | // 3. 合并分块 |
| 699 | + console.log(`[文件夹上传] 步骤 3/3: 合并分块...`); |
653 | 700 | if (progressCallback) { |
654 | 701 | progressCallback({ current: totalChunks, total: totalChunks, merging: true }); |
655 | 702 | } |
|
679 | 726 | mergeUrl.searchParams.set('uploadChannel', config.uploadChannel); |
680 | 727 | } |
681 | 728 |
|
| 729 | + console.log(`[文件夹上传] 合并请求 URL: ${mergeUrl.toString()}`); |
682 | 730 | const mergeResponse = await fetch(mergeUrl.toString(), { |
683 | 731 | method: 'POST', |
684 | 732 | body: mergeFormData, |
685 | 733 | headers: getUploadHeaders() |
686 | 734 | }); |
687 | 735 |
|
| 736 | + console.log(`[文件夹上传] 合并响应状态: ${mergeResponse.status} ${mergeResponse.statusText}`); |
| 737 | + |
688 | 738 | if (!mergeResponse.ok) { |
689 | 739 | const errorText = await mergeResponse.text(); |
690 | | - throw new Error(`合并分块失败: ${errorText}`); |
| 740 | + console.error(`[文件夹上传] 合并失败响应:`, errorText); |
| 741 | + console.groupEnd(); |
| 742 | + throw new Error(`合并分块失败 (${mergeResponse.status}): ${errorText}`); |
691 | 743 | } |
692 | 744 |
|
693 | 745 | const mergeResult = await mergeResponse.json(); |
| 746 | + console.log(`[文件夹上传] 合并结果:`, mergeResult); |
694 | 747 |
|
695 | 748 | // 如果返回的是异步处理状态,需要轮询检查状态 |
696 | 749 | if (mergeResult.status === 'processing' || mergeResult.status === 'merging') { |
| 750 | + console.log(`[文件夹上传] 合并处理中,等待完成...`); |
697 | 751 | if (progressCallback) { |
698 | 752 | progressCallback({ current: totalChunks, total: totalChunks, merging: true, waiting: true }); |
699 | 753 | } |
700 | | - return await waitForMergeCompletion(uploadId, baseUrl); |
| 754 | + const finalResult = await waitForMergeCompletion(uploadId, baseUrl); |
| 755 | + console.log(`[文件夹上传] 分块上传完成!`); |
| 756 | + console.groupEnd(); |
| 757 | + return finalResult; |
701 | 758 | } |
702 | 759 |
|
| 760 | + console.log(`[文件夹上传] 分块上传完成!`); |
| 761 | + console.groupEnd(); |
703 | 762 | return mergeResult; |
704 | 763 | } catch (error) { |
705 | | - console.error('分块上传失败:', error); |
| 764 | + console.error('[文件夹上传] 分块上传失败:', error); |
| 765 | + console.groupEnd(); |
706 | 766 | throw error; |
707 | 767 | } |
708 | 768 | } |
|
0 commit comments