diff --git a/frontend/src/pages/cloud-law/video-call.vue b/frontend/src/pages/cloud-law/video-call.vue index 9b7ba3b..f9a5a7d 100644 --- a/frontend/src/pages/cloud-law/video-call.vue +++ b/frontend/src/pages/cloud-law/video-call.vue @@ -543,30 +543,42 @@ const navigateMiniProgramToReturnUrl = (returnUrl) => { const mp = getMiniProgram() if (!mp) return false const url = String(returnUrl || '').trim() - if (url) { - const attempts = [ - () => mp.reLaunch && mp.reLaunch({ url }), - () => mp.redirectTo && mp.redirectTo({ url }), - () => mp.navigateTo && mp.navigateTo({ url }) - ] - for (let i = 0; i < attempts.length; i++) { - try { - attempts[i]() - return true - } catch (e) { - console.warn('[CloudLawVideoCall] miniProgram navigate failed', e) + const tryBack = () => { + try { + if (typeof mp.navigateBack === 'function') { + mp.navigateBack({ delta: 1 }) } + } catch (e) { + console.warn('[CloudLawVideoCall] miniProgram navigateBack failed', e) } } - try { - if (typeof mp.navigateBack === 'function') { - mp.navigateBack({ delta: 1 }) - return true - } - } catch (e) { - console.warn('[CloudLawVideoCall] miniProgram navigateBack failed', e) + if (!url) { + tryBack() + return true } - return false + // 用 fail 回调级联:reLaunch(最可靠,可跨分包,会清栈)→ redirectTo → navigateTo → navigateBack。 + // 关键:上一版直接 mp.reLaunch({url}) 不带回调、调用即 return true,jweixin 静默失败时 + // 仍被判成功、阻断后续兜底,表现为「停在 EchoChat 已结束页、不跳咨询详情」。 + const tryNavigate = () => { + if (typeof mp.navigateTo === 'function') { + mp.navigateTo({ url, fail: () => tryBack() }) + } else { + tryBack() + } + } + const tryRedirect = () => { + if (typeof mp.redirectTo === 'function') { + mp.redirectTo({ url, fail: () => tryNavigate() }) + } else { + tryNavigate() + } + } + if (typeof mp.reLaunch === 'function') { + mp.reLaunch({ url, fail: () => tryRedirect() }) + } else { + tryRedirect() + } + return true } const notifyMiniProgramCallEnded = () => { @@ -589,13 +601,15 @@ const notifyMiniProgramCallEnded = () => { console.warn('[CloudLawVideoCall] postMessage failed', e) } if (miniProgramRedirected) return - // 首选 URL 桥接:改地址加 cloudLawHangup=1,触发原生页 @load 用同域 token 调 /end 并 reLaunch 跳详情。 - // 这是本环境唯一稳定的「web-view → 原生」通道(jweixin 的 reLaunch/navigateTo/navigateBack 会 timeout)。 - if (notifyNativeMiniProgramHangup()) { + // 首选:直接用 wx.miniProgram 导航到咨询详情 returnUrl(reLaunch 会清栈、销毁承载页, + // 触发承载页 onUnload 调同域 /end 收尾)。这是 hash 路由 SPA 内唯一能直达详情页的路径 + // ——onWebViewLoad/@message 在 SPA 内 hash 变化时不触发,URL 桥接根本不会被原生页命中。 + if (navigateMiniProgramToReturnUrl(returnUrl)) { miniProgramRedirected = true return } - if (navigateMiniProgramToReturnUrl(returnUrl)) { + // 兜底:URL 桥接(改地址加 cloudLawHangup=1,触发原生页 @load 收尾+跳详情)。仅在无 wx.miniProgram 时才会走到。 + if (notifyNativeMiniProgramHangup()) { miniProgramRedirected = true return } @@ -1082,47 +1096,11 @@ const hangup = async () => { if (isLawRole.value) { notifyMiniProgramCallEndedOnce() } else { - // 关键修复(回归点):web-view 内 wx.miniProgram.reLaunch/navigateTo/navigateBack 在本环境 - // 会 navigateTo:fail timeout、根本不触发小程序导航,导致:用户停在 EchoChat 结束页、 - // 原生承载页 onUnload 不执行、同域 /end 不被调、status 一直 accepted、律师端不结束。 - // - // 唯一可靠的「web-view → 原生」信号是「改 URL 触发原生 @load」: - // notifyNativeMiniProgramHangup() 用 location.replace 给当前地址加 cloudLawHangup=1, - // web-view 真实重载 → 原生页 onWebViewLoad 命中 cloudLawHangup=1 → - // 用原生 token 调同域 /end(结束会议、通知律师端 PC/小程序)→ uni.reLaunch 跳咨询详情。 - // 不依赖 jweixin 导航、不依赖 postMessage 销毁时机、不依赖 EchoChat 房间是否先结束。 - const returnUrl = buildMiniProgramReturnUrl() - const mp = getMiniProgram() - try { - if (mp && typeof mp.postMessage === 'function') { - mp.postMessage({ - data: { - type: 'cloudLawCallEnded', - action: 'cloudLawCallEnded', - callId: callId.value, - consultId: consultId.value, - returnUrl - } - }) - } - } catch (e) { - console.warn('[CloudLawVideoCall] postMessage failed', e) - } - // 主路径:URL 桥接(最可靠)。失败再退回 navigateBack 兜底。 - const bridged = notifyNativeMiniProgramHangup() - console.log('[CloudLawVideoCall] hangup finally -> URL桥接结果:', bridged, 'hasMp:', !!mp) - if (!bridged) { - try { - if (mp && typeof mp.navigateBack === 'function') { - mp.navigateBack({ delta: 1 }) - console.log('[CloudLawVideoCall] hangup finally -> 已调 navigateBack 兜底') - } else { - console.warn('[CloudLawVideoCall] hangup finally -> 无 mp.navigateBack,无法兜底导航') - } - } catch (e) { - console.warn('[CloudLawVideoCall] navigateBack failed', e) - } - } + // 用户端挂断:统一走 notifyMiniProgramCallEndedOnce(), + // 它已改为「优先 wx.miniProgram 直达咨询详情 returnUrl(reLaunch 清栈→承载页 onUnload 调 /end 收尾), + // URL 桥接仅作兜底」。避免之前 URL-桥接优先(onWebViewLoad 在 hash SPA 内不触发)+ navigateBack + // 只返回上一页、跳不到咨询详情的问题。 + notifyMiniProgramCallEndedOnce() } } }