var shopID=0; var wsUrl = 'wss://im.admin60.cn:30080'; var myRootDomain = 'gxhcsj.com'; 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('
連接已關閉,點擊可(ke)重新(xin)連接
'); } //監聽窗口關閉事件,當窗口關閉時,主動去關閉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('
服務端已離線,點(dian)擊可(ke)重新連接
'); 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)?'[離線] ':'[在線(xian)] ') + 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_ = '//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(); } } } } }