482 lines
14 KiB
JavaScript
482 lines
14 KiB
JavaScript
// 客服的id
|
|
var kf_id = 0;
|
|
var kf_name = '';
|
|
// 是否点击显示表情的标志
|
|
var flag = 1;
|
|
// 发送锁 标识
|
|
var sendLock = 0;
|
|
// 是否显示默认的聊天记录
|
|
var commChat = 1;
|
|
// 两个时间段的消息相隔时间
|
|
var msg_time = 2;
|
|
var heartTime = 20 * 1000;
|
|
|
|
var lockReconnect = false; //避免重复连接
|
|
|
|
var socket;
|
|
|
|
// 连接服务器
|
|
if (config != undefined && config.socket != undefined) {
|
|
showloading(true);
|
|
var url = config.socket + ':' + config.port;
|
|
createWebSocket(url);
|
|
lockInput();
|
|
}
|
|
|
|
function createWebSocket(url) {
|
|
try {
|
|
socket = new WebSocket(url);
|
|
eventHandle();
|
|
} catch (e) {
|
|
reconnect(url);
|
|
}
|
|
}
|
|
|
|
function reconnect(url) {
|
|
if (lockReconnect) return;
|
|
lockReconnect = true;
|
|
//没连接上会一直重连,设置延迟避免请求过多
|
|
setTimeout(function () {
|
|
console.log('重连..')
|
|
createWebSocket(url);
|
|
lockReconnect = false;
|
|
}, 2000);
|
|
}
|
|
|
|
function eventHandle() {
|
|
// 监听关闭
|
|
socket.onclose = function () {
|
|
console.log('连接关闭')
|
|
reconnect(url);
|
|
};
|
|
|
|
// 监听错误
|
|
socket.onerror = function (err) {
|
|
showSystem({ content: '连接失败' });
|
|
document.getElementById('title').innerText = '连接失败';
|
|
};
|
|
|
|
// 建立连接
|
|
socket.onopen = function (res) {
|
|
console.log('连接成功');
|
|
showloading(false);
|
|
var login_data = '{"path":"api/userInit","param":{"type":"user","kf_type":2,"user_id":"' +
|
|
config.uid + '","user_name":"' + config.name + '","avatar_url":"' +
|
|
config.avatar + '","group_id":"' + config.group + '","data":"" },"access_token":"123456"}'
|
|
socket.send(login_data);
|
|
//心跳检测重置
|
|
heartCheck.reset().start();
|
|
// 解锁
|
|
unlockInput();
|
|
};
|
|
|
|
// 监听消息
|
|
socket.onmessage = function (res) {
|
|
var data = eval("(" + res.data + ")");
|
|
switch (data['message_type']) {
|
|
// 分配到客服
|
|
case 'connect':
|
|
kf_id = data.data.kf_id;
|
|
kf_name = data.data.kf_name;
|
|
var is_online = data.data.is_online == 2 ? "<font style='font-size:8px'>(离线)</font>" : "<font style='font-size:8px; display: none;'>(离线)</font>";
|
|
showSystem({ content: '客服 ' + data.data.kf_name + ' 为您服务' });
|
|
document.getElementById('title').innerHTML = '与 ' + kf_name + ' 交流中' + is_online;
|
|
if (1 == commChat) {
|
|
showChatLog();
|
|
}
|
|
unlockInput();
|
|
break;
|
|
// 排队等待
|
|
case 'wait':
|
|
lockInput();
|
|
document.getElementById('title').innerHTML = '请稍后再来';
|
|
showSystem(data.data);
|
|
break;
|
|
// 监测聊天数据
|
|
case 'text':
|
|
var chekc_msg = checkMsgIsRepeat(data.data.msg_id);
|
|
if (chekc_msg) return;
|
|
showMsg(data.data, data.data.content);
|
|
break;
|
|
case 'img':
|
|
var chekc_msg = checkMsgIsRepeat(data.data.msg_id);
|
|
if (chekc_msg) return;
|
|
var content = data.data.content
|
|
showMsg(data.data, content, 'img');
|
|
break;
|
|
// 转接
|
|
case 'relinkMessage':
|
|
commChat = 2;
|
|
document.getElementById('title').innerHTML = '正在转接中...';
|
|
break;
|
|
// 客服下线
|
|
case 'kf_offline':
|
|
$('#title').children('font').show();
|
|
break;
|
|
// 客服上线
|
|
case 'kf_online':
|
|
// 添加离线
|
|
$('#title').children('font').hide();
|
|
break;
|
|
}
|
|
heartCheck.reset().start();
|
|
};
|
|
}
|
|
|
|
// 图片 文件上传
|
|
layui.use(['upload'], function () {
|
|
var upload = layui.upload;
|
|
|
|
// 执行实例
|
|
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 + ']');
|
|
}
|
|
, error: function () {
|
|
// 请求异常回调
|
|
}
|
|
});
|
|
|
|
$('.layui-upload-file').hide();
|
|
});
|
|
|
|
$(function () {
|
|
|
|
// 监听输入改变发送按钮
|
|
$("#msg").bind('input porpertychange', function () {
|
|
|
|
if ($("#msg").val().length > 0) {
|
|
$(".layim-send").removeClass('layui-disabled');
|
|
} else {
|
|
$(".layim-send").addClass('layui-disabled');
|
|
}
|
|
});
|
|
|
|
// 点击发送
|
|
$("#send").click(function () {
|
|
sendMsg();
|
|
});
|
|
|
|
// 点击表情
|
|
$('#up-face').click(function (e) {
|
|
e.stopPropagation();
|
|
if (1 == flag) {
|
|
showFaces();
|
|
$('#face-box').show();
|
|
flag = 2;
|
|
} else {
|
|
$('#face-box').hide();
|
|
flag = 1;
|
|
}
|
|
});
|
|
|
|
// 监听点击旁边关闭表情
|
|
document.addEventListener("click", function () {
|
|
if (2 == flag) {
|
|
document.getElementById('face-box').style.display = 'none';
|
|
flag = 1;
|
|
}
|
|
});
|
|
});
|
|
|
|
// 发送消息
|
|
function sendMsg(sendMsg) {
|
|
if (1 == sendLock) {
|
|
return false;
|
|
}
|
|
|
|
var msg = (typeof (sendMsg) == 'undefined') ? $('#msg').val() : sendMsg;
|
|
if ('' == msg) {
|
|
return false;
|
|
}
|
|
|
|
var msg_id = uuid();
|
|
var _html = $("#chat-list").html();
|
|
var time = getTime();
|
|
var content = replaceContent(msg);
|
|
let content_type = '';
|
|
// 检测是否显示时间
|
|
var next_time = $("#chat-list").find('span').last().text();
|
|
var check_time = checkMegTime(next_time, time, msg_time);
|
|
if (check_time) {
|
|
_html += '<li class="layim-chat-system"><span>' + time + '</span></li>';
|
|
}
|
|
_html += '<li class="layim-chat-li layim-chat-mine">';
|
|
_html += '<div class="layim-chat-user">';
|
|
_html += '<img src="' + config.avatar + '"><cite>我</cite></div>';
|
|
_html += '<div class="layim-chat-text">' + content + ' </div></li>';
|
|
|
|
$('#chat-list').html(_html);
|
|
if (msg.indexOf('img[') != -1) {
|
|
content_type = 'img'
|
|
}
|
|
msg = getCutout(msg);
|
|
// 发送消息
|
|
socket.send(JSON.stringify({
|
|
path: "api/chat",
|
|
param: {
|
|
"type": "user",
|
|
"to_id": kf_id,
|
|
"to_name": kf_name,
|
|
"group_id": "1",
|
|
"content": msg,
|
|
"content_type": content_type,
|
|
"msg_id": msg_id,
|
|
"from_name": config.name,
|
|
"from_id": config.user_id,
|
|
"from_avatar": config.avatar,
|
|
"data": ""
|
|
},
|
|
"access_token": "123456",
|
|
}));
|
|
|
|
// 储存我发出的信息
|
|
var key = kf_id + '-' + config.uid;
|
|
if (typeof (Storage) !== "undefined") {
|
|
var localMsg = getCache(key);
|
|
if (localMsg == null || localMsg.length == 0) {
|
|
localMsg = [];
|
|
}
|
|
localMsg.push({ type: 'mine', name: '我', time: time, content: content, avatar: config.avatar });
|
|
|
|
cacheChat({ key: key, data: localMsg });
|
|
}
|
|
|
|
$('#msg').val('');
|
|
$(".layim-send").addClass('layui-disabled');
|
|
|
|
// 滚动条自动定位到最底端
|
|
wordBottom();
|
|
}
|
|
|
|
// 展示发送来的消息
|
|
function showMsg(info, content, img, flag) {
|
|
var _html = $("#chat-list").html();
|
|
let index = content.indexOf('[')
|
|
if (index !== -1) {
|
|
content = content.slice(0, index) + 'face' + content.slice(index)
|
|
}
|
|
content = replaceContent(content);
|
|
|
|
// 检测是否显示时间
|
|
var next_time = $("#chat-list").find('span').last().text();
|
|
var check_time = checkMegTime(next_time, info.time, msg_time);
|
|
if (check_time) {
|
|
_html += `<li class="layim-chat-system" id='${info.msg_id}'><span>` + info.time + `</span></li>`;
|
|
}
|
|
// _html += '<li class="layim-chat-system"><span>' + info.time + '</span></li>';
|
|
_html += '<li class="layim-chat-li">';
|
|
_html += '<div class="layim-chat-user">';
|
|
_html += '<img src="' + info.avatar + '"><cite>' + info.name + '</cite></div>';
|
|
if (img == 'img') {
|
|
var type = 'img'
|
|
_html += '<div class="layim-chat-img" style="padding-top: 26px;background-color: transparent;min-height: 22px;line-height: 22px;margin-top: 25px;"><img class="layui-mylink-payment" src="' + content + '" width="100px" height="100px"></div></li>';
|
|
} else {
|
|
var type = 'text'
|
|
_html += '<div class="layim-chat-text">' + content + '</div></li>';
|
|
}
|
|
|
|
$('#chat-list').html(_html);
|
|
|
|
// 滚动条自动定位到最底端
|
|
wordBottom();
|
|
|
|
// 储存我收到的信息
|
|
var key = kf_id + '-' + config.uid;
|
|
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, time: info.time, content: content, avatar: info.avatar, message_type: type });
|
|
|
|
cacheChat({ key: key, data: localMsg });
|
|
}
|
|
}
|
|
|
|
|
|
// 缓存聊天数据 [本地存储策略]
|
|
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 wordBottom() {
|
|
// 滚动条自动定位到最底端
|
|
var box = $(".layim-chat-main");
|
|
box.scrollTop(box[0].scrollHeight);
|
|
}
|
|
|
|
// 锁住输入框
|
|
function lockInput() {
|
|
sendLock = 1;
|
|
document.getElementById('msg').setAttribute('readonly', 'readonly');
|
|
}
|
|
|
|
// 解锁输入框
|
|
function unlockInput() {
|
|
sendLock = 0;
|
|
document.getElementById('msg').removeAttribute('readonly');
|
|
}
|
|
|
|
// 展示表情数据
|
|
function showFaces() {
|
|
var alt = getFacesIcon();
|
|
var _html = '<ul class="layui-layim-face" style="position: absolute;bottom: 0;height: 100px;background-color: white;">'
|
|
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 + '.png" /></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('face-box').style.display = 'none';
|
|
$(".layim-send").removeClass('layui-disabled');
|
|
flag = 1;
|
|
}
|
|
|
|
// 系统消息
|
|
function showSystem(info) {
|
|
|
|
$("#chat-list").append('<li class="layim-chat-system"><span>' + info.content + '</span></li>');
|
|
}
|
|
|
|
// 展示本地聊天缓存
|
|
function showChatLog() {
|
|
|
|
var chatLog = getCache(kf_id + '-' + config.uid);
|
|
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) {
|
|
// 检测上次聊天时间
|
|
var check_time = false;
|
|
if (i > 1) {
|
|
var check_time = checkMegTime(chatLog[i - 1].time, item.time, msg_time);
|
|
}
|
|
|
|
if (check_time) {
|
|
_html += '<li class="layim-chat-system"><span>' + item.time + '</span></li>';
|
|
}
|
|
_html += '<li class="layim-chat-li layim-chat-mine">';
|
|
_html += '<div class="layim-chat-user">';
|
|
_html += '<img src="' + item.avatar + '"><cite>' + item.name + '</cite></div>';
|
|
_html += '<div class="layim-chat-text">' + item.content + ' </div></li>';
|
|
|
|
} else if ('other' == item.type) {
|
|
|
|
_html += '<li class="layim-chat-system"><span>' + item.time + '</span></li>';
|
|
_html += '<li class="layim-chat-li">';
|
|
_html += '<div class="layim-chat-user">';
|
|
_html += '<img src="' + item.avatar + '"><cite>' + item.name + '</cite></div>';
|
|
if (item.message_type == 'img') {
|
|
_html += '<div class="layim-chat-img" style="padding-top: 26px;background-color: transparent;min-height: 22px;line-height: 22px;margin-top: 25px;"><img class="layui-mylink-payment" src="' + item.content + '" width="100px" height="100px"></div></li>';
|
|
} else {
|
|
_html += '<div class="layim-chat-text">' + item.content + '</div></li>';
|
|
}
|
|
}
|
|
}
|
|
|
|
document.getElementById('chat-list').innerHTML = _html;
|
|
|
|
// 滚动条自动定位到最底端
|
|
|
|
wordBottom();
|
|
}
|
|
|
|
// 退出
|
|
function loginOut() {
|
|
window.history.go(-1);
|
|
}
|
|
|
|
/**
|
|
* 检测消息是否重复
|
|
* @param {*} uid 用户id
|
|
* @param {*} msg_id 消息id
|
|
*/
|
|
function checkMsgIsRepeat(msg_id) {
|
|
if (!msg_id) return false;
|
|
var dom = $('chat-list').find('#' + msg_id);
|
|
if (!dom || dom.length == 0) return false;
|
|
return true;
|
|
}
|
|
|
|
// 加载loading
|
|
function showloading(t) {
|
|
if (t) { //如果是true则显示loading
|
|
loading = layer.load(1, {
|
|
shade: [0.1, '#fff'] //0.1透明度的白色背景
|
|
});
|
|
} else { //如果是false则关闭loading
|
|
layer.closeAll('loading');
|
|
}
|
|
}
|
|
|
|
//心跳检测
|
|
var heartCheck = {
|
|
timeout: heartTime,
|
|
timeoutObj: null,
|
|
serverTimeoutObj: null,
|
|
reset: function () {
|
|
clearTimeout(this.timeoutObj);
|
|
clearTimeout(this.serverTimeoutObj);
|
|
return this;
|
|
},
|
|
start: function () {
|
|
var self = this;
|
|
this.timeoutObj = setTimeout(function () {
|
|
//发送心跳
|
|
socket.send(JSON.stringify({
|
|
path: 'ping',
|
|
param: { 'type': 'user' }
|
|
}));
|
|
self.serverTimeoutObj = setTimeout(function () { //如果超过一定时间还没重置,说明后端主动断开了
|
|
reconnect(wsUrl);
|
|
}, self.timeout);
|
|
}, this.timeout);
|
|
}
|
|
};
|
|
|
|
// 显示大图
|
|
function showBigPic(obj) {
|
|
// console.log(obj);
|
|
var src = obj.src;
|
|
layer.photos({
|
|
photos: {
|
|
data: [{
|
|
"alt": "大图模式",
|
|
"src": src
|
|
}]
|
|
},
|
|
shade: 0.5,
|
|
closeBtn: 2,
|
|
anim: 0,
|
|
resize: false,
|
|
success: function (layero, index) {
|
|
|
|
}
|
|
});
|
|
} |