|
|
@@ -16,7 +16,7 @@
|
|
|
<link href="../static/css/style.min.css" th:href="@{/css/style.min.css}" rel="stylesheet"/>
|
|
|
<link href="../static/css/theme-modern.css" th:href="@{/css/theme-modern.css?v=20260524}" rel="stylesheet"/>
|
|
|
<link rel="stylesheet" th:href="@{/phone-bar/page.css?v=1.0.4}"></link>
|
|
|
- <script th:src="@{/phone-bar/ccPhoneBarSocket.js?v=1.0.4}"></script>
|
|
|
+ <script th:src="@{/phone-bar/ccPhoneBarSocket.js?v=1.0.5}"></script>
|
|
|
<script>
|
|
|
//所有的列表页默认显示10条记录;
|
|
|
localStorage["bsTablePageSize"] = 10;
|
|
|
@@ -89,13 +89,74 @@
|
|
|
#popup-container iframe::-webkit-scrollbar-thumb:hover {
|
|
|
background: #a8a8a8;
|
|
|
}
|
|
|
+
|
|
|
+ /* HIS 嵌入模式:隐藏可视 UI,仅保留 PhoneBar 连接 */
|
|
|
+ html.his-ipcc-embed body,
|
|
|
+ html.his-ipcc-embed .wrapper,
|
|
|
+ html.his-ipcc-embed #ccPhoneBar,
|
|
|
+ html.his-ipcc-embed .gray-bg {
|
|
|
+ background: transparent !important;
|
|
|
+ }
|
|
|
+ html.his-ipcc-embed .wrapper,
|
|
|
+ html.his-ipcc-embed form,
|
|
|
+ html.his-ipcc-embed #work-container,
|
|
|
+ html.his-ipcc-embed .ibox,
|
|
|
+ html.his-ipcc-embed .phonebar-box {
|
|
|
+ display: none !important;
|
|
|
+ visibility: hidden !important;
|
|
|
+ height: 0 !important;
|
|
|
+ overflow: hidden !important;
|
|
|
+ }
|
|
|
</style>
|
|
|
+ <script th:inline="javascript">
|
|
|
+ var _hisEmbedMode = /*[[${embedMode}]]*/ false;
|
|
|
+ if (_hisEmbedMode) {
|
|
|
+ try { document.documentElement.className += ' his-ipcc-embed'; } catch (e) {}
|
|
|
+ // 跨域嵌入:禁止访问 top/parent.document,避免 SecurityError 打断外呼
|
|
|
+ window.isScrollToTop = true;
|
|
|
+ (function () {
|
|
|
+ function safeNoop() {}
|
|
|
+ function patchModal() {
|
|
|
+ if (!window.$ || !$.modal) return false;
|
|
|
+ $.modal.loading = safeNoop;
|
|
|
+ $.modal.closeLoading = safeNoop;
|
|
|
+ $.modal.disable = safeNoop;
|
|
|
+ $.modal.enable = safeNoop;
|
|
|
+ var _msg = $.modal.msg;
|
|
|
+ $.modal.msg = function () { try { console.debug.apply(console, arguments); } catch (e) {} };
|
|
|
+ var _alert = $.modal.alert;
|
|
|
+ $.modal.alert = function (m) { try { console.warn('[embed]', m); } catch (e) {} };
|
|
|
+ var _msgSuccess = $.modal.msgSuccess;
|
|
|
+ $.modal.msgSuccess = safeNoop;
|
|
|
+ var _msgError = $.modal.msgError;
|
|
|
+ $.modal.msgError = function (m) { try { console.warn('[embed]', m); } catch (e) {} };
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (!patchModal()) {
|
|
|
+ document.addEventListener('DOMContentLoaded', function () { patchModal(); });
|
|
|
+ setTimeout(patchModal, 0);
|
|
|
+ setTimeout(patchModal, 500);
|
|
|
+ }
|
|
|
+ })();
|
|
|
+ }
|
|
|
+ </script>
|
|
|
</head>
|
|
|
|
|
|
<body class="gray-bg">
|
|
|
|
|
|
+<th:block th:if="${embedMode}">
|
|
|
+<!-- HIS embed:仅加载 IPCC PhoneBar 必要依赖,跳过表格/校验等业务脚本;普通打开工作台不受影响 -->
|
|
|
+<script th:inline="javascript"> var ctx = [[@{/}]]; </script>
|
|
|
+<script th:src="@{/js/bootstrap.min.js?v=3.3.7}"></script>
|
|
|
+<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js?v=2.70.0}"></script>
|
|
|
+<script th:src="@{/ajax/libs/layer/layer.min.js?v=3.7.0}"></script>
|
|
|
+<script th:src="@{/ruoyi/js/common.js?v=4.7.11}"></script>
|
|
|
+<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.11}"></script>
|
|
|
+</th:block>
|
|
|
+<th:block th:unless="${embedMode}">
|
|
|
<th:block th:include="include :: footer" />
|
|
|
<th:block th:include="include :: layout-latest-js" />
|
|
|
+</th:block>
|
|
|
|
|
|
<form>
|
|
|
<!-- 首页/工作台 -->
|
|
|
@@ -331,11 +392,20 @@
|
|
|
<script th:inline="javascript">
|
|
|
var _phoneBar = new ccPhoneBarSocket();
|
|
|
var _scriptServer = window.location.host.split(":")[0];
|
|
|
+ // only when ruoyi.isLocalDebug=true
|
|
|
+ var _isLocalDebug = /*[[${isLocalDebug}]]*/ false;
|
|
|
+ var _localRemoteHost = /*[[${localRemoteHost}]]*/ '129.28.164.235';
|
|
|
+ if (_isLocalDebug && (_scriptServer === '127.0.0.1' || _scriptServer === 'localhost')) {
|
|
|
+ _scriptServer = _localRemoteHost || '129.28.164.235';
|
|
|
+ }
|
|
|
// var _scriptServer = [[${callConfig.scriptServer}]];
|
|
|
var _scriptPort = [[${callConfig.scriptPort}]];
|
|
|
var _loginToken = [[${callConfig.loginToken}]];
|
|
|
var _gatewayList = [[${callConfig.gatewayList}]];
|
|
|
var _autoFree = [[${autoFree}]];
|
|
|
+ var _embedExtNum = /*[[${callConfig.extNum}]]*/ '';
|
|
|
+ var _embedMyGateway = /*[[${callConfig.myGateway}]]*/ '';
|
|
|
+ var _ctxPath = /*[[@{/}]]*/ '/';
|
|
|
|
|
|
var _phoneNum = '';
|
|
|
var _uuid = '';
|
|
|
@@ -346,10 +416,37 @@
|
|
|
var reConnTimes = 0;
|
|
|
|
|
|
var _callConfig = null;
|
|
|
+
|
|
|
+ /** 向 HIS 父页回传 IPCC 状态(embed 模式) */
|
|
|
+ function hisIpccPost(type, payload) {
|
|
|
+ if (!_hisEmbedMode || !window.parent || window.parent === window) return;
|
|
|
+ try {
|
|
|
+ window.parent.postMessage({
|
|
|
+ channel: 'HIS_IPCC_EMBED',
|
|
|
+ type: type,
|
|
|
+ payload: payload || {}
|
|
|
+ }, '*');
|
|
|
+ } catch (e) {}
|
|
|
+ }
|
|
|
+
|
|
|
+ function hisIpccForwardEvent(code, msg) {
|
|
|
+ hisIpccPost('EVENT', {
|
|
|
+ code: String(code),
|
|
|
+ msg: msg || {},
|
|
|
+ connected: !!( _phoneBar && typeof _phoneBar.getIsConnected === 'function' && _phoneBar.getIsConnected()),
|
|
|
+ callConnected: !!( _phoneBar && typeof _phoneBar.getCallConnected === 'function' && _phoneBar.getCallConnected()),
|
|
|
+ activeCallUuid: (_phoneBar && typeof _phoneBar.getActiveCallUuid === 'function') ? (_phoneBar.getActiveCallUuid() || '') : '',
|
|
|
+ isCalling: !!( _phoneBar && _phoneBar.isCalling),
|
|
|
+ agentStatus: (_phoneBar && _phoneBar.agentStatus != null) ? _phoneBar.agentStatus : null,
|
|
|
+ myGateway: _embedMyGateway || ''
|
|
|
+ });
|
|
|
+ }
|
|
|
$(function() {
|
|
|
- // 调用函数填充视频清晰度的下拉列表
|
|
|
- populateVideoLevelDropdown('videoLevelSelect');
|
|
|
- populateVideoLevelDropdown('member_video_level');
|
|
|
+ // 普通工作台才初始化视频下拉;HIS embed 仅要 IPCC 信令,跳过无关 UI
|
|
|
+ if (!_hisEmbedMode) {
|
|
|
+ populateVideoLevelDropdown('videoLevelSelect');
|
|
|
+ populateVideoLevelDropdown('member_video_level');
|
|
|
+ }
|
|
|
|
|
|
// websocket通信对象断开事件;
|
|
|
_phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.ws_disconnected.code, function(msg){
|
|
|
@@ -373,7 +470,9 @@
|
|
|
_phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.user_login_on_other_device.code, function(msg){
|
|
|
console.log(msg, "用户已在其他设备登录");
|
|
|
_phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.user_login_on_other_device.code);
|
|
|
- $.modal.msgWarning(ccPhoneBarSocket.eventListWithTextInfo.user_login_on_other_device.msg);
|
|
|
+ if (!_hisEmbedMode) {
|
|
|
+ $.modal.msgWarning(ccPhoneBarSocket.eventListWithTextInfo.user_login_on_other_device.msg);
|
|
|
+ }
|
|
|
manualDisConn = true; // 被挤掉线的也不自动重连
|
|
|
});
|
|
|
|
|
|
@@ -385,16 +484,16 @@
|
|
|
});
|
|
|
|
|
|
_phoneBar.on(ccPhoneBarSocket.eventList.caller_not_login, function (msg) {
|
|
|
- $.modal.msgError(msg["msg"]);
|
|
|
+ if (!_hisEmbedMode) $.modal.msgError(msg["msg"]);
|
|
|
});
|
|
|
_phoneBar.on(ccPhoneBarSocket.eventList.outbound_finished, function (msg) {
|
|
|
- $.modal.msgError(msg["msg"]);
|
|
|
+ if (!_hisEmbedMode) $.modal.msgError(msg["msg"]);
|
|
|
});
|
|
|
_phoneBar.on(ccPhoneBarSocket.eventList.server_error_audio_codec_not_match, function (msg) {
|
|
|
- $.modal.msgError(msg["msg"]);
|
|
|
+ if (!_hisEmbedMode) $.modal.msgError(msg["msg"]);
|
|
|
});
|
|
|
_phoneBar.on(ccPhoneBarSocket.eventList.server_error, function (msg) {
|
|
|
- $.modal.msgError(msg["msg"]);
|
|
|
+ if (!_hisEmbedMode) $.modal.msgError(msg["msg"]);
|
|
|
});
|
|
|
|
|
|
// 被叫振铃事件
|
|
|
@@ -406,11 +505,12 @@
|
|
|
// 呼入事件
|
|
|
_phoneBar.on(ccPhoneBarSocket.eventList.new_inbound_call, function(msg){
|
|
|
console.log(msg, "呼入" );
|
|
|
-
|
|
|
- // 呼入弹屏
|
|
|
_phoneNum = msg.object.caller;
|
|
|
_uuid = msg.object.uuid;
|
|
|
- addCallRecord(_phoneNum, _uuid, 1);
|
|
|
+ // HIS embed:弹屏/CRM 由父页处理,避免多余 iframe/接口
|
|
|
+ if (!_hisEmbedMode) {
|
|
|
+ addCallRecord(_phoneNum, _uuid, 1);
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
// 主叫接通事件
|
|
|
@@ -418,20 +518,16 @@
|
|
|
console.log(msg, "主叫接通" );
|
|
|
$("#agentStatus").text("通话中");
|
|
|
_phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.caller_answered.code);
|
|
|
- // 外呼弹屏
|
|
|
- // var _phoneNum = $("#ccphoneNumber").val();
|
|
|
- // var _uuid = msg.object.uuid;
|
|
|
- // addCallRecord(_phoneNum, _uuid, 2);
|
|
|
-
|
|
|
});
|
|
|
|
|
|
// 外呼事件
|
|
|
_phoneBar.on(ccPhoneBarSocket.eventList.OUTBOUND_START, function (msg) {
|
|
|
console.log('outbound_start',msg);
|
|
|
- // 外呼弹屏
|
|
|
_phoneNum = msg.object.destPhone;
|
|
|
_uuid = msg.object.uuid;
|
|
|
- addCallRecord(_phoneNum, _uuid, 2);
|
|
|
+ if (!_hisEmbedMode) {
|
|
|
+ addCallRecord(_phoneNum, _uuid, 2);
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
|
|
|
@@ -443,8 +539,10 @@
|
|
|
$("#sendVideoFileBtn").attr("disabled","disabled");
|
|
|
$("#transfer_area").hide();
|
|
|
_phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.caller_hangup.code);
|
|
|
-
|
|
|
- addAsrRecord(_phoneNum, _uuid, _call_type, _asrResult);
|
|
|
+ // HIS embed:话单/ASR 由父页 sipCallCdrSync 负责
|
|
|
+ if (!_hisEmbedMode) {
|
|
|
+ addAsrRecord(_phoneNum, _uuid, _call_type, _asrResult);
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
// 被叫接通事件
|
|
|
@@ -630,9 +728,10 @@
|
|
|
onTransferToConferenceSuccess(msg);
|
|
|
});
|
|
|
|
|
|
- // 订阅的坐席状态列表发生改变
|
|
|
+ // 订阅的坐席状态列表发生改变(转接 UI 仅普通工作台)
|
|
|
_phoneBar.on(ccPhoneBarSocket.eventList.agent_status_data_changed, function (msg) {
|
|
|
console.log("agent_status_data_changed.");
|
|
|
+ if (_hisEmbedMode) return;
|
|
|
// 当 transfer_to_groupId 值改变时更新 transfer_to_member
|
|
|
$(transferToGroupId).off("change");
|
|
|
$(transferToGroupId).on("change", function () {
|
|
|
@@ -643,7 +742,7 @@
|
|
|
|
|
|
// 电话工具条参数配置;
|
|
|
_callConfig = {
|
|
|
- 'useDefaultUi' : true,
|
|
|
+ 'useDefaultUi' : !_hisEmbedMode,
|
|
|
// loginToken 信息是加密的字符串, 包含以下字段信息:extnum[分机号]、opnum[工号]、groupId[业务组]、skillLevel[技能等级]
|
|
|
'loginToken': _loginToken,
|
|
|
|
|
|
@@ -654,30 +753,6 @@
|
|
|
// 注意在注册模式下,网关参数更改之后,必须重启语音服务 [docker restart freeswitch] 方可生效,不支持热更新;
|
|
|
// 支持多个网关同时使用,按照优先级依次使用, 支持网关负载容错溢出 [第一条网关外呼出错后,自动使用第二条网关重试,直至外呼不出错] ;
|
|
|
'gatewayList' : _gatewayList,
|
|
|
- // 'gatewayList': [
|
|
|
- // {
|
|
|
- // uuid: '01', // 网关唯一编号;
|
|
|
- // updateTime: 1712611571863, //网关信息更新时间, 每次修改必须更新这个字段,否则配置无法生效;
|
|
|
- // gatewayAddr: '192.168.67.210:5090', // 网关地址或名称, 如果是注册模式: 网关地址参数则填写为网关名称;
|
|
|
- // callerNumber: '64901409', //主叫号码
|
|
|
- // calleePrefix: '', // 被叫前缀
|
|
|
- // priority: 2, //优先级,数字越小,越优先被使用;
|
|
|
- // concurrency: 20, // 网关并发数,同时支持呼叫数;
|
|
|
- // register: false, // 是否为注册模式
|
|
|
- // audioCodec: 'g711' // 网关通信语音编码;
|
|
|
- // } ,
|
|
|
- // {
|
|
|
- // uuid: '02', // 网关唯一编号;
|
|
|
- // updateTime: 1712611571863, //网关信息更新时间, 每次修改必须更新这个字段,否则配置无法生效;
|
|
|
- // gatewayAddr: '192.168.67.210:5092', // 网关地址或名称, 如果是注册模式: 网关地址参数则填写为网关名称;
|
|
|
- // callerNumber: '64901408', //主叫号码
|
|
|
- // calleePrefix: '', // 被叫前缀
|
|
|
- // priority: 1, //优先级,数字越小,越优先被使用;
|
|
|
- // concurrency: 20, // 网关并发数,同时支持呼叫数;
|
|
|
- // register: false, // 是否为注册模式
|
|
|
- // audioCodec: 'g711' // 网关通信语音编码;
|
|
|
- // }
|
|
|
- // ],
|
|
|
|
|
|
// 网关列表信息是否为加密模式;
|
|
|
'gatewayEncrypted': false
|
|
|
@@ -689,17 +764,225 @@
|
|
|
console.log(_callConfig);
|
|
|
_phoneBar.initConfig(_callConfig);
|
|
|
|
|
|
+ // embed:转发关键 IPCC 事件给父页
|
|
|
+ if (_hisEmbedMode) {
|
|
|
+ var _forwardCodes = [
|
|
|
+ ccPhoneBarSocket.eventListWithTextInfo.ws_connected.code,
|
|
|
+ ccPhoneBarSocket.eventListWithTextInfo.ws_disconnected.code,
|
|
|
+ ccPhoneBarSocket.eventListWithTextInfo.user_login_on_other_device.code,
|
|
|
+ ccPhoneBarSocket.eventListWithTextInfo.request_args_error.code,
|
|
|
+ ccPhoneBarSocket.eventListWithTextInfo.status_changed.code,
|
|
|
+ ccPhoneBarSocket.eventListWithTextInfo.callee_ringing.code,
|
|
|
+ ccPhoneBarSocket.eventListWithTextInfo.caller_answered.code,
|
|
|
+ ccPhoneBarSocket.eventListWithTextInfo.caller_hangup.code,
|
|
|
+ ccPhoneBarSocket.eventListWithTextInfo.callee_answered.code,
|
|
|
+ ccPhoneBarSocket.eventListWithTextInfo.callee_hangup.code,
|
|
|
+ ccPhoneBarSocket.eventList.OUTBOUND_START,
|
|
|
+ ccPhoneBarSocket.eventList.caller_not_login,
|
|
|
+ ccPhoneBarSocket.eventList.outbound_finished,
|
|
|
+ ccPhoneBarSocket.eventList.server_error,
|
|
|
+ ccPhoneBarSocket.eventList.server_error_audio_codec_not_match,
|
|
|
+ ccPhoneBarSocket.eventList.on_audio_call_connected,
|
|
|
+ ccPhoneBarSocket.eventList.customer_channel_hold,
|
|
|
+ ccPhoneBarSocket.eventList.customer_channel_unhold,
|
|
|
+ ccPhoneBarSocket.eventList.customer_on_hold_hangup,
|
|
|
+ ccPhoneBarSocket.eventList.callee_busy,
|
|
|
+ ccPhoneBarSocket.eventList.caller_busy
|
|
|
+ ];
|
|
|
+ _forwardCodes.forEach(function(code) {
|
|
|
+ if (code == null) return;
|
|
|
+ _phoneBar.on(code, function(msg) {
|
|
|
+ hisIpccForwardEvent(code, msg);
|
|
|
+ var codeStr = String(code);
|
|
|
+ if (codeStr === String(ccPhoneBarSocket.eventListWithTextInfo.ws_connected.code)) {
|
|
|
+ hisIpccPost('CONNECTED', {
|
|
|
+ connected: true,
|
|
|
+ extNum: _embedExtNum,
|
|
|
+ myGateway: _embedMyGateway || ''
|
|
|
+ });
|
|
|
+ } else if (codeStr === String(ccPhoneBarSocket.eventListWithTextInfo.ws_disconnected.code)
|
|
|
+ || codeStr === String(ccPhoneBarSocket.eventListWithTextInfo.user_login_on_other_device.code)) {
|
|
|
+ hisIpccPost('DISCONNECTED', {
|
|
|
+ connected: false,
|
|
|
+ code: codeStr,
|
|
|
+ msg: msg
|
|
|
+ });
|
|
|
+ } else if (codeStr === String(ccPhoneBarSocket.eventListWithTextInfo.status_changed.code)) {
|
|
|
+ hisIpccPost('STATUS', {
|
|
|
+ status: msg && msg.object ? msg.object.status : null,
|
|
|
+ text: msg && msg.object ? msg.object.text : '',
|
|
|
+ msg: msg
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ hisIpccPost('READY', { extNum: _embedExtNum, myGateway: _embedMyGateway || '' });
|
|
|
+ }
|
|
|
|
|
|
// 设置自动连接电话工具条
|
|
|
setTimeout(function () {
|
|
|
console.log(" 正在尝试连接电话工具条, 端口 1081 ");
|
|
|
_phoneBar.connect();
|
|
|
- }, 1500);
|
|
|
+ }, _hisEmbedMode ? 300 : 1500);
|
|
|
|
|
|
$("#work-container").hide();
|
|
|
|
|
|
+ // embed 控制指令
|
|
|
+ if (_hisEmbedMode) {
|
|
|
+ initHisIpccEmbedCommandBridge();
|
|
|
+ }
|
|
|
+
|
|
|
});
|
|
|
|
|
|
+ function initHisIpccEmbedCommandBridge() {
|
|
|
+ window.addEventListener('message', function(event) {
|
|
|
+ var data = event.data;
|
|
|
+ if (!data || data.channel !== 'HIS_IPCC_EMBED') return;
|
|
|
+ var type = data.type;
|
|
|
+ var payload = data.payload || {};
|
|
|
+ try {
|
|
|
+ if (type === 'PING') {
|
|
|
+ hisIpccPost('PONG', {
|
|
|
+ connected: !!( _phoneBar && _phoneBar.getIsConnected && _phoneBar.getIsConnected()),
|
|
|
+ callConnected: !!( _phoneBar && _phoneBar.getCallConnected && _phoneBar.getCallConnected()),
|
|
|
+ activeCallUuid: (_phoneBar && _phoneBar.getActiveCallUuid) ? (_phoneBar.getActiveCallUuid() || '') : '',
|
|
|
+ myGateway: _embedMyGateway || ''
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (type === 'CALL') {
|
|
|
+ var phone = payload.phone;
|
|
|
+ var callType = payload.callType || 'audio';
|
|
|
+ var videoLevel = payload.videoLevel;
|
|
|
+ var started = false;
|
|
|
+ var failMsg = '';
|
|
|
+ try {
|
|
|
+ if (!_phoneBar) {
|
|
|
+ failMsg = '电话条未就绪';
|
|
|
+ } else if (!phone) {
|
|
|
+ failMsg = '号码为空';
|
|
|
+ } else if (typeof _phoneBar.getIsConnected === 'function' && !_phoneBar.getIsConnected()) {
|
|
|
+ failMsg = 'IPCC未连接';
|
|
|
+ } else {
|
|
|
+ // call() 本身无布尔返回值,发出指令即视为已受理
|
|
|
+ _phoneBar.call(phone, callType, videoLevel);
|
|
|
+ started = true;
|
|
|
+ }
|
|
|
+ } catch (callErr) {
|
|
|
+ failMsg = (callErr && callErr.message) || String(callErr);
|
|
|
+ started = false;
|
|
|
+ }
|
|
|
+ hisIpccPost('CALL_RESULT', { ok: started, phone: phone, msg: failMsg || '' });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (type === 'HANGUP') {
|
|
|
+ if (_phoneBar) _phoneBar.hangup();
|
|
|
+ hisIpccPost('HANGUP_RESULT', { ok: true });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (type === 'HOLD') {
|
|
|
+ var holdOk = false;
|
|
|
+ if (_phoneBar && typeof _phoneBar.holdCall === 'function') holdOk = !!_phoneBar.holdCall();
|
|
|
+ hisIpccPost('HOLD_RESULT', { ok: holdOk });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (type === 'UNHOLD') {
|
|
|
+ var unholdOk = false;
|
|
|
+ if (_phoneBar && typeof _phoneBar.unHoldCall === 'function') unholdOk = !!_phoneBar.unHoldCall();
|
|
|
+ hisIpccPost('UNHOLD_RESULT', { ok: unholdOk });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (type === 'DISCONNECT') {
|
|
|
+ manualDisConn = true;
|
|
|
+ if (_phoneBar) {
|
|
|
+ if (typeof _phoneBar.forceDisconnect === 'function') _phoneBar.forceDisconnect();
|
|
|
+ else _phoneBar.disconnect();
|
|
|
+ }
|
|
|
+ hisIpccPost('DISCONNECTED', { connected: false, manual: true });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (type === 'SET_STATUS') {
|
|
|
+ var st = payload.status;
|
|
|
+ if (_phoneBar) {
|
|
|
+ if (st === 'busy' && typeof _phoneBar.setStatusBusy === 'function') _phoneBar.setStatusBusy();
|
|
|
+ else if (st === 'free' && typeof _phoneBar.setStatusFree === 'function') _phoneBar.setStatusFree();
|
|
|
+ else if (st != null && typeof _phoneBar.setStatus === 'function') _phoneBar.setStatus(st);
|
|
|
+ }
|
|
|
+ hisIpccPost('SET_STATUS_RESULT', { ok: true, status: st });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (type === 'SWITCH_GATEWAY') {
|
|
|
+ hisIpccSwitchGateway(payload.myGateway);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (type === 'RECONNECT') {
|
|
|
+ manualDisConn = false;
|
|
|
+ if (_phoneBar) {
|
|
|
+ if (typeof _phoneBar.resetKickedState === 'function') _phoneBar.resetKickedState();
|
|
|
+ if (typeof _phoneBar.reconnect === 'function') _phoneBar.reconnect();
|
|
|
+ else _phoneBar.connect();
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ hisIpccPost('ERROR', { msg: (err && err.message) || String(err), type: type });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function hisIpccSwitchGateway(myGateway) {
|
|
|
+ var gw = (myGateway == null || myGateway === '') ? '' : String(myGateway);
|
|
|
+ var extNum = _embedExtNum;
|
|
|
+ if (!extNum) {
|
|
|
+ hisIpccPost('ERROR', { msg: '分机号缺失,无法切换网关' });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ hisIpccPost('SWITCH_GATEWAY_START', { myGateway: gw });
|
|
|
+ $.ajax({
|
|
|
+ url: (typeof ctx !== 'undefined' ? ctx : (_ctxPath || '/')) + 'aicall/api/myPhoneBar/params',
|
|
|
+ type: 'POST',
|
|
|
+ contentType: 'application/json;charset=utf-8',
|
|
|
+ dataType: 'json',
|
|
|
+ data: JSON.stringify({ extNum: String(extNum), myGateway: gw }),
|
|
|
+ success: function(r) {
|
|
|
+ if (!r || (r.code !== 0 && r.code !== 200) || !r.data || !r.data.loginToken) {
|
|
|
+ hisIpccPost('ERROR', { msg: (r && (r.msg || r.message)) || '切换网关失败', type: 'SWITCH_GATEWAY' });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ _embedMyGateway = gw;
|
|
|
+ var data = r.data;
|
|
|
+ var scriptServer = data.scriptServer || _scriptServer;
|
|
|
+ var scriptPort = data.scriptPort || _scriptPort;
|
|
|
+ _callConfig = {
|
|
|
+ useDefaultUi: false,
|
|
|
+ loginToken: data.loginToken,
|
|
|
+ ipccServer: scriptServer + ':' + scriptPort,
|
|
|
+ gatewayList: data.gatewayList || [],
|
|
|
+ gatewayEncrypted: false
|
|
|
+ };
|
|
|
+ try {
|
|
|
+ if (_phoneBar) {
|
|
|
+ if (typeof _phoneBar.forceDisconnect === 'function') _phoneBar.forceDisconnect();
|
|
|
+ else _phoneBar.disconnect();
|
|
|
+ }
|
|
|
+ } catch (e) {}
|
|
|
+ setTimeout(function() {
|
|
|
+ try {
|
|
|
+ _phoneBar.initConfig(_callConfig);
|
|
|
+ if (typeof _phoneBar.resetKickedState === 'function') _phoneBar.resetKickedState();
|
|
|
+ _phoneBar.connect();
|
|
|
+ hisIpccPost('SWITCH_GATEWAY_DONE', { myGateway: gw, ok: true });
|
|
|
+ } catch (err) {
|
|
|
+ hisIpccPost('ERROR', { msg: (err && err.message) || String(err), type: 'SWITCH_GATEWAY' });
|
|
|
+ }
|
|
|
+ }, 400);
|
|
|
+ },
|
|
|
+ error: function(xhr, status, error) {
|
|
|
+ hisIpccPost('ERROR', { msg: error || '切换网关请求失败', type: 'SWITCH_GATEWAY' });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
function onConferenceEnd() {
|
|
|
document.getElementById("endConference").setAttribute("disabled", "true");
|
|
|
document.getElementById("startConference").removeAttribute("disabled");
|
|
|
@@ -810,6 +1093,8 @@
|
|
|
}
|
|
|
|
|
|
function addCallRecord(phoneNum, uuid, call_type) {
|
|
|
+ // HIS iframe 集成:不加载弹屏/CRM iframe,避免多余接口与跨域噪音
|
|
|
+ if (_hisEmbedMode) return;
|
|
|
|
|
|
$("#work-container").show();
|
|
|
$("#chat-container").show();
|
|
|
@@ -830,16 +1115,6 @@
|
|
|
$('#popup-container').empty().append(
|
|
|
'<iframe src="' + url + '" title="' + title + '"></iframe>'
|
|
|
);
|
|
|
-
|
|
|
- // _phoneNum = phoneNum;
|
|
|
- // _uuid = uuid;
|
|
|
- // _call_type = call_type;
|
|
|
- // var modealName = '外呼弹屏';
|
|
|
- // if (_call_type == 1) {
|
|
|
- // modealName = '呼入弹屏';
|
|
|
- // }
|
|
|
- // var url = ctx + "cc/custcallrecord/add?phoneNum=" + _phoneNum + "&callType=" + _call_type + "&uuid=" + _uuid;
|
|
|
- // $.modal.open(modealName, url);
|
|
|
}
|
|
|
|
|
|
$('#onLineBtn').on('click', function () {
|
|
|
@@ -854,23 +1129,26 @@
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- /* asr实时对话文本框的功能 */
|
|
|
- _phoneBar.on(ccPhoneBarSocket.eventList.asr_process_started, function (msg) {
|
|
|
- $(chatMessages).html("");
|
|
|
- });
|
|
|
- _phoneBar.on(ccPhoneBarSocket.eventList.asr_result_generate, function (msg) {
|
|
|
- handleAsrMessage(msg);
|
|
|
- });
|
|
|
- _phoneBar.on(ccPhoneBarSocket.eventList.asr_process_end_customer, function (msg) {
|
|
|
- handleAsrMessage(msg);
|
|
|
- });
|
|
|
- _phoneBar.on(ccPhoneBarSocket.eventList.asr_process_end_agent, function (msg) {
|
|
|
- handleAsrMessage(msg);
|
|
|
- });
|
|
|
+ /* asr实时对话:仅普通工作台;HIS embed 跳过,减少无效监听/接口 */
|
|
|
+ if (!_hisEmbedMode) {
|
|
|
+ _phoneBar.on(ccPhoneBarSocket.eventList.asr_process_started, function (msg) {
|
|
|
+ $(chatMessages).html("");
|
|
|
+ });
|
|
|
+ _phoneBar.on(ccPhoneBarSocket.eventList.asr_result_generate, function (msg) {
|
|
|
+ handleAsrMessage(msg);
|
|
|
+ });
|
|
|
+ _phoneBar.on(ccPhoneBarSocket.eventList.asr_process_end_customer, function (msg) {
|
|
|
+ handleAsrMessage(msg);
|
|
|
+ });
|
|
|
+ _phoneBar.on(ccPhoneBarSocket.eventList.asr_process_end_agent, function (msg) {
|
|
|
+ handleAsrMessage(msg);
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
|
|
|
const chatMessages = document.getElementById('chat-messages');
|
|
|
function handleAsrMessage(data) {
|
|
|
+ if (_hisEmbedMode) return;
|
|
|
$("#chat-container").show();
|
|
|
const { status, object } = data;
|
|
|
if (status === 619 && object) {
|
|
|
@@ -917,7 +1195,8 @@
|
|
|
}
|
|
|
|
|
|
function addAsrRecord(_phoneNum, _uuid, _call_type, _asrResult) {
|
|
|
- console.log(_autoFree);
|
|
|
+ // HIS embed:不写 custDialog / 不点置闲,话单由父页负责
|
|
|
+ if (_hisEmbedMode) return;
|
|
|
if (_autoFree) {
|
|
|
$("#setFree").click();
|
|
|
}
|
|
|
@@ -934,10 +1213,18 @@
|
|
|
"dialog": JSON.stringify(_asrResult),
|
|
|
},
|
|
|
beforeSend: function () {
|
|
|
+ // embed 跨域时 $.modal.disable 会读 parent.document → SecurityError
|
|
|
+ if (_hisEmbedMode) return;
|
|
|
$.modal.loading(i18n("common.tip.loading"));
|
|
|
$.modal.disable();
|
|
|
},
|
|
|
success: function(result) {
|
|
|
+ if (_hisEmbedMode) return;
|
|
|
+ $.modal.closeLoading();
|
|
|
+ $.modal.enable();
|
|
|
+ },
|
|
|
+ error: function () {
|
|
|
+ if (_hisEmbedMode) return;
|
|
|
$.modal.closeLoading();
|
|
|
$.modal.enable();
|
|
|
}
|