parent
5828db7f5c
commit
139804bd2a
@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="main-body-content">
|
||||
<div style="display: flex; align-items: flex-start">
|
||||
<div style="width: 200px; border: 1px solid #ddd; border-radius: 5px; height: calc(50vh + 125px);">
|
||||
<div style="padding: 10px; border-bottom: 1px solid #ddd; color: #000; background-color: #eee">用户</div>
|
||||
<div class="user-list-box" style="height: 80%; overflow-y: scroll">
|
||||
<div class="user-list-item" v-for="item in users.user" @click="selectToUser(item)">
|
||||
<el-avatar icon="el-icon-user-solid"></el-avatar>
|
||||
<span style="flex: 1; margin-left: 10px;" :style="{ color: item.role+ '_' + item.name === toUser ? '#3a8ee6' : '' }">{{ item.name }}</span>
|
||||
<div class="user-list-item-badge" v-if="unRead?.[item.role + '_' + item.name]">{{ unRead?.[item.role + '_' + item.name] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 中间部分 -->
|
||||
<div style="width: 60%; border: 1px solid #ddd; border-radius: 5px; background-color: #f1f1f1; margin: 0 10px;">
|
||||
<div style="padding: 20px 0; text-align: center; border-bottom: 1px solid #ddd; color: #000; background-color: #eee; height: 60px">
|
||||
{{ toUser?.substring(toUser.indexOf('_') + 1) }}
|
||||
</div>
|
||||
<div class="im-message-box">
|
||||
<div v-for="item in messages" :key="item.id">
|
||||
<!-- 右边的气泡 -->
|
||||
<div style="display: flex; flex-direction: row-reverse; align-items: flex-start"
|
||||
v-if="item.fromuser === fromUser">
|
||||
<el-avatar src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"></el-avatar>
|
||||
<div class="im-message im-message-right" v-html="item.content" v-if="item.type === 'text'"></div>
|
||||
</div>
|
||||
<!-- 左边的气泡 -->
|
||||
<div style="display: flex; align-items: flex-start" v-else>
|
||||
<el-avatar icon="el-icon-user-solid"></el-avatar>
|
||||
<div style="width: 100%">
|
||||
<div style="color: #888; font-size: 12px; width: 50%"></div>
|
||||
<div class="im-message im-message-left" v-html="item.content" v-if="item.type === 'text'"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 输入区域 -->
|
||||
<div style="padding: 10px 25px; border-top: 1px solid #ddd; display: flex; align-items: center; width: 90%;">
|
||||
<div id="im-content" contenteditable style="text-align:left;flex: 1; background-color: #fff; margin: 0 5px; padding: 10px; border: 1px solid #ddd; border-radius: 2px; outline: none; font-size: 14px;"></div>
|
||||
<el-button type="primary" @click="send" style="border: none;margin-left: 10px">发送</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 中间部分结束 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import request from "@/utils/request";
|
||||
|
||||
let client
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
user: {},
|
||||
permission: [],
|
||||
messages: [],
|
||||
users: {},
|
||||
fromUser: '',
|
||||
toUser: '',
|
||||
toAvatar: '',
|
||||
unRead: {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.user = {id:10001,name:'admin',role:'ADMIN'}
|
||||
this.fromUser = this.user.role + '_' + this.user.name
|
||||
|
||||
client = new WebSocket(`ws://localhost:8181/imserverSingle`)
|
||||
client.onopen = () => {
|
||||
console.log('websocket open')
|
||||
}
|
||||
client.onclose = () => { // 页面刷新的时候和后台websocket服务关闭的时候
|
||||
console.log('websocket close')
|
||||
}
|
||||
client.onmessage = (msg) => {
|
||||
if (msg.data) {
|
||||
let json = JSON.parse(msg.data)
|
||||
if (json.content && (json.fromuser === this.fromUser && json.touser === this.toUser)
|
||||
|| json.touser === this.fromUser && json.fromuser === this.toUser) { // 聊天消息
|
||||
this.messages.push(json)
|
||||
this.scrollToBottom() // 滚动页面到最底部
|
||||
}
|
||||
// 加载消息数字
|
||||
if (this.toUser === json.fromuser) {
|
||||
this.setUnReadNums() // 清空正在聊天人的消息数字
|
||||
} else {
|
||||
this.loadUnReadNums()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 加载聊天数据
|
||||
this.load()
|
||||
|
||||
// 查询用户
|
||||
request.get('/chatuser').then(res => {
|
||||
res.data = res.data.filter(v => (v.role + '_' + v.name) !== this.fromUser && v.role === 'USER')
|
||||
this.$set(this.users, 'user', res.data)
|
||||
})
|
||||
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (client) {
|
||||
client.close()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
request.get('/imsingle?fromUser=' + this.fromUser + '&toUser=' + this.toUser).then(res => {
|
||||
if (res.code === '0') {
|
||||
this.messages = res.data
|
||||
this.scrollToBottom() // 滚动条滚动到最底部
|
||||
} else {
|
||||
this.$notify.error(res.msg)
|
||||
}
|
||||
this.loadUnReadNums()
|
||||
})
|
||||
},
|
||||
setUnReadNums() {
|
||||
request.get('/imsingle?fromUser=' + this.fromUser + '&toUser=' + this.toUser).then(res => {
|
||||
this.loadUnReadNums()
|
||||
})
|
||||
},
|
||||
loadUnReadNums() {
|
||||
// 查询未读数量
|
||||
request.get('/imsingle/unReadNums?toUsername=' + this.fromUser).then(res => {
|
||||
this.unRead = res.data
|
||||
})
|
||||
},
|
||||
send() {
|
||||
if (!this.toUser) {
|
||||
this.$notify.error('请选择聊天用户')
|
||||
return
|
||||
}
|
||||
if (client) {
|
||||
let message = this.getMessage('text')
|
||||
client.send(JSON.stringify(message))
|
||||
}
|
||||
document.getElementById('im-content').innerHTML = '' // 清空输入框
|
||||
},
|
||||
selectToUser(item) {
|
||||
this.toUser = item.role + '_' + item.name
|
||||
this.toAvatar = item.avatar
|
||||
//查询聊天记录
|
||||
this.load()
|
||||
},
|
||||
getMessage(type) {
|
||||
let inputBox = document.getElementById('im-content')
|
||||
const content = inputBox.innerHTML
|
||||
if (!content && type === 'text') {
|
||||
this.$notify.error('请输入聊天内容')
|
||||
return
|
||||
}
|
||||
return {
|
||||
fromuser: this.fromUser,
|
||||
fromavatar: this.user.avatar,
|
||||
touser: this.toUser,
|
||||
toavatar: this.toAvatar,
|
||||
content: content,
|
||||
type: type
|
||||
}
|
||||
},
|
||||
scrollToBottom() {
|
||||
this.$nextTick(() => {
|
||||
// 设置聊天滚动条到底部
|
||||
let imMessageBox = document.getElementsByClassName("im-message-box")[0]
|
||||
//设置滚动条到最底部
|
||||
imMessageBox.scrollTop = imMessageBox.scrollHeight
|
||||
console.log('触发滚动')
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.im-message-box {
|
||||
height: 50vh;
|
||||
padding: 10px;
|
||||
overflow-y: auto;
|
||||
background-color: white;
|
||||
}
|
||||
.user-list-box {
|
||||
overflow-y: auto;
|
||||
}
|
||||
.im-message {
|
||||
font-size: 14px;
|
||||
padding: 10px;
|
||||
margin: 5px 0;
|
||||
border-radius: 5px;
|
||||
color: #000;
|
||||
max-width: 50%;
|
||||
line-height: 20px;
|
||||
width: fit-content;
|
||||
}
|
||||
.im-message-left {
|
||||
background-color: #DBEDFF;
|
||||
}
|
||||
.im-message-right {
|
||||
background-color: #26d470;
|
||||
}
|
||||
.user-list-item {
|
||||
display: flex;
|
||||
padding: 10px;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #eee;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
.user-list-item-badge {
|
||||
padding: 2px 6px;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
color: white;
|
||||
background-color: red;
|
||||
}
|
||||
.user-list-item:nth-last-child(1) {
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in new issue