From e4263578509c0b067d695bba0b5ad18e87db748d Mon Sep 17 00:00:00 2001 From: duoaohui <928970622@qq.com> Date: Thu, 4 Jun 2026 15:19:31 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=B5=E8=AF=9D=E5=92=A8=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/cloud-law/video-call.vue | 148 ++++++++++++++++---- 1 file changed, 121 insertions(+), 27 deletions(-) diff --git a/frontend/src/pages/cloud-law/video-call.vue b/frontend/src/pages/cloud-law/video-call.vue index e208cda..d12661f 100644 --- a/frontend/src/pages/cloud-law/video-call.vue +++ b/frontend/src/pages/cloud-law/video-call.vue @@ -486,26 +486,77 @@ const notifyCloudLawEnd = () => { } const buildMiniProgramReturnUrl = () => { - const configured = String(miniProgramReturnUrl.value || '').trim() - if (configured) { - try { - return decodeURIComponent(configured) - } catch (e) { - return configured + const decodeRepeated = (value) => { + let text = String(value || '').trim() + if (!text) return '' + for (let i = 0; i < 3; i++) { + try { + const next = decodeURIComponent(text) + if (next === text) break + text = next + } catch (e) { + break + } } + return text + } + const configured = decodeRepeated(miniProgramReturnUrl.value) + if (configured) { + return configured + } + if (!consultId.value) { + // #ifdef H5 + try { + const cached = window.sessionStorage.getItem('echo_cloud_law_return_url') || '' + if (cached) return decodeRepeated(cached) + } catch (e) {} + // #endif + return '' } - if (!consultId.value) return '' return `/pages_work/ai_consult/ai_consult?id=${encodeURIComponent(consultId.value)}&mode=detail&from=videoCall` } let endedRedirectTimer = null let miniProgramRedirected = false +let miniProgramEndNotified = false +let miniProgramRedirectRetryTimer = null const getMiniProgram = () => { return typeof window !== 'undefined' && window.wx && window.wx.miniProgram ? window.wx.miniProgram : null } +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) + } + } + } + try { + if (typeof mp.navigateBack === 'function') { + mp.navigateBack({ delta: 1 }) + return true + } + } catch (e) { + console.warn('[CloudLawVideoCall] miniProgram navigateBack failed', e) + } + return false +} + const notifyMiniProgramCallEnded = () => { + if (isLawRole.value) return const returnUrl = buildMiniProgramReturnUrl() const payload = { type: 'cloudLawCallEnded', @@ -524,31 +575,38 @@ const notifyMiniProgramCallEnded = () => { console.warn('[CloudLawVideoCall] postMessage failed', e) } if (miniProgramRedirected) return - try { - if (miniProgram && returnUrl && typeof miniProgram.redirectTo === 'function') { - miniProgramRedirected = true - miniProgram.redirectTo({ url: returnUrl }) - } else if (miniProgram && typeof miniProgram.navigateBack === 'function') { - // 没有可跳转的咨询详情地址时,至少退回上一页(等待页),由小程序侧轮询兜底跳转 - miniProgramRedirected = true - miniProgram.navigateBack({ delta: 1 }) - } - } catch (e) { - miniProgramRedirected = false - console.warn('[CloudLawVideoCall] redirect mini program failed', e) + if (navigateMiniProgramToReturnUrl(returnUrl)) { + miniProgramRedirected = true + return } + if (miniProgramRedirectRetryTimer) return + let retry = 0 + miniProgramRedirectRetryTimer = setInterval(() => { + retry += 1 + if (navigateMiniProgramToReturnUrl(returnUrl) || retry >= 10) { + clearInterval(miniProgramRedirectRetryTimer) + miniProgramRedirectRetryTimer = null + if (retry < 10) miniProgramRedirected = true + } + }, 300) +} + +const notifyMiniProgramCallEndedOnce = () => { + if (miniProgramEndNotified) return + miniProgramEndNotified = true + notifyMiniProgramCallEnded() } const scheduleEndedRedirect = () => { - if (endedRedirectTimer) return + if (endedRedirectTimer || isLawRole.value) return endedRedirectTimer = setTimeout(() => { endedRedirectTimer = null - notifyCloudLawEnd().finally(() => notifyMiniProgramCallEnded()) + notifyCloudLawEnd().finally(() => notifyMiniProgramCallEndedOnce()) }, 1200) } const goToConsultDetail = () => { - notifyCloudLawEnd().finally(() => notifyMiniProgramCallEnded()) + notifyCloudLawEnd().finally(() => notifyMiniProgramCallEndedOnce()) } const pollCommandsOnce = async () => { @@ -996,20 +1054,41 @@ const hangup = async () => { } finally { ended.value = true leaving.value = false - notifyMiniProgramCallEnded() - scheduleEndedRedirect() + notifyMiniProgramCallEndedOnce() } } onLoad(query => { + const decodeQueryValue = (value) => { + let text = String(value || '').trim() + if (!text) return '' + for (let i = 0; i < 3; i++) { + try { + const next = decodeURIComponent(text) + if (next === text) break + text = next + } catch (e) { + break + } + } + return text + } rawCode.value = query?.code || query?.roomCode || '' callId.value = query?.callId || query?.call_id || '' - consultId.value = query?.consultId || query?.consult_id || '' - miniProgramReturnUrl.value = query?.miniProgramReturnUrl || query?.mini_program_return_url || '' + consultId.value = decodeQueryValue(query?.consultId || query?.consult_id || '') + miniProgramReturnUrl.value = decodeQueryValue(query?.miniProgramReturnUrl || query?.mini_program_return_url || '') cloudLawApiBase.value = query?.cloudLawApiBase || query?.cloud_law_api_base || '' cloudLawToken.value = query?.cloudLawToken || query?.cloud_law_token || '' cloudLawRole.value = query?.cloudLawRole || query?.cloud_law_role || '' // #ifdef H5 + try { + if (consultId.value) { + window.sessionStorage.setItem('echo_cloud_law_consult_id', consultId.value) + } + if (miniProgramReturnUrl.value) { + window.sessionStorage.setItem('echo_cloud_law_return_url', miniProgramReturnUrl.value) + } + } catch (e) {} if (String(cloudLawRole.value).toLowerCase() === 'law') { try { window.sessionStorage.setItem('echo_cloud_law_meeting_role', 'law') @@ -1041,18 +1120,33 @@ onMounted(() => { ended.value = true // 对方挂断或会议结束时,通知小程序跳转到「我的咨询详情」 notifyCloudLawEnd().finally(() => { - notifyMiniProgramCallEnded() + notifyMiniProgramCallEndedOnce() scheduleEndedRedirect() }) } }, { immediate: true }) }) +watch(ended, (value) => { + if (!value || isLawRole.value) return + const returnUrl = buildMiniProgramReturnUrl() + if (!returnUrl) return + setTimeout(() => { + if (ended.value && !miniProgramRedirected) { + notifyMiniProgramCallEndedOnce() + } + }, 1500) +}) + onBeforeUnmount(() => { if (endedRedirectTimer) { clearTimeout(endedRedirectTimer) endedRedirectTimer = null } + if (miniProgramRedirectRetryTimer) { + clearInterval(miniProgramRedirectRetryTimer) + miniProgramRedirectRetryTimer = null + } if (timerHandle) { clearInterval(timerHandle) timerHandle = null