var shopID=1893;
var wsUrl = 'wss://im.admin60.cn:30080';
var myRootDomain = 'admin60.cn';
var shopInfo=null,seatsInfo=null,allSeats=null,seatsID=0,cID='',myItemID=0,indexSend=0,lastMsgID=0,minMsgID=0,unlineNoticeTime=0;
var scID=0,nick='我',uniKey='',wsk=null,_socket=false,activeClose = false,lockReconnect=false,inited = false,juguw_ct=null,pongCheck=null,jg_closeWin_time=0,jg_userOpenedPop=false;
//界面
var jg_im_tpl = '
';
var _jg_body = document.getElementsByTagName('body')[0];
var _jg_css = document.createElement('link');
_jg_css.href = 'h' + 'ttp://wap.ad' + 'min60.cn/css/im.cs' + 's?v=1.0.2';
_jg_css.rel = 'stylesheet';
_jg_css.style = 'text/css';
var _jg_func = document.createElement('script');
_jg_func.src = 'htt' + 'p://wap.admi' + 'n60.cn/js/publicFunc.j' + 's?v=1.0.2';
_jg_func.type = 'text/jscript';
_jg_body.firstChild.parentNode.insertBefore(_jg_css,_jg_body.firstChild);//导入CSS文件
_jg_body.firstChild.parentNode.insertBefore(_jg_func,_jg_body.firstChild);//导入JS文件
_jg_body.insertAdjacentHTML('beforeend',jg_im_tpl); //导入界面
//载入jquery
if(typeof jQuery == 'undefined'){
var _jg_jquery = document.createElement('script');
_jg_jquery.src = 'htt' + 'p://w' + 'ap.ad' + 'min60.cn/comm' + 'on/plug' + 'ins/jqu' + 'ery/jq' + 'uery.min.j' + 's';
_jg_jquery.type = 'text/javascript';
_jg_body.firstChild.parentNode.insertBefore(_jg_jquery,_jg_body.firstChild);//导入JS文件
setTimeout(function(){
setTimeout(function(){
//从缓存中读取终端识别码
uniKey = getCookie('juguw_im_uniKey');
if(isN(uniKey)) uniKey = '';
//创建socket连接
openSocket();
},1500);
},500);
}else{
$('body').append(jg_im_tpl);
$(function(){
setTimeout(function(){
//从缓存中读取终端识别码
uniKey = getCookie('juguw_im_uniKey');
if(isN(uniKey)) uniKey = '';
//创建socket连接
openSocket();
},3000);
});
}
function showImPop(){
$('#im_popWin').show();
$('#im_popWin_btn').hide();
scrollToEnd();
jg_userOpenedPop = true;
}
function closeImPop(){
$('#im_popWin_btn').show();
$('#im_popWin').hide();
jg_closeWin_time = Date.parse(new Date())/1000;
}
function openSocket(){
if(window.WebSocket){
_socket = true;
showTip('加载中...
');
try
{
wsk = new WebSocket(wsUrl);
initSocketAPI();
}
catch (e)
{
//console.log('catch');
reConnect();
}
}else{
//不支持webSocket
console.log('不支持webSocket');
}
}
function initSocketAPI(){
wsk.onopen = function(event){
//发送初始连接
wsk.send(JSON.stringify({"type":"guestconnect","uniKey":uniKey,"shopID":shopID}));
}
wsk.onerror = function(event){
//console.log('webSocket Error');
showTip('连接服务器失败!
');
reConnect();
}
wsk.onmessage = function(event){
if(!inited){
showTip('',1);
}
inited = true;
heartCheck.start();
var ret = JSON.parse(event.data);
if(!isN(ret)){
//console.log(JSON.stringify(ret));
switch (toInt(ret.code)){
case 1802:
//服务端心跳检测,响应一下
wsk.send(JSON.stringify({type:"ping"}));
break;
case 1805:
case 1806:
//消息发送成功了
//更新属性
if(!isN(ret.indexID)){
var _indexID = toInt(ret.indexID);
var _msgID = toInt(ret.msgID);
if(isN(_indexID) || isN(_msgID)) return false;
if(_msgID>lastMsgID) lastMsgID = _msgID;
//如果是当前窗口,更新属性即可,如果不是当前窗口,显示消息
if(hasObj('#jg_msgOutBox #msg_send_'+_indexID)){
if(!isN(ret.cTime)){
$('#msg_send_' + _indexID + ' .c_msg_nick').append(' ' + formatDT2(ret.cTime) + '');
}
$('#msg_send_' + _indexID + ' .c_msg_sending').remove();
$('#msg_send_' + _indexID).attr('id','msg_' + _msgID);
}else{
showMsg({isMine:1,itemID:_msgID,fromTitle:nick,cTime:ret.cTime,content:ret.content});
}
}
if(myEqual(ret.code,1805)) showTip('消息发送成功了,但是对方不在线,对方上线后将收到您的留言
',2000);
break;
case -1806:
//消息发送失败
break;
case 2200:
//连接服务器成功,服务端返回座席列表,一般是客户端首次连接
if(!isN(ret.cID)) cID = ret.cID;
if(!isN(cID)){
myItemID = toInt(cID.replace('c_',''));
}
if(!isN(ret.shopInfo)){
shopInfo = ret.shopInfo;
initPongCheck(shopInfo);
if(!isN(shopInfo['shopName'])) $('#top_title').html(shopInfo['shopName']);
}
if(!myEqual(ret.uniKey,uniKey)){
uniKey = ret.uniKey;
setCookie('juguw_im_uniKey',uniKey,myRootDomain);
}
if(!isN(ret.nick)) nick = ret.nick;
if(!isN(shopInfo)){
if(!isN(shopInfo['firstGreetings']) && !hasObj('#jg_msgOutBox #msg_firstGreetings')){
$('#jg_msgBox').before('' + shopInfo['firstGreetings'] + ' ');
}
}
if(!isN(ret.seatsData)){
allSeats = ret.seatsData;
showSeatsList('');//显示座席列表
}
break;
case 2204:
case 2201:
//客户端与座席连接成功,2204表示新连接
if(!isN(ret.cID)) cID = ret.cID;
if(!isN(cID)){
myItemID = toInt(cID.replace('c_',''));
}
if(!isN(ret.sID)){
seatsID = ret.sID;
}
var topTitle = '';
if(!isN(ret.shopInfo)){
shopInfo = ret.shopInfo;
initPongCheck(shopInfo);
if(!isN(shopInfo['shopName'])) topTitle = shopInfo['shopName'];
}
//连接成功,返回了座席信息
if(!isN(ret.seatsInfo)){
seatsInfo = ret.seatsInfo;
if(!isN(seatsInfo['nick'])) topTitle += ' ' + seatsInfo['nick'];
}
if(!isN(topTitle)) $('#top_title').html(topTitle + ' ');
if(!myEqual(ret.uniKey,uniKey)){
uniKey = ret.uniKey;
setCookie('juguw_im_uniKey',uniKey,myRootDomain);
}
if(!myEqual(scID,toInt(ret.scID))){
scID = toInt(ret.scID);
setCookie('juguw_im_scID',scID,myRootDomain);
}
if(!isN(ret.nick)) nick = ret.nick;
//加载历史消息
if(!isN(scID)) wsk.send(JSON.stringify({type:'msglist',scID:scID,cID:cID,startID:minMsgID,endID:lastMsgID}));
break;
case 2202:
//客户端连接服务器成功,但原座席不在线,由客户端决定换座席还是继续跟那个人联系
if(!isN(ret.cID)) cID = ret.cID;
if(!isN(cID)){
myItemID = toInt(cID.replace('c_',''));
}
if(!isN(ret.sID)){
seatsID = ret.sID;
}
var topTitle = '';
if(!isN(ret.shopInfo)){
shopInfo = ret.shopInfo;
initPongCheck(shopInfo);
if(!isN(shopInfo['shopName'])) topTitle = shopInfo['shopName'];
}
//连接成功,返回了座席信息
if(!isN(ret.seatsInfo)){
seatsInfo = ret.seatsInfo;
if(!isN(seatsInfo['nick'])) topTitle += ' ' + seatsInfo['nick'];
}
if(!isN(topTitle)) $('#top_title').html(topTitle + ' [离线]');
if(!myEqual(ret.uniKey,uniKey)){
uniKey = ret.uniKey;
setCookie('juguw_im_uniKey',uniKey,myRootDomain);
}
if(!myEqual(scID,toInt(ret.scID))){
scID = toInt(ret.scID);
setCookie('juguw_im_scID',scID,myRootDomain);
}
if(!isN(ret.nick)) nick = ret.nick;
if(!isN(ret.seatsData)){
allSeats = ret.seatsData;
//如果只有一个座席,不用弹出座席列表
if(myEqual(getLength(allSeats),1)){
showTip('之前为您服务的客服座席当前不在线,您可以继续留言,客服上线后可收到消息',10000);
}else{
showSeatsList('之前为您服务的客服座席当前不在线,您可以继续与其联系,也可以尝试与其他座席联系。');//显示座席列表
}
}
//加载历史消息
if(!isN(scID)) wsk.send(JSON.stringify({type:'msglist',scID:scID,cID:cID,startID:minMsgID,endID:lastMsgID}));
break;
case 2310:
//座席强制打开客户端聊天窗口
$('#im_popWin').animate({height:'show'});
$('#im_popWin_btn').hide();
scrollToEnd();
break;
case -2104:
case -3104:
//对方不在线回显
var _noticeTime = Date.parse(new Date())/1000;
if(_noticeTime - unlineNoticeTime>60){
showTip('对方当前不在线,上线后将收到您的留言!
',3000);
unlineNoticeTime = _noticeTime;
$('#seats_status').html('[离线]');
}
break;
case 8106:
//成功从服务端获取消息
if(!isN(ret.data)){
var _lastID = 0;
$.each(ret.data,function(idx,itm){
var _itemID = toInt(itm.itemID);
if(_itemID>lastMsgID && !isN(lastMsgID)){
showMsg(itm,0);
}else{
showMsg(itm,1);
}
if(_itemID_lastID) _lastID = _itemID;
});
scrollToEnd();
if(_lastID>lastMsgID) lastMsgID = _lastID;
//console.log(minMsgID + '_' + lastMsgID);
}
break;
case 8107:
//从服务端获取消息操作成功,但是没有新的消息,给出欢迎提示
if(!isN(shopInfo)){
if(!isN(shopInfo['firstGreetings']) && !hasObj('#jg_msgOutBox #msg_firstGreetings')){
$('#jg_msgBox').before('' + shopInfo['firstGreetings'] + ' ');
}
}
break;
case 8200:
//收到新的消息
if(myEqual(ret.scID,scID)){
showMsg({isMine:0,itemID:ret.msgID,fromTitle:ret.fromTitle,cTime:ret.cTime,content:ret.data});
if(Date.parse(new Date())/1000-jg_closeWin_time>60){
//主动弹出窗口
if($('#im_popWin').is(':hidden')){
showImPop();
}
}
}
break;
case 3200:
//座席上线
showTip('' + ret.data + '
',5000);
$('#seats_status').html('');
break;
case 3201:
//座席主动连接客户端
$('#jg_msgBox').before('' + ret.data + '
');
break;
case 1:
case -3106:
case -2404:
case -3404:
showTip(ret.data,5000);
break;
case -8001:
//无对照ID,弹出座席列表
console.log(ret.data);
showSeatsList();
break;
case 0:
case -2106:
case -8002:
console.log(ret.data);
break;
default:
//出错了
break;
}
}
}
wsk.onclose = function(){
showTip('连接已关闭,点击可重新连接
');
}
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function(){
wsk.close();
};
}
//重连函数
function reConnect(url) {
if(lockReconnect || activeClose) {
return;
};
showTip('尝试重新连接服务器
');
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
juguw_ct && clearTimeout(juguw_ct);
juguw_ct = setTimeout(function () {
openSocket();
lockReconnect = false;
}, 20000);
}
//心跳检测
var heartCheck = {
//每隔几秒测试一下心跳是否在继续
timeout: 10000,
timeoutObj: null,
serverTimeoutObj: null,
start: function(){
//console.log('准备检测服务端在线状态');
var self = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function(){
//这里发送一个心跳,后端收到后,返回一个心跳消息,
console.log('发送检测消息');
//发一个消息过去,后台接收,在init()中的onmessage收到消息,说明后台没有挂掉,有心跳
if(isN(seatsID)){
wsk.send(JSON.stringify({"type":"activing"}));
}else{
wsk.send(JSON.stringify({"type":"checkuidonline","uID":'s_' + seatsID}));
}
//console.log(jg_userOpenedPop);
if(jg_userOpenedPop){
//如果用户曾手动点开客服窗口
self.serverTimeoutObj = setTimeout(function() {
//console.log("服务端已离线");
showTip('服务端已离线,点击可重新连接
');
wsk.close();
}, self.timeout);
}
}, this.timeout);
//console.log(this.timeout + '_' + self.timeout);
}
};
//客户端超时提醒
function initPongCheck(vobj){
if(vobj){
if(!isN(vobj.timeOut)){
if(toInt(vobj.timeOut)>0){
pongCheck = {
timeoutObj:null,
pongTimeObj:null,
start:function(){
var _timeOut = toInt(shopInfo.timeOut)*1000;
var _pongTime = 60000;
if(!isN(shopInfo.pongTime)){
_pongTime = toInt(shopInfo.pongTime)*1000;
if(isN(_pongTime)) _pongTime = 60000;
}
if(_timeOut - _pongTime<5000) _pongTime = _timeOut;
_pongStr = shopInfo.pongStr || ((_timeOut - _pongTime)/1000 + '秒后将关闭连接');
this.timeoutObj && clearTimeout(this.timeoutObj);
this.pongTimeObj && clearTimeout(this.pongTimeObj);
this.pongTimeObj = setTimeout(function(){
showTip('' + _pongStr + '
',3000);
},_pongTime);
this.timeoutObj = setTimeout(function(){
console.log('关闭连接');
wsk.close();
}, _timeOut);
}
};
pongCheck.start();
}
}
}
}
function showTip(vstr,vt){
$('#jg_tipBox').html(vstr);
if(!isN(vt)){
setTimeout(function(){
$('#jg_tipBox').html('');
},vt);
}
}
function hideTip(){
$('#jg_tipBox').hide();
}
function sendMsg(){
var _msg = $('#jg_content').html();
var _now = Date.parse(new Date())/1000;
indexSend++;
if(!isN(_msg)){
$('#jg_msgBox').before('');
scrollToEnd();
$('#jg_content').html('');
if(!isN(pongCheck)) pongCheck.start();
wsk.send(JSON.stringify({'type':'say','scID':scID,'indexID':indexSend,'content':_msg}));
}else{
showTip('请输入您要发送的消息内容!',2000);
}
}
function closeMask(){
$('#mask_tip').hide();
}
function guest_bind_seats(vid){
if(!isN(vid)){
if(confirm('您确定要该客服座席为您提供服务吗?!')){
closeMask();
wsk.send(JSON.stringify({'type':'guest_bind_seats',"shopID":shopID,"sID":vid}));
};
}
}
//滚动到最后一条消息
function scrollToEnd(){
$('#jg_msgOutBox').animate({scrollTop:$('#jg_msgOutBox').prop("scrollHeight")}, 400);
}
//显示座席列表给客户端
function showSeatsList(vtip){
if(!isN(allSeats)){
var _html = ''
$.each(allSeats,function(idx,itm){
_html += '
' + (isN(itm.online)?'[离线] ':'[在线] ') + itm.nick + '
';
});
_html += '
关 闭
';
if(!isN(vtip)) _html += '
' + vtip + '
';
_html += '
';
$('#mask_tip').html(_html).show();
}else{
showTip('对不起,当前暂无座席',5000);
}
}
//显示消息列表中的数据,insertType 0追加,1往前追加
function showMsg(ret,insertType){
if(!isN(ret)){
if(hasObj('#jg_msgOutBox #msg_' + ret['itemID'])) return false; //已存在的
//console.log(JSON.stringify(ret));
insertType = toInt(insertType);
if(isN(insertType)) insertType = 0;
//isMine 标识是否为我的信息
var isMine = isN(ret['isMine'])?false:true;;
if(!isN(ret.fromID) && !isN(cID)){
if(myEqual(ret.fromID,'c_'+myItemID)) isMine = true; //如果有fromID和cID,以此为判断依据
}
if(isMine){
var htmlStr = '' + ret.fromTitle + ' ' + formatDT2(ret['cTime']) + '
';
}else{
//客服发送的消息
var thumb_ = 'http://wap.admin60.cn/images/apps/img_userthumb_gray.png';
if(!isN(seatsInfo['thumb'])){
thumb_ = seatsInfo['thumb'];
}else if(!isN(shopInfo['shopLogo'])){
thumb_ = shopInfo['shopLogo'];
}
var htmlStr = '' + ret.fromTitle + ' ' + formatDT2(ret['cTime']) + '
';
}
//console.log(htmlStr);
if(!isN(insertType)){
$('#jg_msgOutBox').prepend(htmlStr);
}else{
$('#jg_msgBox').before(htmlStr);
}
if(isN(insertType)) scrollToEnd();
//获取列表中第一条消息时间显示框的数据
var _cTime = 0;
if(hasObj('#jg_msgOutBox .c_msg_time2')){
_cTime = toInt($("#jg_msgOutBox .c_msg_time2").data('ctime'));
if(!sameDay(_cTime,ret.cTime)){
if(!isN(insertType)){
$('#jg_msgOutBox').prepend('' + formatDT2(ret.cTime) + '
');
}else{
$('#jg_msgBox').before('' + formatDT2(ret.cTime) + '
');
}
if(isN(insertType)) scrollToEnd();
}else{
//同一天的,如果两条消息之间超过10分钟,显示时间
if(Math.abs(_cTime-ret['cTime'])>600){
if(!isN(insertType)){
$('#jg_msgOutBox').prepend('' + formatDT2(ret.cTime) + '
');
}else{
$('#jg_msgBox').before('' + formatDT2(ret.cTime) + '
');
}
if(isN(insertType)) scrollToEnd();
}
}
}
}
}