吉安感知网项目-前端
shuishen
2026-02-03 89380e6260a75d1d3b94de687ebcc2f50d50659d
applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue
@@ -23,11 +23,12 @@
         <div class="status-group">
            <strong v-if="state==='ringing'" class="status-text incoming-status">来电中...</strong>
            <strong v-if="state==='calling'" class="status-text calling-status">呼叫中...</strong>
            <!--   <strong class="status-text">状态:<span :style="{color: getStateColor(state)}">{{ state }}</span></strong>-->
            <strong v-if="state==='in-call'" class="status-text">通话时长:{{ durationText }}</strong>
            <!--  通话结束提示-->
            <strong v-if="callEnded" class="status-text ended-status">{{ endMessage }}</strong>
         </div>
         <div class="button-group">
            <button  @click="requestCall" :disabled="!connected || state!=='idle'" class="btn btn-call">呼叫</button>
            <button v-if="state === 'idle' && !receiveParameters" @click="requestCall" :disabled="!connected" class="btn btn-call">呼叫</button>
            <button v-if="state==='ringing'" @click="acceptCall" class="btn btn-accept incoming-accept">接听</button>
            <button v-if="state==='ringing'" @click="rejectCall" class="btn btn-reject incoming-reject">拒绝</button>
@@ -62,17 +63,51 @@
// 解析URL参数
const parseUrlParams = () => {
   const url = new URL(window.location.href)
   const paramsStr = url.searchParams.get('params')
   if (paramsStr) {
   // 1. 优先从route.query.voiceparams获取参数
   if (route.query && route.query.voiceparams) {
      console.log('从route.query.voiceparams获取参数:', route.query.voiceparams);
      try {
         const params = JSON.parse(decodeURIComponent(paramsStr))
         // 解码并解析voiceparams参数
         const params = JSON.parse(decodeURIComponent(route.query.voiceparams));
         console.log('解析后的voiceparams:', params);
         if (params.peerUid) {
            peerUid.value = String(params.peerUid)
            log('🔗 从URL参数获取peerUid:', params.peerUid)
            peerUid.value = String(params.peerUid);
            log('🔗 从voiceparams获取peerUid:', params.peerUid);
         }
         // 如果是来电类型,直接触发来电状态
         if (params.type === 'incoming') {
            log('📞 voiceparams检测到来电,直接进入来电状态');
            incomingFrom = String(params.from);
            peerUid.value = incomingFrom;
            acceptedByMe = false;
            offeredByPeer = false;
            state.value = 'ringing';
            log('📞 收到来电 call,来自', incomingFrom);
            // 开始来电提示(铃声和震动)
            playRingtone();
            startVibration();
         }
      } catch (e) {
         log('❌ 解析URL参数失败:', String(e))
         log('❌ 解析voiceparams参数失败:', String(e));
      }
   }
   // 2. 同时保留原有的URL参数解析逻辑,作为备选
   const url = new URL(window.location.href);
   const paramsStr = url.searchParams.get('params');
   if (paramsStr) {
      try {
         const params = JSON.parse(decodeURIComponent(paramsStr));
         if (params.peerUid) {
            peerUid.value = String(params.peerUid);
            log('🔗 从URL参数获取peerUid:', params.peerUid);
         }
      } catch (e) {
         log('❌ 解析URL参数失败:', String(e));
      }
   }
}
@@ -94,6 +129,10 @@
const state = ref('idle') // idle | calling | ringing | in-call
const logText = ref('')
const remoteAudio = ref(null)
// 通话结束相关
const callEnded = ref(false)
const endMessage = ref('对方已挂断')
const endTimer = ref(null)
/**
 * 根据状态返回对应颜色
@@ -328,8 +367,6 @@
/* ---------------- 信令处理 ---------------- */
async function onSignal(msg) {
console.log('1cesss',msg);
   if (!msg) return
   const t = (msg.type || '').toString()
@@ -590,23 +627,55 @@
   lastOfferSdp = null
   state.value = 'idle'
   // 返回上一页(uni-app的语音通话列表页面)
   if (window.uni) {
      window.uni.navigateBack()
   // 清除之前的定时器
   if (endTimer.value) {
      clearTimeout(endTimer.value)
      endTimer.value = null
   }
   // 根据是谁发起的挂断决定不同的行为
   if (sendToPeer) {
      // 自己主动挂断:不提示,不延迟,直接跳转
      log('⏰ 自己主动挂断,直接返回')
      callEnded.value = false
      // 返回上一页(uni-app的语音通话列表页面)
      if (window.uni) {
         window.uni.navigateBack()
      } else {
         log('❌ uni对象不存在,无法返回上一页')
      }
   } else {
      log('❌ uni对象不存在,无法返回上一页')
      // 对方挂断:显示提示,延迟10秒跳转
      callEnded.value = true
      endMessage.value = '对方已挂断'
      // 延迟10秒后跳转页面
      endTimer.value = setTimeout(() => {
         log('⏰ 通话结束10秒后自动返回')
         // 返回上一页(uni-app的语音通话列表页面)
         if (window.uni) {
            window.uni.navigateBack()
         } else {
            log('❌ uni对象不存在,无法返回上一页')
         }
         // 重置通话结束状态
         callEnded.value = false
      }, 5000)
   }
}
// 定义receiveParameters变量,用于模板中判断是否显示呼叫按钮
const receiveParameters = ref(route.query.contact || null);
onMounted(() => {
   const receiveParameters = route.query.contact
   console.log('接收参数', receiveParameters)
   console.log('收拾收拾',route.query.voiceparams);
   console.log('接收参数', receiveParameters.value)
   // 解析并使用contact参数
   if (receiveParameters) {
   if (receiveParameters.value) {
      try {
         const contact = JSON.parse(decodeURIComponent(receiveParameters))
         const contact = JSON.parse(decodeURIComponent(receiveParameters.value))
         if (contact.friendId) {
            peerUid.value = contact.friendId
            log('🔗 从contact参数获取peerUid:', contact.friendId)
@@ -621,14 +690,16 @@
   parseUrlParams()
   // 自动连接WebSocket
   connectWS()
})
});
// 监听连接状态,连接成功后自动呼叫
// watch(() => connected.value, (newVal) => {
//    if (newVal && state.value === 'idle') {
//       requestCall()
//    }
// })
// 监听连接状态,当connected变为true且有receiveParameters时自动呼叫
watch(() => connected.value, (newVal) => {
   if (newVal && state.value === 'idle' && receiveParameters.value) {
      log('📞 连接成功且有contact参数,自动发起呼叫');
      requestCall();
   }
});
onBeforeUnmount(() => {
   cleanup(false)
@@ -657,6 +728,15 @@
   padding: 0;
}
/* 通话结束状态样式 */
.status-text.ended-status {
   color: #e74c3c;
   font-size: 18px;
   font-weight: bold;
   margin-top: 10px;
   text-align: center;
}
.content-wrapper {
   display: flex;
   flex-direction: column;