wkw 1 주 전
부모
커밋
24a8560dff
1개의 변경된 파일92개의 추가작업 그리고 31개의 파일을 삭제
  1. 92 31
      src/views/im/chat/index.vue

+ 92 - 31
src/views/im/chat/index.vue

@@ -167,12 +167,20 @@
         </div>
       </div>
     </div>
-    <!-- 语音 -->
-    <VoiceCallModal
-      v-if="showVoiceCall"
-      :user="currentUser"
-      @hangup="handleHangup"
-    />
+
+
+    <!-- 来电弹窗 -->
+    <div v-if="imState.videoCallModal && !inCall" class="call-modal">
+      <p>{{ imState.callName }} 正在呼叫你</p>
+      <button @click="acceptCall">接听</button>
+      <button @click="rejectCall">拒接</button>
+    </div>
+
+    <!-- 通话中显示挂断按钮 -->
+    <div v-if="inCall" class="call-modal">
+      <p>与 {{ imState.callName }} 通话中...</p>
+      <button @click="hangupCall">挂断</button>
+    </div>
   </div>
 </template>
 
@@ -188,7 +196,6 @@ import messageAudio from "@/views/im/components/messageAudio/index.vue";
 import { showToast, showImagePreview } from "vant";
 import { useWebRTCStore } from "@/stores/modules/webrtcStore";
 import * as Constant from "@/common/constant/Constant";
-import VoiceCallModal from "@/views/im/components/VoiceCallModal/index.vue";
 
 const IM_PATH = import.meta.env.VITE_IM_PATH_FIlE;
 // 路由 & store
@@ -209,7 +216,8 @@ const appBoxHeight = ref(210);
 const chatListRef = ref(null);
 const emojiRef = ref(null);
 const toolsRef = ref(null);
-const showVoiceCall = ref(false);
+const imState = reactive(rtcStore.imSate); // 来电弹窗显示,callName,fromUserUuid
+const inCall = ref(false); // 是否处于通话中
 
 // 示例用户
 const currentUser = ref({
@@ -426,33 +434,86 @@ const beforeRead = (file) => {
 };
 
 //  创建呼叫:开启语音电话: 调试用,正式逻辑读src/views/im/hook/messagesHook.js
+// ==== 1. 发起语音通话 ====
 const startAudioOnline = async () => {
-  showVoiceCall.value = true;
-  // 初始化webrtc连接
-  rtcStore.initConnection(true);
-
-  navigator.mediaDevices
-    .getUserMedia({ audio: true })
-    .then((stream) => {
-      rtcStore.addLocalStream(stream);
-      return rtcStore.createOffer();
-    })
-    .then((offer) => {
-      // 发送offer
-      wsStore.sendMessage({
-        contentType: Constant.AUDIO_ONLINE, // 消息内容类型
-        content: JSON.stringify(offer),
-        type: Constant.MESSAGE_TRANS_TYPE,
-      });
-    })
-    .catch((error) => {
-      console.error("发起呼叫失败:", error);
+  try {
+    rtcStore.initConnection(true); // 主叫
+    const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });
+    await rtcStore.addLocalStream(stream);
+
+    const offer = await rtcStore.createOffer();
+
+    wsStore.sendMessage({
+      contentType: Constant.DIAL_AUDIO_ONLINE,
+      content: JSON.stringify(offer),
+      type: Constant.MESSAGE_TRANS_TYPE,
+      to: imState.fromUserUuid || "对方用户ID", // 实际传对方ID
     });
-};
 
-const handleHangup = () => {
-  showVoiceCall.value = false;
+    imState.videoCallModal = true;
+    imState.callName = "对方昵称"; // 实际昵称
+    inCall.value = true;
+  } catch (error) {
+    console.error("发起语音通话失败", error);
+  }
 };
+// ==== 2. 接听来电 ====
+async function acceptCall() {
+  try {
+    rtcStore.initConnection(false); // 被叫
+    const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });
+    await rtcStore.addLocalStream(stream);
+
+    // 远端offer SDP,存在imState.offerContent,messagesHook里收到后需保存offerContent
+    const offerSDP = JSON.parse(imState.offerContent);
+    await rtcStore.setRemoteDescription(new RTCSessionDescription(offerSDP));
+
+    const answer = await rtcStore.createAnswer();
+
+    wsStore.sendMessage({
+      contentType: Constant.ACCEPT_AUDIO_ONLINE,
+      content: JSON.stringify(answer),
+      type: Constant.MESSAGE_TRANS_TYPE,
+      to: imState.fromUserUuid,
+    });
+
+    inCall.value = true;
+    imState.videoCallModal = true;
+  } catch (error) {
+    console.error("接听失败", error);
+  }
+}
+
+// ==== 3. 拒接来电 ====
+function rejectCall() {
+  wsStore.sendMessage({
+    contentType: Constant.REJECT_AUDIO_ONLINE,
+    content: "",
+    type: Constant.MESSAGE_TRANS_TYPE,
+    to: imState.fromUserUuid,
+  });
+
+  rtcStore.videoCallModal = false;
+  inCall.value = false;
+}
+
+// ==== 4. 挂断通话 ====
+function hangupCall() {
+  rtcStore.cleanup();
+  wsStore.sendMessage({
+    contentType: Constant.CANCELL_AUDIO_ONLINE,
+    content: "",
+    type: Constant.MESSAGE_TRANS_TYPE,
+    to: imState.fromUserUuid,
+  });
+  rtcStore.videoCallModal = false;
+  inCall.value = false;
+}
+
+// ==== 5. 监听信令消息 ====
+// 建议你在 useWebSocketStore 里实现 onMessage 订阅信令消息
+// 这里模拟简易监听,示范关键流程
+
 
 // 时间格式化
 const formatTime = (timestamp) => {