吉安感知网项目-前端
chenyao
2026-02-12 6c3a421bce3cdcd5705cd694938642885db605e4
applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue
@@ -8,7 +8,7 @@
         <div class="contactAvatar">
            <img :src="defaultAvatar" alt=""></img>
         </div>
         <!--  联系人名称-->
         <div class="contactName">
            {{ contactName }}
@@ -39,77 +39,14 @@
<script setup>
import { useRoute } from 'vue-router'
import defaultAvatar from '@/appDataSource/appwork/defaultAvatar.svg'
import { showToast } from 'vant'
const route = useRoute()
/** ✅ 你的 WS 地址前缀(后面拼 userId) */
// const WS_BASE = 'ws://218.202.104.82:38201/ws/chat?userId='
const WS_BASE = 'ws://218.202.104.82:38201/ws/chat'
// 解析URL参数
const parseUrlParams = () => {
   // 1. 优先从route.query.voiceparams获取参数
   if (route.query && route.query.voiceparams) {
      console.log('从route.query.voiceparams获取参数:', route.query.voiceparams);
      try {
         // 解码并解析voiceparams参数
         const params = JSON.parse(decodeURIComponent(route.query.voiceparams));
         console.log('解析后的voiceparams:', params);
         if (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('❌ 解析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));
      }
   }
}
// 从URL参数或本地存储获取用户ID
const getUserIdFromStorage = () => {
   // 从url获取用户id
   const contact = JSON.parse(decodeURIComponent(receiveParameters.value))
   console.log('从url获取用户id',contact?.userId)
   // 从本地获取用户id
   const userId = localStorage.getItem('userId') || sessionStorage.getItem('userId')
   console.log('从本地存储获取userId:', userId)
   if (userId) {
      return userId
   }
   return '3' // 默认值
}
const uid = ref('3')
const peerUid = ref('2')
const uid = ref('2021475329842999298')
const peerUid = ref('2021474568497131521')
// 联系人名称
const contactName = ref('张三')
@@ -150,6 +87,70 @@
function stopTimer() {
   if (timer) clearInterval(timer)
   timer = null
}
// 解析URL参数
const parseUrlParams = () => {
   // 1. 优先从route.query.voiceparams获取参数
   if (route.query && route.query.voiceparams) {
      console.log('从route.query.voiceparams获取参数:', route.query.voiceparams);
      try {
         // 解码并解析voiceparams参数
         const params = JSON.parse(decodeURIComponent(route.query.voiceparams));
         console.log('解析后的voiceparams:', params);
         if (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('❌ 解析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));
      }
   }
}
// 从URL参数或本地存储获取用户ID
const getUserIdFromStorage = () => {
   // 从url获取用户id
   const contact = JSON.parse(decodeURIComponent(receiveParameters.value))
   console.log('从url获取用户id',contact?.userId)
   // 从本地获取用户id
   const userId = localStorage.getItem('userId') || sessionStorage.getItem('userId')
   console.log('从本地存储获取userId:', userId)
   if (userId) {
      return userId
   }
   return '2021475329842999298' // 默认值
}
// 心跳
@@ -229,21 +230,43 @@
   }
   try {
      localStream = await navigator.mediaDevices.getUserMedia({
         audio: {
            echoCancellation: true,
            noiseSuppression: true,
            autoGainControl: true,
            // 移动端特定配置
            channelCount: 1,
            sampleRate: 16000,
            sampleSize: 16
         }
        })
      log('✅ 已获取本地麦克风')
      // 尝试使用完整约束
      try {
         localStream = await navigator.mediaDevices.getUserMedia({
            audio: {
               echoCancellation: true,
               noiseSuppression: true,
               autoGainControl: true,
               channelCount: 1,
               sampleRate: 16000,
               sampleSize: 16
            }
         })
         log('✅ 已获取本地麦克风(标准约束)')
      } catch (strictError) {
         // 如果标准约束失败,尝试最简单的约束
         log('⚠️ 标准约束失败,尝试简化约束:', String(strictError))
         localStream = await navigator.mediaDevices.getUserMedia({
            audio: true
         })
         log('✅ 已获取本地麦克风(简化约束)')
      }
      return localStream
   } catch (e) {
      log('❌ 获取麦克风失败:', String(e))
      // 提供更详细的错误信息
      if (e.name === 'NotReadableError') {
         log('❌ NotReadableError: 麦克风可能被其他应用占用,或权限未正确配置')
         showToast('麦克风被占用或权限未授予')
      } else if (e.name === 'NotAllowedError') {
         log('❌ NotAllowedError: 用户拒绝了麦克风权限')
         showToast('请授予麦克风权限')
      } else if (e.name === 'NotFoundError') {
         log('❌ NotFoundError: 未找到麦克风设备')
         showToast('未找到麦克风设备')
      }
      throw e
   }
}
@@ -530,13 +553,13 @@
   lastOfferSdp = null
   state.value = 'idle'
   // 清除之前的定时器
   if (endTimer.value) {
      clearTimeout(endTimer.value)
      endTimer.value = null
   }
   // 根据是谁发起的挂断决定不同的行为
   if (sendToPeer) {
      // 自己主动挂断:不提示,不延迟,直接跳转
@@ -552,7 +575,7 @@
      // 对方挂断:显示提示,延迟10秒跳转
      callEnded.value = true
      endMessage.value = '对方已挂断'
      // 延迟5秒后跳转页面
      endTimer.value = setTimeout(() => {
         // 返回上一页(uni-app的语音通话列表页面)
@@ -580,7 +603,7 @@
         if (params.access_token) {
            accessToken.value = params.access_token;
            log('🔗 从params获取access_token:', accessToken.value);
         }
         }
      } catch (e) {
         log('❌ 解析params参数失败:', String(e));
      }
@@ -882,4 +905,4 @@
   height: 220px;
   margin-bottom: 60px;
}
</style>
</style>