<!DOCTYPE html>
<html  lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script th:src="@{/js/jquery.min.js}"></script>
    <script th:src="@{/js/jquery.i18n.properties.js}"></script>
    <div id="root-path" th:text="${#servletContext.contextPath}" style="display:none;"></div>
    <div id="lang-country" th:text="${#locale.language + '_' + #locale.country}" style="display:none;"></div>
    <script th:src="@{/js/i18n.js}"></script>
    <!--360浏览器优先以webkit内核解析-->
    <title th:text="#{page.title}">我的工作台</title>
    <link rel="shortcut icon" href="favicon.ico">
    <link href="../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
    <link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
    <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.5}"></script>
    <script>
        //所有的列表页默认显示10条记录;
        localStorage["bsTablePageSize"] = 10;
    </script>
    <style>
        html, body {
            margin: 0;
            height: 100%;
            overflow: hidden;
        }

        .wrapper {
            display: flex;
            height: 90%;
        }

        #left-panel {
            flex: 3;
            display: flex;
            flex-direction: column;
        }

        #chat-container {
            flex: 1;
            overflow-y: auto;
            padding: 10px;
        }

        #right-panel {
            flex: 7;
            overflow: hidden;
            display: flex;
            flex-direction: column;
        }

        #popup-container {
            flex: 1;
            display: flex;        /* 让 iframe 撑满 */
            overflow: hidden;     /* 外层不滚动 */
        }
        #popup-container iframe {
            width: 100%;
            border: none;
            overflow-y: auto;     /* 让弹屏页面内部自己滚动 */
        }

        /* 统一滚动条样式（去掉上下边框） */
        #chat-container::-webkit-scrollbar,
        #popup-container::-webkit-scrollbar,
        #popup-container iframe::-webkit-scrollbar {
            width: 8px;
        }

        #chat-container::-webkit-scrollbar-track,
        #popup-container::-webkit-scrollbar-track,
        #popup-container iframe::-webkit-scrollbar-track {
            background: transparent;      /* 去掉背景色/边框感 */
        }

        #chat-container::-webkit-scrollbar-thumb,
        #popup-container::-webkit-scrollbar-thumb,
        #popup-container iframe::-webkit-scrollbar-thumb {
            background: #c1c1c1;
            border-radius: 4px;
            border: none;                 /* 关键：去掉边框 */
        }

        #chat-container::-webkit-scrollbar-thumb:hover,
        #popup-container::-webkit-scrollbar-thumb:hover,
        #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>
    <!-- 首页/工作台 -->
    <table width="1224">
        <tr>
            <td width="70%" colspan="2" height="35" style="text-indent: 20px;">
                <b th:text="#{phonebar.label.loginTime}"></b> <span id="loginTime" title="" class="status4">00:00:00</span> &nbsp;&nbsp;
                <b th:text="#{phonebar.label.agentStatus}"></b> <span id="agentStatus" title="" class="status4" th:text="#{phonebar.msg.free}"></span> &nbsp;&nbsp;
                <b th:text="#{phonebar.label.queueStat}"></b><span id="queueStat" title="" class="status4">0</span>
            </td>
        </tr>
        <tr>
            <td width="70%">
                <div>
                    <div class="head_dial" style="padding-left: 10px; ">
                        <dl class="dial">
                            <dt>
                                <label for="ccphoneNumber"></label><input type="text" name="ccphoneNumber" id="ccphoneNumber" th:placeholder="#{phonebar.placeholder.phonenum}" class="tel_txt" />
                            </dt>
                            <dd>
                                <ul><li id="callStatus" title="" class="status4"><span th:text="#{phonebar.ws.state.noconnected}"></span></li></ul>
                                <span id="showCallLen" style="display:none"><b>00:00</b></span>
                            </dd>
                        </dl>

                        <ul class="dial_btn">
                            <li><a href="#" id="setFree" class="xz_btn off"></a><span th:text="#{phonebar.btn.free}">置闲</span></li>
                            <li><a href="#" id="setBusy" class="sm_btn off"></a>
                                <select style="width: 50px;" id="setBusySubList">
                                    <option value="3" th:text="#{phonebar.btn.busy.sub.busy}">置忙</option>
                                    <option value="31" th:text="#{phonebar.btn.busy.sub.rest}">小休</option>
                                    <option value="32" th:text="#{phonebar.btn.busy.sub.meeting}">会议</option>
                                    <option value="33" th:text="#{phonebar.btn.busy.sub.training}">培训</option>
                                </select>
                            </li>
                            <li><a href="#" id="callBtn" class="wh_btn"></a><span th:text="#{phonebar.btn.call}">外呼</span></li>
                            <li id="holdBtnLi"><a href="#" id="holdBtn" class="bc_btn off"></a><span th:text="#{phonebar.btn.hold}">保 持</span></li>
                            <li id="unHoldBtnLi"><a href="#" id="unHoldBtn" class="bc2_btn off"></a><span th:text="#{phonebar.btn.unhold}">取消保持</span></li>
                            <li><a href="#" id="transferBtn" class="zjie_btn"></a><span th:text="#{phonebar.btn.transfer}">转接</span></li>
                            <li><a href="#" id="consultationBtn" class="zixun_btn"></a><span th:text="#{phonebar.btn.consultation}">咨询</span></li>
                            <li><a href="#" id="conferenceBtn" class="hy_btn"></a><span th:text="#{phonebar.btn.conference}">会议</span></li>
                            <li><a href="#" id="hangUpBtn" class="gj_btn"></a><span th:text="#{phonebar.btn.hangUp}">挂机</span></li>
                            <li><a href="#" id="resetStatus" class="qz_btn"></a><span th:text="#{phonebar.btn.reset}">强置</span></li>
                            <li><a href="#" id="onLineBtn" class="sx_btn on"></a><span th:text="#{phonebar.btn.onLine}">签入</span></li>
                        </ul>

                    </div>
                </div>
            </td>
            <td width="30%" style="display: none;">
                <div>
                    <div  style="padding-left: 10px; ">
                        &nbsp; &nbsp;  <span th:text="#{phonebar.label.callSet}"></span>：
                        <label for="videoCallBtn"> <input type="radio" value="video" name="callType" id="videoCallBtn" th:text="#{phonebar.video.label.video}"/></label>  &nbsp;&nbsp;
                        <label for="audioCallBtn"> <input type="radio" value="audio"  name="callType" checked="checked" id="audioCallBtn"  th:text="#{phonebar.video.label.audio}"/></label>  <br />

                        &nbsp; &nbsp; <span th:text="#{phonebar.label.videoSet}"></span>:
                        <label for="videoLevelSelect"></label><select id="videoLevelSelect">
                    </select>
                        <input type="button" id="reInviteVideoBtn" th:title="#{phonebar.video.title.invite}"
                               onclick="_phoneBar.reInviteVideoCall();"       th:value="#{phonebar.video.input.invite}" disabled="disabled" >

                        &nbsp;&nbsp;&nbsp;&nbsp;
                        <label for="videoListSelect"></label>
                        <select id="videoListSelect">
                            <option value="" th:text="#{phonebar.video.option.empty}"></option>
                            <option value="/usr/local/freeswitchvideo/share/freeswitch/sounds/bank.mp4" th:text="#{phonebar.video.option.bank}"></option>
                            <option value="/usr/local/freeswitchvideo/share/freeswitch/sounds/conference.mp4" th:text="#{phonebar.video.option.conference}"></option>
                            <option value="/usr/local/freeswitchvideo/share/freeswitch/sounds/15-seconds.mp4" th:text="#{phonebar.video.option.demo}"></option>

                        </select>
                        <input type="button" id="sendVideoFileBtn" th:title="#{phonebar.video.title.push}"
                               onclick="_phoneBar.sendVideoFile($('#videoListSelect').val());"   th:value="#{phonebar.video.input.push}" disabled="disabled" >

                    </div>
                </div>
            </td>
        </tr>

        <tr id="conference_area" style="display: none">

            <td colspan="2" style="padding-left: 130px; padding-top: 30px; width: 900px; ">
                <div>
                    <div>
                        <div id="conference_start" style="display: block">
                            <!-- 会议布局: &nbsp; -->
                            <select id="conf_layout" name="conf_layout" style="display: none">
                                <option value="2x2">2x2</option>
                                <option value="3x3">3x3</option>
                                <option value="1up_top_left+3">一主三从</option>
                            </select>
                            &nbsp;
                            <!-- 画布尺寸: -->
                            <select id="conf_template" name="conf_template" style="display: none">
                                <option value="480p" selected="selected">480x640</option>
                                <option value="720p">720x1080</option>
                                <option value="default">default</option>
                            </select>
                            &nbsp;
                            <span th:text="#{phonebar.conference.label.type}"></span>:
                            <select id="conf_call_type2" name="conf_call_type2"  >
                                <!-- <option value="video">视频</option> -->
                                <option value="audio" th:text="#{phonebar.conference.option.audio}"></option>
                            </select>
                            <input type="hidden" value="audio" id="conf_call_type" name="conf_call_type" />
                            &nbsp;
                            <input type="button" name="startConference" id="startConference"
                                   onclick="_phoneBar.conferenceStartBtnUI('')"
                                   style="width: 70px;" th:value="#{phonebar.conference.btn.start}">
                            &nbsp;
                            <input type="button" name="endConference" id="endConference"
                                   onclick="_phoneBar.conferenceEnd()"
                                   disabled="disabled"
                                   style="width: 70px;" th:value="#{phonebar.conference.btn.end}">
                        </div>

                        <div style="width: 100%;"> &nbsp; </div>

                        <div id="conference_member_list" style="display: none">
                            <ul>
                                <li id="conference_header">
                                    <span class="conf_name"> <input id="member_name" name="member_name" th:placeholder="#{phonebar.conference.placeholder.name}" style="width: 60px;" /> </span> &nbsp;
                                    <span class="conf_phone"> <input id="member_phone" name="member_phone" th:placeholder="#{phonebar.conference.placeholder.phone}" style="width: 110px;" /> </span> &nbsp;
                                    <span class="conf_call_type">
                                <select id="member_call_type" name="member_call_type" style="display: none">
                                   <option value="video" th:text="#{phonebar.conference.option.video}"></option>
                                   <option value="audio" selected th:text="#{phonebar.conference.option.audio}"></option>
                               </select>
                            </span>
                                    <span class="conf_video_level" style="display: none">
                                <select id="member_video_level" name="member_video_level">
                               </select>
                            </span>

                                    <span class="conf_name">
                               <input type="button" name="addConfMember" id="addConfMember"
                                      onclick="_phoneBar.conferenceAddMemberBtnUI(0)"
                                      style="width: 70px;" th:value="#{phonebar.conference.btn.join}">
                           </span>
                                </li>

                                <!-- 会议成员展示模版html  -->
                                <li id="conf_member_template"  style="display: none;">
                                    <span class="conf_name">{member_name}</span>
                                    <span class="conf_phone">{member_phone}</span>
                                    <span class="conf_mute"><a href="javascript:void(0)" onclick="_phoneBar.conferenceMuteMember('{member_phone}')"><img th:alt="#{phonebar.conference.alt.mute}" src="../phone-bar/images/mute.jpg" width="15" height="17" /> </a> </span>
                                    <span class="conf_vmute" style="display: none"><a href="javascript:void(0)" onclick="_phoneBar.conferenceVMuteMember('{member_phone}')"><img th:alt="#{phonebar.conference.alt.vmute}" src="../phone-bar/images/video.jpg" /> </a></span>
                                    <span class="conf_remove"><a href="javascript:void(0)" onclick="_phoneBar.conferenceRemoveMembers('{member_phone}')" th:title="#{phonebar.conference.title.remove}" th:text="#{phonebar.conference.btn.remove}">移除</a></span>
                                    <span class="conf_re_invite"><a href="javascript:void(0)" onclick="_phoneBar.conferenceAddMemberBtnUI(1, '{member_phone}', '{member_name}')" th:title="#{phonebar.conference.title.reinvite}" th:text="#{phonebar.conference.btn.reinvite}">重呼</a></span>
                                    <span class="conf_status">{member_status}</span>
                                </li>


                                <li></li>
                            </ul>
                        </div>


                    </div>
                </div>
            </td>

        </tr>

        <tr id="transfer_area" width="100%" style="display: none">

            <td colspan="2" width="100%" style="padding-left: 140px; padding-top: 30px;">
                <table width="100%">
                    <tr>
                        <td width="90" th:text="#{phonebar.transfer.label.group}">业务组   </td>
                        <td width="90" th:text="#{phonebar.transfer.label.member}">坐席成员</td>
                        <td>&nbsp; </td>
                    </tr>
                    <tr>
                        <td>
                            <select size="10" id="transfer_to_groupIds" name="transfer_to_groupIds">
                                <option value="" th:text="#{phonebar.transfer.option.select}">请选择</option>
                            </select>
                        </td>

                        <td>
                            <select size="10" id="transfer_to_member" name="transfer_to_member">
                                <option value="" th:text="#{phonebar.transfer.option.select}">请选择</option>
                            </select>
                        </td>
                        <td valign="middle">


                            &nbsp;&nbsp; <input type="text" name="externalPhoneNumber" id="externalPhoneNumber" th:placeholder="#{phonebar.transfer.placeholder.phone}"
                                                th:title="#{phonebar.transfer.title.externalPhone}"
                                                class="tel_txt" />
                            <br /> <br />

                            &nbsp;&nbsp; <input type="button" name="doTransferBtn" id="doTransferBtn"
                                                onclick="_phoneBar.transferBtnClickUI()"
                                                style="width: 70px;" th:value="#{phonebar.transfer.btn.transfer}" th:title="#{phonebar.transfer.title.transfer}" />

                            &nbsp;&nbsp; <input type="button" name="stopCallWait" id="stopCallWait"
                                                onclick="_phoneBar.stopCallWaitBtnClickUI()"
                                                style="width: 70px;" th:value="#{phonebar.transfer.btn.retrieve}" th:title="#{phonebar.transfer.title.retrieve}" />

                            &nbsp;&nbsp; <input type="button" name="transferCallWait" id="transferCallWait"
                                                onclick="_phoneBar.transferCallWaitBtnClickUI()"
                                                style="width: 70px;" th:value="#{phonebar.transfer.btn.transferCall}" th:title="#{phonebar.transfer.title.transferCall}" />

                            <input type="button" name="doConsultationBtn" id="doConsultationBtn"
                                   onclick="_phoneBar.consultationBtnClickUI()"
                                   style="width: 70px;" th:value="#{phonebar.transfer.btn.consult}" th:title="#{phonebar.transfer.title.consult}" />

                        </td>

                    </tr>
                </table>
            </td>
        </tr>
    </table>
</form>

<div class="wrapper" id="work-container">
    <!-- 左侧：实时对话 -->
    <div id="left-panel">
        <div id="chat-container" style="margin: 20px;">
            <div id="chat-messages" class="message-container"></div>
        </div>
    </div>

    <!-- 右侧：弹屏页面 -->
    <div id="right-panel">
        <div id="popup-container" style="margin: 20px;"></div>
    </div>
</div>

<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 = '';
    var _call_type = 2; // 1:呼入，2:外呼
    var _asrResult = []; // asr结果

    var manualDisConn = false;
    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() {
        // 普通工作台才初始化视频下拉；HIS embed 仅要 IPCC 信令，跳过无关 UI
        if (!_hisEmbedMode) {
            populateVideoLevelDropdown('videoLevelSelect');
            populateVideoLevelDropdown('member_video_level');
        }

        // websocket通信对象断开事件;
        _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.ws_disconnected.code, function(msg){
            console.log(msg, '连接断开');
            _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.ws_disconnected.code);
            $("#transfer_area").hide();

        });

        _phoneBar.on(ccPhoneBarSocket.eventList.OUTBOUND_START, function (msg) {
            console.log('outbound_start',msg);
        });

        // 客户端请求参数错误事件
        _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.request_args_error.code, function(msg){
            console.log(msg, '客户端请求参数错误');
            _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.request_args_error.code);
        });

        //用户已在其他设备登录
        _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);
            if (!_hisEmbedMode) {
                $.modal.msgWarning(ccPhoneBarSocket.eventListWithTextInfo.user_login_on_other_device.msg);
            }
            manualDisConn = true; // 被挤掉线的也不自动重连
        });

        //websocket连接成功
        _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.ws_connected.code, function(msg){
            console.log(msg, "websocket连接成功");
            $("#loginTime").text(new Date().toLocaleTimeString());
            _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.ws_connected.code);
        });

        _phoneBar.on(ccPhoneBarSocket.eventList.caller_not_login, function (msg) {
            if (!_hisEmbedMode) $.modal.msgError(msg["msg"]);
        });
        _phoneBar.on(ccPhoneBarSocket.eventList.outbound_finished, function (msg) {
            if (!_hisEmbedMode) $.modal.msgError(msg["msg"]);
        });
        _phoneBar.on(ccPhoneBarSocket.eventList.server_error_audio_codec_not_match, function (msg) {
            if (!_hisEmbedMode) $.modal.msgError(msg["msg"]);
        });
        _phoneBar.on(ccPhoneBarSocket.eventList.server_error, function (msg) {
            if (!_hisEmbedMode) $.modal.msgError(msg["msg"]);
        });

        // 被叫振铃事件
        _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.callee_ringing.code, function(msg){
            console.log(msg.content, "被叫振铃事件");
            _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.callee_ringing.code);
        });

        // 呼入事件
        _phoneBar.on(ccPhoneBarSocket.eventList.new_inbound_call, function(msg){
            console.log(msg, "呼入" );
            _phoneNum = msg.object.caller;
            _uuid = msg.object.uuid;
            // HIS embed：弹屏/CRM 由父页处理，避免多余 iframe/接口
            if (!_hisEmbedMode) {
                addCallRecord(_phoneNum, _uuid, 1);
            }
        });

        // 主叫接通事件
        _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.caller_answered.code, function(msg){
            console.log(msg, "主叫接通" );
            $("#agentStatus").text("通话中");
            _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.caller_answered.code);
        });

        // 外呼事件
        _phoneBar.on(ccPhoneBarSocket.eventList.OUTBOUND_START, function (msg) {
            console.log('outbound_start',msg);
            _phoneNum = msg.object.destPhone;
            _uuid = msg.object.uuid;
            if (!_hisEmbedMode) {
                addCallRecord(_phoneNum, _uuid, 2);
            }
        });


        // 主叫挂断事件
        _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.caller_hangup.code, function(msg){
            console.log(msg, "主叫挂断");
            $("#agentStatus").text("通话结束");
            $("#reInviteVideoBtn").attr("disabled","disabled");
            $("#sendVideoFileBtn").attr("disabled","disabled");
            $("#transfer_area").hide();
            _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.caller_hangup.code);
            // HIS embed：话单/ASR 由父页 sipCallCdrSync 负责
            if (!_hisEmbedMode) {
                addAsrRecord(_phoneNum, _uuid, _call_type, _asrResult);
            }
        });

        // 被叫接通事件
        _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.callee_answered.code, function(msg){
            console.log(msg, "被叫接通");
            _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.callee_answered.code);

            // // 外呼弹屏
            // var _phoneNum = $("#ccphoneNumber").val();
            // var _uuid = msg.object.uuid;
            // addCallRecord(_phoneNum, _uuid, 2);


        });

        // 被叫挂断事件
        _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.callee_hangup.code, function(msg){
            console.log(msg, "被叫挂断");
            $("#transfer_area").hide();
            _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.callee_hangup.code);
        });

        // 座席状态改变事件
        _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.status_changed.code, function(msg){
            console.log("座席状态改变: " ,msg);
            var agentStatusText = i18n("_phoneBar.agentStatus.text_" + msg["object"]["status"]);
            if (!agentStatusText) {
                agentStatusText = msg["object"]["text"];
            }
            $("#agentStatus").text(agentStatusText);
            _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.status_changed.code);
        });

        // HIS embed 不需要排队人数展示/日志（615 推送很频繁，避免控制台刷屏）
        _phoneBar.on(ccPhoneBarSocket.eventList.acd_group_queue_number, function(msg){
            if (_hisEmbedMode) return;
            console.log("当前排队人数消息: " ,msg);
            $("#queueStat").text(msg["object"]["queue_number"]);
        });

        // 音频通话已建立
        _phoneBar.on(ccPhoneBarSocket.eventList.on_audio_call_connected, function(msg){
            console.log("音频通话已建立: " ,msg);
            $("#reInviteVideoBtn").removeAttr("disabled");
        });

        _phoneBar.on(ccPhoneBarSocket.eventList.customer_channel_hold, function (msg) {
            console.log("客户通话已保持: " ,msg);
            $("#callStatus").text(i18n("phonebar.msg.customer_channel_hold"));
        });

        _phoneBar.on(ccPhoneBarSocket.eventList.customer_channel_unhold, function (msg) {
            console.log("客户通话已接回." ,msg);
            $("#callStatus").text(i18n("phonebar.msg.customer_channel_unhold"));
        });

        // 视频通话已建立
        _phoneBar.on(ccPhoneBarSocket.eventList.on_video_call_connected, function(msg){
            console.log("视频通话已建立: " ,msg);
            $("#sendVideoFileBtn").removeAttr("disabled");
        });

        _phoneBar.on(ccPhoneBarSocket.eventList.inner_consultation_start, function(msg){
            console.log("咨询开始." ,msg);
            $("#callStatus").text(i18n("phonebar.msg.inner_consultation_start"));
        });

        _phoneBar.on(ccPhoneBarSocket.eventList.inner_consultation_stop, function(msg){
            console.log("咨询结束." ,msg);
            $("#callStatus").text(i18n("phonebar.msg.inner_consultation_stop"));
        });

        _phoneBar.on(ccPhoneBarSocket.eventList.transfer_call_success, function(msg){
            console.log("电话转接成功." ,msg);
            $("#callStatus").text(i18n("phonebar.msg.transfer_call_success"));
            $("#externalPhoneNumber").val('');
        });

        // 会议成员已经接通
        _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MEMBER_ANSWERED, function (msg) {
            console.log("会议成员已经接通.", msg);
            var memberPhone = $.trim(msg.object.phone);
            var memberItemId = "#conf_member_" + memberPhone;

            $(".conf_status", $(memberItemId)).text(msg.object.status);
            $(".conf_status", $(memberItemId)).html("通话中").css("color", "green");

            $(".conf_mute", $(memberItemId)).find("img").show();
            $(".conf_vmute", $(memberItemId)).find("img").show();
        });

        // 会议成员已被禁用视频
        _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MEMBER_VMUTED_SUCCESS, function (msg) {
            console.log("会议成员已被禁用视频.", msg);
            var memberPhone = $.trim(msg.object.phone);
            var muteObj = $(".conf_vmute", $("#conf_member_" + memberPhone));
            muteObj.find("img")[0].src = "../phone-bar/images/no_video.jpg";
            muteObj.find("a").removeAttr("onclick");
            muteObj.find("a").off("click");
            muteObj.find("a").on("click", function () {
                _phoneBar.conferenceUnVMuteMember(memberPhone);
            } );
        });

        // 会议成员启用视频成功
        _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MEMBER_UnVMUTED_SUCCESS, function (msg) {
            console.log("会议成员启用视频成功.", msg);
            var memberPhone = $.trim(msg.object.phone);
            var muteObj = $(".conf_vmute", $("#conf_member_" + memberPhone));
            muteObj.find("img")[0].src = "../phone-bar/images/video.jpg";
            muteObj.find("a").removeAttr("onclick");
            muteObj.find("a").off("click");
            muteObj.find("a").on("click", function () {
                _phoneBar.conferenceVMuteMember(memberPhone);
            } );
        });

        // 会议成员已被禁言
        _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MEMBER_MUTED_SUCCESS, function (msg) {
            console.log("会议成员已被禁言.", msg);
            var memberPhone = $.trim(msg.object.phone);
            var muteObj = $(".conf_mute", $("#conf_member_" + memberPhone));
            muteObj.find("img")[0].src = "../phone-bar/images/unmute.jpg";
            muteObj.find("a").removeAttr("onclick");
            muteObj.find("a").off("click");
            muteObj.find("a").on("click", function () {
                _phoneBar.conferenceUnMuteMember(memberPhone);
            } );
        });

        // 会议成员解除禁言成功
        _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MEMBER_UNMUTED_SUCCESS, function (msg) {
            console.log("会议成员解除禁言成功.", msg);
            var memberPhone = $.trim(msg.object.phone);
            var muteObj = $(".conf_mute", $("#conf_member_" + memberPhone));
            muteObj.find("img")[0].src = "../phone-bar/images/mute.jpg";
            muteObj.find("a").removeAttr("onclick");
            muteObj.find("a").off("click");
            muteObj.find("a").on("click", function () {
                _phoneBar.conferenceMuteMember(memberPhone);
            } );
        });

        // 会议成员已经挂机
        _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MEMBER_HANGUP, function (msg) {
            console.log("会议成员已经挂机.", msg);
            var memberPhone = $.trim(msg.object.phone);
            var memberItemId = "#conf_member_" + memberPhone;

            // 隐藏 mute及 vmute按钮
            $(".conf_mute", $(memberItemId)).find("img").hide();
            $(".conf_vmute", $(memberItemId)).find("img").hide();
            $(".conf_re_invite", $(memberItemId)).show();

            var answerStatus = ( msg.object.answeredTime === 0) ? "未接通" :  msg.object.hangupClause;
            var color = ( msg.object.answeredTime === 0) ? "red" : "green";
            $(".conf_status", $(memberItemId)).html("已挂机("+ answerStatus  +")").css("color", color);
            $(".conf_status", $(memberItemId)).fadeTo('fast', 0.1).fadeTo('fast', 1.0);
            var blinkText = setInterval(function () {
                $(".conf_status", $(memberItemId)).fadeTo('fast', 0.1).fadeTo('fast', 1.0);
            }, 700); // 每0.5秒闪烁一次

            setTimeout(function () {
                console.log("memberItemId=", memberItemId);
                clearInterval(blinkText);
                // $(memberItemId).remove(); //暂不自动移除参会者，由主持人手动操作处理;
            }, 5000);
        });

        // 电话会议开始，主持人已接通
        _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MODERATOR_ANSWERED, function (msg) {
            console.log("电话会议开始，主持人已接通.", msg);
            onConferenceStart();
        });

        // 电话会议结束，主持人已挂机
        _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MODERATOR_HANGUP, function (msg) {
            console.log("电话会议结束，主持人已挂机.", msg);
            onConferenceEnd();
        });

        // 成功把通话转接到多人视频会议
        _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_TRANSFER_SUCCESS_FROM_EXISTED_CALL, function (msg) {
            console.log("成功把通话转接到多人视频会议.", msg);
            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 () {
                refreshMemberIdList();
            });
            refreshMemberIdList();
        });

        // 电话工具条参数配置;
        _callConfig = {
            'useDefaultUi' : !_hisEmbedMode,
            // loginToken 信息是加密的字符串， 包含以下字段信息：extnum[分机号]、opnum[工号]、groupId[业务组]、skillLevel[技能等级]
            'loginToken': _loginToken,

            // 电话工具条服务器端的地址; 端口默认是1081
            'ipccServer': _scriptServer + ':' + _scriptPort,

            // 网关列表， 默认需要加密后在在通过客户端向呼叫系统传递;
            // 注意在注册模式下，网关参数更改之后，必须重启语音服务 [docker restart freeswitch] 方可生效，不支持热更新;
            // 支持多个网关同时使用，按照优先级依次使用, 支持网关负载容错溢出 [第一条网关外呼出错后，自动使用第二条网关重试，直至外呼不出错] ;
            'gatewayList' : _gatewayList,

            // 网关列表信息是否为加密模式;
            'gatewayEncrypted': false
        };

        // 使用工具条之前需要先初始化 _callConfig 参数， 填充各个字段的值： 合计7个字段，必须填写正确 ；
        //********************************************************************************************
        // 以下代码设置加密的参数： loginToken、extPassword、gatewayList；   在本页面的demo演示中需要调用服务器端接口获取密文字符串;
        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
                        });
                    }
                });
            });
            try { sessionStorage.removeItem('his_ipcc_login_jump'); } catch (e) {}
            hisIpccPost('READY', { extNum: _embedExtNum, myGateway: _embedMyGateway || '' });
        }

        // 设置自动连接电话工具条
        setTimeout(function () {
            console.log(" 正在尝试连接电话工具条, 端口 1081 ");
            _phoneBar.connect();
        }, _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");
        document.getElementById("conference_member_list").style.display = "none";
        // 启用外呼按钮
        $("#callBtn").addClass('on');
        // 启用置闲按钮
        $("#setFree").addClass('on');
        // 启用签出按钮
        $("#onLineBtn").addClass('on');
        //移除所有的参会成员
        $(".conf_member_item_row").remove();

        let tips = i18n("phonebar.msg.conferenceEnd");
        $("#callStatus").text(tips);
        $("#agentStatus").text(tips);
    }

    function onConferenceStart() {
        document.getElementById("endConference").removeAttribute("disabled");
        document.getElementById("conference_member_list").style.display = "block";
        let tips = i18n("phonebar.msg.conferenceStart");
        $("#callStatus").text(tips);
        $("#agentStatus").text(tips);
    }

    /**
     *  成功把电话转接到多人视频会议
     */
    function onTransferToConferenceSuccess(msg) {
        $("#callStatus").text(i18n("phonebar.msg.transferToConferenceSuccess"));
        $("#setFree").removeClass("on");
        $("#setBusy").removeClass("on");
        $("#callBtn").removeClass("on");

        //界面显示成功转接到视频会议电话
        var phone = msg.object.phone;
        var name = msg.object.phone;
        console.log("onTransferToConferenceSuccess:", msg);
        _phoneBar.conferenceAddMemberFromExistCall(name, phone);
    }

    // 以下是通话转接操作界面的功能
    const transferToGroupId = document.getElementById("transfer_to_groupIds");
    const transferToMember = document.getElementById("transfer_to_member");

    // 填充 transfer_to_groupId 数据
    function populateGroupIdOptions() {
        transferToGroupId.length = 0; //清除所有选项
        let groups = _phoneBar.callConfig.groups;
        groups.forEach(group => {
            const option = document.createElement("option");
            option.value = group.groupId;
            option.textContent = group.bizGroupName;
            transferToGroupId.appendChild(option);
        });
        if(transferToGroupId.selectedIndex == -1){
            transferToGroupId.selectedIndex = 0;
        }
    };

    function refreshMemberIdList() {
        const selectedGroupId = transferToGroupId.value;
        if(selectedGroupId != "") {
            let origValue = transferToMember.value;
            populateMemberIdOptions(_phoneBar.callConfig.agentList, selectedGroupId);
            //判断原始选择项是否还存在，存在则重新赋值;
            let hasValue = transferToMember.querySelector(`option[value="${origValue}"]`) !== null;
            if(hasValue) {
                transferToMember.value = origValue;
            }
        }
    }

    // 根据选中的 groupId 填充 transfer_to_member 数据
    function populateMemberIdOptions(members, selectedGroupId) {
        if (!Array.isArray(members)) {
            console.error("populateMemberOptions: members is not a Array.", members);
            return;
        }
        transferToMember.innerHTML = '<option value="">'+ i18n("phonebar.transfer.option.select") +'</option>';
        members
            .filter(member => member.groupId === selectedGroupId)
            .forEach(member => {
                const option = document.createElement("option");
                const statusMap = { 1 : i18n("phonebar.transfer.status.login"), 2: i18n("phonebar.transfer.status.free"), 3: i18n("phonebar.transfer.status.busy"), 4: i18n("phonebar.transfer.status.calling"), 5: i18n("phonebar.transfer.status.after") };
                option.value = member.opnum;
                option.textContent = `${member.opnum}(${statusMap[member.agentStatus] || ""})`;
                transferToMember.appendChild(option);
            });
    };

    // 将视频级别填充到下拉列表中的函数
    function populateVideoLevelDropdown(objId) {
        let select = document.getElementById(objId);
        if(select == null) return;
        // 遍历视频级别数据
        for (let key in ccPhoneBarSocket.videoLevels) {
            if (ccPhoneBarSocket.videoLevels.hasOwnProperty(key)) {
                let level = ccPhoneBarSocket.videoLevels[key];
                let option = document.createElement('option');
                option.value = level.levelId; // 设置值为 levelId
                option.text = level.description; // 显示文本
                select.appendChild(option);
            }
        }
        select.value = ccPhoneBarSocket.videoLevels.HD.levelId ;
    }

    function addCallRecord(phoneNum, uuid, call_type) {
        // HIS iframe 集成：不加载弹屏/CRM iframe，避免多余接口与跨域噪音
        if (_hisEmbedMode) return;

        $("#work-container").show();
        $("#chat-container").show();
        $(chatMessages).html("");

        _phoneNum = phoneNum;
        _uuid = uuid;
        _call_type = call_type;
        _asrResult = [];

        console.log(_phoneNum);
        console.log(_uuid);
        console.log(_call_type);
        const title = _call_type == 1 ? i18n("phonebar.popup.inbound") : i18n("phonebar.popup.outbound");
        const url = ctx + 'cc/custcallrecord/add?phoneNum=' + _phoneNum +
            '&callType=' + _call_type + '&uuid=' + _uuid;
        console.log(url);
        $('#popup-container').empty().append(
            '<iframe src="' + url + '" title="' + title + '"></iframe>'
        );
    }

    $('#onLineBtn').on('click', function () {
        if ($(this).hasClass('on')) {
            if (_phoneBar.getIsConnected()) {
                manualDisConn = true
                console.log("手动断开连接！")
            } else {
                manualDisConn = false
                console.log("手动建立连接！")
            }
        }
    });

    /* 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) {
            const { role, text, vadType } = object;
            if(vadType == 1) {
                addMessageToChat(role, text);
            }
        } else if (status === 620 || status === 621) {
            addSystemMessage(i18n("phonebar.chat.dialog.end"));
        }
    }
    function addMessageToChat(role, text) {
        const messageDiv = document.createElement('div');
        messageDiv.className = 'message ' + (role === 1 ? 'customer' : 'agent');

        // 添加角色名称
        const roleHeader = document.createElement('div');
        roleHeader.className = 'message-header';
        roleHeader.textContent = role === 1 ? i18n("phonebar.chat.role.customer") : i18n("phonebar.chat.role.agent");

        const messageContent = document.createElement('div');
        messageContent.textContent = text;

        console.log("========" + text);
        _asrResult.push({
            "role": role === 1 ? 'customer' : 'agent',
            "content": text
        })

        // messageDiv.appendChild(roleHeader);
        messageDiv.appendChild(messageContent);
        chatMessages.appendChild(messageDiv);
        scrollToBottom();
    }
    function addSystemMessage(text) {
        const systemMessage = document.createElement('div');
        systemMessage.className = 'system-message';
        systemMessage.textContent = text;
        chatMessages.appendChild(systemMessage);
        scrollToBottom();
    }
    function scrollToBottom() {
        chatMessages.scrollTop = chatMessages.scrollHeight;
    }

    function addAsrRecord(_phoneNum, _uuid, _call_type, _asrResult) {
        // HIS embed：不写 custDialog / 不点置闲，话单由父页负责
        if (_hisEmbedMode) return;
        if (_autoFree) {
            $("#setFree").click();
        }
        console.log(_asrResult);
        if (_asrResult && _asrResult.length > 0) {
            var config = {
                url: ctx + "cc/custDialog/add",
                type: "post",
                dataType: "json",
                data: {
                    "uuid": _uuid,
                    "phoneNum": _phoneNum,
                    "callType": _call_type,
                    "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();
                }
            };
            $.ajax(config)
        }
    }

</script>
</body>
</html>
