|
@@ -8,1912 +8,1917 @@
|
|
|
import $ from './jquery-1.11.0.js';
|
|
import $ from './jquery-1.11.0.js';
|
|
|
|
|
|
|
|
function _phoneBarObserver(){
|
|
function _phoneBarObserver(){
|
|
|
- if(!(this instanceof _phoneBarObserver)){
|
|
|
|
|
- return new _phoneBarObserver();
|
|
|
|
|
- }
|
|
|
|
|
- this.listeners = {}
|
|
|
|
|
|
|
+ if(!(this instanceof _phoneBarObserver)){
|
|
|
|
|
+ return new _phoneBarObserver();
|
|
|
|
|
+ }
|
|
|
|
|
+ this.listeners = {}
|
|
|
};
|
|
};
|
|
|
_phoneBarObserver.prototype = {
|
|
_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 = {}
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ 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通信对象
|
|
//呼叫中心websocket通信对象
|
|
|
"use strict";
|
|
"use strict";
|
|
|
function ccPhoneBarSocket() {
|
|
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': '129.28.164.235:8443',
|
|
|
|
|
- //是否启用websocket安全连接
|
|
|
|
|
- 'enableWss' : false,
|
|
|
|
|
- //语音编码
|
|
|
|
|
- '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;
|
|
|
|
|
|
|
+ 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 = {
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
- * 获取通话状态
|
|
|
|
|
- * @returns {boolean} true通话中,false通话未建立;
|
|
|
|
|
|
|
+ * 读取 URL 中的指定查询参数值
|
|
|
|
|
+ * @param {string} paramName - 要获取的参数名称
|
|
|
|
|
+ * @returns {string|null} 返回参数值,如果不存在则返回 null
|
|
|
*/
|
|
*/
|
|
|
- this.getCallConnected = function(){
|
|
|
|
|
- return callConnected;
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ 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 = {
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
- * 设置通话状态;
|
|
|
|
|
- * @param value true通话中,false通话未建立
|
|
|
|
|
- * @returns {*}
|
|
|
|
|
|
|
+ * 刚刚上线,尚未就绪中;
|
|
|
*/
|
|
*/
|
|
|
- this.setCallConnected = function(value){
|
|
|
|
|
- callConnected = value;
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ "justLogin" : 1,
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 设置一个标志,指示是否可以发起视频通话;
|
|
|
|
|
- * 仅限通话为音频通话且通话已经接通时方可允许发起视频邀请;
|
|
|
|
|
- * @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));
|
|
|
|
|
- wsuri = 'ws://' + this.callConfig.ipccServer +
|
|
|
|
|
- '/call-center/websocketServer?' +
|
|
|
|
|
- '&loginToken=' + this.callConfig.loginToken;
|
|
|
|
|
-
|
|
|
|
|
- console.log("ipccServer ws 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;
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 空闲
|
|
|
|
|
+ */
|
|
|
|
|
+ "free" : 2,
|
|
|
|
|
|
|
|
- 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));
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 忙碌
|
|
|
|
|
+ */
|
|
|
|
|
+ "busy" : 3,
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 在咨询成功的情况下使用该按钮,把电话转接给专家坐席。
|
|
|
|
|
|
|
+ * 小休
|
|
|
*/
|
|
*/
|
|
|
- this.transferCallWaitBtnClickUI = function () {
|
|
|
|
|
- this.callControl("transferCallWait", {})
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ "busy_rest" : 31,
|
|
|
|
|
|
|
|
- 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;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 线下会议
|
|
|
|
|
+ */
|
|
|
|
|
+ "busy_meeting" : 32,
|
|
|
|
|
|
|
|
- var selectText = $('#transfer_to_member option:selected').text();
|
|
|
|
|
- if (selectText.indexOf("空闲") == -1) {
|
|
|
|
|
- alert("请选择空闲的坐席成员!");
|
|
|
|
|
- $("#transfer_to_member").focus();
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 培训
|
|
|
|
|
+ */
|
|
|
|
|
+ "busy_training" : 33,
|
|
|
|
|
|
|
|
- if (member == this.getOpNum()) {
|
|
|
|
|
- alert("不能咨询自己,请选择其他坐席成员!");
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- phoneNumber = member;
|
|
|
|
|
- }
|
|
|
|
|
- this.callControl("consultation", {"to": phoneNumber, "transferType": transferType});
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 通话中
|
|
|
|
|
+ */
|
|
|
|
|
+ "incall" : 4,
|
|
|
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 话后处理,填写表单中
|
|
|
|
|
+ */
|
|
|
|
|
+ "fill_form" : 5,
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 处理通话转接按钮点击事件
|
|
|
|
|
- */
|
|
|
|
|
- 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;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 电话会议中
|
|
|
|
|
+ */
|
|
|
|
|
+ "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",
|
|
|
|
|
|
|
|
- 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));
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ "transfer_call_recv" : 616,
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 拉取排队中的电话列表
|
|
|
|
|
- */
|
|
|
|
|
- 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));
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 锁定坐席失败
|
|
|
|
|
+ */
|
|
|
|
|
+ "lock_agent_fail" : 617,
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 通话监听
|
|
|
|
|
- * @param { 通话id } callId
|
|
|
|
|
- * @returns
|
|
|
|
|
|
|
+ * 通话已经转接成功
|
|
|
*/
|
|
*/
|
|
|
- this.callMonitorStart = function(callId){
|
|
|
|
|
- if(callId == null || callId.length === 0) {
|
|
|
|
|
- console.log('请提供待监听电话的 callId !');
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ "transfer_call_success" : 618,
|
|
|
|
|
|
|
|
- if(!_cc.getIsConnected()){
|
|
|
|
|
- console.log('请先上线.');
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 产生asr语音识别结果
|
|
|
|
|
+ */
|
|
|
|
|
+ "asr_result_generate" : 619,
|
|
|
|
|
|
|
|
- this.monitorControl(
|
|
|
|
|
- "startMonitoring",
|
|
|
|
|
- {
|
|
|
|
|
- 'callSpyId': callId
|
|
|
|
|
- }
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 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 组件自行处理
|
|
|
*/
|
|
*/
|
|
|
- this.callMonitorEnd = function(){
|
|
|
|
|
- if(!_cc.getIsConnected()){
|
|
|
|
|
- console.log('请先上线.');
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ 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 数据绑定自动更新
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- this.monitorControl(
|
|
|
|
|
- "endMonitoring",{}
|
|
|
|
|
|
|
+ $('#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",{}
|
|
|
|
|
+ );
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|