qa-prevention-gwj-vue/src/views/emergen_cyrescue/emergency_map/components/chat.vue

287 lines
6.9 KiB
Vue
Raw Normal View History

<template>
<div class="chat">
<div class="chat-title">
欢迎您,在这里可查看城市的重点隐患信息!
</div>
<div class="content">
<div class="item item-right">
<div class="bubble bubble-right">
刚刚不在不好意思
</div>
<div class="avatar">
<img src="https://tse1-mm.cn.bing.net/th/id/OIP-C.4XP3SrYigaDrlkbG_uFkzQAAAA?rs=1&pid=ImgDetMain">
</div>
</div>
<div class="item item-left">
<div class="avatar">
<img src="https://tse4-mm.cn.bing.net/th/id/OIP-C.-byzt1F3AA9UcVgO_DOIwQAAAA?rs=1&pid=ImgDetMain">
</div>
<div class="bubble bubble-left">
没事
<br>
你继续
</div>
</div>
<!-- 服务端向客户端推送的消息队列 -->
<div v-for="(item, index) in receiveMessageList" :key="index" :class="item.className">
<div style="display: flex;" v-html="item.content" />
</div>
<!-- 客户端向服务端主动发送的消息队列 -->
<div v-for="(item, index) in sendMessageList" :key="index" :class="item.className">
<div style="display: flex;" v-html="item.content" />
</div>
</div>
<div class="input-area">
<textarea id="textarea" v-model="inputTextValue" class="input-text-area" name="text" />
<div class="button-area">
<button class="btnSend" @click="handleSendMessage"> (S) </button>
</div>
</div>
</div>
</template>
<script>
let socketIOInstance
export default {
name: 'Chat',
data() {
return {
websocketonline: '',
inputTextValue: '',
/** 发送消息列表 */
sendMessageList: [],
/** 接收消息列表 */
receiveMessageList: []
}
},
created() {
this.getWebsocketController()
},
beforeDestroy() {
socketIOInstance.close()
},
methods: {
// 启动 websocket 连接控制器
getWebsocketController() {
if (window.WebSocket) {
socketIOInstance = new WebSocket(encodeURI('ws://192.168.0.35:8089/getMapData/1'))
socketIOInstance.onopen = () => {
console.log('socket 连接成功!')
}
socketIOInstance.onerror = () => {
console.log('socket 连接失败!')
}
socketIOInstance.onclose = () => {
console.log('socket 连接断开!')
}
socketIOInstance.onmessage = (message) => {
this.handleReceiveMessage(message)
}
}
},
/** 处理服务端向客户端推送的消息并展示到消息列表内 */
handleReceiveMessage(val) {
this.sendMessageList.push({
className: 'item item-left',
content: `<div class="avatar"><img src="https://tse4-mm.cn.bing.net/th/id/OIP-C.-byzt1F3AA9UcVgO_DOIwQAAAA?rs=1&pid=ImgDetMain"></div><div class="bubble bubble-left">${val.data}</div>`
})
},
// 处理客户端向服务端发送消息
handleSendMessage() {
if (this.inputTextValue === '') {
this.$message('消息不能为空!')
return
}
socketIOInstance.send(this.inputTextValue) // 向 websocket 服务发送消息
this.sendMessageList.push({
className: 'item item-right',
content: `<div class="bubble bubble-left">${this.inputTextValue}</div><div class="avatar"><img src="https://tse1-mm.cn.bing.net/th/id/OIP-C.4XP3SrYigaDrlkbG_uFkzQAAAA?rs=1&pid=ImgDetMain" /></div>`
})
this.inputTextValue = ''
this.$nextTick(() => {
// 滚动条置底
const height = document.querySelector('.content').scrollHeight
document.querySelector('.content').scrollTop = height
})
}
}
}
</script>
<style lang="scss">
* {
padding: 0;
margin: 0;
font-size: 15px;
font-family: '微软雅黑', "宋体", "Arial Narrow", Helvetica, sans-serif;
}
.chat {
box-sizing: border-box;
width: 100%;
height: 100%;
.chat-title {
font-size: 20px;
text-align: center;
color: #fff;
height: 35px;
border-bottom: 1px solid white
}
.content {
overflow-y: auto;
overflow-x: hidden;
height: 648px;
&::-webkit-scrollbar {
width: 7px;
}
// 滚动条的滚动区域(轨道)
&::-webkit-scrollbar-track {
width: 8px;
border-radius: 18px;
background: transparent;
}
// 滚动条的可拖拽部分(滑块)
&::-webkit-scrollbar-thumb {
width: 8px;
border-radius: 18px;
background: rgba(20, 31, 168, .8);
}
.bubble {
max-width: 300px;
padding: 10px;
border-radius: 5px;
position: relative;
color: #000;
word-wrap: break-word;
word-break: normal;
}
.item-left .bubble {
margin-left: 15px;
background-color: #fff;
}
.item-left .bubble:before {
content: "";
position: absolute;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-top: 10px solid transparent;
border-right: 10px solid #fff;
border-bottom: 10px solid transparent;
left: -20px;
}
.item-right .bubble {
margin-right: 15px;
background-color: #9eea6a;
}
.item-right .bubble:before {
content: "";
position: absolute;
width: 0;
height: 0;
border-left: 10px solid #9eea6a;
border-top: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid transparent;
right: -20px;
}
.item {
margin-top: 15px;
display: flex;
width: 100%;
}
.item.item-right {
justify-content: flex-end;
}
.avatar img {
width: 42px;
height: 42px;
border-radius: 50%;
}
}
.input-area {
position: relative;
width: 100%;
height: 100px;
.input-text-area {
// 去除选中后的边框
outline: none;
resize: none;
background: none;
caret-color: #fff;
border: 1px solid #fff;
color: #fff;
width: 100%;
height: 100%;
border-radius: 6px;
padding: 10px;
overflow: auto;
line-height: 20px;
&::-webkit-scrollbar {
width: 7px;
}
// 滚动条的滚动区域(轨道)
&::-webkit-scrollbar-track {
width: 8px;
border-radius: 18px;
background: transparent;
}
// 滚动条的可拖拽部分(滑块)
&::-webkit-scrollbar-thumb {
width: 8px;
border-radius: 18px;
background: rgba(20, 31, 168, .8);
}
}
.button-area {
margin-top: 5px;
text-align: right;
.btnSend {
width: 85px;
height: 37px;
background: none;
border: 1px solid #fff;
border-radius: 6px;
color: #fff;
cursor: pointer;
font-weight: 800;
transition: transform ease-in-out .2s;
&:active {
transform: scale(0.9);
}
}
}
}
}
</style>