diff --git a/frontend/src/pages/cloud-law/video-call.vue b/frontend/src/pages/cloud-law/video-call.vue index 4e7f3ed..e208cda 100644 --- a/frontend/src/pages/cloud-law/video-call.vue +++ b/frontend/src/pages/cloud-law/video-call.vue @@ -60,13 +60,14 @@ + {{ durationText }} - + {{ durationText }} @@ -206,6 +207,10 @@ const captureIconError = ref(false) const flipCameraIconError = ref(false) const snapshotPreviewUrl = ref('') const snapshotBusy = ref(false) +/** 用户点击挂断(区别于返回上一页最小化会议) */ +const userInitiatedHangup = ref(false) +/** 律师端从小程序 web-view 返回:仅本地离会,不结束云律通话、不通知小程序通话已结束 */ +const minimizingToMiniProgram = ref(false) const digitsOf = (value) => String(value || '').replace(/\D/g, '').slice(0, 9) const sameUser = (a, b) => String(a || '') === String(b || '') @@ -926,8 +931,36 @@ const onCamToggle = async () => { } } +const onTopBack = () => { + if (isLawRole.value) { + minimizeToMiniProgram() + } else { + hangup() + } +} + +/** 律师端返回小程序上一页:保留进行中通话,便于「返回会议」浮窗再次进入 */ +const minimizeToMiniProgram = () => { + if (leaving.value || ended.value || minimizingToMiniProgram.value) return + minimizingToMiniProgram.value = true + stopCommandPolling() + meetingStore.leave().catch(() => {}) + const mp = getMiniProgram() + try { + if (mp && typeof mp.navigateBack === 'function') { + mp.navigateBack({ delta: 1 }) + return + } + } catch (e) { + console.warn('[CloudLawVideoCall] minimize navigateBack failed', e) + } + minimizingToMiniProgram.value = false + uni.showToast({ title: '请使用左上角返回', icon: 'none' }) +} + const hangup = async () => { if (leaving.value) return + userInitiatedHangup.value = true leaving.value = true stopCommandPolling() try { @@ -997,6 +1030,11 @@ onMounted(() => { } if (s === MEETING_LOCAL_STATE_ENDED) { stopCommandPolling() + // 律师端仅「返回上一页」最小化:不结束云律通话、不 postMessage 通知小程序通话结束 + if (minimizingToMiniProgram.value) { + minimizingToMiniProgram.value = false + return + } const reason = meetingStore.lastEndedReason const label = MEETING_ENDED_REASON_LABEL?.[reason] || '视频咨询已结束' uni.showToast({ title: label, icon: 'none' }) @@ -1032,6 +1070,13 @@ onBeforeUnmount(() => { onUnload(() => { stopCommandPolling() + if (isLawRole.value && !ended.value && !userInitiatedHangup.value) { + minimizingToMiniProgram.value = true + if (meetingStore.isInMeeting && meetingStore.localState !== MEETING_LOCAL_STATE_LEAVING) { + meetingStore.leave().catch(() => {}) + } + return + } if (!ended.value && callId.value) { notifyCloudLawEnd().catch(() => {}) } @@ -1186,6 +1231,13 @@ onUnload(() => { height: 100%; border-radius: 0; } +.video-back { + font-size: 56rpx; + line-height: 1; + color: #ffffff; + padding: 0 12rpx; + flex-shrink: 0; +} .video-topbar { position: absolute; left: 0; @@ -1196,6 +1248,7 @@ onUnload(() => { display: flex; align-items: center; justify-content: space-between; + gap: 16rpx; background: linear-gradient(180deg, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 100%); box-sizing: border-box; z-index: 6;