运营数据

This commit is contained in:
duoaohui
2026-06-06 11:39:15 +08:00
parent 9e9573a35d
commit 3b0f1f84ff
3 changed files with 163 additions and 2 deletions

View File

@@ -242,7 +242,8 @@ import {
isCloudLawLawRoleInMeeting,
isCloudLawPcIframe,
notifyCloudLawBackendEnd,
notifyCloudLawParentCallEnded
notifyCloudLawParentCallEnded,
queryCloudLawCallStatus
} from '@/utils/cloudLawVoiceCall'
const meetingStore = useMeetingStore()
@@ -843,6 +844,82 @@ const syncViewportHeight = () => {
// #endif
}
let cloudLawStatusPollTimer = null
let cloudLawParticipantStopWatch = null
let cloudLawSoloCheckTimer = null
let cloudLawConsultEnding = false
const hadRemoteParticipant = ref(false)
const getMyUserId = () => userStore.userInfo?.id || userStore.userInfo?.user_id
const countRemoteActiveParticipants = () => {
const myUid = getMyUserId()
return meetingStore.activeParticipants.filter(p => String(p.user_id) !== String(myUid)).length
}
const stopCloudLawStatusPoll = () => {
if (cloudLawStatusPollTimer) {
clearInterval(cloudLawStatusPollTimer)
cloudLawStatusPollTimer = null
}
}
const handleCloudLawConsultEnded = async (tip = '用户已退出咨询') => {
if (cloudLawConsultEnding || !isCloudLawLawRoleInMeeting(cloudLawRole.value)) return
cloudLawConsultEnding = true
stopCloudLawStatusPoll()
if (cloudLawSoloCheckTimer) {
clearTimeout(cloudLawSoloCheckTimer)
cloudLawSoloCheckTimer = null
}
try {
if (cloudLawCallId.value) {
await notifyCloudLawBackendEnd(cloudLawCallId.value, 'law', cloudLawApiBase.value)
notifyCloudLawParentCallEnded(cloudLawCallId.value)
}
if (meetingStore.isInMeeting) {
await meetingStore.leave().catch(() => {})
}
uni.showToast({ title: tip, icon: 'none' })
if (!isCloudLawPcIframe()) {
setTimeout(() => redirectHome(true), 800)
}
} finally {
cloudLawConsultEnding = false
}
}
const pollCloudLawCallStatusOnce = async () => {
if (!isCloudLawLawRoleInMeeting(cloudLawRole.value) || !cloudLawCallId.value || cloudLawConsultEnding) return
if (meetingStore.localState === MEETING_LOCAL_STATE_ENDED || meetingStore.localState === MEETING_LOCAL_STATE_LEAVING) return
const data = await queryCloudLawCallStatus(cloudLawCallId.value, 'law', cloudLawApiBase.value)
const status = String(data?.status || data?.callStatus || '').toLowerCase()
if (['ended', 'cancelled', 'failed'].includes(status)) {
await handleCloudLawConsultEnded('咨询已结束')
}
}
const startCloudLawStatusPoll = () => {
if (!isCloudLawLawRoleInMeeting(cloudLawRole.value) || !cloudLawCallId.value) return
stopCloudLawStatusPoll()
pollCloudLawCallStatusOnce()
cloudLawStatusPollTimer = setInterval(pollCloudLawCallStatusOnce, 1000)
}
const scheduleCloudLawSoloCheck = () => {
if (cloudLawSoloCheckTimer) {
clearTimeout(cloudLawSoloCheckTimer)
}
cloudLawSoloCheckTimer = setTimeout(async () => {
cloudLawSoloCheckTimer = null
if (!hadRemoteParticipant.value || cloudLawConsultEnding) return
if (meetingStore.localState !== MEETING_LOCAL_STATE_CONNECTED) return
if (countRemoteActiveParticipants() === 0) {
await handleCloudLawConsultEnded('用户已退出咨询')
}
}, 500)
}
// ============ 生命周期 ============
let stateStopWatch = null
@@ -919,6 +996,25 @@ onMounted(() => {
}
})
// 云律律师端:轮询通话状态 + 对方离会后自动收尾(用户挂断不一定能推到 room.ended
if (isCloudLawLawRoleInMeeting(cloudLawRole.value)) {
startCloudLawStatusPoll()
cloudLawParticipantStopWatch = watch(
() => meetingStore.activeParticipants,
() => {
const remoteCount = countRemoteActiveParticipants()
if (remoteCount > 0) {
hadRemoteParticipant.value = true
return
}
if (hadRemoteParticipant.value && remoteCount === 0) {
scheduleCloudLawSoloCheck()
}
},
{ deep: true }
)
}
// #ifdef H5
if (showCloudLawBack.value) {
try {
@@ -941,6 +1037,15 @@ onBeforeUnmount(() => {
}
if (viewportCleanup) { viewportCleanup(); viewportCleanup = null }
if (stateStopWatch) { stateStopWatch(); stateStopWatch = null }
stopCloudLawStatusPoll()
if (cloudLawParticipantStopWatch) {
cloudLawParticipantStopWatch()
cloudLawParticipantStopWatch = null
}
if (cloudLawSoloCheckTimer) {
clearTimeout(cloudLawSoloCheckTimer)
cloudLawSoloCheckTimer = null
}
// #ifdef H5
if (popstateHandler) {
window.removeEventListener('popstate', popstateHandler)