515 lines
14 KiB
JavaScript
515 lines
14 KiB
JavaScript
// 客服的id
|
||
var kf_id = 0;
|
||
var kf_name = '';
|
||
// 是否点击显示表情的标志
|
||
var flag = 1;
|
||
// 发送锁 标识
|
||
var sendLock = 0;
|
||
// 窗口大小标识
|
||
var size = 1;
|
||
// 是否显示默认的聊天记录
|
||
var commChat = 1;
|
||
|
||
var wsUrl = 'ws://' + config.socket;
|
||
|
||
//websocket实例
|
||
var ws;
|
||
|
||
//避免重复连接
|
||
var lockReconnect = false;
|
||
|
||
// 创建一个Socket实例
|
||
function createWebSocket(url){
|
||
try {
|
||
ws = new WebSocket(url);
|
||
// 加锁
|
||
lockTextarea();
|
||
// showSystem({content: '连接中...'});
|
||
document.getElementById('title').innerText = '连接中...';
|
||
eventHandle();
|
||
} catch (e) {
|
||
reconnect(url);
|
||
}
|
||
}
|
||
|
||
function eventHandle(){
|
||
ws.onclose = function () {
|
||
reconnect(wsUrl);
|
||
};
|
||
|
||
ws.onerror = function () {
|
||
showSystem({content: '连接失败,正在重新连接...'});
|
||
document.getElementById('title').innerText = '连接失败,重连中...';
|
||
reconnect(wsUrl);
|
||
};
|
||
|
||
ws.onopen = function () {
|
||
|
||
// 登录
|
||
var login_data = '{"path":"api\/userInit","param":{"type":"user","group" : "' + config.group + '","group_id":"2"},"access_token" : "123456"}';
|
||
ws.send(login_data);
|
||
|
||
// 解锁
|
||
unlockTextarea();
|
||
//心跳检测重置
|
||
heartCheck.reset().start();
|
||
};
|
||
|
||
ws.onmessage = function (res) {
|
||
var data = eval("("+res.data+")");
|
||
if (data['type'] != 'ping') {
|
||
console.log("监听消息");
|
||
console.log(data);
|
||
}
|
||
switch(data['message_type']){
|
||
// 服务端ping客户端
|
||
case 'ping':
|
||
ws.send('{"path":"ping"}');
|
||
break;
|
||
// 已经被分配了客服
|
||
case 'connect':
|
||
kf_id = data.data.kf_id;
|
||
kf_name = data.data.kf_name;
|
||
kf_avatar = data.data.kf_avatar;
|
||
// var input_name = prompt("请输入用户名:");
|
||
console.log(kf_name);
|
||
showSystem({content: '客服 ' + data.data.kf_name + ' 为您服务'});
|
||
document.getElementById('title').innerHTML = '与 ' + kf_name + ' 交流中';
|
||
if(1 == commChat){
|
||
showChatLog();
|
||
}
|
||
unlockTextarea();
|
||
break;
|
||
// 排队等待
|
||
case 'wait':
|
||
lockTextarea();
|
||
document.getElementById('title').innerHTML = '请稍后再来';
|
||
showSystem(data.data);
|
||
break;
|
||
// 监测聊天数据
|
||
case 'chat':
|
||
showMsg(data.data);
|
||
break;
|
||
// 问候语
|
||
case 'helloMessage':
|
||
showMsg(data.data, 1);
|
||
break;
|
||
// 转接
|
||
case 'relinkMessage':
|
||
commChat = 2;
|
||
document.getElementById('title').innerHTML = '正在转接中...';
|
||
break;
|
||
// 提示信息
|
||
case 'alert':
|
||
layer.msg(data.data);
|
||
break;
|
||
}
|
||
//如果获取到消息,心跳检测重置. 拿到任何消息都说明当前连接是正常的
|
||
heartCheck.reset().start();
|
||
}
|
||
}
|
||
|
||
function reconnect(url) {
|
||
if(lockReconnect) return;
|
||
lockReconnect = true;
|
||
//没连接上会一直重连,设置延迟避免请求过多
|
||
setTimeout(function () {
|
||
createWebSocket(url);
|
||
lockReconnect = false;
|
||
}, 2000);
|
||
}
|
||
|
||
//心跳检测
|
||
var heartCheck = {
|
||
timeout: 30000,//10秒
|
||
timeoutObj: null,
|
||
serverTimeoutObj: null,
|
||
reset: function(){
|
||
clearTimeout(this.timeoutObj);
|
||
clearTimeout(this.serverTimeoutObj);
|
||
return this;
|
||
},
|
||
start: function(){
|
||
var self = this;
|
||
this.timeoutObj = setTimeout(function(){
|
||
//这里发送一个心跳,后端收到后,返回一个心跳消息,
|
||
//onmessage拿到返回的心跳就说明连接正常
|
||
ws.send(JSON.stringify({
|
||
path: 'ping',
|
||
param: {'type':'user'}
|
||
}));
|
||
self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了
|
||
ws.close();//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
|
||
}, self.timeout);
|
||
}, this.timeout);
|
||
}
|
||
};
|
||
|
||
if(config != undefined && config.socket != undefined){
|
||
createWebSocket(wsUrl);
|
||
}
|
||
|
||
|
||
// 点击表情
|
||
document.getElementById('up-face').onclick = function(e){
|
||
e.stopPropagation();
|
||
if(1 == flag){
|
||
showFaces();
|
||
document.getElementById('face-box').style.display = 'block';
|
||
flag = 2;
|
||
}else{
|
||
document.getElementById('face-box').style.display = 'none';
|
||
flag = 1;
|
||
}
|
||
};
|
||
|
||
// 监听点击旁边关闭表情
|
||
document.addEventListener("click",function(){
|
||
if(2 == flag){
|
||
document.getElementById('face-box').style.display = 'none';
|
||
flag = 1;
|
||
}
|
||
});
|
||
|
||
// 点击发送消息
|
||
document.getElementById('send').onclick = function(){
|
||
sendMsg();
|
||
document.getElementById('msg').value = '';
|
||
// 滚动条自动定位到最底端
|
||
wordBottom();
|
||
};
|
||
|
||
document.getElementById('msg').onkeydown = function (event) {
|
||
if (event.ctrlKey && event.keyCode == 13) {
|
||
|
||
sendMsg();
|
||
document.getElementById('msg').value = '';
|
||
// 滚动条自动定位到最底端
|
||
wordBottom();
|
||
|
||
}
|
||
};
|
||
|
||
|
||
|
||
// 改变窗体事件
|
||
window.onresize = function(){
|
||
if(1 == size){
|
||
size = 2;
|
||
document.getElementById('face-box').style.top = '58%';
|
||
document.getElementById('chat-content-box').style.height = '75%';
|
||
}else if(2 == size){
|
||
size = 1;
|
||
document.getElementById('face-box').style.top = '190px';
|
||
document.getElementById('chat-content-box').style.height = '60%';
|
||
}
|
||
};
|
||
|
||
// 图片 文件上传
|
||
layui.use(['upload', 'layer'], function () {
|
||
var upload = layui.upload;
|
||
var layer = layui.layer;
|
||
|
||
// 执行实例
|
||
var uploadInstImg = upload.render({
|
||
elem: '#up-image' // 绑定元素
|
||
, accept: 'images'
|
||
, exts: 'jpg|jpeg|png|gif'
|
||
, url: '/index/upload/uploadImg' // 上传接口
|
||
, done: function (res) {
|
||
|
||
sendMsg('img[' + res.data.src + ']');
|
||
showBigPic();
|
||
}
|
||
, error: function () {
|
||
// 请求异常回调
|
||
}
|
||
});
|
||
|
||
});
|
||
|
||
// 获取时间
|
||
function getTime(){
|
||
var myDate = new Date();
|
||
var hour = myDate.getHours();
|
||
var minute = myDate.getMinutes();
|
||
var second = myDate.getSeconds();
|
||
if(hour < 10) hour = '0' + hour;
|
||
if(minute < 10) minute = '0' + minute;
|
||
if(second < 10) second = '0' + second;
|
||
|
||
return hour + ':' + minute + ':' + second;
|
||
}
|
||
|
||
// 展示系统消息
|
||
function showSystem(msg){
|
||
var _html = document.getElementById('chat-list').innerHTML;
|
||
_html += '<div class="mylink-chat-system"><span>' + msg.content + '</span></div>';
|
||
|
||
document.getElementById('chat-list').innerHTML = _html;
|
||
}
|
||
|
||
|
||
// 发送信息
|
||
function sendMsg(sendMsg){
|
||
console.log("客户端发送消息了");
|
||
|
||
if(1 == sendLock){
|
||
return false;
|
||
}
|
||
|
||
var msg = (typeof(sendMsg) == 'undefined') ? document.getElementById('msg').value : sendMsg;
|
||
if('' == msg){
|
||
return false;
|
||
}
|
||
|
||
var _html = document.getElementById('chat-list').innerHTML;
|
||
var time = getTime();
|
||
var content = replaceContent(msg);
|
||
|
||
_html +=
|
||
'<div class="chat-mine">' +
|
||
'<div class="chat-mine-left">' +
|
||
'<div class="author-name">我 <small class="chat-date">' + time + '</small></div>' +
|
||
'<div class="chat-text">' + content + '</div>' +
|
||
'</div>' +
|
||
'<div class="chat-mine-right"><img src="' + config.avatar + '">' +
|
||
'</div>' +
|
||
'</div>';
|
||
|
||
// 发送消息
|
||
ws.send(JSON.stringify({
|
||
path: 'api\/chat',
|
||
param: {type:'user',to_id: kf_id, to_name: kf_name, content: msg, from_name: config.name,
|
||
from_id: JSON.parse(config.token).user.user_id, from_avatar: config.avatar},
|
||
access_token: JSON.parse(config.token)
|
||
}));
|
||
|
||
// 储存我发出的信息
|
||
var key = kf_id + '-' + JSON.parse(config.token).user.user_id;
|
||
if(typeof(Storage) !== "undefined"){
|
||
var localMsg = getCache(key);
|
||
if(localMsg == null || localMsg.length == 0){
|
||
localMsg = [];
|
||
}
|
||
localMsg.push({type: 'mine', name: '我', avatar: config.avatar, time: time, content: content});
|
||
|
||
cacheChat({key: key, data: localMsg});
|
||
}
|
||
|
||
document.getElementById('chat-list').innerHTML = _html;
|
||
|
||
// 滚动条自动定位到最底端
|
||
wordBottom();
|
||
|
||
showBigPic();
|
||
}
|
||
|
||
// 展示发送来的消息
|
||
function showMsg(info, flag){
|
||
console.log("展示发送来的消息");
|
||
//发送消息提醒
|
||
sendWarnAudio('msg');
|
||
|
||
// 清除系统消息
|
||
document.getElementsByClassName('mylink-chat-system').innerHTML = '';
|
||
|
||
var _html = document.getElementById('chat-list').innerHTML;
|
||
var content = replaceContent(info.content);
|
||
_html +=
|
||
'<div class="chat-other">' +
|
||
'<div class="chat-other-left">' +
|
||
'<img src="' + info.avatar + '">' +
|
||
'</div>' +
|
||
'<div class="chat-other-right">' +
|
||
'<div class="author-name">' + info.name + ' ' +
|
||
'<small class="chat-date">' + info.time + '</small>' +
|
||
'</div>' +
|
||
'<div class="chat-text">' + content + '</div>' +
|
||
'</div> ' +
|
||
'</div>';
|
||
|
||
document.getElementById('chat-list').innerHTML = _html;
|
||
|
||
showBigPic();
|
||
// 滚动条自动定位到最底端
|
||
wordBottom();
|
||
// 储存我收到的信息
|
||
var key = kf_id + '-' + JSON.parse(config.token).user.user_id;
|
||
if(typeof(Storage) !== "undefined" && typeof(flag) == "undefined"){
|
||
var localMsg = getCache(key);
|
||
if(localMsg == null || localMsg.length == 0){
|
||
localMsg = [];
|
||
}
|
||
localMsg.push({type: 'other', name: info.name, avatar: info.avatar, time: info.time, content: content});
|
||
|
||
cacheChat({key: key, data: localMsg});
|
||
}
|
||
}
|
||
|
||
// 展示表情数据
|
||
function showFaces(){
|
||
var alt = getFacesIcon();
|
||
var _html = '<ul>';
|
||
var len = alt.length;
|
||
for(var index = 0; index < len; index++){
|
||
_html += '<li title="' + alt[index] + '" onclick="checkFace(this)"><img src="/static/customer/images/face/'+ index + '.gif" /></li>';
|
||
}
|
||
_html += '</ul>';
|
||
|
||
document.getElementById('face-box').innerHTML = _html;
|
||
}
|
||
|
||
// 选择表情
|
||
function checkFace(obj){
|
||
var msg = document.getElementById('msg').value;
|
||
document.getElementById('msg').value = msg + ' face' + obj.title + ' ';
|
||
document.getElementById('msg').focus();
|
||
document.getElementById('face-box').style.display = 'none';
|
||
flag = 1;
|
||
}
|
||
|
||
// 缓存聊天数据 [本地存储策略]
|
||
function cacheChat(obj){
|
||
if(typeof(Storage) !== "undefined"){
|
||
localStorage.setItem(obj.key, JSON.stringify(obj.data));
|
||
}
|
||
}
|
||
|
||
// 从本地缓存中,拿出数据
|
||
function getCache(key){
|
||
return JSON.parse(localStorage.getItem(key));
|
||
}
|
||
|
||
// 展示本地聊天缓存
|
||
function showChatLog(){
|
||
|
||
var chatLog = getCache(kf_id + '-' + JSON.parse(config.token).user.user_id);
|
||
if(chatLog == null || chatLog.length == 0){
|
||
return ;
|
||
}
|
||
|
||
var _html = '';
|
||
var len = chatLog.length;
|
||
for(var i = 0; i < len; i++){
|
||
var item = chatLog[i];
|
||
|
||
if('mine' == item.type){
|
||
_html +=
|
||
'<div class="chat-mine">' +
|
||
'<div class="chat-mine-left">' +
|
||
'<div class="author-name">' + item.name + ' ' +
|
||
'<small class="chat-date">' + item.time + '</small>' +
|
||
'</div>' +
|
||
'<div class="chat-text">' + item.content + '</div>' +
|
||
'</div>' +
|
||
'<div class="chat-mine-right">' +
|
||
'<img src="' + item.avatar + '">' +
|
||
'</div>' +
|
||
'</div>';
|
||
}
|
||
else if('other' == item.type){
|
||
_html +=
|
||
'<div class="chat-other">' +
|
||
'<div class="chat-other-left">' +
|
||
'<img src="' + item.avatar + '">' +
|
||
'</div>' +
|
||
'<div class="chat-other-right">' +
|
||
'<div class="author-name">' + item.name + ' ' +
|
||
'<small class="chat-date">' + item.time + '</small>' +
|
||
'</div>' +
|
||
'<div class="chat-text">' + item.content + '</div>' +
|
||
'</div> ' +
|
||
'</div>';
|
||
}
|
||
}
|
||
|
||
document.getElementById('chat-list').innerHTML = _html;
|
||
|
||
showBigPic();
|
||
// 滚动条自动定位到最底端
|
||
wordBottom();
|
||
}
|
||
|
||
// 锁住输入框
|
||
function lockTextarea(){
|
||
sendLock = 1;
|
||
document.getElementById('msg').setAttribute('readonly', 'readonly');
|
||
}
|
||
|
||
// 解锁输入框
|
||
function unlockTextarea(){
|
||
sendLock = 0;
|
||
document.getElementById('msg').removeAttribute('readonly');
|
||
}
|
||
|
||
// 双击图片
|
||
function showBigPic(){
|
||
layui.use('jquery', function(){
|
||
var $ = layui.jquery;
|
||
|
||
$(".layui-mylink-photos").on('click', function () {
|
||
var src = this.src;
|
||
layer.photos({
|
||
photos: {
|
||
data: [{
|
||
"alt": "大图模式",
|
||
"src": src
|
||
}]
|
||
}
|
||
, shade: 0.5
|
||
, closeBtn: 2
|
||
, anim: 0
|
||
, resize: false
|
||
, success: function (layero, index) {
|
||
|
||
}
|
||
});
|
||
});
|
||
});
|
||
}
|
||
|
||
// 对话框定位到最底端
|
||
function wordBottom(){
|
||
var ex = document.getElementById("chat-list");
|
||
ex.scrollTop = ex.scrollHeight;
|
||
}
|
||
|
||
/**
|
||
* 发送播放声音
|
||
* @param type
|
||
*/
|
||
function sendWarnAudio(type) {
|
||
|
||
//获取播放器
|
||
var turnAudio = document.getElementById("myWarnAudio");
|
||
|
||
var outTime = 0;
|
||
if(!turnAudio){
|
||
|
||
console.log('初始化');
|
||
turnAudio = document.createElement("audio");
|
||
document.body.appendChild(turnAudio);
|
||
turnAudio.id = "myWarnAudio";
|
||
turnAudio.controls = false;
|
||
turnAudio.loop = false;
|
||
turnAudio.hidden = true;
|
||
outTime = 2000;
|
||
}
|
||
|
||
//声音类型
|
||
if(type == 'msg') {
|
||
turnAudio.src = "/static/common/mp3/iqq.mp3";
|
||
}
|
||
|
||
//播放声音
|
||
turnAudio.play();
|
||
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
|