From 25dacb8f020ad0be72cf2dc615fb8f165573ffa0 Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Mon, 09 Feb 2026 15:50:47 +0800
Subject: [PATCH] Merge branch 'master' of http://139.196.74.78:10010/r/jagzwxm/ja_web

---
 applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue |  210 +++++++++++++---------------------------------------
 1 files changed, 53 insertions(+), 157 deletions(-)

diff --git a/applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue b/applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue
index fb4aff4..8ad9923 100644
--- a/applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue
+++ b/applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue
@@ -1,18 +1,6 @@
 <template>
 	<div class="call-container" :class="{'incoming-call': state === 'ringing'} ">
 		<div class="content-wrapper">
-			<!--		<div class="input-group">
-					<div class="input-item">
-						<span class="input-label">我的 userId:</span>
-						<input v-model="uid" class="input-field" />
-					</div>
-
-					<div class="input-item">
-						<span class="input-label">对方 userId:</span>
-						<input v-model="peerUid" class="input-field" />
-					</div>
-				</div>-->
-
 			<div class="button-group" v-if="false">
 				<button @click="connectWS" :disabled="connected" class="btn btn-connect">连接WS</button>
 			</div>
@@ -20,6 +8,12 @@
 			<div class="contactAvatar">
 				<img :src="defaultAvatar" alt=""></img>
 			</div>
+			
+			<!--  联系人名称-->
+			<div class="contactName">
+				{{ contactName }}
+			</div>
+
 			<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>
@@ -38,18 +32,6 @@
 
 
 		</div>
-
-		<!--	<div class="tip-message">
-			<small>提示:若 getUserMedia 不可用,请用 https 或 localhost 访问页面。</small>
-			</div>-->
-
-		<!--	<div class="log-container">
-			<div class="log-box">
-				<div class="log-title">日志信息:</div>
-				<pre class="log-content">{{ logText }}</pre>
-			</div>
-			</div>-->
-
 		<audio ref="remoteAudio" autoplay class="hidden-audio"></audio>
 	</div>
 </template>
@@ -86,10 +68,7 @@
 				
 				state.value = 'ringing';
 				log('📞 收到来电 call,来自', incomingFrom);
-				
-				// 开始来电提示(铃声和震动)
-				playRingtone();
-				startVibration();
+
 			}
 		} catch (e) {
 			log('❌ 解析voiceparams参数失败:', String(e));
@@ -97,26 +76,30 @@
 	}
 	
 	// 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));
-		}
-	}
+	// 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)).userId
+	console.log('从url获取用户id',contact)
+	// 从本地获取用户id
 	const userId = localStorage.getItem('userId') || sessionStorage.getItem('userId')
+	console.log('从本地存储获取userId:', userId)
 	if (userId) {
-		log('🔗 从本地存储获取userId:', userId)
 		return userId
 	}
 	return '3' // 默认值
@@ -124,6 +107,8 @@
 
 const uid = ref('3')
 const peerUid = ref('2')
+// 联系人名称
+const contactName = ref('张三')
 
 const connected = ref(false)
 const state = ref('idle') // idle | calling | ringing | in-call
@@ -133,19 +118,6 @@
 const callEnded = ref(false)
 const endMessage = ref('对方已挂断')
 const endTimer = ref(null)
-
-/**
- * 根据状态返回对应颜色
- */
-const getStateColor = (state) => {
-	const colors = {
-		'idle': '#666',
-		'calling': '#2196F3',
-		'ringing': '#FF9800',
-		'in-call': '#4CAF50'
-	}
-	return colors[state] || '#666'
-}
 
 let ws = null
 let pc = null
@@ -185,76 +157,6 @@
 	}, 25000)
 }
 
-// 来电提示相关
-let ringtoneAudio = null
-let vibrationTimer = null
-
-// 播放来电铃声
-function playRingtone() {
-	// 创建音频对象(使用默认的系统提示音)
-	ringtoneAudio = new Audio('data:audio/wav;base64,UklGRigAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQAAAAAAA==');
-	ringtoneAudio.loop = true;
-	ringtoneAudio.volume = 0.5;
-
-	try {
-		ringtoneAudio.play();
-		log('🔊 开始播放来电铃声')
-	} catch (e) {
-		log('❌ 播放来电铃声失败:', String(e))
-	}
-}
-
-// 停止来电铃声
-function stopRingtone() {
-	if (ringtoneAudio) {
-		try {
-			ringtoneAudio.pause();
-			ringtoneAudio.currentTime = 0;
-			ringtoneAudio = null;
-			log('🔇 停止播放来电铃声')
-		} catch (e) {
-			log('❌ 停止来电铃声失败:', String(e))
-		}
-	}
-}
-
-// 开始震动
-function startVibration() {
-	// 检查浏览器是否支持震动 API
-	if ('vibrate' in navigator) {
-		// 震动模式:震动1秒,暂停0.5秒,重复
-		const vibrationPattern = [1000, 500];
-
-		try {
-			navigator.vibrate(vibrationPattern);
-			vibrationTimer = setInterval(() => {
-				navigator.vibrate(vibrationPattern);
-			}, 1500); // 每1.5秒重复一次震动模式
-			log('📳 开始震动提示')
-		} catch (e) {
-			log('❌ 震动失败:', String(e))
-		}
-	} else {
-		log('ℹ️ 当前浏览器不支持震动功能')
-	}
-}
-
-// 停止震动
-function stopVibration() {
-	if (vibrationTimer) {
-		clearInterval(vibrationTimer);
-		vibrationTimer = null;
-	}
-
-	if ('vibrate' in navigator) {
-		try {
-			navigator.vibrate(0); // 停止震动
-			log('📳 停止震动提示')
-		} catch (e) {
-			log('❌ 停止震动失败:', String(e))
-		}
-	}
-}
 function stopPing() {
 	if (pingTimer) clearInterval(pingTimer)
 	pingTimer = null
@@ -297,7 +199,7 @@
 			send('candidate', peerUid.value, { candidate: e.candidate.toJSON ? e.candidate.toJSON() : e.candidate })
 		}
 	}
-
+// 步骤七:建立连接
 	pc.ontrack = (e) => {
 		log('✅ 收到远端音频流')
 		const stream = e.streams[0]
@@ -312,7 +214,7 @@
 		log('pc.connectionState =', pc.connectionState)
 	}
 }
-
+// 步骤六:连接音频
 async function getLocalAudio() {
 	if (localStream) return localStream
 
@@ -330,7 +232,7 @@
 		throw e
 	}
 }
-
+// 步骤5 确保本地音频流已添加
 /** ✅ 关键:只 addTrack 一次,避免 “sender already exists” */
 async function ensureLocalTracksAdded() {
 	if (!pc) createPC()
@@ -351,7 +253,7 @@
 
 	return stream
 }
-
+// 步骤4 发送本地音频流
 async function flushCandidates() {
 	if (!pc || !pc.remoteDescription) return
 	while (pendingCandidates.length) {
@@ -391,12 +293,7 @@
 		offeredByPeer = false
 
 		state.value = 'ringing'
-		log('📞 收到来电 call,来自', incomingFrom)
-
-		// 开始来电提示(铃声和震动)
-		playRingtone()
-		startVibration()
-
+			log('📞 收到来电 call,来自', incomingFrom)
 		return
 	}
 
@@ -426,12 +323,12 @@
 			lastOfferSdp = msg.payload?.sdp
 			return
 		}
-
+  // 步骤2
 		// 已接听:直接 answer
 		await answerOffer(msg.payload?.sdp, incomingFrom)
 		return
 	}
-
+// 步骤3 接收 answer
 	if (t === 'answer') {
 		log('✅ 收到 answer,通话建立')
 		if (!pc) createPC()
@@ -500,7 +397,7 @@
 		onSignal(msg)
 	}
 }
-
+// 发送呼叫信息
 function requestCall() {
 	state.value = 'calling'
 	incomingFrom = null
@@ -511,14 +408,10 @@
 	send('call', peerUid.value, null)
 	log('➡️ 发起呼叫 call 给', peerUid.value)
 }
-
+// 接收信息
 function acceptCall() {
 	if (!incomingFrom) return
 	acceptedByMe = true
-
-	// 停止来电提示
-	stopRingtone()
-	stopVibration()
 
 	// 先告诉对方我接听了(后端会把双方置忙)
 	send('accept', incomingFrom, null)
@@ -535,10 +428,6 @@
 
 function rejectCall() {
 	if (!incomingFrom) return
-
-	// 停止来电提示
-	stopRingtone()
-	stopVibration()
 
 	// 你后端没有 reject,用 busy 表示拒绝/不可接听
 	send('busy', incomingFrom, null)
@@ -563,14 +452,14 @@
 
 	// ✅ 不会重复 addTrack
 	await ensureLocalTracksAdded()
-
+// 步骤1:创建 offer
 	const offer = await pc.createOffer()
 	await pc.setLocalDescription(offer)
 
 	send('offer', peerUid.value, { sdp: pc.localDescription })
 	log('➡️ 已发送 offer 给', peerUid.value)
 }
-
+// 步骤2:等待 answer
 async function answerOffer(offerSdp, from) {
 	if (!offerSdp) {
 		log('❌ offer sdp 为空,无法接听')
@@ -605,9 +494,6 @@
 	} catch {}
 
 	stopTimer()
-	// 停止来电提示
-	stopRingtone()
-	stopVibration()
 
 	if (pc) {
 		pc.getSenders().forEach(s => s.track && s.track.stop())
@@ -650,9 +536,8 @@
 		callEnded.value = true
 		endMessage.value = '对方已挂断'
 		
-		// 延迟10秒后跳转页面
+		// 延迟5秒后跳转页面
 		endTimer.value = setTimeout(() => {
-			log('⏰ 通话结束10秒后自动返回')
 			// 返回上一页(uni-app的语音通话列表页面)
 			if (window.uni) {
 				window.uni.navigateBack()
@@ -670,7 +555,7 @@
 
 onMounted(() => {
 	console.log('收拾收拾',route.query.voiceparams);
-	console.log('接收参数', receiveParameters.value)
+	console.log('接收参数', JSON.parse(decodeURIComponent(receiveParameters.value)))
 
 	// 解析并使用contact参数
 	if (receiveParameters.value) {
@@ -678,8 +563,9 @@
 			const contact = JSON.parse(decodeURIComponent(receiveParameters.value))
 			if (contact.friendId) {
 				peerUid.value = contact.friendId
+				contactName.value = contact.friendNickName || '未知联系人'
 				log('🔗 从contact参数获取peerUid:', contact.friendId)
-				log('👤 联系人名称:', contact.friendNickName || '未知联系人')
+				log('👤 联系人名称:', contactName.value)
 			}
 		} catch (e) {
 			log('❌ 解析contact参数失败:', String(e))
@@ -863,6 +749,17 @@
 	margin-bottom: 20px;
 }
 
+	/* 联系人名称样式 */
+	.contactName {
+		font-size: 18px;
+		font-weight: bold;
+		color: #333;
+		text-align: center;
+		margin-top: 10px;
+			margin-bottom: 40px;
+
+	}
+
 /* 来电状态样式 */
 .status-text.incoming-status {
 	font-size: 24px;
@@ -939,7 +836,6 @@
 	display: flex;
 	justify-content: center;
 	align-items: center;
-	margin-bottom: 40px;
 	border-radius: 50%;
 	background-color: #f0f0f0;
 	overflow: hidden;

--
Gitblit v1.9.3