|
@@ -20,9 +20,7 @@
|
|
<div class="box">
|
|
<div class="box">
|
|
<div
|
|
<div
|
|
class="list-item"
|
|
class="list-item"
|
|
- :class="
|
|
|
|
- isSender(item.toUsername) ? '' : 'flex-reverse'
|
|
|
|
- "
|
|
|
|
|
|
+ :class="isSender(item.toUsername) ? '' : 'flex-reverse'"
|
|
>
|
|
>
|
|
<!-- 头像 -->
|
|
<!-- 头像 -->
|
|
<van-image
|
|
<van-image
|
|
@@ -42,7 +40,10 @@
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- 图片消息 -->
|
|
<!-- 图片消息 -->
|
|
- <div class="img-message" v-else-if="item.contentType === MSG_TYPE.IMAGE">
|
|
|
|
|
|
+ <div
|
|
|
|
+ class="content"
|
|
|
|
+ v-else-if="item.contentType === MSG_TYPE.IMAGE"
|
|
|
|
+ >
|
|
<van-image
|
|
<van-image
|
|
:src="item?.localUrl || IM_PATH + item.url"
|
|
:src="item?.localUrl || IM_PATH + item.url"
|
|
style="max-width: 120px; border-radius: 8px" @click="previewImage(item)"
|
|
style="max-width: 120px; border-radius: 8px" @click="previewImage(item)"
|
|
@@ -75,7 +76,10 @@
|
|
controls
|
|
controls
|
|
style="width: 200px"
|
|
style="width: 200px"
|
|
/> -->
|
|
/> -->
|
|
- <messageAudio :src="item?.localUrl || IM_PATH + item.url" :isSender="isSender(item.toUsername)"/>
|
|
|
|
|
|
+ <messageAudio
|
|
|
|
+ :src="item?.localUrl || IM_PATH + item.url"
|
|
|
|
+ :isSender="isSender(item.toUsername)"
|
|
|
|
+ />
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- 其他未知类型 -->
|
|
<!-- 其他未知类型 -->
|
|
@@ -175,7 +179,8 @@ import { Capacitor } from "@capacitor/core";
|
|
import { MSG_TYPE, MESSAGE_TYPE_USER } from "@/common/constant/msgType";
|
|
import { MSG_TYPE, MESSAGE_TYPE_USER } from "@/common/constant/msgType";
|
|
import messageAudio from "@/views/im/components/messageAudio/index.vue";
|
|
import messageAudio from "@/views/im/components/messageAudio/index.vue";
|
|
import { showToast,showImagePreview } from 'vant';
|
|
import { showToast,showImagePreview } from 'vant';
|
|
-import {useWebRTCStore} from "@/stores/modules/webrtcStore";
|
|
|
|
|
|
+import {useWebRTCStore} from "@/stores/modules/webrtcStore";
|
|
|
|
+import * as Constant from "@/common/constant/Constant";
|
|
|
|
|
|
const IM_PATH = import.meta.env.VITE_IM_PATH_FIlE;
|
|
const IM_PATH = import.meta.env.VITE_IM_PATH_FIlE;
|
|
// 路由 & store
|
|
// 路由 & store
|
|
@@ -183,7 +188,7 @@ const router = useRouter();
|
|
const route = useRoute();
|
|
const route = useRoute();
|
|
const wsStore = useWebSocketStore();
|
|
const wsStore = useWebSocketStore();
|
|
const walletStore = useWalletStore();
|
|
const walletStore = useWalletStore();
|
|
-const webRTCStore = useWebRTCStore()
|
|
|
|
|
|
+const rtcStore = useWebRTCStore();
|
|
|
|
|
|
// 输入框文本
|
|
// 输入框文本
|
|
const text = ref("");
|
|
const text = ref("");
|
|
@@ -326,7 +331,6 @@ const stopRecording = async () => {
|
|
});
|
|
});
|
|
};
|
|
};
|
|
|
|
|
|
-
|
|
|
|
// 发送音频消息
|
|
// 发送音频消息
|
|
const sendAudioMessage = async (event) => {
|
|
const sendAudioMessage = async (event) => {
|
|
if (isTouchDevice.value && event.type === "mouseup") {
|
|
if (isTouchDevice.value && event.type === "mouseup") {
|
|
@@ -342,7 +346,7 @@ const sendAudioMessage = async (event) => {
|
|
content: text.value, // 如果有文本内容
|
|
content: text.value, // 如果有文本内容
|
|
contentType: MSG_TYPE.AUDIO, // 音频消息类型
|
|
contentType: MSG_TYPE.AUDIO, // 音频消息类型
|
|
messageType: MESSAGE_TYPE_USER, // 单聊消息
|
|
messageType: MESSAGE_TYPE_USER, // 单聊消息
|
|
- to: route.query.uuid, // 接收方ID
|
|
|
|
|
|
+
|
|
fileSuffix: "wav", // 使用webm后缀更准确
|
|
fileSuffix: "wav", // 使用webm后缀更准确
|
|
file: audioData, // 将Uint8Array转为普通数组
|
|
file: audioData, // 将Uint8Array转为普通数组
|
|
};
|
|
};
|
|
@@ -364,7 +368,7 @@ const sendMessage = () => {
|
|
content: text.value,
|
|
content: text.value,
|
|
contentType: MSG_TYPE.TEXT, // 1: 文本消息
|
|
contentType: MSG_TYPE.TEXT, // 1: 文本消息
|
|
messageType: MESSAGE_TYPE_USER, // 1: 单聊天
|
|
messageType: MESSAGE_TYPE_USER, // 1: 单聊天
|
|
- to: route.query.uuid,
|
|
|
|
|
|
+
|
|
};
|
|
};
|
|
wsStore.sendMessage(message);
|
|
wsStore.sendMessage(message);
|
|
text.value = "";
|
|
text.value = "";
|
|
@@ -372,17 +376,16 @@ const sendMessage = () => {
|
|
};
|
|
};
|
|
|
|
|
|
// 发送图片消息
|
|
// 发送图片消息
|
|
-const afterRead = async (file) => {
|
|
|
|
- const arrayBuffer = await file.file.arrayBuffer();
|
|
|
|
|
|
+const afterRead = async (file) => {
|
|
|
|
+ const arrayBuffer = await file.file.arrayBuffer();
|
|
const message = {
|
|
const message = {
|
|
content: text.value, // 如果有文本内容
|
|
content: text.value, // 如果有文本内容
|
|
contentType: MSG_TYPE.IMAGE, // 音频消息类型
|
|
contentType: MSG_TYPE.IMAGE, // 音频消息类型
|
|
messageType: MESSAGE_TYPE_USER, // 单聊消息
|
|
messageType: MESSAGE_TYPE_USER, // 单聊消息
|
|
- to: route.query.uuid, // 接收方ID
|
|
|
|
fileSuffix: file.type, // 使用webm后缀更准确
|
|
fileSuffix: file.type, // 使用webm后缀更准确
|
|
file: new Uint8Array(arrayBuffer), // 将Uint8Array转为普通数组
|
|
file: new Uint8Array(arrayBuffer), // 将Uint8Array转为普通数组
|
|
};
|
|
};
|
|
-
|
|
|
|
|
|
+
|
|
wsStore.sendMessage(message);
|
|
wsStore.sendMessage(message);
|
|
};
|
|
};
|
|
// 图片类型
|
|
// 图片类型
|
|
@@ -399,15 +402,40 @@ const beforeRead = (file) => {
|
|
};
|
|
};
|
|
|
|
|
|
// 开启语音电话
|
|
// 开启语音电话
|
|
-const startAudioOnline = () => {
|
|
|
|
- webRTCStore.initConnection(
|
|
|
|
- MESSAGE_TYPE_USER,
|
|
|
|
- {
|
|
|
|
- fromUsername: walletStore.username,
|
|
|
|
- from: walletStore.account,
|
|
|
|
- to: route.query.uuid,
|
|
|
|
- }
|
|
|
|
- )
|
|
|
|
|
|
+const startAudioOnline = async () => {
|
|
|
|
+ // 初始化webrtc连接
|
|
|
|
+ rtcStore.initConnection(MESSAGE_TYPE_USER, {
|
|
|
|
+ fromUsername: walletStore.username,
|
|
|
|
+ from: walletStore.account,
|
|
|
|
+ });
|
|
|
|
+ // 获取本地媒体流并添加到连接
|
|
|
|
+ try {
|
|
|
|
+ const stream = await navigator.mediaDevices.getUserMedia({
|
|
|
|
+ audio: true,
|
|
|
|
+ video: true,
|
|
|
|
+ });
|
|
|
|
+ rtcStore.addLocalStream(stream);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error("获取媒体流失败:", error);
|
|
|
|
+ }
|
|
|
|
+ // 创建呼叫
|
|
|
|
+ try {
|
|
|
|
+ await startLocalStream();
|
|
|
|
+ const offer = await rtcStore.createOffer();
|
|
|
|
+ // 发送 offer 给对等端
|
|
|
|
+ let data = {
|
|
|
|
+ contentType: Constant.AUDIO_ONLINE, // 消息内容类型
|
|
|
|
+ content: JSON.stringify(offer),
|
|
|
|
+ type: Constant.MESSAGE_TRANS_TYPE, // 消息传输类型
|
|
|
|
+ };
|
|
|
|
+ wsStore.sendMessage(data);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error("发起呼叫失败:", error);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // rtcStore.addLocalStream(stream)
|
|
|
|
+ // // 流获取:再进行offer创建
|
|
|
|
+ // const webRTCStore.createOffer()
|
|
};
|
|
};
|
|
|
|
|
|
// 时间格式化
|
|
// 时间格式化
|
|
@@ -420,6 +448,7 @@ const formatTime = (timestamp) => {
|
|
|
|
|
|
// 页面生命周期
|
|
// 页面生命周期
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
|
+ wsStore.toUserInfo.uuid = route.query.uuid;
|
|
wsStore.getMessages({
|
|
wsStore.getMessages({
|
|
uuid: walletStore.account,
|
|
uuid: walletStore.account,
|
|
messageType: 1,
|
|
messageType: 1,
|