From 484e68a82d90ed457e1be25646357700b888ee48 Mon Sep 17 00:00:00 2001 From: x1ao4 Date: Thu, 28 Aug 2025 22:05:29 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=B8=BA=E6=96=87=E4=BB=B6=E5=A4=B9/?= =?UTF-8?q?=E5=88=86=E4=BA=AB=E8=AF=A6=E6=83=85=E5=8A=A0=E8=BD=BD=E5=BC=95?= =?UTF-8?q?=E5=85=A5=E6=97=A0=E6=84=9F=E8=87=AA=E5=8A=A8=E9=87=8D=E8=AF=95?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E5=A4=B1=E8=B4=A5=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增:在 `getSavepathDetail` 失败时自动无感重试一次 - 仅在 `#fileSelectModal` 仍显示时触发重试,避免误重试 - 为请求参数追加 `_ts` 时间戳,绕过浏览器/代理缓存导致的伪重试 - 新增:在 `getShareDetail` 失败时自动无感重试一次 - 重试前强制清空 `this.fileSelect.stoken`,让后端重新获取有效 `stoken` - 仅在 `#fileSelectModal` 仍显示时触发重试 - 超过最大重试次数后,立即提示“获取文件夹列表失败,请关闭窗口再试一次”,不再继续等待 原因: - 原有“等待1秒再调一次”的重试在令牌失效或缓存命中时无效,用户需手动关窗再点 - 本次改动通过刷新 `stoken` 与规避缓存,实现与“手动关窗再点”接近的效果,且对用户无感 --- app/templates/index.html | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/app/templates/index.html b/app/templates/index.html index 98acf0f..c96ce44 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -4628,15 +4628,23 @@ } this.modalLoading = false; }).catch(error => { - // 如果还有重试次数,则进行重试 + // 增强版无感重试:添加缓存破坏参数,并仅在模态框仍打开时重试 if (retryCount < maxRetries) { console.log(`获取文件夹列表失败,正在进行第 ${retryCount + 1} 次重试...`); - // 短暂延迟后重试 setTimeout(() => { + // 确保模态框仍处于打开状态,否则中止并结束loading + const fileSelectModal = document.getElementById('fileSelectModal'); + if (!(fileSelectModal && fileSelectModal.classList.contains('show'))) { + this.modalLoading = false; + return; + } + // 为请求参数添加时间戳,避免潜在的缓存干扰 + if (typeof params === 'object' && params !== null) { + params._ts = Date.now(); + } this.getSavepathDetail(params, retryCount + 1, maxRetries); - }, 1000); // 1秒后重试 + }, 600); } else { - // 超过最大重试次数,显示错误信息 this.fileSelect.error = "获取文件夹列表失败,请关闭窗口再试一次"; this.modalLoading = false; } @@ -4768,15 +4776,20 @@ } this.modalLoading = false; }).catch(error => { - // 如果还有重试次数,则进行重试 + // 增强版无感重试:清空 stoken 强制刷新令牌,并仅在模态框仍打开时重试 if (retryCount < maxRetries) { console.log(`获取文件夹列表失败,正在进行第 ${retryCount + 1} 次重试...`); - // 短暂延迟后重试 setTimeout(() => { + const fileSelectModal = document.getElementById('fileSelectModal'); + if (!(fileSelectModal && fileSelectModal.classList.contains('show'))) { + this.modalLoading = false; + return; + } + // 清空stoken,促使后端重新获取有效的stoken + this.fileSelect.stoken = ""; this.getShareDetail(retryCount + 1, maxRetries); - }, 1000); // 1秒后重试 + }, 600); } else { - // 超过最大重试次数,显示错误信息 this.fileSelect.error = "获取文件夹列表失败,请关闭窗口再试一次"; this.modalLoading = false; } From 72a2b862a384a1d97beec67b0637cff845692cd7 Mon Sep 17 00:00:00 2001 From: x1ao4 Date: Thu, 28 Aug 2025 22:45:31 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=B8=BA=E6=96=87=E4=BB=B6=E5=A4=B9/?= =?UTF-8?q?=E5=88=86=E4=BA=AB=E8=AF=A6=E6=83=85=E5=8A=A0=E8=BD=BD=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E5=8F=AF=E6=81=A2=E5=A4=8D=E9=94=99=E8=AF=AF=E9=87=8D?= =?UTF-8?q?=E8=AF=95=E8=8C=83=E5=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - retry: 在 `getShareDetail` 将 “非法token/Bad Parameter/request error” 纳入可恢复错误 - 模态仍显示时清空 `stoken` 并延迟 600ms 自动重试一次 - 重试失败统一提示 “获取文件夹列表失败,请关闭窗口再试一次” --- app/templates/index.html | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/app/templates/index.html b/app/templates/index.html index c96ce44..7a1b390 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -4770,11 +4770,38 @@ this.checkPreviewScrollbar(); }); } + // 成功加载后关闭加载状态 + this.modalLoading = false; } else { - // 使用格式化函数处理错误信息 - this.fileSelect.error = this.formatShareUrlBanMessage(response.data.data.error); + // 非法token等可恢复错误:执行一次无感自动重试 + const rawError = (response && response.data && response.data.data && response.data.data.error) ? response.data.data.error : ''; + const errorText = typeof rawError === 'string' ? rawError : String(rawError || ''); + const isIllegalToken = errorText.includes('非法token') || errorText.includes('Bad Parameter'); + const isRequestError = errorText.toLowerCase().includes('request error'); + if (isIllegalToken || isRequestError) { + if (retryCount < maxRetries) { + console.log(`分享详情获取失败(${isIllegalToken ? '非法token' : 'request error'}),进行第 ${retryCount + 1} 次重试...`); + setTimeout(() => { + const fileSelectModal = document.getElementById('fileSelectModal'); + if (!(fileSelectModal && fileSelectModal.classList.contains('show'))) { + this.modalLoading = false; + return; + } + // 清空stoken以强制刷新 + this.fileSelect.stoken = ""; + this.getShareDetail(retryCount + 1, maxRetries); + }, 600); + return; // 等待重试结果,不立刻结束loading + } + // 重试已用尽,给出统一提示 + this.fileSelect.error = "获取文件夹列表失败,请关闭窗口再试一次"; + this.modalLoading = false; + } else { + // 使用格式化函数处理不可恢复错误 + this.fileSelect.error = this.formatShareUrlBanMessage(rawError); + this.modalLoading = false; + } } - this.modalLoading = false; }).catch(error => { // 增强版无感重试:清空 stoken 强制刷新令牌,并仅在模态框仍打开时重试 if (retryCount < maxRetries) { From f0f608b398ed84320c1bfd3602c92fa3b2ef741a Mon Sep 17 00:00:00 2001 From: x1ao4 Date: Thu, 28 Aug 2025 23:23:16 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E4=B8=8B=E6=8B=89=E4=B8=8E=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=B9=E9=80=89=E6=8B=A9=E6=A8=A1=E6=80=81=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E5=85=B3=E9=97=AD=E6=97=B6=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - keep: 打开/关闭选择需转存的文件夹模态不再自动关闭下拉 - add: 点击模态右上角关闭按钮或模态内部区域不关闭下拉 - change: 仅在 “转存当前文件夹/保存到当前文件夹” 确认时,同时关闭模态与下拉 - fix: 在多处初始化分支补充 “点击发生在 #fileSelectModal 内部时不关闭下拉” 的判断 - chore: 在 `selectCurrentFolder()` 中显式关闭下拉,避免确认后下拉残留 --- app/templates/index.html | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/templates/index.html b/app/templates/index.html index 7a1b390..55e7c94 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -2675,7 +2675,9 @@ if (e.target.closest('.input-group input') || e.target.closest('.btn-primary[type="button"]') || e.target.closest('.dropdown-menu.task-suggestions') || - e.target.closest('.bi-search')) { + e.target.closest('.bi-search') || + // 新增:点击发生在文件选择模态框内(包括右上角关闭按钮)时,不关闭下拉 + e.target.closest('#fileSelectModal')) { return; } // 只隐藏下拉菜单,不清空搜索结果,这样点击同一任务的输入框时还能看到之前的搜索结果 @@ -4510,8 +4512,6 @@ this.smart_param.showSuggestions = true; }, selectSuggestion(index, suggestion) { - this.smart_param.showSuggestions = false; - // 不直接设置分享链接到输入框,只是打开文件选择模态框让用户浏览 // 用户在模态框中导航后,最终的 this.fileSelect.shareurl 才是需要的地址 @@ -4972,6 +4972,8 @@ } if (!this.fileSelect.moveMode) { $('#fileSelectModal').modal('hide') + // 用户已确认选择,自动关闭搜索结果下拉菜单 + this.smart_param.showSuggestions = false; } }, // 移动文件到当前文件夹 @@ -8669,7 +8671,9 @@ if (e.target.closest('.input-group input') || e.target.closest('.btn-primary[type="button"]') || e.target.closest('.dropdown-menu.task-suggestions') || - e.target.closest('.bi-search')) { + e.target.closest('.bi-search') || + // 点击发生在文件选择模态框内(包括右上角关闭按钮)时,不关闭下拉 + e.target.closest('#fileSelectModal')) { return; } // 只隐藏下拉菜单,不清空搜索结果,这样点击同一任务的输入框时还能看到之前的搜索结果