説明なし

main.js 15KB

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