No Description

main.js 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. if(typeof console == "undefined") {
  2. this.console = {
  3. log: function(msg) {}
  4. };
  5. }
  6. // 如果浏览器不支持websocket,会使用这个flash自动模拟websocket协议,此过程对开发者透明
  7. WEB_SOCKET_SWF_LOCATION = "./js/websocket/WebSocketMain.swf";
  8. // 开启flash的websocket debug
  9. WEB_SOCKET_DEBUG = true;
  10. var ws, n = 0,
  11. timer;
  12. var lockReconnect = false; //避免重复连接
  13. var obj = {};
  14. var Statess;
  15. var cls = 0;
  16. var dataLength; //坐席数量
  17. let distributionData = []; //话务数据统计数据
  18. let callDate = []; //话务坐席数据
  19. let hwcount;
  20. let jtcount;
  21. let daySeatName = ['登陆坐席数量', '呼叫排队数量', '话务量', '呼入接通量'];
  22. let callSeatStateName = ['等待', '通话中', '话后处理', '置忙', '空闲']
  23. var lasttime = new Date().getTime();
  24. let callSeatStateData;
  25. let locationNum = 0;
  26. //坐席分析
  27. $(document).ready(function() {
  28. agentCount();
  29. getPhoneCount();
  30. GetDistributionCount()
  31. setInterval(function() {
  32. agentCount();
  33. getPhoneCount();
  34. GetDistributionCount();
  35. }, 120000)
  36. })
  37. //坐席数量
  38. function agentCount() {
  39. $.ajax({
  40. url: huayi.config.callcenter_url + "SeatMonitoring/getlist",
  41. data: {
  42. token: $.cookie("token"),
  43. },
  44. async: false,
  45. dataType: 'json',
  46. success: function(res) {
  47. dataLength = res.data.length;
  48. }
  49. })
  50. }
  51. //话务量接通量
  52. function getPhoneCount() {
  53. $.ajax({
  54. url: huayi.config.callcenter_url + "/InfoNew/GetTrafficCountByNow",
  55. data: {
  56. token: $.cookie("token"),
  57. },
  58. async: false,
  59. dataType: 'json',
  60. success: function(res) {
  61. hwcount = res.data.hw[0].hwcount;
  62. jtcount = res.data.hw[0].jtcount
  63. }
  64. })
  65. }
  66. //话务数据统计
  67. function GetDistributionCount() {
  68. $.ajax({
  69. url: huayi.config.callcenter_url + "InfoNew/GetDistributionCount",
  70. data: {
  71. token: $.cookie("token"),
  72. },
  73. async: false,
  74. dataType: 'json',
  75. success: function(res) {
  76. distributionData = [];
  77. let hw = res.data.hw[0];
  78. let gd = res.data.gd[0];
  79. Object.keys(hw).forEach((key, n) => {
  80. if(key == 'hrjtcount') {
  81. distributionData.push({
  82. name: '呼入接通数量',
  83. value: hw[key]
  84. })
  85. }
  86. if(key == 'hcjtcount') {
  87. distributionData.push({
  88. name: '呼出接通数量',
  89. value: hw[key]
  90. })
  91. }
  92. if(key == 'hrtime') {
  93. distributionData.push({
  94. name: '呼入通话时长',
  95. value: hw[key]
  96. })
  97. }
  98. if(key == 'hctime') {
  99. distributionData.push({
  100. name: '呼出通话时长',
  101. value: hw[key]
  102. })
  103. }
  104. if(key == 'pjhrtime') {
  105. distributionData.push({
  106. name: '平均呼入通时',
  107. value: hw[key]
  108. })
  109. }
  110. if(key == 'pjhctime') {
  111. distributionData.push({
  112. name: '平均呼出通时',
  113. value: hw[key]
  114. })
  115. }
  116. if(key == 'fqcount') {
  117. distributionData.push({
  118. name: '放弃呼叫量',
  119. value: hw[key]
  120. })
  121. }
  122. if(key == 'hscount') {
  123. distributionData.push({
  124. name: '日呼损量',
  125. value: hw[key]
  126. })
  127. }
  128. if(key == 'sdhscount') {
  129. distributionData.push({
  130. name: '时段呼损量',
  131. value: hw[key]
  132. })
  133. }
  134. })
  135. Object.keys(gd).forEach((key, n) => {
  136. if(key == 'dxcount') {
  137. distributionData.push({
  138. name: '短信受理量',
  139. value: gd[key]
  140. })
  141. }
  142. if(key == 'wxcount') {
  143. distributionData.push({
  144. name: '微信受理量',
  145. value: gd[key]
  146. })
  147. }
  148. if(key == 'wbcount') {
  149. distributionData.push({
  150. name: '微博受理量',
  151. value: gd[key]
  152. })
  153. }
  154. if(key == 'apcount') {
  155. distributionData.push({
  156. name: 'APP受理量',
  157. value: gd[key]
  158. })
  159. }
  160. if(key == 'xxcount') {
  161. distributionData.push({
  162. name: '市长信箱受理量',
  163. value: gd[key]
  164. })
  165. }
  166. })
  167. distributionData.unshift({
  168. name: '登陆坐席数量',
  169. value: 0
  170. })
  171. distributionData.unshift({
  172. name: '呼叫排队数量',
  173. value: 0
  174. })
  175. }
  176. })
  177. }
  178. Connect()
  179. //创建scoket连接
  180. function createWebSocket() {
  181. try {
  182. Connect();
  183. } catch(e) {
  184. reconnect();
  185. }
  186. }
  187. //连接
  188. function Connect() {
  189. // debugger
  190. ws = new WebSocket("ws://" + huayi.config.socket_ip + ":" + huayi.config.socket_port);
  191. ws.onopen = function() {
  192. console.log(new Date() + " " + "建立连接");
  193. //心跳检测重置
  194. heartCheck.reset().start();
  195. cls = 0;
  196. $(".Login").addClass("active");
  197. lasttime = new Date().getTime();
  198. // debugger
  199. //话务坐席情况
  200. obj = {
  201. "Type": 'GetAgentDetail', //话后处理时长设置,0代表一致话后处理,除非发送置闲 (按照历史习惯,字符串形式)
  202. };
  203. Send();
  204. };
  205. //接收到消息的回调方法
  206. ws.onmessage = function(evt) {
  207. //如果获取到消息,心跳检测重置
  208. //拿到任何消息都说明当前连接是正常的
  209. heartCheck.reset().start();
  210. var myDate = new Date();
  211. data = JSON.parse(evt.data)[0];
  212. if(data.Type == "GetAgentDetail") {
  213. distributionData[0].value = data.WaiteCallCount;
  214. distributionData[1].value = data.AgentOnlineCount
  215. let disStr = ''
  216. distributionData.forEach(function(v, n) {
  217. disStr += '<li><label>' + v.name + '</label><span class="num_roll" id="">' + parseInt(v.value % 100000 / 10000) +
  218. '</span><span class="num_roll" id="">' + parseInt(v.value % 10000 / 1000) +
  219. '</span><span class="num_roll" id="">' + parseInt(v.value % 1000 / 100) +
  220. '</span><span class="num_roll"id="">' + parseInt((v.value % 100) / 10) +
  221. '</span><span class="num_roll" id="">' + parseInt(v.value % 10) + '</span></li>'
  222. })
  223. $('.callTraffic .data_info').html(disStr)
  224. callDate = [Number(data.AgentOnlineCount), Number(data.WaiteCallCount), Number(hwcount), Number(jtcount)]
  225. const outLine = dataLength - data.AgentOnlineCount;
  226. callSeatStateData = [data.WaiteCallCount, data.AgentSpeakCount, data.AgentProcessingCount, data.AgentReposeCount, data.AgentFreeCount]
  227. hotThingsChart('callSeatState', callSeatStateName, callSeatStateData, 500)
  228. }
  229. if(data) {
  230. var rlt = data.Result;
  231. if(rlt == true) {
  232. var type = data.Type;
  233. switch(type.toLowerCase()) {
  234. case "subscribe":
  235. SubScribeBack();
  236. break; //监测
  237. case "subscribecancel":
  238. SubScribeCancelBack();
  239. break; //停止监测
  240. case "agentstate":
  241. AgentStateBack(data);
  242. break; //坐席状态
  243. case "linestate":
  244. // LineStateBack(data);
  245. break; //线路状态
  246. }
  247. } else {
  248. if(rlt == false) {
  249. //layer.confirm('操作失败!', {
  250. // btn: ['确定']
  251. //});
  252. $(".hwzt").text('操作失败!');
  253. } else {
  254. $(".hwzt").text(rlt);
  255. //layer.confirm(rlt, {
  256. // btn: ['确定']
  257. //});
  258. switch(data.Type.toLowerCase()) {
  259. case "waitcount":
  260. backstageQueue(data);
  261. break; //后台排队
  262. }
  263. }
  264. }
  265. }
  266. }
  267. };
  268. //连接关闭的回调方法
  269. ws.onclose = function(evt) {
  270. if(cls == 0) {
  271. cls = 1;
  272. //console.log("连接关闭!");
  273. //layer.confirm('连接关闭!', {
  274. // btn: ['确定']
  275. //});
  276. $(".hwzt").text('连接关闭!');
  277. $("#top-search li i").removeClass("active");
  278. reconnect();
  279. }
  280. };
  281. //连接发生错误的回调方法
  282. ws.onerror = function(evt) {
  283. //产生异常
  284. $(".hwzt").text('连接出现异常!');
  285. console.log(ws);
  286. if(ws == null || ws.readyState != ws.OPEN) {
  287. console.log(new Date() + "开始重连");
  288. reconnect();
  289. }
  290. };
  291. //}
  292. //重连
  293. function reconnect() {
  294. if(lockReconnect) return;
  295. lockReconnect = true;
  296. //没连接上会一直重连,设置延迟避免请求过多
  297. setTimeout(function() {
  298. console.log(new Date() + " " + "重连中……");
  299. createWebSocket("ws://" + huayi.config.socket_ip + ":" + huayi.config.socket_port);
  300. lockReconnect = false;
  301. }, 2000);
  302. }
  303. //发送
  304. function Send() {
  305. if(ws.readyState != ws.OPEN) {
  306. reconnect();
  307. }
  308. if(ws.readyState == ws.OPEN) {
  309. console.log(new Date() + " send " + JSON.stringify(obj));
  310. ws.send(JSON.stringify(obj));
  311. }
  312. }
  313. //心跳检测
  314. var heartCheck = {
  315. timeout: 25000, //25秒
  316. timeoutObj: null,
  317. serverTimeoutObj: null,
  318. reset: function() {
  319. clearTimeout(this.timeoutObj);
  320. clearTimeout(this.serverTimeoutObj);
  321. return this;
  322. },
  323. start: function() {
  324. var self = this;
  325. this.timeoutObj = setTimeout(function() {
  326. //这里发送一个心跳,后端收到后,返回一个心跳消息,
  327. //onmessage拿到返回的心跳就说明连接正常
  328. obj.Type = "Heart";
  329. Send();
  330. self.serverTimeoutObj = setTimeout(function() { //如果超过一定时间还没重置,说明后端主动断开了
  331. ws
  332. .close(); //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
  333. }, self.timeout)
  334. }, this.timeout)
  335. }
  336. }
  337. //开始监测
  338. function SubScribeBack() {
  339. $(".star_btn").css("background-color", 'rgb(1,216,235)');
  340. $(".stop_btn").css("background-color", '#064695');
  341. }
  342. //取消监测
  343. function SubScribeCancelBack() {
  344. $(".people_list").show()
  345. $(".people_list i").hide()
  346. $(".stop_btn").css("background-color", 'rgb(1,216,235)');
  347. $(".star_btn").css("background-color", '#064695');
  348. $(".stop_btn").addClass("dis");
  349. $(".star_btn").removeClass("dis");
  350. $(".zx_people i").removeClass().addClass("lx");
  351. $(".zx_people i").removeClass().addClass("lx").attr("zx_item", "0").attr("xl_item", "0");
  352. }
  353. //班长监测返回状态
  354. //坐席状态
  355. function AgentStateBack(data) {
  356. // console.log(data)
  357. var sts = "";
  358. switch(data.State) {
  359. case "0":
  360. sts = "lx";
  361. break; //离线
  362. case "1":
  363. break; //登录中
  364. case "2":
  365. sts = "kx";
  366. break; //空闲
  367. case "3":
  368. sts = "th";
  369. break; //通话中
  370. case "4":
  371. sts = "hh";
  372. break; //话后处理中
  373. case "5":
  374. sts = "ml";
  375. break; //小休
  376. case "6":
  377. sts = "zl";
  378. break; //被请求
  379. case "7":
  380. sts = "lx";
  381. break; //注销
  382. }
  383. if(data.AgentID * 1 < 10) {
  384. data.AgentID = '0' + data.AgentID;
  385. }
  386. var ele = $("." + data.AgentID).find("i");
  387. if(sts) {
  388. ele.removeClass().addClass(sts);
  389. }
  390. ele.attr("zx_item", data.State);
  391. if($(".zxtp .g_nums").text() == data.AgentID) {
  392. if(sts) {
  393. $(".zxtp i").removeClass().addClass(sts);
  394. }
  395. }
  396. if(data.State === "2") {
  397. // console.log(data.AgentID,data.State,data.Group,)
  398. }
  399. $(".people_list dl dt").each(function() {
  400. // console.log($(this).find("i").attr("zxGroup"))
  401. // if($(this).find("i").attr("class")==='lx'){
  402. //// console.log($(this).find("i").attr("zxGroup"))
  403. //// console.log(data.AgentID,$(this).find("i").attr("zxGroup"))
  404. // if ($(this).find("i").attr("zxGroup")==data.Group) {
  405. // $(this).show()
  406. // $(this).find("i").show()
  407. // $(this).find("i").removeClass().addClass("dg");
  408. // console.log($(this).find("i").attr("zxGroup"))
  409. // }
  410. // if($(this).find("i").attr("class")==='lx'){
  411. // $(this).find("i").hide()
  412. // }
  413. // }else{
  414. // $(this).find("i").show()
  415. // }
  416. // $(this).find("i").removeClass().addClass("dg");
  417. $(this).find("i").show()
  418. })
  419. // $(".people_list dl dt").eq(0).before($('.' + data.AgentID))
  420. // $(document.getElementsByClassName('seatList')[locationNum]).before($('.' + data.AgentID))
  421. }
  422. //线路状态
  423. function LineStateBack(data) {
  424. //data.Type,data,
  425. // console.log(data.AgentID,data.State)
  426. if(data.State.indexOf("|") != -1) {
  427. arr = data.State.split("|");
  428. data.State = arr[0];
  429. }
  430. if(data.AgentID * 1 < 10) {
  431. data.AgentID = '0' + data.AgentID;
  432. }
  433. var ele = $("." + data.AgentID).find("i");
  434. var sts = "";
  435. switch(data.State) {
  436. case "0":
  437. sts = "lx";
  438. break; //分机不可用
  439. case "1":
  440. if(!(ele.hasClass("hh") || ele.hasClass("ml"))) {
  441. sts = "kx";
  442. }
  443. break; //空闲
  444. case "2":
  445. sts = "ml";
  446. break; //摘机等待拨号
  447. case "3":
  448. sts = "ml";
  449. break; //正在拨号
  450. case "4":
  451. sts = "zl";
  452. break; //呼出振铃
  453. case "5":
  454. sts = "zl";
  455. break; //来电振铃
  456. case "6":
  457. sts = "th";
  458. break; //通话中
  459. case "7":
  460. sts = "ml";
  461. break; //播放忙音中
  462. case "8":
  463. sts = "th";
  464. break; //通话保持中
  465. case "9":
  466. break; //话机移除
  467. case "10":
  468. break; //保持/空闲
  469. case "11":
  470. break; //保持/摘机等待拨号
  471. case "12":
  472. break; //保持/正在拨号
  473. case "13":
  474. break; //保持/呼出振铃
  475. case "14":
  476. break; //保持/通话中
  477. }
  478. if(sts) {
  479. ele.removeClass().addClass(sts);
  480. }
  481. ele.attr("xl_item", data.State);
  482. if($(".zxtp .g_nums").text() == data.AgentID) {
  483. if(sts) {
  484. $(".zxtp i").removeClass().addClass(sts);
  485. }
  486. }
  487. }
  488. function toDub(i) {
  489. return i < 10 ? "0" + i : "" + i;
  490. }
  491. //默认记忆上次是否签入,是否置忙置闲 0表示已签入 空闲,1表示签入置忙,2表示签出
  492. function SetStateCookie(state) {
  493. $.cookie("socket_state", state);
  494. }
  495. function backstageQueue(data) {
  496. var obj = $("iframe:visible")
  497. // if (obj.attr("data-id") == "index_v1.html") {
  498. window.frames[obj.attr("name")].realTimeMonitorQueue(data.WaitCount);
  499. // }
  500. }
  501. //在线坐席信息
  502. function GetAgentListBack(data) {
  503. $.ajax({
  504. type: "get",
  505. url: huayi.config.callcenter_url + "SeatMonitoring/GetAgentList",
  506. async: true,
  507. dataType: 'json',
  508. data: {
  509. "token": $.cookie("token")
  510. },
  511. success: function(result) {
  512. var user = result.data;
  513. $(user).each(function(j, m) {
  514. $(data.AgentList).each(function(k, g) {
  515. if(g.AgentID == m.UserCode) {
  516. g.userName = m.UserName;
  517. }
  518. })
  519. })
  520. $(data.AgentList).each(function(k, m) {
  521. var strr = '';
  522. switch(m.State) {
  523. case "0":
  524. strr = "离线";
  525. break; //离线
  526. case "1":
  527. break; //登录中
  528. case "2":
  529. strr = "空闲";
  530. break; //空闲
  531. case "3":
  532. strr = "通话中";
  533. break; //通话中
  534. case "4":
  535. strr = "话后处理中";
  536. break; //话后处理中
  537. case "5":
  538. strr = "忙碌";
  539. break; //小休
  540. case "6":
  541. strr = "振铃";
  542. break; //被请求
  543. case "7":
  544. strr = "注销";
  545. break; //注销
  546. }
  547. var html = '<tr fjh="' + m.AgentExten + '">' +
  548. '<td>' + (m.userName ? '' : m.userName) + '</td>' //姓名
  549. +
  550. '<td>' + m.AgentID + '</td>' //工号
  551. +
  552. '<td>' + m.AgentExten + '</td>' //分机号
  553. +
  554. '<td class=" ' + m.UserCode + 'state">' + strr + '</td>' //状态
  555. +
  556. '</tr>';
  557. $(html).appendTo("#zxTable tbody");
  558. })
  559. }
  560. });
  561. }
  562. //获取当前的日期时间 格式“yyyy-MM-dd HH:mm:ss”
  563. function getNowFormatDate() {
  564. var date = new Date();
  565. var seperator1 = "-";
  566. var seperator2 = ":";
  567. var month = date.getMonth() + 1;
  568. var strDate = date.getDate();
  569. if(month >= 1 && month <= 9) {
  570. month = "0" + month;
  571. }
  572. if(strDate >= 0 && strDate <= 9) {
  573. strDate = "0" + strDate;
  574. }
  575. var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate +
  576. " " + date.getHours() + seperator2 + date.getMinutes() +
  577. seperator2 + date.getSeconds();
  578. return currentdate;
  579. }
  580. var iswebcloase = 1;
  581. window.onunload = function() {
  582. if(iswebcloase) {
  583. iswebcloase = 0;
  584. if(ws.readyState == ws.OPEN) {
  585. obj.Type = 'Logout';
  586. Send();
  587. ws.onclose();
  588. }
  589. }
  590. }
  591. window.onbeforeunload = function() {
  592. if(iswebcloase) {
  593. iswebcloase = 0;
  594. if(ws.readyState == ws.OPEN) {
  595. obj.Type = 'Logout';
  596. Send();
  597. ws.onclose();
  598. }
  599. }
  600. }