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

287 lines
6.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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>