var shopID=133; var wsUrl = 'wss://im.admin60.cn:30080'; var myRootDomain = 'juguw.net'; 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 = '
联系在线客服!
X
在线客服
'; 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(); },1500); }); } 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('
' + nick + '
' + _msg + '
'); 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']) + '
' + ret['content'] + '
'; }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']) + '
' + ret['content'] + '
'; } //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(); } } } } }