From f54a103de55ae6426bf532535fa7d674a0f2d955 Mon Sep 17 00:00:00 2001 From: liqi Date: Thu, 4 Dec 2025 10:09:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E8=81=94=E7=B3=BB=E4=BA=BA=E4=BF=A1=E6=81=AF=E5=8F=91=E9=80=81?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E7=9A=84=E6=97=B6=E5=80=99=E6=88=BF=E9=97=B4?= =?UTF-8?q?id=E7=BB=91=E5=AE=9A=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/modules/contact.ts | 12 ++++++++++-- src/composables/useWebRTC.ts | 10 ++++++++++ src/types/api.ts | 1 + src/views/chat/ChatView.vue | 7 ++++++- src/views/contact/ContactDetail.vue | 6 ++++-- src/views/contact/ContactDetailCard.vue | 6 ++++-- 6 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/api/modules/contact.ts b/src/api/modules/contact.ts index b7e2e84..2cccd8a 100644 --- a/src/api/modules/contact.ts +++ b/src/api/modules/contact.ts @@ -58,8 +58,16 @@ export function deleteGroup(id: number) { } // 获取好友详情 -export function getContactDetail(id: string) { - return request.get(`/contacts/${id}`) +export async function getContactDetail(id: string): Promise { + const response = await request.get<{ contact: any; user: User }>(`/contacts/${id}`) + // 合并 contact 和 user 数据为完整的 Contact 对象 + return { + ...response.contact, + id: response.contact.id?.toString() || response.contact.contact_id, + user_id: response.contact.contact_id || response.contact.user_id, + contact_user_id: response.contact.contact_id, + user: response.user, + } as Contact } // 更新好友信息 diff --git a/src/composables/useWebRTC.ts b/src/composables/useWebRTC.ts index d628dd1..0aec8c6 100644 --- a/src/composables/useWebRTC.ts +++ b/src/composables/useWebRTC.ts @@ -392,6 +392,11 @@ export function useWebRTC(userId: string, onIncomingCall?: (senderUserId: string call.status = 'connected' call.statusText = '通话中' startCallTimer() + // 确保 pc 已创建 + if (!pc) { + await initMedia(call.type === 'video') + await createPC() + } const offer = await pc!.createOffer() await pc!.setLocalDescription(offer) sendSignal('offer', offer) @@ -412,6 +417,11 @@ export function useWebRTC(userId: string, onIncomingCall?: (senderUserId: string startCallTimer() } else if (signal === 'answer') { + // 确保 pc 已创建 + if (!pc) { + await initMedia(call.type === 'video') + await createPC() + } await pc!.setRemoteDescription(content) processPendingCandidates() diff --git a/src/types/api.ts b/src/types/api.ts index 8e4c62b..c1c9af1 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -49,6 +49,7 @@ export interface Contact { id: string user_id: string contact_user_id: string + room_id?: string // 房间ID(雪花ID) remark_name?: string group_id?: number is_top: boolean diff --git a/src/views/chat/ChatView.vue b/src/views/chat/ChatView.vue index 794feb5..f7edf50 100644 --- a/src/views/chat/ChatView.vue +++ b/src/views/chat/ChatView.vue @@ -328,7 +328,12 @@ const currentMessages = computed(() => { }) function getRoomId(contact: Contact): string { - const userIds = [authStore.user!.id, contact.user_id || contact.id].sort() + // 优先使用 contact.room_id(雪花ID),如果没有则使用旧的生成方式作为后备 + if (contact.room_id) { + return contact.room_id + } + // 后备方案:使用旧的格式(兼容旧数据) + const userIds = [authStore.user!.id, contact.user_id || contact.id || contact.contact_user_id].sort() return userIds.join('_') } diff --git a/src/views/contact/ContactDetail.vue b/src/views/contact/ContactDetail.vue index e68e6ff..22a44f9 100644 --- a/src/views/contact/ContactDetail.vue +++ b/src/views/contact/ContactDetail.vue @@ -274,7 +274,8 @@ function handleSendMessage() { function handleAudioCall() { if (contact.value) { - const receiverUserId = contact.value.user_id || contact.value.id || contact.value.contact_user_id + // contact_id 或 contact_user_id 是联系人的用户ID(接收者) + const receiverUserId = contact.value.contact_user_id || contact.value.contact_id || contact.value.user_id || contact.value.id // 直接发起通话,不跳转到会话模块 webrtc.startCall('audio', receiverUserId) } @@ -282,7 +283,8 @@ function handleAudioCall() { function handleVideoCall() { if (contact.value) { - const receiverUserId = contact.value.user_id || contact.value.id || contact.value.contact_user_id + // contact_id 或 contact_user_id 是联系人的用户ID(接收者) + const receiverUserId = contact.value.contact_user_id || contact.value.contact_id || contact.value.user_id || contact.value.id // 直接发起通话,不跳转到会话模块 webrtc.startCall('video', receiverUserId) } diff --git a/src/views/contact/ContactDetailCard.vue b/src/views/contact/ContactDetailCard.vue index 92cf88f..8233f9e 100644 --- a/src/views/contact/ContactDetailCard.vue +++ b/src/views/contact/ContactDetailCard.vue @@ -287,7 +287,8 @@ function handleSendMessage() { function handleAudioCall() { if (contact.value) { - const receiverUserId = contact.value.user_id || contact.value.id + // contact_id 或 contact_user_id 是联系人的用户ID + const receiverUserId = contact.value.contact_user_id || contact.value.contact_id || contact.value.user_id || contact.value.id // 直接发起通话,不跳转到会话模块 webrtc.startCall('audio', receiverUserId) } @@ -295,7 +296,8 @@ function handleAudioCall() { function handleVideoCall() { if (contact.value) { - const receiverUserId = contact.value.user_id || contact.value.id + // contact_id 或 contact_user_id 是联系人的用户ID + const receiverUserId = contact.value.contact_user_id || contact.value.contact_id || contact.value.user_id || contact.value.id // 直接发起通话,不跳转到会话模块 webrtc.startCall('video', receiverUserId) }