624 lines
18 KiB
Vue
624 lines
18 KiB
Vue
<template>
|
||
<div class="service_page">
|
||
<div class="chatroom">
|
||
<div class="header">
|
||
<img src="@/assets/logo/logo.png" alt="嘉策人工logo" />
|
||
<p>嘉策人工客服</p>
|
||
</div>
|
||
<div class="content">
|
||
<!-- 聊天区域 -->
|
||
<div class="chatBox">
|
||
<!-- 聊天窗 -->
|
||
<div class="chatWindow" id="chatWindow">
|
||
<div class="loading" v-if="isLoading">
|
||
<img
|
||
class="loadingImg"
|
||
src="../assets/loading.gif"
|
||
alt="加载中"
|
||
/>
|
||
</div>
|
||
<div
|
||
class="chatBubbleBox"
|
||
v-for="(item, index) in chats"
|
||
:key="index"
|
||
>
|
||
<div
|
||
class="chatBubbleTime"
|
||
v-if="item.send_timestamp && item.time_show"
|
||
>
|
||
<span>{{ item.show_time }}</span>
|
||
</div>
|
||
<div
|
||
class="chatBubble"
|
||
:class="{ chatBubbleUser: item.sender != 0 }"
|
||
>
|
||
<div name="亮亮" class="avatar" v-if="item.sender == 0"></div>
|
||
<div class="msgBox">
|
||
<div class="bubbleBox" v-if="item.sender == 1">
|
||
<p>{{ item.send_con }}</p>
|
||
</div>
|
||
<div
|
||
class="bubbleBox"
|
||
v-else-if="item.sender == 0 && item.send_con[0].msgInfo"
|
||
>
|
||
<p
|
||
v-for="(item_msg, index_msg) in item.send_con"
|
||
:key="index_msg"
|
||
>
|
||
{{ item_msg.msgInfo }}
|
||
</p>
|
||
</div>
|
||
<div class="bubbleBox" v-else-if="item.sender == 0">
|
||
<p>{{ item.send_con }}</p>
|
||
</div>
|
||
<div
|
||
class="bubbleBox listBox"
|
||
v-if="item.sender == 0 && item.list"
|
||
>
|
||
<div
|
||
class="bubbleList"
|
||
v-for="(item_list, index_list) in item.list"
|
||
:key="index_list"
|
||
@click="goDetail(item_list)"
|
||
>
|
||
<div class="listTitle">
|
||
{{
|
||
item_list.title ||
|
||
item_list.lawTitle ||
|
||
item_list.contractName ||
|
||
item_list.caseTitle
|
||
}}
|
||
</div>
|
||
<img src="@/assets/logo/logo.png" alt="查看详情" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 聊天输入框 -->
|
||
<div class="chatInput">
|
||
<textarea
|
||
placeholder="请输入您的问题..."
|
||
v-model="message"
|
||
@keydown="stopEnter"
|
||
@keyup.enter="send"
|
||
></textarea>
|
||
<div class="sendBtn" @click="send">发送</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { send } from '@/api/service';
|
||
export default {
|
||
data() {
|
||
return {
|
||
path:
|
||
'ws://192.168.0.125:1919/webStock/' + localStorage.getItem('userId'),
|
||
socket: '',
|
||
userid: '23941',
|
||
// 待发送信息
|
||
message: '',
|
||
isEnter: false, //是否处于停止回车
|
||
// 聊天记录(假设)
|
||
chats: [
|
||
{
|
||
sender: 0, //发送人,0机器人 1用户
|
||
send_con: '你好,我是嘉策人工客服,有问题请咨询我!',
|
||
send_timestamp: '1607731220000' //发送时间,存时间戳好进行判断,若聊天间隔3分钟内,不重复显示时间
|
||
}
|
||
],
|
||
// 答复详情
|
||
replyDetail: {},
|
||
isLoading: 0 //是否正在加载中,0否1是
|
||
};
|
||
},
|
||
created() {
|
||
// localStorage.removeItem("chatsHistory");
|
||
this.chats = JSON.parse(localStorage.getItem('chatsHistory'));
|
||
if (!this.chats) {
|
||
var chat = [
|
||
{
|
||
sender: 0, //发送人,0机器人1用户
|
||
send_con: '你好,我是嘉策人工客服,有问题请咨询我!'
|
||
}
|
||
];
|
||
chat[0].send_timestamp = this.getTime();
|
||
localStorage.setItem('chatsHistory', JSON.stringify(chat));
|
||
this.chats = JSON.parse(localStorage.getItem('chatsHistory'));
|
||
this.getIsShowTime();
|
||
} else {
|
||
this.getIsShowTime();
|
||
}
|
||
},
|
||
mounted() {
|
||
this.chatWindowActive();
|
||
this.init();
|
||
},
|
||
methods: {
|
||
init: function() {
|
||
if (typeof WebSocket === 'undefined') {
|
||
alert('您的浏览器不支持socket');
|
||
} else {
|
||
// 实例化socket
|
||
this.socket = new WebSocket(this.path);
|
||
console.log(this.socket);
|
||
// 监听socket连接
|
||
this.socket.onopen = this.open;
|
||
// 监听socket错误信息
|
||
this.socket.onerror = this.error;
|
||
// 监听socket消息
|
||
this.socket.onmessage = this.getMessage;
|
||
}
|
||
},
|
||
open: function() {
|
||
console.log('socket连接成功');
|
||
},
|
||
error: function() {
|
||
console.log('连接错误');
|
||
},
|
||
getMessage(msg) {
|
||
console.log(JSON.parse(msg.data));
|
||
this.a = JSON.parse(msg.data);
|
||
},
|
||
send: function(params) {
|
||
this.socket.send(params);
|
||
},
|
||
close: function() {
|
||
console.log('socket已经关闭');
|
||
},
|
||
// 原回车键失去回车功能
|
||
stopEnter(event) {
|
||
if (event.keyCode === 13) {
|
||
event.preventDefault(); // 阻止浏览器默认换行操作
|
||
return false;
|
||
}
|
||
},
|
||
// 获取当前时间戳
|
||
getTime() {
|
||
var now_timestamp = Date.parse(new Date());
|
||
return now_timestamp;
|
||
},
|
||
// 获取是否展示时间的标志
|
||
getIsShowTime() {
|
||
var now_timestamp = Date.parse(new Date());
|
||
var minute_timestamp = 3 * 60 * 1000; //3分钟
|
||
var day_timestamp = 24 * 60 * 60 * 1000; //1天
|
||
var week_timestamp = day_timestamp * 7; //7天
|
||
|
||
var i = 0;
|
||
for (var chat of this.chats) {
|
||
var howlong = now_timestamp - chat.send_timestamp;
|
||
var time = new Date(parseInt(chat.send_timestamp));
|
||
var hour = time.getHours().toString();
|
||
if (hour.length < 2) {
|
||
hour = '0' + hour;
|
||
}
|
||
var minute = time.getMinutes().toString();
|
||
if (minute.length < 2) {
|
||
minute = '0' + minute;
|
||
}
|
||
// 展示时间格式
|
||
if (howlong > week_timestamp) {
|
||
//距今7天以上,显示日期
|
||
var year = time.getFullYear().toString();
|
||
var month = (time.getMonth() + 1).toString();
|
||
if (month.length < 2) {
|
||
month = '0' + month;
|
||
}
|
||
var day = time.getDate().toString();
|
||
if (day.length < 2) {
|
||
day = '0' + day;
|
||
}
|
||
chat.show_time =
|
||
year + '年' + month + '月' + day + '日 ' + hour + ':' + minute;
|
||
} else if (howlong > day_timestamp) {
|
||
// 距今7天以内超过1天,显示星期
|
||
var weekdays = [
|
||
'星期天',
|
||
'星期一',
|
||
'星期二',
|
||
'星期三',
|
||
'星期四',
|
||
'星期五',
|
||
'星期六'
|
||
];
|
||
var weekday = time.getDay().toString();
|
||
chat.show_time = weekdays[weekday] + ' ' + hour + ':' + minute;
|
||
} else {
|
||
// 24小时内,显示今天
|
||
var day_now = new Date(parseInt(now_timestamp)).getDate();
|
||
var day_time = time.getDate();
|
||
if (day_now == day_time) {
|
||
chat.show_time = '今天 ' + hour + ':' + minute;
|
||
} else {
|
||
chat.show_time = '昨天 ' + hour + ':' + minute;
|
||
}
|
||
}
|
||
// 是否展示时间
|
||
this.chats[0].time_show = true;
|
||
if (i > 0) {
|
||
var interval = chat.send_timestamp - this.chats[i - 1].send_timestamp;
|
||
if (interval > minute_timestamp) {
|
||
chat.time_show = true;
|
||
} else {
|
||
chat.time_show = false;
|
||
}
|
||
}
|
||
i++;
|
||
}
|
||
},
|
||
// 查看详情
|
||
goDetail(item) {
|
||
if (item.contractName) {
|
||
//答复类型为“合同”
|
||
alert('程序员还在开发中...');
|
||
return;
|
||
} else {
|
||
this.tool_show = -2;
|
||
this.replyDetail = item;
|
||
}
|
||
},
|
||
// 聊天窗内容置底
|
||
chatWindowActive() {
|
||
this.$nextTick(() => {
|
||
var div = document.getElementById('chatWindow');
|
||
div.scrollTop = div.scrollHeight;
|
||
});
|
||
},
|
||
// 发送消息
|
||
send() {
|
||
if (this.message == '') {
|
||
alert('不能发送空白信息');
|
||
return;
|
||
}
|
||
this.chats.push({
|
||
sender: 1,
|
||
send_con: this.message,
|
||
send_timestamp: this.getTime()
|
||
});
|
||
this.getIsShowTime();
|
||
this.chatWindowActive();
|
||
let message = this.message;
|
||
this.message = '';
|
||
this.isLoading = 1; //加载中
|
||
send({ sendText: message, receiverUserId: '1385154178159804416' }).then(
|
||
res => {
|
||
console.log(res);
|
||
var that = this;
|
||
if (
|
||
res.data.replayType == 'NEEDCONTRACTUSER' ||
|
||
res.data.replayType == 'MSG' ||
|
||
res.data.replayType == 'UNKNOWN'
|
||
) {
|
||
setTimeout(function() {
|
||
that.chats.push({
|
||
sender: 0,
|
||
send_con: res.data.msgInfos,
|
||
send_timestamp: that.getTime(),
|
||
type: res.data.replayType
|
||
});
|
||
that.isLoading = 0;
|
||
that.getIsShowTime();
|
||
that.chatWindowActive();
|
||
that.updateHistory(that.chats.length);
|
||
}, 1000);
|
||
} else {
|
||
let all;
|
||
if (res.data.replayType == 'QA') {
|
||
//输入"你能做些什么"测试,右侧进入问答页面
|
||
all = res.data.replyQADatas;
|
||
} else if (res.data.replayType == 'CONTRACT') {
|
||
//输入"劳动合同"测试,跳转下载链接
|
||
all = res.data.replyContractDatas;
|
||
} else if (res.data.replayType == 'LAW') {
|
||
//输入"宪法"测试,右侧进入法律页面
|
||
all = res.data.replyLawDatas;
|
||
} else if (res.data.replayType == 'CASE') {
|
||
//输入"强奸案案例"测试,右侧进入案例页面
|
||
all = res.data.replyCaseDatas;
|
||
}
|
||
let list = [];
|
||
for (let i = 0; i < 5; i++) {
|
||
if (all[i]) {
|
||
list.push(all[i]);
|
||
}
|
||
}
|
||
setTimeout(function() {
|
||
that.chats.push({
|
||
sender: 0,
|
||
send_con: res.data.msgInfos,
|
||
send_timestamp: that.getTime(),
|
||
type: res.data.replayType,
|
||
list
|
||
});
|
||
that.isLoading = 0;
|
||
that.getIsShowTime();
|
||
that.chatWindowActive();
|
||
that.updateHistory(that.chats.length);
|
||
}, 1000);
|
||
}
|
||
}
|
||
);
|
||
},
|
||
// 更新聊天记录
|
||
updateHistory(len) {
|
||
let chats = [];
|
||
for (let i = 1; i <= 20; i++) {
|
||
// unshift 将新项添加到数组起始位置
|
||
// 这里是倒着把this.chats的最近20条数据作为历史记录插入chats数组
|
||
if (this.chats[len - i]) {
|
||
chats.unshift(this.chats[len - i]);
|
||
}
|
||
}
|
||
localStorage.setItem('chatsHistory', JSON.stringify(chats));
|
||
},
|
||
// 获取工具
|
||
getTool(index) {
|
||
this.tool_show = index;
|
||
}
|
||
},
|
||
destroyed() {
|
||
// 销毁监听
|
||
this.socket.onclose = this.close;
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.service_page {
|
||
width: 100%;
|
||
height: 100vh;
|
||
overflow: auto;
|
||
position: relative;
|
||
top: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
left: 0;
|
||
background: #c0cad5;
|
||
|
||
.chatroom {
|
||
width: 73%;
|
||
min-width: 1000px;
|
||
position: absolute;
|
||
top: 80px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
|
||
background: #ffffff;
|
||
border-radius: 20px;
|
||
overflow: hidden;
|
||
box-shadow: 0px 5px 24px 0px rgba(0, 0, 0, 0.2);
|
||
|
||
.header {
|
||
width: 100%;
|
||
height: 80px;
|
||
background: #3699ff;
|
||
display: flex;
|
||
align-items: center;
|
||
-webkit-user-select: none;
|
||
-moz-user-select: none;
|
||
-ms-user-select: none;
|
||
user-select: none;
|
||
img {
|
||
width: 42px;
|
||
height: 42px;
|
||
display: block;
|
||
margin-left: 40px;
|
||
margin-right: 12px;
|
||
}
|
||
p {
|
||
font-size: 20px;
|
||
font-family: PingFang SC;
|
||
font-weight: bold;
|
||
color: #ffffff;
|
||
}
|
||
}
|
||
.content {
|
||
width: 100%;
|
||
height: 720px;
|
||
display: flex;
|
||
.chatBox {
|
||
width: 100%;
|
||
height: 720px;
|
||
border-right: 4px solid #e6e6e6;
|
||
.chatWindow {
|
||
height: 586px;
|
||
background: #f2f2f2;
|
||
border-bottom: 4px solid #e6e6e6;
|
||
overflow-y: scroll;
|
||
padding: 0 40px;
|
||
position: relative;
|
||
.loading {
|
||
position: fixed;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
img {
|
||
display: block;
|
||
width: 240px;
|
||
height: 60px;
|
||
}
|
||
}
|
||
.chatBubbleBox {
|
||
.chatBubbleTime {
|
||
text-align: center;
|
||
span {
|
||
display: inline-block;
|
||
margin: 4px 0 16px;
|
||
|
||
padding: 4px 8px;
|
||
text-align: center;
|
||
background: #dadada;
|
||
border-radius: 4px;
|
||
|
||
font-size: 14px;
|
||
font-family: PingFang SC;
|
||
color: #ffffff;
|
||
}
|
||
}
|
||
.chatBubble {
|
||
margin-bottom: 16px;
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: flex-start;
|
||
flex-wrap: wrap;
|
||
.avatar {
|
||
width: 45px;
|
||
height: 45px;
|
||
border-radius: 50%;
|
||
// background-color: #ffffff;
|
||
background-image: url('~@/assets/logo/logo.png');
|
||
background-size: cover;
|
||
background-position: center;
|
||
background-repeat: no-repeat;
|
||
margin-right: 10px;
|
||
}
|
||
.msgBox {
|
||
max-width: 50%;
|
||
.bubbleBox {
|
||
p {
|
||
font-size: 15px;
|
||
font-family: PingFang SC;
|
||
color: #3b3b3b;
|
||
display: inline-block;
|
||
padding: 12.5px 20px;
|
||
background: #ffffff;
|
||
border-radius: 10px;
|
||
margin-bottom: 16px;
|
||
}
|
||
}
|
||
.listBox {
|
||
padding: 12.5px 20px;
|
||
background: #ffffff;
|
||
border-radius: 10px;
|
||
.bubbleList {
|
||
cursor: pointer;
|
||
border-bottom: 1px solid #f2f2f2;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
.listTitle {
|
||
width: 90%;
|
||
height: 30px;
|
||
line-height: 30px;
|
||
|
||
font-size: 14px;
|
||
font-family: PingFang SC;
|
||
color: #3699ff;
|
||
|
||
text-overflow: ellipsis;
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
}
|
||
img {
|
||
width: 9px;
|
||
height: 16px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.chatBubbleUser {
|
||
justify-content: flex-end;
|
||
}
|
||
}
|
||
.chatBubbleBox:first-child {
|
||
margin-top: 30px;
|
||
}
|
||
}
|
||
.chatWindow::-webkit-scrollbar {
|
||
width: 8px;
|
||
}
|
||
.chatWindow::-webkit-scrollbar-thumb {
|
||
background-color: #d2d2d2;
|
||
border-radius: 5px;
|
||
}
|
||
.chatInput {
|
||
width: 100%;
|
||
height: 130px;
|
||
position: relative;
|
||
|
||
textarea {
|
||
width: 93%;
|
||
height: 60px;
|
||
position: absolute;
|
||
top: 15px;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
|
||
display: block;
|
||
border: 0;
|
||
resize: none;
|
||
outline: none;
|
||
cursor: default;
|
||
|
||
font-size: 16px;
|
||
font-family: PingFang SC;
|
||
}
|
||
|
||
textarea::-webkit-scrollbar {
|
||
width: 8px;
|
||
}
|
||
textarea::-webkit-scrollbar-thumb {
|
||
background-color: #d2d2d2;
|
||
border-radius: 5px;
|
||
}
|
||
|
||
.sendBtn {
|
||
width: 80px;
|
||
height: 32px;
|
||
text-align: center;
|
||
line-height: 32px;
|
||
|
||
font-size: 16px;
|
||
font-family: PingFang SC;
|
||
font-weight: bold;
|
||
color: #ffffff;
|
||
|
||
cursor: pointer;
|
||
-webkit-user-select: none;
|
||
-moz-user-select: none;
|
||
-ms-user-select: none;
|
||
user-select: none;
|
||
|
||
background: #3699ff;
|
||
border-radius: 4px;
|
||
|
||
position: absolute;
|
||
right: 45px;
|
||
bottom: 14px;
|
||
}
|
||
}
|
||
}
|
||
.tools {
|
||
width: 27%;
|
||
min-width: 268px;
|
||
height: 720px;
|
||
.toolsBox {
|
||
margin-top: 45px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-wrap: wrap;
|
||
img {
|
||
width: 81px;
|
||
height: 80px;
|
||
display: block;
|
||
cursor: pointer;
|
||
padding: 15px 30px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|