Keine Beschreibung

main.js 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. var ws, hidTel, hidCallID;
  2. var cls = 0;
  3. var lockReconnect = false; //避免重复连接
  4. var scoketDatas = {}; //发送和接收的scoket数据
  5. //var lasttime = new Date().getTime();
  6. //创建scoket连接
  7. function createWebSocket() {
  8. try {
  9. $("#top-search li i").removeClass("active");
  10. Connect();
  11. } catch(e) {
  12. reconnect();
  13. }
  14. }
  15. //连接
  16. function Connect() {
  17. ws = new WebSocket("ws://" + huayi.config.socket_ip + ":" + huayi.config.socket_port);
  18. ws.onopen = function() {
  19. console.log(new Date() + " " + "建立连接");
  20. //心跳检测重置
  21. heartCheck.reset().start();
  22. cls = 0;
  23. $(".Login").addClass("active");
  24. //自动签入
  25. //lasttime = new Date().getTime();
  26. //scoketDatas.Type = "Login";
  27. //scoketDatas.AgentType = "0";
  28. //Send();
  29. };
  30. //接收到消息的回调方法
  31. ws.onmessage = function(evt) {
  32. //如果获取到消息,心跳检测重置
  33. //拿到任何消息都说明当前连接是正常的
  34. heartCheck.reset().start();
  35. var myDate = new Date();
  36. console.log(myDate + " receive " + evt.data);
  37. var data = JSON.parse(evt.data)[0];
  38. if(data) {
  39. var rlt = data.Result;
  40. if(rlt === true) {
  41. var type = data.Type;
  42. console.log("================" + type + "=====================");
  43. switch(type.toLowerCase()) {
  44. case "login":
  45. LoginBack();
  46. break; //签入
  47. case "logout":
  48. LogoutBack();
  49. break; //签出
  50. case "dropcall":
  51. DropCallBack();
  52. break; //挂断
  53. case "makecall":
  54. MakeCallBack();
  55. break; //外呼
  56. case "setstate":
  57. SetState(data);
  58. break; //置忙置闲
  59. case "meeting":
  60. MeetingBack();
  61. break; //多方通话
  62. case "transfer":
  63. TransferBack();
  64. break; //转移
  65. case "consult":
  66. ConsultBack();
  67. break; //协商呼叫
  68. case "hold":
  69. HoldBack();
  70. break; //保持
  71. case "retrieve":
  72. RetrieveBack();
  73. break; //接回
  74. case "incoming":
  75. IncomingBack(data);
  76. break; //来电
  77. case "linestateagent":
  78. LineStateAgentBack(data);
  79. break; //线路状态通知
  80. case "recordpath":
  81. RecordPathBack(data);
  82. break; //录音返回
  83. case "listen":
  84. layer.msg('监听操作成功!');
  85. break;
  86. case "forceagentstate":
  87. updateSeatMonitorlists(); //更新坐席监控内坐席的状态
  88. layer.msg('置闲操作成功!');
  89. break;
  90. case "replace":
  91. updateSeatMonitorlists(); //更新坐席监控内坐席的状态
  92. layer.msg('代接操作成功!');
  93. break;
  94. case "insert":
  95. updateSeatMonitorlists(); //更新坐席监控内坐席的状态
  96. layer.msg('强插操作成功!');
  97. break;
  98. case "intercept":
  99. updateSeatMonitorlists(); //更新坐席监控内坐席的状态
  100. layer.msg('拦截操作成功!');
  101. break;
  102. case "cut":
  103. updateSeatMonitorlists(); //更新坐席监控内坐席的状态
  104. layer.msg('强拆操作成功!');
  105. break;
  106. }
  107. } else {
  108. if(rlt === false) {
  109. var errCode = data.Error % 10000;
  110. var errTips = getErrTips(errCode); //获取错误信息
  111. if(errTips){
  112. layer.msg(errTips + '!');
  113. }else{
  114. layer.msg('失败');
  115. }
  116. $(".hwzt").text(errTips + '!');
  117. } else {
  118. $(".hwzt").text(rlt);
  119. }
  120. }
  121. }
  122. };
  123. //连接关闭的回调方法
  124. ws.onclose = function(evt) {
  125. if(cls == 0) {
  126. cls = 1;
  127. $(".hwzt").text('连接关闭!');
  128. $("#top-search li i").removeClass("active");
  129. reconnect();
  130. }
  131. };
  132. //连接发生错误的回调方法
  133. ws.onerror = function(evt) {
  134. //产生异常
  135. $(".hwzt").text('连接出现异常!');
  136. console.log(ws);
  137. if(ws == null || ws.readyState != ws.OPEN) {
  138. console.log(new Date() + "开始重连");
  139. reconnect();
  140. }
  141. }
  142. }
  143. //重连
  144. function reconnect() {
  145. if(lockReconnect) return;
  146. lockReconnect = true;
  147. //没连接上会一直重连,设置延迟避免请求过多
  148. setTimeout(function() {
  149. console.log(new Date() + " " + "重连中……");
  150. createWebSocket("ws://" + huayi.config.socket_ip + ":" + huayi.config.socket_port);
  151. lockReconnect = false;
  152. }, 2000);
  153. }
  154. //发送
  155. function Send() {
  156. if(ws.readyState != ws.OPEN) {
  157. reconnect();
  158. }
  159. if(ws.readyState == ws.OPEN) {
  160. var myDate = new Date();
  161. console.log(new Date() + " send " + JSON.stringify(scoketDatas));
  162. ws.send(JSON.stringify(scoketDatas));
  163. }
  164. }
  165. //心跳检测
  166. var heartCheck = {
  167. timeout: 25000, //25秒
  168. timeoutObj: null,
  169. serverTimeoutObj: null,
  170. reset: function() {
  171. clearTimeout(this.timeoutObj);
  172. clearTimeout(this.serverTimeoutObj);
  173. return this;
  174. },
  175. start: function() {
  176. var self = this;
  177. this.timeoutObj = setTimeout(function() {
  178. //这里发送一个心跳,后端收到后,返回一个心跳消息,
  179. //onmessage拿到返回的心跳就说明连接正常
  180. scoketDatas.Type = "Heart";
  181. Send();
  182. self.serverTimeoutObj = setTimeout(function() { //如果超过一定时间还没重置,说明后端主动断开了
  183. ws.close(); //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
  184. }, self.timeout)
  185. }, this.timeout)
  186. }
  187. }
  188. //签入
  189. function LoginBack() {
  190. $("#top-search li i").removeClass("active");
  191. $(".Logout").addClass("active");
  192. $(".SayBusy").addClass("active");
  193. $(".MakeCall").addClass("active");
  194. $(".zxzt").removeClass("br").addClass("bl");
  195. $(".fwzt").removeClass("br").addClass("bl");
  196. $(".hwzt").text('空闲');
  197. //弹出 相关计划任务
  198. // btn_joinTask().then(function(){
  199. // //签入成功后 显示右上角 当前参与任务信息
  200. // $('#task_real_info').show();
  201. // //绑定切换按钮
  202. // $(document).off('click', '#btn_switching', switchingTask);
  203. // $(document).on('click', '#btn_switching', switchingTask);
  204. // //获取当前任务信息
  205. // getTaskRealInfo();
  206. // if(taskRealInfoTimer) {
  207. // clearInterval(taskRealInfoTimer); //停止刷新数据
  208. // }
  209. // isTaskTimerOn = true;
  210. // //每间隔 huayi.config.taskRealInfoTime 刷新数据
  211. // refreshTaskRealInfo(huayi.config.taskRealInfoTime);
  212. // });
  213. }
  214. //签出
  215. function LogoutBack() {
  216. layer.msg('签出成功!');
  217. $("#top-search li i").removeClass("active");
  218. $(".Login").addClass("active");
  219. $(".zxzt").removeClass("bl").addClass("br");
  220. $(".fwzt").removeClass("bl").addClass("br");
  221. $(".hwzt").text('');
  222. isTaskTimerOn = false;
  223. //停止刷新数据
  224. clearInterval(taskRealInfoTimer);
  225. //签出成功后 隐藏右上角 当前参与任务信息
  226. $('#task_real_info').hide();
  227. //取消绑定切换按钮
  228. $(document).off('click', '#btn_switching', switchingTask);
  229. }
  230. //来电
  231. function IncomingBack(data) {
  232. //组id和group一致是正常弹屏;不一致是预测外呼弹屏;
  233. var openUrl = '';
  234. var openTxt = '';
  235. // if(data.TaskIcon === window.localStorage.getItem("group")) {
  236. openUrl = './callScreen/callScreen.html';
  237. openTxt = '来电弹屏';
  238. // } else {
  239. // openUrl = './autoCallScreen/autoCallScreen.html';
  240. // openTxt = '自动外呼弹屏';
  241. // }
  242. var p = '<a href="javascript:;" class="active J_menuTab" data-id="' + openUrl + '?tel=' + data.Number + '&CallID=' + data.CallID + '">' + openTxt + data.Number + ' <i class="glyphicon glyphicon-remove-sign"></i></a>';
  243. $(".J_menuTab").removeClass("active");
  244. var nif = '<iframe class="J_iframe J_iframeNew" name="iframe' + data.CallID + '" width="100%" height="100%" src="' + openUrl + '?Number=' + data.Number + '&CallID=' + data.CallID + '" frameborder="0" data-id="' + openUrl + '?tel=' + data.Number + '&CallID=' + data.CallID + '" seamless></iframe>';
  245. $(".J_mainContent").find("iframe.J_iframe").hide().parents(".J_mainContent").append(nif);
  246. $(".J_menuTabs .page-tabs-content").append(p);
  247. hidTel = data.Number;
  248. hidCallID = data.CallID;
  249. }
  250. //挂断
  251. function DropCallBack() {
  252. $("#top-search li i").removeClass("active");
  253. $(".Logout").addClass("active");
  254. $(".SayBusy").addClass("active");
  255. $(".MakeCall").addClass("active");
  256. }
  257. //线路状态通知
  258. function LineStateAgentBack(data) {
  259. //var obj = $("iframe:visible")
  260. //0分机不可用,1空闲,2摘机等待拨号,3正在拨号,4呼出振铃,5来电振铃,6通话中,7播放忙音中,8移除IP分机,9通话保持中
  261. if(data.State == '0') {
  262. $(".hwzt").text('分机不可用'); //左下角状态显示
  263. $(".fwzt").removeClass("bl").addClass("br"); //话机状态灯
  264. $(".zxzt").removeClass("bl").addClass("br"); //坐席状态灯
  265. }
  266. if(data.State == '1') {
  267. if($("#isml").val() == 1) {
  268. $(".hwzt").text('置忙'); //左下角状态显示
  269. $(".zxzt").removeClass("bl").addClass("br");
  270. } else {
  271. $(".hwzt").text('空闲'); //左下角状态显示
  272. $(".zxzt").removeClass("br").addClass("bl");
  273. }
  274. $(".fwzt").removeClass("br").addClass("bl");
  275. if(window.frames['iframe' + hidCallID + '']) {
  276. window.frames['iframe' + hidCallID + ''].clearInter();
  277. }
  278. $("#top-search li i").removeClass("active");
  279. $(".Logout").addClass("active");
  280. if($("#isml").val() == 0) {
  281. $(".SayBusy").addClass("active");
  282. } else {
  283. $(".SayFree").addClass("active");
  284. }
  285. $(".MakeCall").addClass("active");
  286. }
  287. if(data.State == '2') {
  288. $(".hwzt").text('摘机等待拨号'); //左下角状态显示
  289. }
  290. if(data.State == '3') {
  291. $(".hwzt").text('正在拨号'); //左下角状态显示
  292. }
  293. if(data.State == '4') {
  294. $(".hwzt").text('呼出振铃'); //左下角状态显示
  295. }
  296. if(data.State == '5') {
  297. $(".hwzt").text('来电振铃'); //左下角状态显示
  298. $(".fwzt").removeClass("br").addClass("bl"); //话机状态灯
  299. $(".zxzt").removeClass("bl").addClass("br"); //坐席状态灯
  300. }
  301. if(data.State == '6') {
  302. // debugger
  303. $(".hwzt").text('通话中'); //左下角状态显示
  304. $(".fwzt").removeClass("bl").addClass("br");
  305. $(".zxzt").removeClass("bl").addClass("br");
  306. $("#top-search li i").removeClass("active");
  307. $(".DropCall").addClass("active");
  308. $(".Hold").addClass("active");
  309. $(".Transfer").addClass("active");
  310. $(".Consult").addClass("active");
  311. $(".Meeting").addClass("active");
  312. if(window.frames['iframe' + hidCallID + '']) {
  313. // setTimeout(window.frames['iframe' + hidCallID + ''].calling(), 500); /*因软电话设置为 自动应答 通话时间不计时问题*/
  314. window.frames['iframe' + hidCallID + ''].calling(); /*因软电话设置为 自动应答 通话时间不计时问题*/
  315. }
  316. }
  317. if(data.State == '7') {
  318. $(".hwzt").text('播放忙音中'); //左下角状态显示
  319. }
  320. if(data.State == '8') {
  321. $(".hwzt").text('移除IP分机'); //左下角状态显示
  322. }
  323. if(data.State == '9') {
  324. $(".hwzt").text('通话保持中'); //左下角状态显示
  325. }
  326. }
  327. //外呼
  328. function MakeCallBack() {
  329. $("#top-search li i").removeClass("active");
  330. $(".DropCall").addClass("active");
  331. //20180920新增
  332. $(".Meeting").addClass("active");
  333. $(".Transfer").addClass("active");
  334. $(".Consult").addClass("active");
  335. $(".Hold").addClass("active");
  336. }
  337. /**
  338. * 置忙置闲
  339. * sayOption (点击置忙置闲后的返回值)
  340. * */
  341. function SetState(sayOption) {
  342. if(sayOption.State == '5') {
  343. $(".SayBusy").removeClass("active");
  344. $(".SayFree").addClass("active");
  345. $(".zxzt").removeClass("bl").addClass("br");
  346. $(".hwzt").text('置忙');
  347. $("#isml").val(1);
  348. }
  349. if(sayOption.State == '2') {
  350. $(".SayBusy").addClass("active");
  351. $(".SayFree").removeClass("active");
  352. $(".zxzt").removeClass("br").addClass("bl");
  353. $(".hwzt").text('空闲');
  354. $("#isml").val(0);
  355. }
  356. }
  357. //置忙
  358. function SayBusyBack() {
  359. $(".SayBusy").removeClass("active");
  360. $(".SayFree").addClass("active");
  361. $("#isml").val(1)
  362. }
  363. //坐席班长置闲
  364. function SayFreeBack() {
  365. $(".SayBusy").addClass("active");
  366. $(".SayFree").removeClass("active");
  367. $(".zxzt").removeClass("br").addClass("bl"); // 坐席状态指示
  368. $(".hwzt").text('空闲'); // 坐席状态指示
  369. $("#isml").val(0)
  370. }
  371. //多方通话
  372. function MeetingBack() {
  373. }
  374. //转移
  375. function TransferBack() {
  376. $("#top-search li i").removeClass("active");
  377. $(".Logout").addClass("active");
  378. $(".SayBusy").addClass("active");
  379. $(".MakeCall").addClass("active");
  380. }
  381. //协商呼叫
  382. function ConsultBack() {
  383. // console.log('.....协商呼叫成功!....');
  384. layer.confirm('请您确认转移或者挂机?', {
  385. icon: 3,
  386. btn: ['转移', '挂机'], //按钮
  387. }, function(index, layero) {
  388. // console.log('转移');
  389. scoketDatas = {
  390. "Type": "ConfirmTransfer",
  391. "AgentID": window.localStorage.getItem('userCode'),
  392. "AgentExten": window.localStorage.getItem("extno"),
  393. "EndParmer": "1" //1.转移 3.将对方挂断
  394. };
  395. Send();
  396. layer.close(index);
  397. }, function(index) {
  398. // console.log('挂机');
  399. scoketDatas = {
  400. "Type": "ConfirmTransfer",
  401. "AgentID": window.localStorage.getItem('userCode'),
  402. "AgentExten": window.localStorage.getItem("extno"),
  403. "EndParmer": "3" //1.转移 3.将对方挂断
  404. };
  405. Send();
  406. });
  407. }
  408. //保持
  409. function HoldBack() {
  410. $(".Hold").removeClass("active");
  411. $(".Retrieve").addClass("active");
  412. }
  413. //接回
  414. function RetrieveBack() {
  415. $(".Hold").addClass("active");
  416. $(".Retrieve").removeClass("active");
  417. }
  418. //录音返回
  419. function RecordPathBack(data) {
  420. // $(".hidCallID").val(data.CallID);
  421. // if(hidTel) {
  422. // $.post(huayi.config.callcenter_url + 'CallInScreen/UpdateLY', {
  423. // callid: data.CallID,
  424. // path: data.RecPath,
  425. // }, function(result) {
  426. // result = JSON.parse(result);
  427. // if(result.state.toLowerCase() == "success") {}
  428. // })
  429. // }
  430. }
  431. //更新坐席监控内坐席的状态
  432. function updateSeatMonitorlists() {
  433. top.$("iframe:visible")[0].contentWindow.getSeatsRealStates();
  434. }
  435. //获取 错误信息
  436. //errCode 错误代码
  437. function getErrTips(errCode) {
  438. var errTips = '';
  439. switch(errCode) {
  440. case 9011:
  441. errTips = '分机号不存在';
  442. break;
  443. case 9012:
  444. errTips = '分机号已绑定';
  445. break;
  446. case 9013:
  447. errTips = '坐席已登陆';
  448. break;
  449. case 9058:
  450. errTips = '授权验证失败';
  451. break;
  452. case 10:
  453. errTips = '没有找到线路';
  454. break;
  455. case 11:
  456. errTips = '线路忙';
  457. break;
  458. case 12:
  459. errTips = '线路非空闲';
  460. break;
  461. case 13:
  462. errTips = '线路非振铃';
  463. break;
  464. case 14:
  465. errTips = '非通话';
  466. break;
  467. case 15:
  468. errTips = '线路空闲';
  469. break;
  470. case 16:
  471. errTips = '线路已邦定任务';
  472. break;
  473. case 50:
  474. errTips = '对端线路空';
  475. break;
  476. case 51:
  477. errTips = '对端线路忙';
  478. break;
  479. case 52:
  480. errTips = '非分机';
  481. break;
  482. case 20:
  483. errTips = '没找到座席';
  484. break;
  485. case 21:
  486. errTips = '坐席绑定异常';
  487. break;
  488. case 22:
  489. errTips = '坐席非空闲';
  490. break;
  491. case 30:
  492. errTips = '被监控中';
  493. break;
  494. case 31:
  495. errTips = '错误指令';
  496. break;
  497. case 100:
  498. errTips = '线路关联任务失败';
  499. break;
  500. case 101:
  501. errTips = '执行操作失败';
  502. break;
  503. case 102:
  504. errTips = '呼叫取消';
  505. break;
  506. case 103:
  507. errTips = '挂机失败';
  508. break;
  509. case 104:
  510. errTips = '禁止自呼';
  511. break;
  512. case 110:
  513. errTips = '不是保持状态';
  514. break;
  515. case 111:
  516. errTips = '不在放音';
  517. break;
  518. case 250:
  519. errTips = '正常挂机';
  520. break;
  521. case 251:
  522. errTips = '用户忙';
  523. break;
  524. case 252:
  525. errTips = '未接听';
  526. break;
  527. case 253:
  528. errTips = '没响应';
  529. break;
  530. case 254:
  531. errTips = '拒接';
  532. break;
  533. case 255:
  534. errTips = '未没注册';
  535. break;
  536. case 259:
  537. errTips = '未知';
  538. break;
  539. default:
  540. errTips = errCode;
  541. break;
  542. }
  543. return errTips;
  544. }