<template>
<el-card class="box-card" shadow="always" :style="{width: panelWidth + 'px'}">
<div class="chat-panel" :style="{ height: panelHeight + 'px' }">
<div class="chat-history" style=" border: 2px solid #ccc;" :style="{ height: panelHeight - 250 + 'px' }">
<el-scrollbar ref="scrollbarRef" always>
<!-- 聊天内容 -->
<div ref="innerRef" v-for="message in messagesList" :class="{ 'sent-message': message.senderID === 1, 'received-message': message.senderID !== 1 }" class="message" style="padding: 10px">
<div>{{ formatTime(message.sendTime) }} {{ message.senderNickname }}</div>
<div>{{ message.textElem.content }}</div>
</div>
</el-scrollbar>
</div>
<div class="chat-input" style="padding: 20px">
<el-row :gutter="20">
<el-col :span="2">
<el-button>表情</el-button>
</el-col>
<el-col :span="2">
<el-button>图片</el-button>
</el-col>
<el-col :span="2">
<el-button>文件</el-button>
</el-col>
<el-col :span="2">
<el-button>邀评</el-button>
</el-col>
<el-col :span="2">
<el-button>结束</el-button>
</el-col>
<el-col :span="2">
<el-button>转移</el-button>
</el-col>
<el-col :span="2">
<el-button>常用语</el-button>
</el-col>
<el-col :span="20" style="padding-top:10px;">
<el-input rows="4" type="textarea" v-model="newMessage" @keyup.enter="sendMessage"></el-input>
</el-col>
<el-col :span="2" style="padding: 40px">
<el-button type="primary" @click="sendMessage">发送</el-button>
</el-col>
</el-row>
</div>
</div>
</el-card>
</template>
<script setup>
import {getSDK, CbEvents} from 'open-im-sdk-wasm';
import {ref, onMounted, onUnmounted, nextTick} from 'vue';
import {ElScrollbar} from 'element-plus'
const IMS = getSDK();
//聊天内容
const messagesList = ref([]);
//待发送消息
const newMessage = ref('');
//页面高度
const panelHeight = ref(0);
//页面宽度
const panelWidth = ref(0);
//对话框高度
const max = ref(0)
//聊天框滚动条ref
const scrollbarRef = ref()
//对话框ref
const innerRef = ref();
IMS.on(CbEvents.OnConnecting, () => {
// 连接中
console.log("连接中")
})
IMS.on(CbEvents.OnConnectSuccess, () => {
// 连接成功
console.log("连接成功")
})
IMS.on(CbEvents.OnConnectFailed, () => {
// 连接失败
console.log("连接失败")
})
IMS.on(CbEvents.OnUserTokenExpired, () => {
// token无效
console.log("token无效")
})
//登录
IMS.login({
userID: "XXXX", // IM 用户 userID
token: "XXXX.eyJVc2VySUQiOiI2OTM1NjgxMDEzIiwiUGxhdGZvcm1JRCI6NSwiZXhwIjoxNzIxMjY1Mzk2LCJuYmYiOjE3MTM0ODkwOTYsImlhdCI6MTcxMzQ4OTM5Nn0.N2YOD-GA35LvkM_CZ79MMbOkFNcxVKrs3bCOKEAoMBc", // IM 用户令牌
platformID: 5, // 当前登录平台号,web端为5
apiAddr: "http://X.X.X.X:10002", // IM api 地址,一般为`http://your-server-ip:10002`
wsAddr: "ws://X.X.X.X:10001" // IM ws 地址,一般为`ws://your-server-ip:10001`
})
.then(() => {
// 登录完成
console.log("登录成功")
})
.catch(({errCode, errMsg}) => {
// 登录失败
console.log("登录失败")
});
//收发消息
IMS.on(CbEvents.OnRecvNewMessages, async ({data: messages}) => {
// 收到新消息
if (messages && messages[0].textElem) {
messagesList.value.push(messages[0])
await nextTick(() => {
scrollbarRef.value.setScrollTop(panelHeight.value + innerRef.value.length * 58);
})
}
})
//发送消息
async function sendMessage() {
const {data: message} = await IMS.createTextMessage(newMessage.value)
if (message && message.textElem && message.textElem.content.replace(/\s+/g, '')) {
IMS.sendMessage({
recvID: "XXXXXX",
groupID: "",
message: message
})
.then(async ({data}) => {
console.log("调用成功 :" + data)
const newMessage = {
sendTime: Date.now(),
senderNickname: message.senderNickname,
textElem: {
content: message.textElem.content
},
senderID : 1
};
// 将新的消息对象添加到 messagesList 中
messagesList.value.push(newMessage);
//重新定位滚动条
await nextTick(() => {
scrollbarRef.value.setScrollTop(panelHeight.value + innerRef.value.length * 58);
})
})
.catch(({errCode, errMsg}) => {
console.log("调用失败 :" + errMsg)
});
}
newMessage.value = '';
}
//页面初始化方法
onMounted(() => {
updatePanelHeight();
window.addEventListener('resize', updatePanelHeight); // 更新窗口大小时重新计算高度
});
//计算屏幕高度及对话框宽度
function updatePanelHeight() {
panelHeight.value = window.innerHeight - 250; // 根据窗口高度动态计算面板高度
panelWidth.value = window.innerWidth - 650;//获取浏览器宽度 避免宽度超出
}
//页面关闭
onUnmounted(() => {
window.removeEventListener('resize', updatePanelHeight); // 清理事件监听器
});
function formatTime(timestamp) {
const date = new Date(timestamp);
return date.toLocaleString(); // 或者使用你喜欢的其他时间格式化方式
}
</script>
<style scoped>
/* 保留其他CSS规则 */
.side-panel, .chat-panel {
overflow: auto; /* 滚动条出现在每个区域内部 */
overflow-x: hidden; /* 隐藏横向滚动条 */
}
.chat-input {
display: flex;
flex-direction: column;
}
/* 确保其他相关样式不会干扰滚动条的显示 */
.chat-history, .list, .info {
overflow-y: auto; /* 垂直滚动条仅在需要时出现 */
overflow-x: hidden; /* 隐藏横向滚动条 */
}
.sent-message {
text-align: right;
}
.received-message {
text-align: left;
}
</style>
OPEN-IM SERVER 3.6