374 lines
9.1 KiB
Vue
374 lines
9.1 KiB
Vue
<template>
|
|
<view class="common-room">
|
|
<view class="main">
|
|
|
|
<view class="queue" :class="{'last':index+1===list.length}" v-for="(item,index) in list" :key="index">
|
|
<view class="datetime">{{ item.created_at }}</view>
|
|
|
|
<view class="service-box flex" v-if="item.user_type===1">
|
|
<image class="cover" :src="item.header || webUrl+'/20221114155314348118.png'"/>
|
|
<view class="text">
|
|
<view class="name one-t">{{ item.username }}</view>
|
|
<text class="msg" v-if="item.msg_type===0">{{ item.msg_content }}</text>
|
|
<view class="msg" v-if="item.msg_type===1">
|
|
<image class="img" :src="item.msg_content" @click="preview(item.msg_content)"></image>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="customer-box flex jc-end" v-else>
|
|
<view class="text flex flex-col ai-end">
|
|
<view class="name one-t">{{ item.username }}</view>
|
|
<text class="msg" v-if="item.msg_type===0">{{ item.msg_content }}</text>
|
|
<view class="msg" v-if="item.msg_type===1">
|
|
<image class="img" :src="item.msg_content" @click="preview(item.msg_content)"></image>
|
|
</view>
|
|
</view>
|
|
<image class="cover" :src="item.header || webUrl+'/20221114155314348118.png'"/>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="footer flex jc-between ai-end">
|
|
<image :src="webUrl+'/20221014095236624035.png'" @click="getUploadToken"></image>
|
|
<view class="input-box">
|
|
<textarea
|
|
v-model="content"
|
|
maxlength="150"
|
|
:auto-height="true"
|
|
:fixed="true"
|
|
:show-confirm-bar="false"
|
|
confirm-type="send"
|
|
@input="userInput"
|
|
@confirm="userSend"
|
|
/>
|
|
</view>
|
|
<button @click="userSend">发送</button>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapGetters } from 'vuex'
|
|
export default {
|
|
name: "room",
|
|
data() {
|
|
return {
|
|
webUrl: this.$VUE_APP_RESOURCES_URL,
|
|
token: null,
|
|
uid: null,
|
|
userInfo: null,
|
|
storeId: null,
|
|
merName: null,
|
|
uploadToken: null, //上传token
|
|
|
|
socketOpen: false,
|
|
socketTask: null,
|
|
socketMsgQueue: [],
|
|
|
|
roomId: null, //房间ID
|
|
content: "", //消息内容
|
|
list: [], //消息列表
|
|
}
|
|
},
|
|
computed: mapGetters(['userInfo']),
|
|
onLoad(options) {
|
|
this.storeId = options.id;
|
|
this.merName = options.name;
|
|
if (this.merName!="undefined" && this.merName!="null") {
|
|
uni.setNavigationBarTitle({
|
|
title: this.merName
|
|
})
|
|
}
|
|
this.token = uni.getStorageSync("login_status");
|
|
this.userInfo = uni.getStorageSync("userInfo");
|
|
this.uid = this.userInfo.uid
|
|
this.connectSocketInit()
|
|
},
|
|
onUnload() {
|
|
if (this.socketOpen) {
|
|
this.socketTask.close();
|
|
}
|
|
},
|
|
methods: {
|
|
getUploadToken() {
|
|
let that = this;
|
|
|
|
uni.request({
|
|
url: this.$SERVICE_API_URL + "/get-upload-token",
|
|
method: "POST",
|
|
success: ({data}) => {
|
|
if (data.status === "success") {
|
|
this.uploadToken = data.content;
|
|
|
|
uni.chooseImage({
|
|
count: 1, //数量
|
|
sizeType: ['original'], //可以指定是原图还是压缩图,默认二者都有
|
|
sourceType: ['album', 'camera'], //从相册选择
|
|
success: (chooseImageRes) => {
|
|
const tempFilePaths = chooseImageRes.tempFilePaths;
|
|
|
|
uni.uploadFile({
|
|
url: 'https://up-z2.qiniup.com', //接口地址
|
|
filePath: tempFilePaths[0],
|
|
name: 'file',
|
|
formData: {
|
|
'token': that.uploadToken
|
|
},
|
|
success: (uploadFileRes) => {
|
|
// uni.showModal({
|
|
// title: that.uploadToken + ' ',
|
|
// content: uploadFileRes.data + ' ',
|
|
// showCancel: false
|
|
// })
|
|
|
|
let imgKey = JSON.parse(uploadFileRes.data).key;
|
|
|
|
if (imgKey.length > 0) {
|
|
let param = {
|
|
type: "msg",
|
|
user_type: 0,
|
|
uid: that.uid,
|
|
username: that.userInfo.nickname,
|
|
header: that.userInfo.avatar,
|
|
room_id: that.roomId,
|
|
msg_type: 1,
|
|
content: imgKey,
|
|
token: that.token
|
|
}
|
|
that.sendSocketMessage(JSON.stringify(param));
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
})
|
|
},
|
|
|
|
// 预览图片
|
|
preview(url) {
|
|
uni.previewImage({
|
|
urls: [url]
|
|
});
|
|
},
|
|
|
|
// 进入这个页面的时候创建websocket连接【整个页面随时使用】
|
|
connectSocketInit() {
|
|
// 创建一个this.socketTask对象【发送、接收、关闭socket都由这个对象操作】
|
|
this.socketTask = uni.connectSocket({
|
|
url: this.$SOCKET_URL,
|
|
success: () => {
|
|
}
|
|
})
|
|
|
|
uni.onSocketOpen(res => {
|
|
console.log('WebSocket连接已打开!', res);
|
|
this.socketOpen = true;
|
|
this.createRoom();
|
|
});
|
|
|
|
uni.onSocketError(err => {
|
|
console.log('WebSocket连接打开失败,请检查!', err);
|
|
});
|
|
|
|
uni.onSocketMessage(res => {
|
|
console.log('收到服务器内容:', res.data);
|
|
this.handleMessage(res.data);
|
|
});
|
|
|
|
uni.onSocketClose(res => {
|
|
console.log('WebSocket 已关闭!', res);
|
|
});
|
|
},
|
|
|
|
userInput(event) {
|
|
this.content = event.detail.value;
|
|
},
|
|
|
|
userSend() {
|
|
if (this.content.length === 0) return;
|
|
|
|
let param = {
|
|
type: "msg",
|
|
user_type: 0,
|
|
uid: this.uid,
|
|
username: this.userInfo.nickname,
|
|
header: this.userInfo.avatar,
|
|
room_id: this.roomId,
|
|
msg_type: 0,
|
|
content: this.content,
|
|
token: this.token
|
|
}
|
|
this.sendSocketMessage(JSON.stringify(param));
|
|
this.content = "";
|
|
},
|
|
|
|
createRoom() {
|
|
let param = {
|
|
type: "join",
|
|
user_type: 0,
|
|
uid: this.uid,
|
|
username: this.userInfo.nickname,
|
|
header: this.userInfo.avatar,
|
|
store_id: this.storeId
|
|
};
|
|
this.sendSocketMessage(JSON.stringify(param));
|
|
},
|
|
|
|
sendSocketMessage(msg) {
|
|
if (this.socketOpen) {
|
|
uni.sendSocketMessage({
|
|
data: msg,
|
|
success(res) {
|
|
console.log("消息发送成功", res,msg);
|
|
}
|
|
});
|
|
} else {
|
|
this.socketMsgQueue.push(msg);
|
|
}
|
|
},
|
|
|
|
handleMessage(str) {
|
|
let data = JSON.parse(str);
|
|
switch (data.type) {
|
|
case "room_id":
|
|
this.roomId = data.msg_content;
|
|
break;
|
|
case "service_join":
|
|
break;
|
|
case "leave":
|
|
break;
|
|
case "msg":
|
|
this.list.push(data.msg_content);
|
|
this.scrollLast();
|
|
break;
|
|
case "msg_history":
|
|
this.list = data.msg_content.concat(this.list);
|
|
this.scrollLast();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
},
|
|
|
|
scrollLast() {
|
|
setTimeout(() => {
|
|
uni.pageScrollTo({
|
|
selector: ".last .msg",
|
|
duration: 1
|
|
})
|
|
}, 50)
|
|
}
|
|
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.common-room {
|
|
min-height: 100vh;
|
|
background: #F5F5F5;
|
|
font-size: 26rpx;
|
|
line-height: 38rpx;
|
|
color: #333333;
|
|
|
|
view {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.main {
|
|
padding: 0 32rpx 130rpx;
|
|
|
|
.datetime {
|
|
margin: 30rpx 0;
|
|
font-size: 22rpx;
|
|
line-height: 32rpx;
|
|
color: #999999;
|
|
text-align: center;
|
|
}
|
|
|
|
.cover {
|
|
width: 48rpx;
|
|
height: 48rpx;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.text {
|
|
width: 550rpx;
|
|
margin: 0 20rpx;
|
|
}
|
|
|
|
.name {
|
|
margin-bottom: 16rpx;
|
|
font-size: 22rpx;
|
|
line-height: 32rpx;
|
|
}
|
|
|
|
.msg {
|
|
display: inline-block;
|
|
max-width: 560rpx;
|
|
padding: 16rpx;
|
|
background: #FFFFFF;
|
|
font-weight: bold;
|
|
word-break: break-all;
|
|
word-wrap: break-word;
|
|
|
|
.img {
|
|
max-width: 214rpx;
|
|
max-height: 214rpx;
|
|
vertical-align: middle;
|
|
}
|
|
}
|
|
|
|
.service-box {
|
|
margin: 30rpx 0;
|
|
}
|
|
|
|
.customer-box {
|
|
margin: 30rpx 0;
|
|
}
|
|
}
|
|
|
|
.footer {
|
|
position: fixed;
|
|
bottom: 0;
|
|
width: 100vw;
|
|
padding: 30rpx 32rpx 28rpx;
|
|
border-radius: 24rpx 24rpx 0 0;
|
|
background: #FFFFFF;
|
|
|
|
image {
|
|
width: 64rpx;
|
|
height: 64rpx;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.input-box {
|
|
width: 472rpx;
|
|
min-height: 64rpx;
|
|
box-sizing: border-box;
|
|
padding: 18rpx 30rpx;
|
|
border-radius: 32rpx;
|
|
background: #F5F5F5;
|
|
|
|
textarea {
|
|
width: 100%;
|
|
}
|
|
}
|
|
|
|
|
|
button {
|
|
width: 120rpx;
|
|
height: 64rpx;
|
|
margin: 0;
|
|
border-radius: 32rpx;
|
|
background: #FD574B;
|
|
font-size: 28rpx;
|
|
color: #FFFFFF;
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
}
|
|
</style> |