vue实现在线客服功能(附完整代码)
公司需要在网站实现一个在线客服的功能,开始是用的jq实现的,但是!!!把代码拿到vue里使用的时候,Jq的事件一直没有办法触发,各种百度都没有结果然后就放弃了,最后找到一种很好的解决方法,完美实现了功能!!!还有感谢我的外援,哈哈哈哈哈,一直是我的后盾!!!!!!!!哈哈哈哈哈主要是循环info里的数据,通过type来判断显示机器人还是用户。用户发送消息后直接push进数组里即可...
·
公司需要在网站实现一个在线客服的功能,开始是用的jq实现的,但是!!!把代码拿到vue里使用的时候,Jq的事件一直没有办法触发,各种百度都没有结果然后就放弃了,最后找到一种很好的解决方法,完美实现了功能!!!还有感谢我的外援,哈哈哈哈哈,一直是我的后盾!!!!!!!!哈哈哈哈哈
以下为vue部分
主要是循环info里的数据,通过type来判断显示机器人还是用户。
用户发送消息后直接push进数组里即可
<template>
<div class="container">
<div class="main">
<div class="box">
<div class="title">
<img src="" alt class="logo" />
<span class="title-hn">人工客服</span>
</div>
<div id="content" class="content">
<div v-for="(item,index) in info" :key="index">
<div class="info_r info_default" v-if="item.type == 'leftinfo'">
<span class="circle circle_r"></span>
<div class="con_r con_text">
<div>{{item.content}}</div>
<div v-for="(item2,index) in item.question" :key="index">
<div class="con_que" @click="clickRobot(item2.content,item2.id)">
<div class="czkj-question-msg">
{{item2.index}}
{{item2.content}}
</div>
</div>
</div>
</div>
<div class="time_r">{{item.time}}</div>
</div>
<div class="info_l" v-if="item.type == 'rightinfo'">
<div class="con_r con_text">
<span class="con_l">{{item.content}}</span>
<span class="circle circle_l">
<img src class="pic_l" />
</span>
</div>
<div class="time_l">{{item.time}}</div>
</div>
</div>
</div>
<div class="setproblem">
<textarea
placeholder="请输入您的问题..."
style="height: 68px;width: 100%;resize:none;padding-right:80px;outline: none;border-color:#ccc;border-radius:5px;"
id="text"
v-model="customerText"
@keyup.enter="sentMsg()"
></textarea>
<button @click="sentMsg()" class="setproblems">
<span style="vertical-align: 4px;">发 送</span>
</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "onlineCustomer",
components: {},
computed: {},
data() {
return {
customerText: "",
info: [
{
type: "leftinfo",
time: this.getTodayTime(),
name: "robot",
content:
"您好,欢迎使用网上营业厅,为保证账户安全,在会话过程中请勿透露您的账号、",
question: [],
},
],
timer: null,
robotQuestion: [
{ id: 1, content: "客户资料完善后是由谁来审批", index: 1 },
{ id: 2, content: "客户资料审批一直不通过", index: 2 },
{ id: 3, content: "客户资料审批需要多长时间", index: 3 },
{
id: 4,
content: "注册网站时需要一次填写完所有的客户资料吗",
index: 4,
},
{ id: 5, content: "注册时使用的手机号变更怎么办", index: 5 },
],
robotAnswer: [
{
id: 1,
content:
"答案客户资料完善后是由谁来审批,答案客户资料完善后是由谁来审批,答案客户资料完善后是由谁来审批",
index: 1,
},
{ id: 2, content: "测试", index: 2 },
{ id: 3, content: "测试", index: 3 },
{
id: 4,
content: "3333333",
index: 4,
},
{ id: 5, content: "44444444", index: 5 },
],
};
},
created() {
this.showTimer();
},
watch: {},
methods: {
// 用户发送消息
sentMsg() {
clearTimeout(this.timer);
this.showTimer();
let text = this.customerText.trim();
if (text != "") {
var obj = {
type: "rightinfo",
time: this.getTodayTime(),
content: text,
};
this.info.push(obj);
this.appendRobotMsg(this.customerText);
this.customerText = "";
this.$nextTick(() => {
var contentHeight = document.getElementById("content");
contentHeight.scrollTop = contentHeight.scrollHeight;
});
}
},
// 机器人回答消息
appendRobotMsg(text) {
clearTimeout(this.timer);
this.showTimer();
text = text.trim();
let answerText = "";
let flag;
for (let i = 0; i < this.robotAnswer.length; i++) {
if (this.robotAnswer[i].content.indexOf(text) != -1) {
flag = true;
answerText = this.robotAnswer[i].content;
break;
}
}
if (flag) {
let obj = {
type: "leftinfo",
time: this.getTodayTime(),
name: "robot",
content: answerText,
question: [],
};
this.info.push(obj);
} else {
answerText = "您可能想问:";
let obj = {
type: "leftinfo",
time: this.getTodayTime(),
name: "robot",
content: answerText,
question: this.robotQuestion,
};
this.info.push(obj);
}
this.$nextTick(() => {
var contentHeight = document.getElementById("content");
contentHeight.scrollTop = contentHeight.scrollHeight;
});
},
sentMsgById(val, id) {
clearTimeout(this.timer);
this.showTimer();
let robotById = this.robotAnswer.filter((item) => {
return item.id == id;
});
let obj_l = {
type: "leftinfo",
time: this.getTodayTime(),
name: "robot",
content: robotById[0].content,
question: [],
};
let obj_r = {
type: "rightinfo",
time: this.getTodayTime(),
name: "robot",
content: val,
question: [],
};
this.info.push(obj_r);
this.info.push(obj_l);
this.$nextTick(() => {
var contentHeight = document.getElementById("content");
contentHeight.scrollTop = contentHeight.scrollHeight;
});
},
// 点击机器人的单个问题
clickRobot(val, id) {
this.sentMsgById(val, id);
},
// 结束语
endMsg() {
let happyEnding = {
type: "leftinfo",
time: this.getTodayTime(),
content: "退下吧",
question: [],
};
this.info.push(happyEnding);
this.$nextTick(() => {
var contentHeight = document.getElementById("content");
contentHeight.scrollTop = contentHeight.scrollHeight;
});
},
showTimer() {
this.timer = setTimeout(this.endMsg, 1000*60);
},
getTodayTime() {
// 获取当前时间
var day = new Date();
let seconds = day.getSeconds();
if (seconds < 10) {
seconds = "0" + seconds;
} else {
seconds = seconds;
}
let minutes = day.getMinutes();
if (minutes < 10) {
minutes = "0" + minutes;
} else {
minutes = minutes;
}
let time =
day.getFullYear() +
"-" +
(day.getMonth() + 1) +
"-" +
day.getDate() +
" " +
day.getHours() +
":" +
minutes +
":" +
seconds;
return time;
},
},
mounted() {},
props: {},
destroyed() {},
};
</script>
<style lang="scss">
.main {
width: 100%;
// height: 100vh;
background: linear-gradient(
180deg,
rgba(149, 179, 212, 1) 0%,
rgba(74, 131, 194, 1) 100%
);
overflow: hidden;
.box {
width: 100%;
/* width: 680px; */
height: 500px;
background-color: #fafafa;
position: relative;
padding: 1.25rem;
#content {
height: 340px;
overflow-y: scroll;
font-size: 14px;
width: 100%;
.circle {
display: inline-block;
width: 34px;
height: 34px;
border-radius: 50%;
background-color: #eff1f3;
}
.con_text {
color: #333;
margin-bottom: 5px;
}
.con_que {
color: #1c88ff;
height: 30px;
line-height: 30px;
cursor: pointer;
}
.info_r {
position: relative;
.circle_r {
position: absolute;
left: 0%;
}
.pic_r {
width: 17px;
height: 17px;
margin: 8px;
}
.con_r {
display: inline-block;
/* max-width: 253px; */
width: 55%;
min-height: 55px;
/* min-height: 20px; */
background-color: #e2e2e2;
border-radius: 6px;
padding: 10px;
margin-left: 40px;
}
.time_r {
margin-left: 45px;
color: #999999;
font-size: 12px;
}
}
.info_l {
text-align: right;
// margin-right: 20px;
color: #ffffff;
color: #3163C5;
margin-top: 10px;
// .circle_l {
// // vertical-align: -10px;
// }
.pic_l {
width: 13px;
height: 17px;
margin: 8px 10px;
}
.time_l {
margin-right: 45px;
color: #999999;
font-size: 12px;
margin-top: 5px;
}
.con_l {
display: inline-block;
width: 220px;
min-height: 51px;
background-color: #3163C5;
border-radius: 6px;
padding: 10px;
text-align: left;
color: #fff;
margin-right: 5px;
}
}
#question {
cursor: pointer;
}
}
}
}
.setproblem {
width: 100%;
height: 68px;
background-color: #ffffff;
position: relative;
margin-top: 3.75rem;
}
.setproblem textarea {
color: #999999;
padding: 10px;
box-sizing: border-box;
}
.setproblem button {
width: 5.875rem;
height: 2.5rem;
line-height: 2.5rem;
background: #3163C5;
opacity: 1;
border-radius: 4px;
font-size: 10px;
color: #ffffff;
position: absolute;
right: 5%;
top: 30%;
cursor: pointer;
border: none;
}
.czkj-item-title {
line-height: 25px;
border-bottom: 1px solid #ccc;
padding-bottom: 5px;
margin-bottom: 5px;
}
.czkj-item-question {
cursor: pointer;
display: block;
padding: 8px;
position: relative;
border-bottom: 1px dashed #ccc;
line-height: 20px;
min-height: 20px;
overflow: hidden;
}
.czkj-question-msg {
float: left;
font-size: 14px;
color: #3163C5;
}
</style>
原生部分。对比之下还是vue更舒服一点。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<meta name="description"
content="">
<meta name="keywords" content="">
<link rel="stylesheet" type="text/css" href="../css/base.css">
<link rel="stylesheet" type="text/css" href="../css/customer.css">
<script src="../js/jquery-1.8.3.min.js"></script>
</head>
<body>
<div class="header" id="top" style="display:none">
</div>
<div class="main">
<div class="box">
<div class="title">
<img src="../images/logo0701.png" alt="" class="logo">
<span class="title-hn"></span>
</div>
<!-- 聊天内容区域 -->
<div class="content" id="content">
<div class="info_r info_default">
<span class="circle circle_r"><img src="../images/robot0701.png" class='pic_r'></span>
<div class='con_r con_text'>
<div>
您好,欢迎使用网上营业厅,为保证账户安全,
在会话过程中请勿透露您的账号、密码等信息。
</div>
<div class="con_que" data-index="1" data-questionid="1">1</div>
<div class="con_que">2</div>
<div class="con_que">3</div>
</div>
</div>
<!-- <ul class="info_r info_default">
<span class="circle circle_r"><img src="../images/robot0701.png" class='pic_r'></span>
<div class='con_r con_text'>
<div>111</div>
<div>1222211</div>
</div>
</ul> -->
</div>
<!-- 发送问题区域 -->
<div class="setproblem">
<textarea placeholder="请输入您的问题..." style="height: 68px;width: 100%;resize:none;padding-right:80px"
id="text"></textarea>
<button onclick="sentMsg()" class="setproblems">
<img src="../images/fs0702.png" alt="" style="width: 15px;height:15px;">
<span style="vertical-align: 4px;">发 送</span>
</button>
</div>
</div>
</div>
</body>
<script src="../js/index.js"></script>
<script>
nHnSite.subServiceInit();
// nHnSite.initAbout();
window.onload = setWelcomeTime;
// 打开页面默认展示问候语添加时间
function setWelcomeTime() {
showTimer();
// 获取当前时间
var day = new Date();
let time = getTodayTime();
var commentLi = '<div class="time_r">' + time + '</div>';
$('.info_default').append(commentLi);
// 获取当前登录的用户名称
let city = $('#cityChoice').text();
// 拆分为简称
let cityJc = city.split('销售');
console.log(cityJc)
cityShow = cityJc[0] + '销售智能客服';
$('.title-hn').text(cityShow);
}
// 发送消息
function sentMsg() {
clearTimeout(timer);
showTimer();
let time = getTodayTime();
let text = $('#text').val();
console.log(text)
var commentLi = '';
commentLi = '<div class="info_l">';
commentLi += '<span class="con_l">' + text + '</span>';
commentLi += '<span class="circle circle_l"><img src="../images/people0701.png" class="pic_l"></span>';
commentLi += '<div class="time_l">' + time + '</div>';
commentLi += '</div>';
$('.content').append(commentLi);
$.ajax({
url: '/api/admin/reg/getNetInfo',
type: 'get',
contentType: "application/json; charset=utf-8",
success: function (res) {
console.log(res,'0000')
// checkNetInfo(resultData);
},
error: function (data) {
// var resultData = { "status": 200, "data": { "id": "1", "province": "BJ", "url": "://www.chngyx.com.cn", "provinceName": "北京" }, "rel": true }
// checkNetInfo(resultData);
}
});
// 发送过消息后将页面滚动到底部
var contentHeight = document.getElementById('content');
contentHeight.scrollTop = contentHeight.scrollHeight;
appendRobotMsg(text)
}
// 选中问题后再次发送消息
function selMsg(text) {
clearTimeout(timer);
showTimer();
let time = getTodayTime();
var commentLi = '';
commentLi = '<div class="info_l">';
commentLi += '<span class="con_l">' + text + '</span>';
commentLi += '<span class="circle circle_l"><img src="../images/people0701.png" class="pic_l"></span>';
commentLi += '<div class="time_l">' + time + '</div>';
commentLi += '</div>';
$('.content').append(commentLi);
appendRobotMsg(text)
// 发送过消息后将页面滚动到底部
var contentHeight = document.getElementById('content');
contentHeight.scrollTop = contentHeight.scrollHeight;
}
// 键盘回车事件
$(document).keypress(function (e) {
if (e.keyCode == '13') {
sentMsg();
}
});
// 结束语
function endMsg() {
let time = getTodayTime();
var commentLi = '';
commentLi = '<div class="info_r">';
commentLi += '<span class="circle circle_r"><img src="../images/robot0701.png" class="pic_r"></span>';
commentLi += '<span class="con_r con_text">' + '借宿了' + '</span>';
commentLi += '<div class="time_r">' + time + '</div>';
commentLi += '</div>';
$('.content').append(commentLi);
// 发送过消息后将页面滚动到底部
var contentHeight = document.getElementById('content');
contentHeight.scrollTop = contentHeight.scrollHeight;
}
function showTimer() {
console.log(000)
timer = setTimeout(endMsg, 5000 * 60);
}
//点击单个问答
$('.content').on('click', '.con_que', function (event) {
let text = $(event)[0].currentTarget.innerText;
console.log($(event))
selectAnswer(text)
// var dataSet = $(event)[0].currentTarget.dataset;
// var parent = $($(event)[0].currentTarget).parents('.czkj-msg');
// var flag = $(parent).data('choosed')
// selectAnswer(parent, dataSet.index, dataSet.questionid, flag)
})
//多个答案选择一个
function selectAnswer(text) {
// parent, index, questionId, flag
var questionObj = {}, parent = {}
// for (var i = 0; i < questionArr.length; i++) {
// for (var j = 0; j < questionArr[i].questionList.length; j++) {
// if (questionArr[i].questionList[j].questionId === questionId) {
// questionObj = questionArr[i].questionList[j]
// parent = questionArr[i]
// }
// }
// }
selMsg(text)
// sentMsg(questionObj.question)
// appendRobotMsg(questionObj, questionObj.answer, parent)
}
// 获取当前时间
function getTodayTime() {
// 获取当前时间
var day = new Date();
let seconds = day.getSeconds();
if (seconds < 10) {
seconds = "0" + seconds;
} else {
seconds = seconds;
}
let minutes = day.getMinutes();
if (minutes < 10) {
minutes = "0" + minutes;
} else {
minutes = minutes;
}
let time = day.getFullYear() + "-" + (day.getMonth() + 1) + "-" + day.getDate() + " " + day.getHours() + ":" + minutes + ":" + seconds;
return time
}
// 新增机器人回复
function appendRobotMsg(text) {
console.log(text)
// text = text.replace(/\n/g, '<br>')
text = text.trim();
let time = getTodayTime();
// 输入内容为空时提示
var questionList = [{ msg: '问题1,好嘞啊啊啊啊啊', questionId: '1', }, { msg: '问题2:我真的好嘞啊', questionId: '2', }];
let title = '嘎嘎嘎嘎嘎过过嘎嘎嘎嘎嘎'
let commentLi;
if (text == '1') {
let time = getTodayTime()
var questions = ''
for (var i = 0; i < questionList.length; i++) {
questions += '<div class="con_que"' + ' data-index="' + i + '" data-questionid="' +
questionList[i].questionId + '"><div class="czkj-question-msg">' + questionList[i].msg + '</div></div>'
}
commentLi = '<div class="info_r">' +
'<span class="circle circle_r"><img src="../images/robot0701.png" class="pic_r"></span>' +
'<div class="con_r con_text"><div>' +
title + '</div>' + questions + '</div>'
+ '<div class="time_r">' + time + '</div>' + '</div>'
}else if (text == ''){
commentLi = '<div class="info_r">';
commentLi += '<span class="circle circle_r"><img src="../images/robot0701.png" class="pic_r"></span>';
commentLi += '<span class="con_r con_text ">' + '说人话' + '</span>';
commentLi += '<div class="time_r">' + time + '</div>';
commentLi += '</div>';
}else {
commentLi = '<div class="info_r">';
commentLi += '<span class="circle circle_r"><img src="../images/robot0701.png" class="pic_r"></span>';
commentLi += '<span class="con_r con_text ">' + '这道题我不会换一个' + '</span>';
commentLi += '<div class="time_r">' + time + '</div>';
commentLi += '</div>';
}
$('.content').append(commentLi);
$('#text').val('');
// 发送过消息后将页面滚动到底部
var contentHeight = document.getElementById('content');
contentHeight.scrollTop = contentHeight.scrollHeight;
}
</script>
</html>
样式
.main {
width: 100vw;
height: 100vh;
background:linear-gradient(180deg,rgba(149,179,212,1) 0%,rgba(74,131,194,1) 100%);
overflow: hidden;
}
.box {
width: 58%;
/* width: 680px; */
height: 500px;
background-color: #FAFAFA;
border-radius:10px;
margin:10vh auto;
position: relative;
}
.title{
width: 100%;
height: 10vh;
background-color: #FFFFFF;
border-radius:10px 10px 0 0 ;
}
.logo{
width: 50px;
height: 40px;
margin: 11px 0 0 25px;
}
.title .title-hn {
font-size: 25px;
color: #3F5267;
vertical-align: 10px;
}
.setproblem{
width: 80%;
height: 68px;
background-color: #FFFFFF;
border:1px solid rgba(221,221,221,1);
border-radius:2px;
position: absolute;
bottom: 10%;
left: 10%;
}
.setproblem textarea {
color:#999999;
padding: 10px;
box-sizing: border-box;
}
.setproblem button {
width:53px;
height:23px;
line-height: 23px;
background:rgba(28,136,255,1);
opacity:1;
border-radius:2px;
font-size: 10px;
color: #FFFFFF;
position: absolute;
right: 5%;
top: 30%;
cursor: pointer;
}
.content {
height: 300px;
overflow-y:scroll;
font-size: 14px;
}
.content .circle {
display: inline-block;
width: 34px;
height: 34px;
border-radius: 50%;
background-color: #EFF1F3;
}
.content .circle_r {
position: absolute;
left: 0%;
}
.content .circle_l {
vertical-align: -10px;
}
.content .info_r .pic_r{
width: 17px;
height: 17px;
margin: 8px;
}
.content .info_l .pic_l{
width: 13px;
height: 17px;
margin: 8px 10px;
}
.content .info_r{
margin-left: 20px;
margin-top: 15px;
position: relative;
}
.content .info_l{
text-align: right;
margin-right: 20px;
color: #FFFFFF;
margin-top: 10px;
}
.content .con_r{
display: inline-block;
/* max-width: 253px; */
width: 253px;
min-height: 55px;
/* min-height: 20px; */
background-color: #E3EAF2;
border-radius: 6px;
padding: 10px;
margin-left: 40px;
}
.content .con_text {
color: #333;
margin-bottom: 5px;
}
.content .con_que {
color: #1C88FF;
height: 30px;
line-height: 30px;
cursor: pointer;
}
.content .con_l {
display: inline-block;
width: 253px;
/* min-height: 20px; */
min-height: 51px;
background-color: #1C88FF;
border-radius: 6px;
padding: 10px;
text-align: left;
color: #fff;
margin-right: 5px;
}
.content .time_r {
margin-left: 45px;
color: #999999;
font-size: 12px;
}
.content .time_l {
margin-right: 45px;
color: #999999;
font-size: 12px;
margin-top: 5px;
}
#question {
cursor: pointer;
}
.czkj-item-title {
line-height: 25px;
border-bottom: 1px solid #ccc;
padding-bottom: 5px;
margin-bottom: 5px;
}
.czkj-item-question {
cursor: pointer;
display: block;
padding: 8px;
position: relative;
border-bottom: 1px dashed #ccc;
line-height: 20px;
min-height: 20px;
overflow: hidden;
}
.czkj-question-msg {
float: left;
font-size: 14px;
color: #4aa4eb;
}
更多推荐
已为社区贡献1条内容
所有评论(0)