| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926 |
- /*
- * 呼叫中心电话工具条
- * author: easycallcenter365@126.com
- * 2025-04-08
- */
- // 导入 jQuery
- import $ from './jquery-1.11.0.js';
- function _phoneBarObserver(){
- if(!(this instanceof _phoneBarObserver)){
- return new _phoneBarObserver();
- }
- this.listeners = {}
- };
- _phoneBarObserver.prototype = {
- on: function (key, callback) { this.addListener(key, callback); },
- off: function (key, callback) { this.removeListener(key, callback); },
- addListener: function (key, callback) {
- if(!this.listeners[key]) {
- this.listeners[key] = [];
- }
- this.listeners[key].push(callback);
- },
- removeListener: function (key, callback) {
- if(this.listeners[key]) {
- if(callback) {
- const index = this.listeners[key].indexOf(callback);
- if (index > -1) {
- this.listeners[key].splice(index, 1);
- }
- }else {
- this.listeners[key] = [];
- }
- }
- },
- notifyAll: function (key, info) {
- if(!this.listeners[key]) return;
- for (var i = 0; i < this.listeners[key].length; i++) {
- if (typeof this.listeners[key][i] === 'function') {
- this.listeners[key][i](info);
- }
- }
- },
- make: function (o) {
- for (var i in this) {
- o[i] = this[i];
- o.listeners = {}
- }
- }
- };
- //呼叫中心websocket通信对象
- "use strict";
- function ccPhoneBarSocket() {
- var observer = new _phoneBarObserver();
- observer.make(this);
- var _cc = this;
- var ws = null;
- var wsuri = null;
- var isConnected = false;
- /* 通话已建立 */
- var callConnected = false;
- /*
- * 是否可以发送视频通话邀请;
- */
- var canSendVideoReInvite = false;
- /**
- * 是否开启了坐席状态列表订阅
- * @type {boolean}
- */
- this.subscribeAgentListStarted = false;
- this.iframe = null;
- this.callConfig = {
- // 使用默认的UI,还是使用自定义的UI
- 'useDefaultUi': false,
- //呼叫控制服务器地址
- 'ipccServer': 'sip.ylrzcloud.com',
- //是否启用websocket安全连接
- 'enableWss' : true,
- //语音编码
- 'callCodec' : 'pcma',
- //是否发送心跳数据
- 'enableHeartBeat' : true,
- //送心跳数据的时间间隔; 秒;
- 'heartBeatIntervalSecs' : 16,
- // 工具条外呼时: 软电话和外呼通话,使用相同的语音编码,避免转码,从而提高性能;
- // 但是!: 如果客户端是网页电话,且外呼线路使用g729编码时,该参数需要设置为false,
- // 因为网页电话不支持g729编码; [此时会产生语音编码的转码]
- 'useSameAudioCodeForOutbound' : true,
- // 令牌
- 'loginToken' : '',
- // 网关列表, 如果是注册模式: 网关地址参数则填写为网关名称;
- // 安全起见,生产环境,需要把该参数加密为base64格式;
- 'gatewayList' : [
- {
- uuid : '01',
- updateTime : 1675953810492,
- gatewayAddr : '113.207.68.30:5543;external', // 网关地址 + 外呼环境[可选参数,默认为external];
- callerNumber : '02386990208', // 主叫号码
- calleePrefix : '', // 被叫前缀
- priority : 1, // 优先级
- concurrency : 1000, // 并发数
- register : false, // 是否注册模式
- audioCodec : 'g711' // 语音编码,可用选择项 g711、g729
- }
- ],
- 'gatewayEncrypted' : false,
- // 分机注册配置;
- //Freeswitch服务器地址
- 'fsServer' : '129.28.164.235:5060',
- // 分机账户
- 'extnum' : '1001',
- // 工号
- 'opnum' : 'admin',
- //业务组编号
- 'groupId' : '1',
- //全部业务组列表
- 'groups' : null,
- //全部坐席人员列表
- 'agentList' : null,
- 'extPassword': '0406f9d44bb8fe195a1ee2557bbeebf7', // 分机密码
- 'phoneType': 'EyeBeam', // 电话类型
- 'webPhoneUrl' : 'None',
- // 客户端软电话代理配置信息
- 'localHostProxyVersion' : 'v20221130_1736', // 本地代理软件的版本信息
- 'localHostProxyPort' : 8888 // 本地代理软件端口;
- };
- /**
- * 在指定html对象后追加新元素
- * @param newElement
- * @param targetElement
- */
- this.insertAfter = function(newElement,targetElement)
- {
- var parent = targetElement.parentNode;
- if(parent.lastChild === targetElement)
- {
- parent.appendChild(newElement);
- }else{
- parent.insertBefore(newElement,targetElement.nextSibling);
- }
- };
- this.trim = function (str) {
- return str.replace(/^\s\s*/,'').replace(/\s\s*$/, '');
- };
- this.getIsConnected = function(){
- return isConnected;
- };
- /**
- * 获取通话状态
- * @returns {boolean} true通话中,false通话未建立;
- */
- this.getCallConnected = function(){
- return callConnected;
- };
- /**
- * 设置通话状态;
- * @param value true通话中,false通话未建立
- * @returns {*}
- */
- this.setCallConnected = function(value){
- callConnected = value;
- };
- /**
- * 设置一个标志,指示是否可以发起视频通话;
- * 仅限通话为音频通话且通话已经接通时方可允许发起视频邀请;
- * @param value
- */
- this.setCanSendVideoReInvite = function(value){
- canSendVideoReInvite = value;
- };
- /**
- * 设置一个标志,指示是否可以发起视频通话;
- * @param value
- */
- this.getCanSendVideoReInvite = function(){
- return canSendVideoReInvite;
- };
- this.setHeartbeat = function()
- {
- setInterval(function(){
- //如果启用了心跳,而且用户已经登录上线,则发送心跳数据
- if(_cc.callConfig.enableHeartBeat && _cc.getIsConnected()){
- console.debug("try to send heartbeat.");
- var heartBeat = {};
- heartBeat.action="setHearBeat";
- heartBeat.body = "{}";
- _cc.sendMsg(heartBeat);
- }
- }, _cc.callConfig.heartBeatIntervalSecs * 1000);
- };
- this.loadScript = function(destUrl, callbackFunc){
- var script = document.createElement("script");
- script.type = "text/javascript";
- script.src = destUrl;
- if(null != callbackFunc){
- script.onload=function(){callbackFunc();}
- }
- document.getElementsByTagName('head')[0].appendChild(script);
- };
- // 初始化websocket连接参数
- this.initConfig = function(config) {
- //把config中的属性全部拷贝到callConfig中;
- for(var element in config) {
- this.callConfig[element] = config[element];
- }
- var _loginToken = this.callConfig["loginToken"];
- if(typeof(_loginToken) == "undefined" && _loginToken === "") {
- alert("电话工具条:无法获取 loginToken!");
- return;
- }
- console.log("callConfig:", JSON.stringify(this.callConfig));
- //线上enableWss: true 本地调试为false
- if(_cc.callConfig.enableWss){
- wsuri = 'wss://' + this.callConfig.ipccServer +
- '/call-center/websocketServer?' +
- '&loginToken=' + this.callConfig.loginToken;
- }else{
- wsuri = 'ws://129.28.164.235:1081/call-center/websocketServer?' +
- '&loginToken=' + this.callConfig.loginToken;
- }
- console.log("ipccServer url: " + wsuri);
- var ipccServerIpAddr = this.callConfig.ipccServer.split(":");
- if(this.callConfig.enableWss && this.checkIP(ipccServerIpAddr)){
- var tipsError = "ERROR! 启用了wss之后,必须使用域名访问websocketServer! " + this.callConfig.ipccServer;
- console.log(tipsError);
- alert(tipsError);
- }
- if(this.callConfig.enableHeartBeat) {
- _cc.setHeartbeat();
- }
- //var downLoadUrl = "http://192.168.66.71:81/soft/callcenter-soft/LocalHostProxy/LocalHostProxy-" +
- _cc.callConfig["localHostProxyVersion"] + ".zip";
- //console.log("客户端代理软件的下载地址:", downLoadUrl);
- //this.createIframe("http://127.0.0.1:8888/getVersion");
- if(_cc.callConfig["useDefaultUi"]){
- this.initPhoneBarUI();
- }
- };
- //检测ip地址是否合法;
- this.checkIP = function (ip)
- {
- var re = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/ ;
- return re.test(ip);
- };
- //断开到呼叫控制服务器的连接
- this.disconnect = function(){
- // 检查 WebSocket 是否存在且连接正常
- if (!ws || ws.readyState !== WebSocket.OPEN) {
- console.log('WebSocket 未连接或已关闭,无需发送断开指令');
- return;
- }
- var cmdInfo = {};
- cmdInfo.action="setAgentStatus";
- cmdInfo.body = {"cmd" : "disconnect", "args" : { "msg" : "disconnection opt triggered by js client." } };
- ws.send(JSON.stringify(cmdInfo));
- // 立即关闭 WebSocket 连接
- ws.close();
- };
- /**
- * 获取当前坐席登录的分机号码
- * @returns {string|*}
- */
- this.getExtNum = function(){
- return this.callConfig.extnum;
- };
- /**
- * 获取当前坐席登录的工号
- * @returns {string|*}
- */
- this.getOpNum = function(){
- return this.callConfig.opnum;
- };
- /**
- * 获取当前坐席的业务组编号
- * @returns {string|*}
- */
- this.getGroupId = function(){
- return this.callConfig.groupId;
- };
- /**
- * 获取全部业务组列表
- * @returns {string|*}
- */
- this.getGroups = function(){
- return JSON.parse(JSON.stringify(this.callConfig.groups));
- };
- this.findAgentByOpNum = function (opnum){
- if(_cc.callConfig.agentList == null) return null;
- for (var key in _cc.callConfig.agentList) {
- let item = _cc.callConfig.agentList[key];
- if(item["opnum"] === opnum){
- //add _arrayIndex property to record index
- item["_arrayIndex"] = key;
- return item;
- }
- }
- return null;
- };
- this.updateAgentList = function (agentList) {
- for (var key in agentList) {
- let item = agentList[key];
- var existItem = this.findAgentByOpNum(item["opnum"]);
- if(existItem != null){
- var newStatus = item["agentStatus"];
- var oldStatus = existItem["agentStatus"];
- var logoutTime = item["logoutTime"];
- if(logoutTime > 0){
- //删除元素
- console.info("delete offline user",item["opnum"], "index=", key);
- _cc.callConfig.agentList.splice(existItem["_arrayIndex"], 1);
- continue;
- }
- if(newStatus != oldStatus){
- existItem["agentStatus"] = newStatus;
- }
- }else{
- if(_cc.callConfig.agentList != null) {
- _cc.callConfig.agentList.push(item);
- }
- }
- }
- };
- //连接到呼叫控制服务器
- this.connect = function() {
- // 如果已经在连接中,直接返回
- if (ws && ws.readyState === WebSocket.CONNECTING) {
- console.log('[connect] WebSocket 正在连接中,请勿重复操作');
- return;
- }
- // 先关闭旧的连接,避免重复登录
- if (ws) {
- console.log('[connect] 检测到旧连接存在,先关闭旧连接');
- try {
- ws.close();
- } catch(e) {
- console.error('[connect] 关闭旧连接失败:', e);
- }
- ws = null;
- }
- if ('WebSocket' in window)
- ws = new WebSocket(wsuri);
- else {
- console.log('您的浏览器不支持 websocket,您无法使用本页面的功能!');
- return;
- }
- //收到消息
- ws.onmessage = function(evt) {
- console.log("recv msg from websocket server: ", evt.data);
- var msg = JSON.parse(evt.data);
- console.log("parsed json data:", msg);
- var resp_status = msg["status"];
- switch(resp_status) {
- case 200:
- isConnected = true;
- _cc.callConfig.extnum = msg.object["extnum"];
- _cc.callConfig.opnum = msg.object["opnum"];
- _cc.callConfig.groupId = msg.object["groupId"];
- _cc.callConfig.groups = msg.object["groups"];
- console.log('ipcc 连接成功.', 'connected_ipcc_server');
- // WebSocket 连接成功后自动设置为置忙状态,以便可以外呼
- _cc.setStatus(ccPhoneBarSocket.agentStatusEnum.busy);
- _cc.notifyAll(ccPhoneBarSocket.eventList.ws_connected, msg);
- break;
- default:
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.caller_hangup) ||
- parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.CONFERENCE_MODERATOR_HANGUP)) {
- _cc.setCallConnected(false);
- _cc.setCanSendVideoReInvite(false);
- _cc.callConfig.agentList = null;
- _cc.unSubscribeAgentList();
- // 重置呼叫标志
- _cc.isCalling = false;
- console.log("caller_hangup")
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.callee_hangup)) {
- // 重置呼叫标志
- _cc.isCalling = false;
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.callee_answered)) {
- _cc.setCallConnected(true);
- console.log("callee_answered")
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.new_inbound_call)) {
- _cc.setCallConnected(true);
- console.log("new_inbound_call")
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.caller_answered) ||
- parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.callee_answered)) {
- if (msg["object"]["callType"] === "audio") {
- _cc.setCanSendVideoReInvite(true);
- _cc.notifyAll(ccPhoneBarSocket.eventList.on_audio_call_connected, "audio call connected.")
- console.log("current callType is audio.")
- }
- if (msg["object"]["callType"] === "video") {
- _cc.setCanSendVideoReInvite(false);
- _cc.notifyAll(ccPhoneBarSocket.eventList.on_video_call_connected, "video call connected.")
- console.log("current callType is video.")
- }
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.customer_channel_hold)) {
- _cc.changeUiOnHold();
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.customer_channel_unhold)) {
- _cc.changeUiOnUnHold();
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.customer_on_hold_hangup)) {
- _cc.changeUiOnUnHold();
- $("#holdBtn").removeClass('on');
- $("#callStatus").text("保持的通话已挂机.");
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.customer_channel_call_wait)) {
- $("#stopCallWait").show();
- $("#doConsultationBtn").hide();
- $("#callStatus").text("客户电话等待中.");
- _cc.showTransferAreaUI();
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.customer_channel_off_call_wait)) {
- $("#stopCallWait").hide();
- $("#transferCallWait").hide();
- _cc.hideTransferAreaUI();
- $("#callStatus").text("等待的电话已接回.");
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.inner_consultation_start)) {
- $("#callStatus").text("咨询已开始.");
- $("#transferCallWait").show();
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.inner_consultation_stop)) {
- $("#callStatus").text("咨询已结束.");
- $("#transferCallWait").hide();
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.customer_on_call_wait_hangup)) {
- $("#stopCallWait").hide();
- $("#transferCallWait").hide();
- $("#callStatus").text("等待的客户已挂机.");
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.inner_consultation_start)) {
- $("#holdBtn").removeClass('on');
- $("#hangUpBtn").removeClass('on');
- $("#transferBtn").removeClass('on');
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.transfer_call_success)) {
- var extNum = msg["object"]["callee"];
- if(extNum === _cc.getExtNum()) {
- $("#holdBtn").addClass('on');
- $("#hangUpBtn").addClass('on');
- $("#transferBtn").addClass('on');
- }
- }
- if (parseInt(resp_status) === parseInt(ccPhoneBarSocket.eventList.agent_status_data_changed)) {
- if(_cc.subscribeAgentListStarted) {
- if (_cc.callConfig.agentList == null) {
- _cc.callConfig.agentList = JSON.parse(msg.object);
- }else{
- // 更新列表;
- _cc.updateAgentList(JSON.parse(msg.object));
- }
- }
- }
- _cc.notifyAll(resp_status, msg);
- break;
- }
- };
- //关闭连接时触发
- ws.onclose = function(evt) {
- isConnected = false;
- _cc.notifyAll(ccPhoneBarSocket.eventList.ws_disconnected, "ipccserver 连接断开.");
- console.log("ipcc连接断开.", "disconnected");
- console.log(evt);
- ws.close();
- };
- ws.onopen = function(evt) {
- console.log("ipccserver websocket onopen...");
- };
- };
- //发送消息给呼叫控制服务器
- this.sendMsg = function(jsonObject) {
- console.debug("ws.send:", jsonObject);
- ws.send(JSON.stringify(jsonObject));
- };
- this.changeUiOnHold = function() {
- $("#holdBtnLi").hide();
- $("#unHoldBtnLi").show();
- $("#unHoldBtn").addClass('on');
- };
- this.changeUiOnUnHold = function() {
- $("#holdBtnLi").show();
- $("#holdBtn").addClass('on');
- $("#unHoldBtnLi").hide();
- };
- this.hideTransferAreaUI = function(){
- var transferArea = document.getElementById("transfer_area");
- transferArea.style.display = "none";
- };
- this.showTransferAreaUI = function(){
- var transferArea = document.getElementById("transfer_area");
- transferArea.style.display = "block";
- };
- /**
- * 设置状态为空闲
- */
- this.setStatusFree = function(){
- this.setStatus(ccPhoneBarSocket.agentStatusEnum.free);
- };
- /**
- * 设置状态为忙碌
- */
- this.setStatusBusy = function(){
- this.setStatus(ccPhoneBarSocket.agentStatusEnum.busy);
- };
- ccPhoneBarSocket.utils = {
- /**
- * 读取 URL 中的指定查询参数值
- * @param {string} paramName - 要获取的参数名称
- * @returns {string|null} 返回参数值,如果不存在则返回 null
- */
- getQueryParam : function (paramName) {
- const url = window.location.href; // 获取当前页面 URL
- const params = new URLSearchParams(new URL(url).search); // 创建 URLSearchParams 对象
- return params.get(paramName); // 获取指定参数值
- }
- };
- /**
- * 座席状态枚举;
- * @type {{rest: number, calling: number, busy: number, free: number, justLogin: number, meeting: number, train: number}}
- */
- ccPhoneBarSocket.agentStatusEnum = {
- /**
- * 刚刚上线,尚未就绪中;
- */
- "justLogin" : 1,
- /**
- * 空闲
- */
- "free" : 2,
- /**
- * 忙碌
- */
- "busy" : 3,
- /**
- * 小休
- */
- "busy_rest" : 31,
- /**
- * 线下会议
- */
- "busy_meeting" : 32,
- /**
- * 培训
- */
- "busy_training" : 33,
- /**
- * 通话中
- */
- "incall" : 4,
- /**
- * 话后处理,填写表单中
- */
- "fill_form" : 5,
- /**
- * 电话会议中
- */
- "conference" : 6
- };
- //定义视频level-id
- ccPhoneBarSocket.videoLevels = {
- "Smooth" : { "levelId" : "42e00b", "description" : "流畅" },
- "Smooth2" : { "levelId" : "42e00c", "description" : "流畅+" },
- "Smooth3" : { "levelId" : "42e00d", "description" : "流畅++" },
- "Clear" : { "levelId" : "42e014", "description" : "清晰" },
- "Clear2" : { "levelId" : "42e015", "description" : "清晰+" },
- "Clear3" : { "levelId" : "42e016", "description" : "清晰++" },
- "HD" : { "levelId" : "42e01e", "description" : "高清" },
- "HD2" : { "levelId" : "42e01f", "description" : "高清+" }
- };
- /**
- * 系统事件列表;
- * @type {{}}
- */
- ccPhoneBarSocket.eventList = {
- // 当音频通话已建立
- "on_audio_call_connected" : "100",
- "on_video_call_connected" : "101",
- // websocketServer连接成功
- "ws_connected": "200",
- // 当前用户已在其他设备登录;
- "user_login_on_other_device" : "201",
- // 用户下线
- "ws_disconnected" : "202",
- // 通话状态发生改变 [监听的数据]
- "call_session_status_data_changed" : "203",
- // 坐席状态列表发生改变
- "agent_status_data_changed" : "205",
- //请求参数错误
- "request_args_error" : "400",
- // unauthorized
- "unauthorized" : "401",
- //服务器内部错误
- "server_error" : "500",
- // 语音编码不匹配
- "server_error_audio_codec_not_match" : "501",
- // 主叫接通
- "caller_answered" : "600",
- // 主叫挂断
- "caller_hangup" : "601",
- // 主叫忙; 上一通电话未挂机
- "caller_busy" : "602",
- //主叫未登录
- "caller_not_login" : "603",
- //主叫应答超时
- "caller_respond_timeout" : "604",
- // 被叫接通
- "callee_answered" : "605",
- // 被叫挂断
- "callee_hangup" : "606",
- //被叫振铃
- "callee_ringing" : "607",
- // 座席状态改变
- "status_changed" : "608",
- // 一个完整的外呼任务结束: [可能尝试了一个或多个网关]
- "outbound_finished" : "611",
- // 预测外呼,分配的来电;
- "PREDICTIVE_CALL_INBOUND" : "612",
- // ACD队列分配的新来电
- "new_inbound_call" : "613",
- // 当前业务组实时排队人数
- "acd_group_queue_number" : "615",
- /**
- * 收到转接的来电请求
- */
- "transfer_call_recv" : 616,
- /**
- * 锁定坐席失败
- */
- "lock_agent_fail" : 617,
- /**
- * 通话已经转接成功
- */
- "transfer_call_success" : 618,
- /**
- * 产生asr语音识别结果
- */
- "asr_result_generate" : 619,
- /**
- * ASR语音识别流程结束(坐席侧)
- */
- "asr_process_end_agent" : 620,
- /**
- * ASR语音识别流程结束(客户侧)
- */
- "asr_process_end_customer" : 621,
- "asr_process_started" : 622,
- /**
- * customer call session hold.
- */
- "customer_channel_hold" : 623,
- /**
- * customer call session unHold.
- */
- "customer_channel_unhold" : 624,
- /**
- * customer call session on hold is hangup.
- */
- "customer_on_hold_hangup" : 625,
- "inner_consultation_request" : 626,
- /**
- * customer call session on call-wait.
- */
- "customer_channel_call_wait" : 627,
- /**
- * customer call session off call-wait.
- */
- "customer_channel_off_call_wait" : 628,
- /**
- * customer call session on call-wait is hangup.
- */
- "customer_on_call_wait_hangup" : 629,
- /**
- * extension on line event
- */
- "extension_on_line" : 630,
- /**
- * extension off line event
- */
- "extension_off_line" : 631,
- /**
- * Notify the agent that the call consultation has started.
- */
- "inner_consultation_start" : 632,
- /**
- * Notify the agent that the call consultation has stopped.
- */
- "inner_consultation_stop" : 633,
- /**
- * 多人电话会议,重复的被叫 ,
- */
- "conference_repeat_callee" : 660 ,
- /**
- * 多人电话会议,呼叫成员超时 ,
- */
- "CONFERENCE_CALL_MODERATOR_TIMEOUT" : 661 ,
- /**
- * 多人电话会议,成员接通 ,
- */
- "CONFERENCE_MEMBER_ANSWERED" : 662 ,
- /**
- * 多人电话会议,成员挂机 ,
- */
- "CONFERENCE_MEMBER_HANGUP" : 663 ,
- /**
- * 多人电话会议,成员禁言成功 ,
- */
- "CONFERENCE_MEMBER_MUTED_SUCCESS" : 666 ,
- /**
- * 多人电话会议,成员禁言失败 ,
- */
- "CONFERENCE_MEMBER_MUTED_FAILED" : 665 ,
- /**
- * 多人电话会议,成员解除禁言成功 ,
- */
- "CONFERENCE_MEMBER_UNMUTED_SUCCESS" : 667 ,
- /**
- * 多人电话会议,成员解除禁言失败 ,
- */
- "CONFERENCE_MEMBER_UNMUTED_FAILED" : 668 ,
- /**
- * 多人电话会议,会议成员不存在,无法执行相关操作:
- */
- "CONFERENCE_MEMBER_NOT_EXISTS" : "669" ,
- /**
- * 多人电话会议,主持人重置会议 ,
- */
- "CONFERENCE_MODERATOR_RESET" : "670" ,
- /**
- * 多人电话会议,主持人接通 ,
- */
- "CONFERENCE_MODERATOR_ANSWERED" : "671" ,
- /**
- * 多人电话会议,主持人挂机,会议结束 ,
- */
- "CONFERENCE_MODERATOR_HANGUP" : "672",
- /*
- * 成员视频禁用成功
- */
- "CONFERENCE_MEMBER_VMUTED_SUCCESS" : "674",
- /*
- * 成员解除视频禁用成功
- */
- "CONFERENCE_MEMBER_UnVMUTED_SUCCESS" : "676",
- /**
- * 多人电话会议,成员解除视频禁用失败;
- */
- "CONFERENCE_MEMBER_UnVMUTED_FAILED" : "677",
- /**
- * 成功把通话转接到多人视频会议
- */
- "CONFERENCE_TRANSFER_SUCCESS_FROM_EXISTED_CALL" : "678",
- /**
- * outbound start event
- */
- "OUTBOUND_START" : "679"
- };
- this.createIframe = function(src){
- var _iframe = document.createElement("iframe");
- _iframe.style.width = '0';
- _iframe.style.height = '0';
- _iframe.style.margin = '0';
- _iframe.style.padding = '0';
- _iframe.style.overflow = 'hidden';
- _iframe.style.border = 'none';
- _iframe.src = src;
- document.body.appendChild(_iframe);
- _cc.iframe = _iframe;
- };
- this.openSoftPhone = function (){
- //打开软电话
- var softPhoneUrl = "http://127.0.0.1:" + _cc.callConfig["localHostProxyPort"] +
- "/autoSetExtension?server=" + encodeURIComponent(_cc.callConfig["fsServer"].split(':')[0]) +
- "&port=" + _cc.callConfig["fsServer"].split(':')[1] +
- "&extnum=" + _cc.callConfig["extnum"] +
- "&pass=" + encodeURIComponent(_cc.callConfig["extPassword"]) +
- "&phoneType=" + _cc.callConfig["phoneType"] +
- "&version=" + encodeURIComponent(_cc.callConfig["localHostProxyVersion"]) +
- "&webPhoneUrl=" + encodeURIComponent(_cc.callConfig["webPhoneUrl"]) +
- "";
- console.log("softPhoneUrl:", softPhoneUrl);
- _cc.iframe.src = softPhoneUrl;
- };
- /**
- * 设置座席状态
- * @param status agentStatusEnum
- */
- this.setStatus = function (status) {
- var cmdInfo = {};
- cmdInfo.action="setAgentStatus";
- cmdInfo.body = {"cmd" : "setStatus", "args" : { "status" : status } };
- ws.send(JSON.stringify(cmdInfo));
- };
- //注销登录;
- this.logOff = function () {
- var cmdInfo = {};
- cmdInfo.action="setAgentStatus";
- cmdInfo.body = {"cmd" : "disconnect", "args" : { "cause": "disconnect request from js client." } };
- ws.send(JSON.stringify(cmdInfo));
- };
- /**
- * 在咨询失败的情况下使用该按钮,接回处于等待中的电话
- */
- this.stopCallWaitBtnClickUI = function () {
- var cmd = {};
- cmd.action="callWait";
- cmd.body = {"cmd" : "stop", "args" : {} };
- ws.send(JSON.stringify(cmd));
- };
- /**
- * 在咨询成功的情况下使用该按钮,把电话转接给专家坐席。
- */
- this.transferCallWaitBtnClickUI = function () {
- this.callControl("transferCallWait", {})
- };
- this.consultationBtnClickUI = function () {
- let transferType = "outer";
- let phoneNumber = $("#externalPhoneNumber").val().trim();
- if (phoneNumber === "") {
- transferType = "inner";
- var groupId = $("#transfer_to_groupIds").val();
- if ($.trim(groupId) == "") {
- alert("请选择业务组!");
- $("#transfer_to_groupIds").focus();
- return;
- }
- var member = $("#transfer_to_member").val();
- if ($.trim(member) == "") {
- alert("请选择要咨询的坐席成员!");
- $("#transfer_to_member").focus();
- return;
- }
- var selectText = $('#transfer_to_member option:selected').text();
- if (selectText.indexOf("空闲") == -1) {
- alert("请选择空闲的坐席成员!");
- $("#transfer_to_member").focus();
- return;
- }
- if (member == this.getOpNum()) {
- alert("不能咨询自己,请选择其他坐席成员!");
- return;
- }
- phoneNumber = member;
- }
- this.callControl("consultation", {"to": phoneNumber, "transferType": transferType});
- };
- /**
- * 处理通话转接按钮点击事件
- */
- this.transferBtnClickUI = function() {
- let transferType = "outer";
- let phoneNumber = $("#externalPhoneNumber").val().trim();
- if(phoneNumber === "") {
- transferType = "inner";
- var groupId = $("#transfer_to_groupIds").val();
- if ($.trim(groupId) === "") {
- alert("请选择转接的业务组!");
- $("#transfer_to_groupIds").focus();
- return;
- }
- var member = $("#transfer_to_member").val();
- if ($.trim(member) === "") {
- alert("请选择转接的坐席成员!");
- $("#transfer_to_member").focus();
- return;
- }
- var selectText = $('#transfer_to_member option:selected').text();
- if (selectText.indexOf("空闲") === -1) {
- alert("请选择空闲的坐席成员!");
- $("#transfer_to_member").focus();
- return;
- }
- if (member === this.getOpNum()) {
- alert("不能转给自己,请选择其他坐席成员!");
- return;
- }
- phoneNumber = member;
- }
- this.transferCall(phoneNumber, transferType);
- };
- /**
- * 处理通话转接
- * @param userCodeOrPhone 工号或者电话号码
- * @param transferType 转接类型:工号还是外部号码(inner or outer)
- */
- this.transferCall = function(userCodeOrPhone, transferType) {
- if(transferType === "inner") {
- if (userCodeOrPhone !== this.getOpNum()) {
- this.callControl("transferCall", {"to": userCodeOrPhone, "transferType" : "inner" })
- } else {
- console.error("cant not transfer call to yourself.")
- }
- }else{
- this.callControl("transferCall", {"to": userCodeOrPhone, "transferType" : "outer" })
- }
- };
- //挂机
- this.hangup = function() {
- this.callControl("endSession", {})
- };
- // 呼叫控制相关操作;
- this.callControl = function(action, argsObject){
- var sessionControl = {};
- sessionControl.action="call";
- sessionControl.body = {"cmd" : action, "args" : argsObject };
- ws.send(JSON.stringify(sessionControl));
- };
- this.checkCallConfirmed = function () {
- if(!_cc.getIsConnected()){
- console.log('请先上线.');
- return false;
- }
- if(!_cc.getCallConnected()){
- console.log('当前没有通话.');
- return false;
- }
- return true;
- };
- /**
- * send and play mp4 video file.
- */
- this.sendVideoFile = function (mp4FilePath) {
- if(!_cc.checkCallConfirmed()){
- return false;
- }
- if(typeof(mp4FilePath) == "undefined" || mp4FilePath.trim().length === 0){
- console.log("Parameter mp4FilePath is missing!")
- return false;
- }
- this.callControl(
- "playMp4File",
- { "mp4FilePath" : mp4FilePath }
- );
- return true;
- };
- /**
- * 发起视频通话邀请
- */
- this.reInviteVideoCall = function(){
- if(!_cc.checkCallConfirmed()){
- return false;
- }
- if(!_cc.getCanSendVideoReInvite()){
- console.log('cant not send video reInvite. ',
- 'Precondition is: Call is connected and callType is audio.');
- return false;
- }
- this.callControl(
- "reInviteVideo",
- {}
- );
- return true;
- };
- /**
- * 发起外呼
- * @param phoneNumber 被叫号码
- * @param callType 通话类型:视频通话、音频通话
- * @param videoLevel 视频通话的profile-level-id
- */
- this.call = function(phoneNumber, callType, videoLevel){
- // 防止重复调用
- if(_cc.isCalling) {
- console.log('正在呼叫中,请勿重复操作');
- return;
- }
- if(typeof(videoLevel) == "undefined" || videoLevel.trim().length === 0){
- videoLevel = ccPhoneBarSocket.videoLevels.HD.levelId;
- console.log("auto default set videoLevel=", videoLevel);
- }
- if(typeof(callType) == "undefined" || callType.trim().length === 0){
- callType = "audio";
- console.log("auto default set callType=", callType);
- }
- console.log("call config videoLevel=" + videoLevel + ", callType=" + callType);
- if(phoneNumber==null || phoneNumber.length===0) {
- console.log('请输入外呼号码!');
- return;
- }
- if(phoneNumber.trim().length < 3){
- alert('请输入正确格式的外呼号码!');
- return;
- }
- if(!_cc.getIsConnected()){
- console.log('请先上线.');
- return;
- }
- let outboundInfo = {
- "gatewayList": _cc.callConfig.gatewayList,
- 'destPhone': phoneNumber,
- 'gatewayEncrypted' : _cc.callConfig.gatewayEncrypted,
- 'useSameAudioCodeForOutbound' : _cc.callConfig.useSameAudioCodeForOutbound,
- 'callType' : callType,
- 'videoLevel' : videoLevel
- };
- this.callControl(
- "startSession",
- outboundInfo
- );
- // 设置呼叫标志
- _cc.isCalling = true;
- };
- this.callEx = function(phoneNumber){
- if(phoneNumber == null || phoneNumber.length === 0) {
- console.log('请输入外呼号码!');
- return;
- }
- if(!_cc.getIsConnected()){
- _cc.connect();
- _cc.on(ccPhoneBarSocket.eventList.ws_connected, function(){
- _cc.off(ccPhoneBarSocket.eventList.ws_connected); //取消事件订阅
- _cc.call(phoneNumber);
- });
- return;
- }
- _cc.call(phoneNumber);
- };
- /************************ 以下是网页工具条ui代码 ************************/
- /**
- * 根据服务器响应状态码去查找action
- * @param code
- * @returns {string}
- */
- ccPhoneBarSocket.findItemByCode = function(code){
- for(var item in ccPhoneBarSocket.eventListWithTextInfo ){
- if(ccPhoneBarSocket.eventListWithTextInfo[item].code === code){
- return ccPhoneBarSocket.eventListWithTextInfo[item];
- }
- }
- };
- /**
- * 服务器响应状态枚举值;
- */
- ccPhoneBarSocket.eventListWithTextInfo = {
- "ws_connected": { "code": 200, msg:"已签入",
- btn_text:[{id:"#onLineBtn",name:"签出"}],
- enabled_btn:['#setFree','#callBtn','#onLineBtn', '#consultationBtn']
- },
- "ws_disconnected": { "code" : 202, msg:"服务器连接断开",
- btn_text:[{id:"#onLineBtn",name:"签入"}],
- enabled_btn:['#onLineBtn']
- },
- "user_login_on_other_device": { "code" : 201, msg:"用户已在其他设备登录",
- btn_text:[{id:"#onLineBtn",name:"签入"}],
- enabled_btn:['#onLineBtn']
- },
- "request_args_error":{ "code" : 400, msg:"客户端请求参数错误",
- btn_text:[],
- enabled_btn:[]
- },
- "server_error":{ "code" : 500, msg:"服务器内部错误",
- btn_text:[],
- enabled_btn:[]
- },
- "caller_answered":{ "code" : 600, msg:"分机已接通",
- btn_text:[],
- enabled_btn:['#resetStatus', '#hangUpBtn', '#transferBtn', '#holdBtn', '#consultationBtn']
- },
- "caller_hangup":{ "code" : 601, msg:"分机已挂断",
- btn_text:[],
- enabled_btn:['#onLineBtn', '#resetStatus', '#callBtn', '#setFree', '#consultationBtn' ]
- },
- "caller_busy":{ "code" : 602, msg:"分机忙,上一通电话未挂断",
- btn_text:[],
- enabled_btn:['#onLineBtn', '#resetStatus', '#callBtn', '#setFree', '#consultationBtn']
- },
- "caller_not_login":{ "code" : 603, msg:"分机未登录,请检查",
- btn_text:[],
- enabled_btn:['#onLineBtn', '#resetStatus', '#callBtn', '#setFree', '#consultationBtn']
- },
- "caller_respond_timeout":{ "code" : 604, msg:"分机未应答超时,请重新打开分机",
- btn_text:[],
- enabled_btn:['#onLineBtn', '#resetStatus', '#callBtn', '#setFree', '#consultationBtn']
- },
- "callee_answered":{ "code" : 605, msg:"被叫已接通",
- btn_text:[],
- enabled_btn:['#resetStatus', '#hangUpBtn', '#transferBtn', '#holdBtn', '#consultationBtn' ]
- },
- "callee_hangup":{ "code" : 606, msg:"通话结束",
- btn_text:[],
- enabled_btn:['#onLineBtn', '#resetStatus', '#callBtn', '#setFree' , '#consultationBtn']
- },
- "callee_ringing":{ "code" : 607, msg:"被叫振铃中",
- btn_text:[],
- enabled_btn:['#resetStatus', '#hangUpBtn', '#transferBtn', '#consultationBtn']
- },
- "status_changed":{ "code" : 608, msg:"状态已改变",
- btn_text:[],
- enabled_btn:[ ]
- },
- "free":{ "code" : 0, msg:"空闲中",
- btn_text:[],
- enabled_btn:['#setBusy','#onLineBtn', '#consultationBtn']
- },
- "busy":{ "code" : 1, msg:"忙碌",
- btn_text:[],
- enabled_btn:['#setFree', '#onLineBtn', '#callBtn', '#consultationBtn'] // '#transferBtn'
- },
- "customer_channel_hold" : { "code" : 623, msg:"通话已保持.",
- btn_text:[],
- enabled_btn:['#setFree', '#callBtn', '#unHoldBtn', '#consultationBtn' ]
- },
- "customer_channel_unhold" : { "code" : 624, msg:"通话已接回.",
- btn_text:[],
- enabled_btn:[ '#hangUpBtn', '#holdBtn' ]
- }
- };
- ccPhoneBarSocket.phone_buttons = ['#setFree', '#setBusy', '#callBtn','#hangUpBtn' , '#resetStatus' ,'#onLineBtn', '#transferBtn', '#holdBtn', '#unHoldBtn', '#consultationBtn'];
- // 更新状态显示
- this.updatePhoneBar = function (msg, status_key) {
- if(!_cc.callConfig.useDefaultUi){
- console.log("callConfig.useDefaultUi = false , 已禁用默认ui工具条按钮.");
- return;
- }
- if (msg) {
- $("#callStatus").text(msg.msg);
- }
- var status_info = ccPhoneBarSocket.findItemByCode(status_key);
- if (!status_info) {
- return;
- }
- if(status_info.code === ccPhoneBarSocket.eventListWithTextInfo.status_changed.code){
- if(msg.object.status === ccPhoneBarSocket.agentStatusEnum.free){
- status_info = ccPhoneBarSocket.eventListWithTextInfo.free;
- }else{
- status_info = ccPhoneBarSocket.eventListWithTextInfo.busy;
- }
- }
- // 判断当前是否为状态改变的事件;
- // 显示预设的消息;
- var msgSet = status_info.msg;
- if(msgSet && msgSet.length > 0){
- $("#callStatus").text(msgSet);
- }
- var btn_text = status_info.btn_text;
- var enabled_btn = status_info.enabled_btn;
- if (btn_text) {
- $.each(btn_text, function (i, d) {
- $(d.id).next().text(d.name);
- });
- }
- if (enabled_btn.length === 0) {
- return;
- }
- var all_btn = ccPhoneBarSocket.phone_buttons;
- for (var i in all_btn) {
- var idx = $.inArray(all_btn[i], enabled_btn);
- if (idx < 0) {
- $(all_btn[i]).removeClass('on');
- } else {
- $(enabled_btn[idx]).addClass('on');
- }
- }
- };
- /**
- * 初始化电话工具条ui按钮;
- */
- this.initPhoneBarUI = function () {
- window.onbeforeunload = function () {
- if (!confirm('关闭网页将导致您无法接听电话,确定要关闭吗 ?')) return false;
- };
- $("#unHoldBtnLi").hide();
- if(!_cc.callConfig.useDefaultUi){
- console.log("callConfig.useDefaultUi = false , 已禁用默认ui工具条按钮.");
- return;
- }
- $('#conferenceBtn').on('click', function () {
- if(!_cc.getIsConnected()){
- console.log('请先上线.');
- return;
- }
- var confObjId = document.getElementById("conference_area");
- if(confObjId.style.display === "block"){
- confObjId.style.display = "none";
- }else{
- confObjId.style.display = "block";
- }
- });
- $('#callBtn').on('click', function () {
- if ($(this).hasClass('on')) {
- var destPhone = $.trim($("#ccphoneNumber").val());
- var videoLevel = document.getElementById("videoLevelSelect").value;
- var callType = document.forms[0].callType.value;
- _cc.call(destPhone, callType, videoLevel);
- }
- });
- $('#setFree').on('click', function () {
- if ($(this).hasClass('on')) {
- _cc.setStatus(ccPhoneBarSocket.agentStatusEnum.free);
- }
- });
- $('#setBusy').on('click', function () {
- if ($(this).hasClass('on')) {
- _cc.setStatus(ccPhoneBarSocket.agentStatusEnum.busy);
- }
- });
- $('#setBusySubList').on('change', function () {
- let itemValue = $('#setBusySubList').val();
- console.log('set busy subStatus', itemValue);
- _cc.setStatus(itemValue);
- });
- $('#hangUpBtn').on('click', function () {
- if ($(this).hasClass('on')) {
- _cc.hangup();
- }
- });
- $('#holdBtn').on('click', function () {
- if ($(this).hasClass('on')) {
- _cc.holdCall();
- }
- });
- $('#unHoldBtn').on('click', function () {
- if ($(this).hasClass('on')) {
- _cc.unHoldCall();
- }
- });
- $("#doTransferBtn").hide();
- /**
- * 填充业务组选项
- * 注意:该函数仅用于原始 HTML 版本,Vue + Element UI 版本中由 Vue 组件自行处理
- */
- function populateGroupIdOptions() {
- var groups = _cc.callConfig.groups;
- if (groups) {
- var selectObj = document.getElementById("transfer_to_groupIds");
- if (selectObj) {
- // 检查是否为原生 select 元素
- if (selectObj.tagName.toLowerCase() === 'select') {
- // 清空现有选项(保留第一个"请选择")
- var firstOption = selectObj.options[0];
- selectObj.innerHTML = '';
- selectObj.add(firstOption);
- // 添加业务组选项
- for (var i = 0; i < groups.length; i++) {
- var group = groups[i];
- var option = document.createElement("option");
- option.value = group.groupId;
- option.text = group.bizGroupName;
- selectObj.add(option);
- }
- // 默认选中第一个
- if (groups.length > 0 && selectObj.options.length > 1) {
- selectObj.selectedIndex = 1;
- }
- }
- // 如果是 el-select 组件,则不处理,由 Vue 数据绑定自动更新
- }
- }
- }
- $('#transferBtn').on('click', function () {
- if ($(this).hasClass('on')) {
- if(!_cc.getIsConnected()){
- console.log('请先上线.');
- return;
- }
- var transferArea = document.getElementById("transfer_area");
- if(transferArea.style.display === "block"){
- transferArea.style.display = "none";
- _cc.unSubscribeAgentList();
- $("#doTransferBtn").hide();
- $("#doConsultationBtn").hide();
- }else{
- transferArea.style.display = "block";
- populateGroupIdOptions();
- // 不再自动订阅坐席状态列表,由外部控制
- // _cc.subscribeAgentList();
- $("#doTransferBtn").show();
- $("#doConsultationBtn").hide();
- }
- }
- });
- $("#stopCallWait").hide();
- $("#transferCallWait").hide();
- $("#doConsultationBtn").hide();
- $('#consultationBtn').on('click', function () {
- if ($(this).hasClass('on')) {
- if(!_cc.getIsConnected()){
- console.log('请先上线.');
- return;
- }
- var transferArea = document.getElementById("transfer_area");
- if(transferArea.style.display === "block"){
- transferArea.style.display = "none";
- _cc.unSubscribeAgentList();
- $("#doConsultationBtn").hide();
- $("#doTransferBtn").hide();
- }else{
- transferArea.style.display = "block";
- populateGroupIdOptions();
- // 不再自动订阅坐席状态列表,由外部控制
- // _cc.subscribeAgentList();
- $("#doConsultationBtn").show();
- $("#doTransferBtn").hide();
- }
- }
- });
- $('#onLineBtn').on('click', function () {
- if ($(this).hasClass('on')) {
- if (_cc.getIsConnected()) {
- _cc.disconnect();
- } else {
- _cc.connect();
- }
- }else {
- alert('当前不允许签出!');
- }
- });
- $('#resetStatus').on('click', function () {
- window.onbeforeunload = null;
- location.reload();
- });
- //拨号文本框;收到键盘回车事件之后立即拨号
- $("#ccphoneNumber").keydown(function (e) {
- var curKey = e.which;
- if (curKey === 13) {
- var destPhone = $.trim($("#ccphoneNumber").val());
- var videoLevel = document.getElementById("videoLevelSelect").value;
- var callType = document.forms[0].callType.value;
- _cc.call(destPhone,callType, videoLevel);
- return false;
- }
- });
- //ESC按键挂机功能支持
- $(document).keyup(function (e) {
- var key = e.which;
- if (key === 27) {
- console.log('按下了ESC键, 即将发送挂机指令.');
- if(_cc.getIsConnected()){
- if(_cc.callConfig["useDefaultUi"]) {
- if ($('#hangUpBtn').hasClass('on')) {
- _cc.hangup();
- }
- }else{
- _cc.hangup();
- }
- }
- }
- });
- };
- /**
- * 保持通话
- */
- this.holdCall = function(){
- var cmd = {};
- cmd.action="callHold";
- cmd.body = {"cmd" : "hold", "args" : {} };
- ws.send(JSON.stringify(cmd));
- };
- /**
- * 接回保持的通话
- */
- this.unHoldCall = function(){
- var cmd = {};
- cmd.action="callHold";
- cmd.body = {"cmd" : "unhold", "args" : {} };
- ws.send(JSON.stringify(cmd));
- };
- /**
- * 订阅坐席状态列表
- */
- this.subscribeAgentList = function(){
- var cmd = {};
- cmd.action="pollAgentList";
- cmd.body = {"cmd" : "subscribe", "args" : {} };
- ws.send(JSON.stringify(cmd));
- _cc.subscribeAgentListStarted = true;
- };
- /**
- * 取消订阅坐席状态列表
- */
- this.unSubscribeAgentList = function(){
- if(_cc.subscribeAgentListStarted) {
- _cc.subscribeAgentListStarted = false;
- _cc.callConfig.agentList = null;
- var cmd = {};
- cmd.action = "pollAgentList";
- cmd.body = {"cmd": "unSubscribe", "args": {}};
- ws.send(JSON.stringify(cmd));
- }
- };
- /************************* 以下是电话会议相关 ***************************/
- /**
- * 启动会议; 仅限使用默认UI场景下使用;
- */
- this.conferenceStartBtnUI = function(customerName){
- var callType = document.getElementById("conf_call_type").value;
- var confTemplate = document.getElementById("conf_template").value;
- var layOut = document.getElementById("conf_layout").value;
- _cc.setStatusBusy();
- // 禁用外呼按钮
- $("#callBtn").removeClass('on');
- // 禁用置闲按钮
- $("#setFree").removeClass('on');
- // 禁用签出按钮
- $("#onLineBtn").removeClass('on');
- document.getElementById("startConference").setAttribute("disabled", "true");
- if(_cc.getCallConnected()) {
- let tips = "是否把当前通话转换为会议 ?";
- console.log(tips);
- if(confirm(tips)) {
- _cc.transferToConference(layOut, confTemplate, callType, customerName);
- }else{
- document.getElementById("startConference").removeAttribute("disabled");
- }
- }else {
- _cc.conferenceStart(layOut, confTemplate, callType);
- }
- };
- /**
- * 添加会议成员; 仅限使用默认UI场景下使用;
- */
- this.conferenceAddMemberBtnUI = function (reInvite, memberPhoneParam, memberNameParam) {
- var memberName = "";
- var memberPhone = "";
- var memberCallType = $.trim(document.getElementById("member_call_type").value);
- var memberVideoLevel = $.trim(document.getElementById("member_video_level").value);
- if(reInvite === 0) {
- memberName = $("#member_name").val();
- memberPhone = $("#member_phone").val();
- if (memberName.length === 0 || $.trim(memberName) === "") {
- alert('请填写参会者姓名!');
- return;
- }
- if (memberPhone.length === 0 || $.trim(memberPhone) === "") {
- alert('请填写参会者手机号!');
- return;
- }
- memberName = $.trim(memberName);
- memberPhone = $.trim(memberPhone);
- // 使用会员成员html模版添加新成员
- var templateObj = document.getElementById("conf_member_template");
- var existMember = document.getElementById("conf_member_" + memberPhone) != null;
- if (existMember) {
- alert('会议成员已经存在,请不要重复添加!');
- return;
- }
- var memberHtmlItem = templateObj.innerHTML;
- memberHtmlItem = memberHtmlItem.replace(new RegExp("{member_name}", "gm"), memberName);
- memberHtmlItem = memberHtmlItem.replace(new RegExp("{member_phone}", "gm"), memberPhone);
- memberHtmlItem = memberHtmlItem.replace(new RegExp("{member_status}", "gm"), "即将呼叫");
- var li = document.createElement("li");
- li.setAttribute("id", "conf_member_" + memberPhone);
- li.setAttribute("class", "conf_member_item_row");
- li.innerHTML = memberHtmlItem;
- _cc.insertAfter(li, templateObj);
- $("#member_name").val('');
- $("#member_phone").val('');
- }else{
- memberName = memberNameParam;
- memberPhone = memberPhoneParam;
- }
- // 隐藏 mute及 vmute按钮
- var memberItemId = "#conf_member_" + memberPhone;
- $(".conf_mute", $(memberItemId)).find("img").hide();
- $(".conf_vmute", $(memberItemId)).find("img").hide();
- $(".conf_re_invite", $(memberItemId)).hide();
- $(".conf_status", $(memberItemId)).html("即将呼叫");
- _cc.conferenceAddMembers( [
- {"name": memberName, "phone": memberPhone, "callType" : memberCallType, "videoLevel": memberVideoLevel}
- ]);
- };
- /**
- * 从现有通话添加会议成员;
- */
- this.conferenceAddMemberFromExistCall = function (memberName, memberPhone) {
- if (memberName.length === 0 || $.trim(memberName) === "") {
- alert('请填写参会者姓名!');
- return;
- }
- if (memberPhone.length === 0 || $.trim(memberPhone) === "") {
- alert('请填写参会者手机号!');
- return;
- }
- memberName = $.trim(memberName);
- memberPhone = $.trim(memberPhone);
- // 使用html模版添加新成员
- var templateObj = document.getElementById("conf_member_template");
- var existMember = document.getElementById("conf_member_" + memberPhone) != null;
- if (existMember) {
- alert('会议成员已经存在,请不要重复添加!');
- return;
- }
- var memberHtmlItem = templateObj.innerHTML;
- memberHtmlItem = memberHtmlItem.replace(new RegExp("{member_name}", "gm"), memberName);
- memberHtmlItem = memberHtmlItem.replace(new RegExp("{member_phone}", "gm"), memberPhone);
- memberHtmlItem = memberHtmlItem.replace(new RegExp("{member_status}", "gm"), "即将呼叫");
- var li = document.createElement("li");
- li.setAttribute("id", "conf_member_" + memberPhone);
- li.setAttribute("class", "conf_member_item_row");
- li.innerHTML = memberHtmlItem;
- _cc.insertAfter(li, templateObj);
- // 隐藏 mute及 vmute按钮
- var memberItemId = "#conf_member_" + memberPhone;
- $(".conf_mute", $(memberItemId)).find("img").show();
- $(".conf_vmute", $(memberItemId)).find("img").show();
- $(".conf_re_invite", $(memberItemId)).hide();
- $(".conf_status", $(memberItemId)).html("通话中").css("color", "green");
- };
- /**
- * 通话转为会议
- * @param layOut
- * @param confTemplate
- * @param callType
- * @param customerName
- */
- this.transferToConference = function (layOut, confTemplate, callType, customerName) {
- console.log("try to transferToConference: ", layOut, confTemplate, callType, customerName);
- _cc.callControl(
- "transferToConference",
- {
- "layOut": layOut,
- 'callType': callType,
- 'confTemplate': confTemplate,
- 'customerName' : customerName
- }
- );
- };
- /**
- * 主持人启动电话会议
- * @param layOut 会议布局
- * @param confTemplate 会议模版
- * @param callType 会议类型
- */
- this.conferenceStart = function(layOut, confTemplate, callType) {
- console.log("正常发起多方通话");
- var cmd = {};
- cmd.action = "conference";
- cmd.body = {"method": "startconf", "args": {
- "layOut": layOut,
- 'callType': callType,
- 'confTemplate': confTemplate
- }};
- ws.send(JSON.stringify(cmd));
- };
- /**
- * VMute会议成员(不显示视频);
- **/
- this.conferenceVMuteMember = function(members) {
- // single phone
- if(typeof(members) === "string") {
- this.conferenceControl("vmute",
- [
- {"phone": members}
- ]
- );
- }else{
- // multiple phones array, e.g.: [ {"phone": '15005600321'}, {"phone": '15005600323'} ]
- this.conferenceControl("vmute", members);
- }
- };
- /**
- * UnVMute会议成员(显示视频);
- **/
- this.conferenceUnVMuteMember = function(members) {
- // single phone
- if(typeof(members) === "string") {
- this.conferenceControl("unvmute",
- [
- {"phone": members}
- ]
- );
- }else{
- // multiple phones array, e.g.: [ {"phone": '15005600321'}, {"phone": '15005600323'} ]
- this.conferenceControl("unvmute", members);
- }
- };
- /**
- * 禁言会议成员
- **/
- this.conferenceMuteMember = function(members) {
- // single phone
- if(typeof(members) === "string") {
- this.conferenceControl("mute",
- [
- {"phone": members}
- ]
- );
- }else{
- // multiple phones array, e.g.: [ {"phone": '15005600321'}, {"phone": '15005600323'} ]
- this.conferenceControl("mute", members);
- }
- };
- /**
- * 解禁会议成员
- **/
- this.conferenceUnMuteMember = function(members) {
- // single phone
- if(typeof(members) === "string") {
- this.conferenceControl("unmute",
- [
- {"phone": members}
- ]
- );
- }else{
- // multiple phones array, e.g.: [ {"phone": '15005600321'}, {"phone": '15005600323'} ]
- this.conferenceControl("unmute", members);
- }
- };
- /**
- * 增加会议成员
- **/
- this.conferenceAddMembers = function(members) {
- this.conferenceControl("add", members)
- };
- /**
- * 移除会议成员
- **/
- this.conferenceRemoveMembers = function(members) {
- // single phone
- if(typeof(members) === "string") {
- var memberItemObj = $("#conf_member_" + members);
- if($(".conf_status", memberItemObj).text() === "通话中") {
- this.conferenceControl("remove",
- [
- {"phone": members}
- ]
- );
- }
- memberItemObj.remove();
- }else{
- // multiple phones array, e.g.: [ {"phone": '15005600321'}, {"phone": '15005600323'} ]
- this.conferenceControl("remove", members);
- }
- };
- /**
- * 结束电话会议
- **/
- this.conferenceEnd = function() {
- this.conferenceControl("endconf", [])
- };
- /**
- * 电话会议控制相关操作
- * @param action 操作
- * @param phoneList 会议成员
- */
- this.conferenceControl = function (action, phoneList) {
- var cmd = {};
- cmd.action = "conference";
- cmd.body = { "method": action, "memberList": phoneList };
- ws.send(JSON.stringify(cmd));
- };
- /************************* 以下是通话监听相关 ***************************/
- /**
- * 拉取监听的通话列表
- */
- this.callMonitorDataPull = function (){
- var cmd = {};
- cmd.action = "monitorData";
- cmd.body = {};
- ws.send(JSON.stringify(cmd));
- };
- /**
- * 拉取排队中的电话列表
- */
- this.inboundCallQueuePull = function (){
- var cmd = {};
- cmd.action = "inboundMonitorData";
- cmd.body = {};
- ws.send(JSON.stringify(cmd));
- };
- // 构造通话监听参数
- this.monitorControl = function(action, argsObject){
- var sessionControl = {};
- sessionControl.action="callMonitor";
- sessionControl.body = {"cmd" : action, "args" : argsObject };
- ws.send(JSON.stringify(sessionControl));
- };
- /**
- * 通话监听
- * @param { 通话id } callId
- * @returns
- */
- this.callMonitorStart = function(callId){
- if(callId == null || callId.length === 0) {
- console.log('请提供待监听电话的 callId !');
- return;
- }
- if(!_cc.getIsConnected()){
- console.log('请先上线.');
- return;
- }
- this.monitorControl(
- "startMonitoring",
- {
- 'callSpyId': callId
- }
- );
- };
- /**
- * 结束监听
- */
- this.callMonitorEnd = function(){
- if(!_cc.getIsConnected()){
- console.log('请先上线.');
- return;
- }
- this.monitorControl(
- "endMonitoring",{}
- );
- };
- }
- export default ccPhoneBarSocket;
|