ysyt-agent-sdk 1.0.82 → 1.0.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,9 +9,7 @@ declare class CallApi {
9
9
  cancelCall(): void;
10
10
  consultCall(agentNo: string): Promise<void>;
11
11
  answerCall(): Promise<void>;
12
- rejectInCall(): Promise<void>;
13
12
  makeCall(number: string): Promise<void>;
14
- rejectOutCall(): Promise<void>;
15
13
  hangup(): Promise<void>;
16
14
  mute(): void;
17
15
  unmute(): void;
@@ -911,4 +911,4 @@ const ms=A=>(e,t)=>{void 0!==t?t.addInitializer(()=>{customElements.define(A,e)}
911
911
  `:""}
912
912
  </div>
913
913
  </my-popover>
914
- `;ss(s,this.rttHTML)}}class Zs{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const A=await navigator.mediaDevices.enumerateDevices();if(A.some(A=>"audioinput"===A.kind&&""!==A.label))return null;return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(A){return console.warn("获取音频权限失败:",A),null}}static show(A,e,t){if("Notification"in window&&"granted"===Notification.permission){const s=new Notification(A,{body:e,tag:"xy-global-notification",renotify:!0});s.onclick=()=>{window.focus(),s.close(),t?.()},setTimeout(()=>s.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(A=>"audioinput"===A.kind&&""!==A.label)}catch(A){return console.warn("无法检查设备权限:",A),!1}}}const Ks=console.log,Os=(...A)=>{Ve.logBuiltinEnabled&&Ks(...A)};let Ns=null;class bs{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Us,this.initWebSocket()}static getInstance(A){if(!Ns){if(!A)throw new Error("WebSocket 尚未初始化");Ns=new bs(A)}return Ns}stateIdleChange(){const{state:A}=Ve.stateObject;A!==exports.AgentStatus.IDLE&&this.apiClient._changeState({data:{...Ve.stateBeforeChange}})}async getCustomerInfo(A){try{await this.apiClient._getInCallCrmDetail({data:{phone:A},success:A=>{const{contact_count:e,customer_name:t,phone:s,city:i,province:r}=A.data;ae.emit(exports.CallSipCallEvent.CUSTOMER_INFO,{customer_name:t||"未知客户",phone:s,city:i||"未知",province:r||"未知",contact_count:e||0})}})}catch(A){}}putAgentState(){Ve.sessionId="";const{post_call_process_time:A}=Ve.agentInfo,e=A||0;Ve.autoStateTimer&&(clearTimeout(Ve.autoStateTimer),Ve.autoStateTimer=null),ae.emit(exports.CallSipCallEvent.CUSTOMER_INFO,void 0),e>0?Ve.autoStateTimer=setTimeout(()=>{Ve.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){const A=be(Le,We);this.ws=new WebSocket(this.url+A),this.ws.onopen=()=>{this.sendMessage({type:0}),this.startHeartbeat()},this.ws.onmessage=A=>{const e=JSON.parse(A.data),{type:t,data:s,code:i,msg:r}=e;if(0!==t&&Os("%cWebSocket 收到消息:","color: blue; font-weight: bold;",e),t===exports.WebsocketTypeEnum.OUT_CALL&&(0!==i?(he.reset(),ae.emit(exports.CallSipCallEvent.OUT_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r),setTimeout(()=>{ae.emit(exports.CallSipCallEvent.CUSTOMER_INFO,void 0)},500),this.stateIdleChange()):0===i&&ae.emit(exports.CallSipCallEvent.OUT_SUCCESS)),t===exports.WebsocketTypeEnum.AGENT_STATE){Ve.stateObject.state!==exports.AgentStatus.IDLE&&Ve.stateObject.state!==exports.AgentStatus.BUSY||(Ve.stateBeforeChange=Ve.stateObject);const{state:A,state_name:e}=s;Ve.stateObject={state:A,state_name:e},"振铃中"===e&&he.updateDisplayText(exports.DisplayTextEnum.AGENT_RINGING),ae.emit(exports.CallSipCallEvent.AGENT_STATE,{state:A,state_name:e})}if(t===exports.WebsocketTypeEnum.OUT_CALL_INCOMING_CALL&&(ae.emit(exports.CallSipCallEvent.OUT_INCOMING_CALL),Ve.sessionId=s.session_id,he.updateActionConfigs(cs)),t===exports.WebsocketTypeEnum.OUT_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.OUT_HANGUP,s),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(exports.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(hs)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(as)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.TRANSFER_END),he.updateActionConfigs(as))),t===exports.WebsocketTypeEnum.OUT_CALL_RINGING&&1===s.type&&(ae.emit(exports.CallSipCallEvent.OUT_RINGING,s),he.updateDisplayText(exports.DisplayTextEnum.RINGING)),t===exports.WebsocketTypeEnum.OUT_CALL_ANSWER&&(ae.emit(exports.CallSipCallEvent.OUT_OFF_ANSWER,s),he.updateOutCallIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(hs)),t===exports.WebsocketTypeEnum.CONSULT_RINGING&&(ae.emit(exports.CallSipCallEvent.CONSULT_RINGING),he.updateDisplayText(exports.DisplayTextEnum.AGENT_RINGING),he.updateActionConfigs([])),t===exports.WebsocketTypeEnum.CONSULT_ANSWER&&(ae.emit(exports.CallSipCallEvent.CONSULT_OFF_HOOK,s),he.updateConsultIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CONSULTING),he.updateActionConfigs(ls)),t===exports.WebsocketTypeEnum.CONSULT_FAIL&&(ae.emit(exports.CallSipCallEvent.CONSULT_FAILED,{custom_reason:s.custom_reason}),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(hs)),t===exports.WebsocketTypeEnum.CONSULT_CALL_IN&&(ae.emit(exports.CallSipCallEvent.CONSULT_INCOMING,s),he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.CONSULT),he.updateDisplayText(exports.DisplayTextEnum.CONSULT_CALL_IN),he.updateActionConfigs(ds),Ve.enableBrowserAlert&&Zs.show("📞 咨询来电",`坐席 [${s.agent_name}] 正在咨询...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{agent_mane:s.agent_name})})),t===exports.WebsocketTypeEnum.CONSULT_CALL_IN_SUCCESS&&(Ve.sessionId=s.session_id,ae.emit(exports.CallSipCallEvent.CONSULT_CALL_IN_SUCCESS),he.updateConsultIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(gs)),t===exports.WebsocketTypeEnum.CONSULT_RETURN_CALL_SUCCESS&&(he.updateConsultIsAnswer(!1),ae.emit(exports.CallSipCallEvent.CONSULT_RETURN_CALL_SUCCESS),he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(hs)),t===exports.WebsocketTypeEnum.MUTE&&(0===i?(he.updateIsMuted(!0),ae.emit(exports.CallSipCallEvent.MUTE_SUCCESS),he.updateDisplayText(exports.DisplayTextEnum.MUTING)):(ae.emit(exports.CallSipCallEvent.MUTE_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.UNMUTE&&(0===i?(he.updateIsMuted(!1),ae.emit(exports.CallSipCallEvent.UNMUTE_SUCCESS),he.updateDisplayText(exports.DisplayTextEnum.CALLING)):(ae.emit(exports.CallSipCallEvent.UNMUTE_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CALL_HOLD&&(0===i?(he.updateIsHold(!0),he.updateDisplayText(exports.DisplayTextEnum.HOLDING),ae.emit(exports.CallSipCallEvent.HOLD_SUCCESS)):(ae.emit(exports.CallSipCallEvent.HOLD_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CALL_UNHOLD&&(0===i?(he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateIsHold(!1),ae.emit(exports.CallSipCallEvent.UNHOLD_SUCCESS)):(ae.emit(exports.CallSipCallEvent.UNHOLD_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER&&(0===i?ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_SUCCESS):(ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER_FAILED&&ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_FAILED,s.status),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER_OFF_HOOK&&(he.updateDirection(exports.DirectionEnum.INCOMING),he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_OFF_HOOK),he.updateActionConfigs(ps),he.updateIncomingIsAnswer(!0),he.updateConsultIsAnswer(!1)),t===exports.WebsocketTypeEnum.INCOMING_CALL&&(Ve.sessionId=s.session_id,he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.INCOMING),he.updateDisplayText(exports.DisplayTextEnum.INCOMING_CALL),ae.emit(exports.CallSipCallEvent.INCOMING_CALL,{customer_phone:s.customer_phone}),he.updateActionConfigs(ds),this.getCustomerInfo(s.customer_phone),Ve.enableBrowserAlert&&Zs.show("📞 客户来电",`客户 [${s.customer_phone}] 正在呼入...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{customer_phone:s.customer_phone})})),t===exports.WebsocketTypeEnum.INCOMING_CALL_OFF_HOOK&&(he.updateIncomingIsAnswer(!0),ae.emit(exports.CallSipCallEvent.INCOMING_CALL_OFF_HOOK),he.updateActionConfigs(ps),he.updateDisplayText(exports.DisplayTextEnum.CALLING)),t===exports.WebsocketTypeEnum.INCOMING_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.INCOMING_CALL_END),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(exports.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(hs)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(as)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.TRANSFER_END),he.updateActionConfigs(as))),t===exports.WebsocketTypeEnum.SATISFACTION_EVALUATION&&(0===i?ae.emit(exports.CallSipCallEvent.SATISFACTION_EVALUATION_SUCCESS):(ae.emit(exports.CallSipCallEvent.SATISFACTION_EVALUATION_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CONSULT_THREE_WAY&&(0!==i?(ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r)):0===i&&he.updateIsMeeting(!0)),t===exports.WebsocketTypeEnum.CONSULT_THREE_WAY_RESULT&&("success"===s.status?(he.updateDirection(exports.DirectionEnum.MEETING),he.updateDisplayText(exports.DisplayTextEnum.MEETING),he.updateActionConfigs(qs),ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_SUCCESS)):(ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,{conf_name:s.conf_name}),he.updateIsMeeting(!1))),t===exports.WebsocketTypeEnum.TRANSFER_INCOMING_CALL&&(s.agent_no===Ve.agentInfo.agent_no?(he.updateDisplayText(exports.DisplayTextEnum.TRANSFERRING),ae.emit(exports.CallSipCallEvent.TRANSFER_PROGRESS),he.updateActionConfigs([]),he.updateTransferIsAnswer(!0)):(ae.emit(exports.CallSipCallEvent.TRANSFER_INCOMING_CALL,s),he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.TRANSFER),he.updateDisplayText(exports.DisplayTextEnum.TRANSFER_INCOMING_CALL),he.updateActionConfigs(ds),Ve.enableBrowserAlert&&Zs.show("📞 转接来电",`坐席 [${s.agent_no}] 正在转接...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{agent_mane:s.agent_no})}))),t===exports.WebsocketTypeEnum.TRANSFER_OFF_HOOK&&(Ve.sessionId=s.session_id,ae.emit(exports.CallSipCallEvent.TRANSFER_OFF_HOOK),he.updateTransferIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(ps)),t===exports.WebsocketTypeEnum.TRANSFER_FAILED&&"failed"===s.status){ae.emit(exports.CallSipCallEvent.TRANSFER_FAILED,"未知原因");const A=he.get("direction");A===exports.DirectionEnum.OUTGOING?he.updateActionConfigs(hs):A===exports.DirectionEnum.INCOMING&&he.updateActionConfigs(ps)}},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const A=new Blob(["\n let timer;\n self.onmessage = function (e) {\n if (e.data === 'start') {\n timer = setInterval(() => {\n self.postMessage('heartbeat');\n }, 14000);\n } else if (e.data === 'stop') {\n clearInterval(timer);\n }\n };\n "],{type:"application/javascript"}),e=URL.createObjectURL(A);this.heartbeatWorker=new Worker(e),this.heartbeatWorker.onmessage=()=>{this.sendMessage({type:0})},this.heartbeatWorker.postMessage("start")}stopHeartbeat(){this.heartbeatWorker&&(this.heartbeatWorker.postMessage("stop"),this.heartbeatWorker.terminate(),this.heartbeatWorker=null)}sendMessage(A){this.ws?.readyState===WebSocket.OPEN?(100===A.type&&this.getCustomerInfo(A.data.customer_phone),this.ws.send(JSON.stringify(A)),0!==A.type&&Os("%cWebSocket 发送消息:","color: green; font-weight: bold;",A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Ns&&(Ns.close(),Ns=null)}static __internalSend(A){if(!Ns)throw new Error("WebSocket 尚未初始化");Ns.sendMessage(A)}}class Js{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=he.get("isCalling"),e=Ve.sessionId;if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}))}holdCall(){this.roleMute();const A=he.get("isHold"),{sessionId:e}=Ve;if(!e)return;if(!he.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(A)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));bs.__internalSend({type:exports.WebsocketTypeEnum.CALL_HOLD,data:{session_id:e}})}unholdCall(){this.roleMute();const{isHold:A}=he.getState(),{sessionId:e}=Ve;if(!he.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(e){if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));bs.__internalSend({type:exports.WebsocketTypeEnum.CALL_UNHOLD,data:{session_id:e}})}}sendDTMF(A){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!he.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=he.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){this.hangup()}async consultCall(A){this.roleMute();const{isCalling:e,outCallIsAnswer:t,consultIsAnswer:s,incomingIsAnswer:i}=he.getState(),r=Ve.sessionId;if(!he.get("actionConfigs").includes("consult"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询"}));if(s)throw new Error(JSON.stringify({code:1,msg:"当前正在咨询"}));if(!(e||t||i))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!r)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));bs.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_REQUEST,data:{session_id:r,consultation_agent_no:A}})}async answerCall(){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async rejectInCall(){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));const{isCalling:A}=he.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectInCall()}async makeCall(A){const e=he.get("isCalling"),t=he.get("selectOutNumber")||"";if(e)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.OUTGOING),bs.__internalSend({type:exports.WebsocketTypeEnum.OUT_CALL,data:{customer_phone:A,caller:t}})}async rejectOutCall(){const{isCalling:A}=he.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const e=Ve.sessionId;bs.__internalSend({type:exports.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:e}})}async hangup(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;bs.__internalSend({type:exports.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:A}})}mute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!A.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));bs.__internalSend({type:exports.WebsocketTypeEnum.MUTE,data:{session_id:t}})}unmute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!A.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));bs.__internalSend({type:exports.WebsocketTypeEnum.UNMUTE,data:{session_id:t}})}consultTransfer(){this.roleMute();const A=he.get("consultIsAnswer"),e=Ve.sessionId;if(!he.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_TRANSFER,data:{session_id:e}})}satisfactionEvaluation(){this.roleMute();const A=Ve.sessionId;if(!he.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));bs.__internalSend({type:exports.WebsocketTypeEnum.SATISFACTION_EVALUATION,data:{session_id:A}})}startConference(){this.roleMute();if(!he.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_THREE_WAY,data:{session_id:A}})}consultRetrieve(){this.roleMute();if(!he.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_RETURN_CALL,data:{session_id:A}})}async transferAgent(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));bs.__internalSend({type:exports.WebsocketTypeEnum.TRANSFER,data:{session_id:t,transfer_type:0,transfer_dest:A}})}async transferOutline(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"号码不能为空"}));if(!/^\d+$/.test(A))throw new Error(JSON.stringify({code:1,msg:"号码格式错误"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));bs.__internalSend({type:exports.WebsocketTypeEnum.TRANSFER,data:{session_id:t,transfer_type:2,transfer_dest:A}})}}class Hs{static{this._instance=null}#A=null;#e=new Us;#t;#s=null;#i=!1;#r;#o=!1;constructor(){if(!Hs._creatingInstance)throw new Error("请使用 YSYTAgentSdk.getInstance() 获取实例");clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#n();Xe.updateRttObject(A)},2e3),Zs.requestMediaPermissions(),this.#r=he.subscribeKey("answerDevice",A=>{1===A?this.initWebRtc():this.#A=null})}static get instance(){return this._instance}static async destroyInstance(){this._instance&&(await this._instance.destroy(),this._instance=null)}static getInstance(){return this._instance||(Hs._creatingInstance=!0,this._instance=new Hs,delete Hs._creatingInstance,window.addEventListener("beforeunload",()=>{this._instance?.destroy()})),this._instance}getInit(){return this.#o}async initWebRtc(){if(this.#A)return;const A=Ve.agentInfo.sip_account_list.find(A=>1===A.device_type);if(!A)throw new Error(JSON.stringify({code:1,msg:"未找到 sip_account_list"}));{const e=A.sip_register_addr;this.#A=new _e({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#a),await this.#A.start()}}async init({actionNodeParams:A,url:e,appKey:t,appSecret:s,agentNo:i,enableBrowserAlert:r,logBuiltinEnabled:o}){try{const{viewHtmlElement:n,rttHTML:a}=A||{},V=e||"https://aicc.yescloudy.com";je=V,Le=t,We=s,Ve.logBuiltinEnabled=o||!1,await this.#e._agentLogin(i);const{agent_no:c,current_answer_device:h,current_state:l,out_display_number:g,out_display_select_switch:q}=Ve.agentInfo;l===exports.AgentStatus.IDLE?(he.updateActionConfigs(as),Ve.stateObject={state:l,state_name:"空闲"}):l===exports.AgentStatus.BUSY&&(he.updateActionConfigs(Vs),Ve.stateObject={state:l,state_name:"忙碌"}),1===q?he.updateSelectOutNumber(g):he.updateSelectOutNumber("");let d="";const p=new URL(V).host;d=V.includes("https")?`wss://${p}`:`ws://${p}`,bs.getInstance(`${d}/ccs-ws/api/v1/ws/call/${c}?Authorization=`),he.updateAnswerDevice(h),1===h&&await this.initWebRtc(),this.#t=new Js(this.#A),A&&n&&(this.#i=!0,new vs({container:n,rttHTML:a,statusParams:{state:exports.AgentStatus.IDLE,statusName:"空闲"}},this,this.#t)),Ve.enableBrowserAlert=r,r&&Zs.requestPermission(),ae.emit(exports.EventName.AGENT_INIT_STATUS,!0),this.#o=!0}catch(A){this.#i&&Fs("初始化失败"),ae.emit(exports.EventName.AGENT_INIT_STATUS,!1),this.#o=!1}}#a=A=>{const{type:e,data:t}=A;ae.emit(e,t)};on(A,e){return ae.on(A,e),this}off(A,e){ae.off(A,e)}offAll(){ae.clearAllListeners()}async destroyRtc(){await(this.#A?.destroy())}async destroy(){Hs._instance&&(await this.destroyRtc(),clearInterval(this.#s),bs.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#i=!1,Hs._instance=null)}async#n(){return this.#A?this.#A.getNetworkStats():{}}get call_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{answerCall:A(()=>this.#t.answerCall()),makeCall:A=>this.#t.makeCall(A),cancelCall:A(()=>this.#t.cancelCall()),hangup:A(()=>this.#t.hangup()),sendDTMF:A(A=>this.#t.sendDTMF(A)),holdCall:A(()=>this.#t.holdCall()),unholdCall:A(()=>this.#t.unholdCall()),consultCall:A(async A=>{try{await this.#t.consultCall(A)}catch(A){throw console.warn(A),A}}),consultRetrieve:A(()=>this.#t.consultRetrieve()),consultTransfer:A(()=>this.#t.consultTransfer()),mute:A(()=>this.#t.mute()),unmute:A(()=>this.#t.unmute()),satisfactionEvaluation:A(()=>this.#t.satisfactionEvaluation()),startConference:A(()=>this.#t.startConference()),transferAgent:A(A=>this.#t.transferAgent(A)),transferOutline:A(A=>this.#t.transferOutline(A))}}get agent_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{changeDevice:A(A=>this.#e.changeDevice(A)),changeState:A(A=>this.#e.changeState(A)),getIdleAgentList:A(A=>this.#e.getIdleAgentList(A)),getAgentState:A(A=>this.#e.getAgentState(A)),setAgentExplicit:A(A=>this.#e.setAgentExplicit(A))}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,out_display_data:s,out_display_select_switch:i,current_answer_device:r,current_state:o}=Ve.agentInfo,{stateObject:n}=Ve,a={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:o,default_device:r,out_display_data:s,out_display_select_switch:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:a[Number(A)]})),stateObject:n}}}exports.default=Hs;
914
+ `;ss(s,this.rttHTML)}}class Zs{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const A=await navigator.mediaDevices.enumerateDevices();if(A.some(A=>"audioinput"===A.kind&&""!==A.label))return null;return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(A){return console.warn("获取音频权限失败:",A),null}}static show(A,e,t){if("Notification"in window&&"granted"===Notification.permission){const s=new Notification(A,{body:e,tag:"xy-global-notification",renotify:!0});s.onclick=()=>{window.focus(),s.close(),t?.()},setTimeout(()=>s.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(A=>"audioinput"===A.kind&&""!==A.label)}catch(A){return console.warn("无法检查设备权限:",A),!1}}}const Ks=console.log,Os=(...A)=>{Ve.logBuiltinEnabled&&Ks(...A)};let Ns=null;class bs{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Us,this.initWebSocket()}static getInstance(A){if(!Ns){if(!A)throw new Error("WebSocket 尚未初始化");Ns=new bs(A)}return Ns}stateIdleChange(){const{state:A}=Ve.stateObject;A!==exports.AgentStatus.IDLE&&this.apiClient._changeState({data:{...Ve.stateBeforeChange}})}async getCustomerInfo(A){try{await this.apiClient._getInCallCrmDetail({data:{phone:A},success:A=>{const{contact_count:e,customer_name:t,phone:s,city:i,province:r}=A.data;ae.emit(exports.CallSipCallEvent.CUSTOMER_INFO,{customer_name:t||"未知客户",phone:s,city:i||"未知",province:r||"未知",contact_count:e||0})}})}catch(A){}}putAgentState(){Ve.sessionId="";const{post_call_process_time:A}=Ve.agentInfo,e=A||0;Ve.autoStateTimer&&(clearTimeout(Ve.autoStateTimer),Ve.autoStateTimer=null),ae.emit(exports.CallSipCallEvent.CUSTOMER_INFO,void 0),e>0?Ve.autoStateTimer=setTimeout(()=>{Ve.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){const A=be(Le,We);this.ws=new WebSocket(this.url+A),this.ws.onopen=()=>{this.sendMessage({type:0}),this.startHeartbeat()},this.ws.onmessage=A=>{const e=JSON.parse(A.data),{type:t,data:s,code:i,msg:r}=e;if(0!==t&&Os("%cWebSocket 收到消息:","color: blue; font-weight: bold;",e),t===exports.WebsocketTypeEnum.OUT_CALL&&(0!==i?(he.reset(),ae.emit(exports.CallSipCallEvent.OUT_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r),setTimeout(()=>{ae.emit(exports.CallSipCallEvent.CUSTOMER_INFO,void 0)},500),this.stateIdleChange()):0===i&&ae.emit(exports.CallSipCallEvent.OUT_SUCCESS)),t===exports.WebsocketTypeEnum.AGENT_STATE){Ve.stateObject.state!==exports.AgentStatus.IDLE&&Ve.stateObject.state!==exports.AgentStatus.BUSY||(Ve.stateBeforeChange=Ve.stateObject);const{state:A,state_name:e}=s;Ve.stateObject={state:A,state_name:e},"振铃中"===e&&he.updateDisplayText(exports.DisplayTextEnum.AGENT_RINGING),ae.emit(exports.CallSipCallEvent.AGENT_STATE,{state:A,state_name:e})}if(t===exports.WebsocketTypeEnum.OUT_CALL_INCOMING_CALL&&(ae.emit(exports.CallSipCallEvent.OUT_INCOMING_CALL),Ve.sessionId=s.session_id,he.updateActionConfigs(cs)),t===exports.WebsocketTypeEnum.OUT_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.OUT_HANGUP,s),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(exports.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(hs)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(as)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.TRANSFER_END),he.updateActionConfigs(as))),t===exports.WebsocketTypeEnum.OUT_CALL_RINGING&&1===s.type&&(ae.emit(exports.CallSipCallEvent.OUT_RINGING,s),he.updateDisplayText(exports.DisplayTextEnum.RINGING)),t===exports.WebsocketTypeEnum.OUT_CALL_ANSWER&&(ae.emit(exports.CallSipCallEvent.OUT_OFF_ANSWER,s),he.updateOutCallIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(hs)),t===exports.WebsocketTypeEnum.CONSULT_RINGING&&(ae.emit(exports.CallSipCallEvent.CONSULT_RINGING),he.updateDisplayText(exports.DisplayTextEnum.AGENT_RINGING),he.updateActionConfigs([])),t===exports.WebsocketTypeEnum.CONSULT_ANSWER&&(ae.emit(exports.CallSipCallEvent.CONSULT_OFF_HOOK,s),he.updateConsultIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CONSULTING),he.updateActionConfigs(ls)),t===exports.WebsocketTypeEnum.CONSULT_FAIL&&(ae.emit(exports.CallSipCallEvent.CONSULT_FAILED,{custom_reason:s.custom_reason}),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(hs)),t===exports.WebsocketTypeEnum.CONSULT_CALL_IN&&(ae.emit(exports.CallSipCallEvent.CONSULT_INCOMING,s),he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.CONSULT),he.updateDisplayText(exports.DisplayTextEnum.CONSULT_CALL_IN),he.updateActionConfigs(ds),Ve.enableBrowserAlert&&Zs.show("📞 咨询来电",`坐席 [${s.agent_name}] 正在咨询...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{agent_mane:s.agent_name})})),t===exports.WebsocketTypeEnum.CONSULT_CALL_IN_SUCCESS&&(Ve.sessionId=s.session_id,ae.emit(exports.CallSipCallEvent.CONSULT_CALL_IN_SUCCESS),he.updateConsultIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(gs)),t===exports.WebsocketTypeEnum.CONSULT_RETURN_CALL_SUCCESS&&(he.updateConsultIsAnswer(!1),ae.emit(exports.CallSipCallEvent.CONSULT_RETURN_CALL_SUCCESS),he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(hs)),t===exports.WebsocketTypeEnum.MUTE&&(0===i?(he.updateIsMuted(!0),ae.emit(exports.CallSipCallEvent.MUTE_SUCCESS),he.updateDisplayText(exports.DisplayTextEnum.MUTING)):(ae.emit(exports.CallSipCallEvent.MUTE_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.UNMUTE&&(0===i?(he.updateIsMuted(!1),ae.emit(exports.CallSipCallEvent.UNMUTE_SUCCESS),he.updateDisplayText(exports.DisplayTextEnum.CALLING)):(ae.emit(exports.CallSipCallEvent.UNMUTE_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CALL_HOLD&&(0===i?(he.updateIsHold(!0),he.updateDisplayText(exports.DisplayTextEnum.HOLDING),ae.emit(exports.CallSipCallEvent.HOLD_SUCCESS)):(ae.emit(exports.CallSipCallEvent.HOLD_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CALL_UNHOLD&&(0===i?(he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateIsHold(!1),ae.emit(exports.CallSipCallEvent.UNHOLD_SUCCESS)):(ae.emit(exports.CallSipCallEvent.UNHOLD_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER&&(0===i?ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_SUCCESS):(ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER_FAILED&&ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_FAILED,s.status),t===exports.WebsocketTypeEnum.CONSULT_TRANSFER_OFF_HOOK&&(he.updateDirection(exports.DirectionEnum.INCOMING),he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.CONSULT_TRANSFER_OFF_HOOK),he.updateActionConfigs(ps),he.updateIncomingIsAnswer(!0),he.updateConsultIsAnswer(!1)),t===exports.WebsocketTypeEnum.INCOMING_CALL&&(Ve.sessionId=s.session_id,he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.INCOMING),he.updateDisplayText(exports.DisplayTextEnum.INCOMING_CALL),ae.emit(exports.CallSipCallEvent.INCOMING_CALL,{customer_phone:s.customer_phone}),he.updateActionConfigs(ds),this.getCustomerInfo(s.customer_phone),Ve.enableBrowserAlert&&Zs.show("📞 客户来电",`客户 [${s.customer_phone}] 正在呼入...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{customer_phone:s.customer_phone})})),t===exports.WebsocketTypeEnum.INCOMING_CALL_OFF_HOOK&&(he.updateIncomingIsAnswer(!0),ae.emit(exports.CallSipCallEvent.INCOMING_CALL_OFF_HOOK),he.updateActionConfigs(ps),he.updateDisplayText(exports.DisplayTextEnum.CALLING)),t===exports.WebsocketTypeEnum.INCOMING_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.INCOMING_CALL_END),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(exports.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(exports.DisplayTextEnum.CALLING),ae.emit(exports.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(hs)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(as)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(exports.CallSipCallEvent.TRANSFER_END),he.updateActionConfigs(as))),t===exports.WebsocketTypeEnum.SATISFACTION_EVALUATION&&(0===i?ae.emit(exports.CallSipCallEvent.SATISFACTION_EVALUATION_SUCCESS):(ae.emit(exports.CallSipCallEvent.SATISFACTION_EVALUATION_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r))),t===exports.WebsocketTypeEnum.CONSULT_THREE_WAY&&(0!==i?(ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,r),ae.emit(exports.EventName.FAIL_NOTIFICATION,r)):0===i&&he.updateIsMeeting(!0)),t===exports.WebsocketTypeEnum.CONSULT_THREE_WAY_RESULT&&("success"===s.status?(he.updateDirection(exports.DirectionEnum.MEETING),he.updateDisplayText(exports.DisplayTextEnum.MEETING),he.updateActionConfigs(qs),ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_SUCCESS)):(ae.emit(exports.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,{conf_name:s.conf_name}),he.updateIsMeeting(!1))),t===exports.WebsocketTypeEnum.TRANSFER_INCOMING_CALL&&(s.agent_no===Ve.agentInfo.agent_no?(he.updateDisplayText(exports.DisplayTextEnum.TRANSFERRING),ae.emit(exports.CallSipCallEvent.TRANSFER_PROGRESS),he.updateActionConfigs([]),he.updateTransferIsAnswer(!0)):(ae.emit(exports.CallSipCallEvent.TRANSFER_INCOMING_CALL,s),he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.TRANSFER),he.updateDisplayText(exports.DisplayTextEnum.TRANSFER_INCOMING_CALL),he.updateActionConfigs(ds),Ve.enableBrowserAlert&&Zs.show("📞 转接来电",`坐席 [${s.agent_no}] 正在转接...`,()=>{ae.emit(exports.EventName.NOTIFICATION_CLICK,{agent_mane:s.agent_no})}))),t===exports.WebsocketTypeEnum.TRANSFER_OFF_HOOK&&(Ve.sessionId=s.session_id,ae.emit(exports.CallSipCallEvent.TRANSFER_OFF_HOOK),he.updateTransferIsAnswer(!0),he.updateDisplayText(exports.DisplayTextEnum.CALLING),he.updateActionConfigs(ps)),t===exports.WebsocketTypeEnum.TRANSFER_FAILED&&"failed"===s.status){ae.emit(exports.CallSipCallEvent.TRANSFER_FAILED,"未知原因");const A=he.get("direction");A===exports.DirectionEnum.OUTGOING?he.updateActionConfigs(hs):A===exports.DirectionEnum.INCOMING&&he.updateActionConfigs(ps)}},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const A=new Blob(["\n let timer;\n self.onmessage = function (e) {\n if (e.data === 'start') {\n timer = setInterval(() => {\n self.postMessage('heartbeat');\n }, 14000);\n } else if (e.data === 'stop') {\n clearInterval(timer);\n }\n };\n "],{type:"application/javascript"}),e=URL.createObjectURL(A);this.heartbeatWorker=new Worker(e),this.heartbeatWorker.onmessage=()=>{this.sendMessage({type:0})},this.heartbeatWorker.postMessage("start")}stopHeartbeat(){this.heartbeatWorker&&(this.heartbeatWorker.postMessage("stop"),this.heartbeatWorker.terminate(),this.heartbeatWorker=null)}sendMessage(A){this.ws?.readyState===WebSocket.OPEN?(100===A.type&&this.getCustomerInfo(A.data.customer_phone),this.ws.send(JSON.stringify(A)),0!==A.type&&Os("%cWebSocket 发送消息:","color: green; font-weight: bold;",A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Ns&&(Ns.close(),Ns=null)}static __internalSend(A){if(!Ns)throw new Error("WebSocket 尚未初始化");Ns.sendMessage(A)}}class Js{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=he.get("isCalling"),e=Ve.sessionId;if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}))}holdCall(){this.roleMute();const A=he.get("isHold"),{sessionId:e}=Ve;if(!e)return;if(!he.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(A)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));bs.__internalSend({type:exports.WebsocketTypeEnum.CALL_HOLD,data:{session_id:e}})}unholdCall(){this.roleMute();const{isHold:A}=he.getState(),{sessionId:e}=Ve;if(!he.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(e){if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));bs.__internalSend({type:exports.WebsocketTypeEnum.CALL_UNHOLD,data:{session_id:e}})}}sendDTMF(A){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!he.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=he.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;bs.__internalSend({type:exports.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:A}})}async consultCall(A){this.roleMute();const{isCalling:e,outCallIsAnswer:t,consultIsAnswer:s,incomingIsAnswer:i}=he.getState(),r=Ve.sessionId;if(!he.get("actionConfigs").includes("consult"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询"}));if(s)throw new Error(JSON.stringify({code:1,msg:"当前正在咨询"}));if(!(e||t||i))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!r)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));bs.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_REQUEST,data:{session_id:r,consultation_agent_no:A}})}async answerCall(){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async makeCall(A){const e=he.get("isCalling"),t=he.get("selectOutNumber")||"";if(e)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));he.updateIsCalling(!0),he.updateDirection(exports.DirectionEnum.OUTGOING),bs.__internalSend({type:exports.WebsocketTypeEnum.OUT_CALL,data:{customer_phone:A,caller:t}})}async hangup(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;bs.__internalSend({type:exports.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:A}})}mute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!A.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));bs.__internalSend({type:exports.WebsocketTypeEnum.MUTE,data:{session_id:t}})}unmute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!A.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));bs.__internalSend({type:exports.WebsocketTypeEnum.UNMUTE,data:{session_id:t}})}consultTransfer(){this.roleMute();const A=he.get("consultIsAnswer"),e=Ve.sessionId;if(!he.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_TRANSFER,data:{session_id:e}})}satisfactionEvaluation(){this.roleMute();const A=Ve.sessionId;if(!he.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));bs.__internalSend({type:exports.WebsocketTypeEnum.SATISFACTION_EVALUATION,data:{session_id:A}})}startConference(){this.roleMute();if(!he.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_THREE_WAY,data:{session_id:A}})}consultRetrieve(){this.roleMute();if(!he.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:exports.WebsocketTypeEnum.CONSULT_RETURN_CALL,data:{session_id:A}})}async transferAgent(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));bs.__internalSend({type:exports.WebsocketTypeEnum.TRANSFER,data:{session_id:t,transfer_type:0,transfer_dest:A}})}async transferOutline(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"号码不能为空"}));if(!/^\d+$/.test(A))throw new Error(JSON.stringify({code:1,msg:"号码格式错误"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));bs.__internalSend({type:exports.WebsocketTypeEnum.TRANSFER,data:{session_id:t,transfer_type:2,transfer_dest:A}})}}class Hs{static{this._instance=null}#A=null;#e=new Us;#t;#s=null;#i=!1;#r;#o=!1;constructor(){if(!Hs._creatingInstance)throw new Error("请使用 YSYTAgentSdk.getInstance() 获取实例");clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#n();Xe.updateRttObject(A)},2e3),Zs.requestMediaPermissions(),this.#r=he.subscribeKey("answerDevice",A=>{1===A?this.initWebRtc():this.#A=null})}static get instance(){return this._instance}static async destroyInstance(){this._instance&&(await this._instance.destroy(),this._instance=null)}static getInstance(){return this._instance||(Hs._creatingInstance=!0,this._instance=new Hs,delete Hs._creatingInstance,window.addEventListener("beforeunload",()=>{this._instance?.destroy()})),this._instance}getInit(){return this.#o}async initWebRtc(){if(this.#A)return;const A=Ve.agentInfo.sip_account_list.find(A=>1===A.device_type);if(!A)throw new Error(JSON.stringify({code:1,msg:"未找到 sip_account_list"}));{const e=A.sip_register_addr;this.#A=new _e({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#a),await this.#A.start()}}async init({actionNodeParams:A,url:e,appKey:t,appSecret:s,agentNo:i,enableBrowserAlert:r,logBuiltinEnabled:o}){try{const{viewHtmlElement:n,rttHTML:a}=A||{},V=e||"https://aicc.yescloudy.com";je=V,Le=t,We=s,Ve.logBuiltinEnabled=o||!1,await this.#e._agentLogin(i);const{agent_no:c,current_answer_device:h,current_state:l,out_display_number:g,out_display_select_switch:q}=Ve.agentInfo;l===exports.AgentStatus.IDLE?(he.updateActionConfigs(as),Ve.stateObject={state:l,state_name:"空闲"}):l===exports.AgentStatus.BUSY&&(he.updateActionConfigs(Vs),Ve.stateObject={state:l,state_name:"忙碌"}),1===q?he.updateSelectOutNumber(g):he.updateSelectOutNumber("");let d="";const p=new URL(V).host;d=V.includes("https")?`wss://${p}`:`ws://${p}`,bs.getInstance(`${d}/ccs-ws/api/v1/ws/call/${c}?Authorization=`),he.updateAnswerDevice(h),1===h&&await this.initWebRtc(),this.#t=new Js(this.#A),A&&n&&(this.#i=!0,new vs({container:n,rttHTML:a,statusParams:{state:exports.AgentStatus.IDLE,statusName:"空闲"}},this,this.#t)),Ve.enableBrowserAlert=r,r&&Zs.requestPermission(),ae.emit(exports.EventName.AGENT_INIT_STATUS,!0),this.#o=!0}catch(A){this.#i&&Fs("初始化失败"),ae.emit(exports.EventName.AGENT_INIT_STATUS,!1),this.#o=!1}}#a=A=>{const{type:e,data:t}=A;ae.emit(e,t)};on(A,e){return ae.on(A,e),this}off(A,e){ae.off(A,e)}offAll(){ae.clearAllListeners()}async destroyRtc(){await(this.#A?.destroy())}async destroy(){Hs._instance&&(await this.destroyRtc(),clearInterval(this.#s),bs.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#i=!1,Hs._instance=null)}async#n(){return this.#A?this.#A.getNetworkStats():{}}get call_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{answerCall:A(()=>this.#t.answerCall()),makeCall:A=>this.#t.makeCall(A),cancelCall:A(()=>this.#t.cancelCall()),hangup:A(()=>this.#t.hangup()),sendDTMF:A(A=>this.#t.sendDTMF(A)),holdCall:A(()=>this.#t.holdCall()),unholdCall:A(()=>this.#t.unholdCall()),consultCall:A(async A=>{try{await this.#t.consultCall(A)}catch(A){throw console.warn(A),A}}),consultRetrieve:A(()=>this.#t.consultRetrieve()),consultTransfer:A(()=>this.#t.consultTransfer()),mute:A(()=>this.#t.mute()),unmute:A(()=>this.#t.unmute()),satisfactionEvaluation:A(()=>this.#t.satisfactionEvaluation()),startConference:A(()=>this.#t.startConference()),transferAgent:A(A=>this.#t.transferAgent(A)),transferOutline:A(A=>this.#t.transferOutline(A))}}get agent_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{changeDevice:A(A=>this.#e.changeDevice(A)),changeState:A(A=>this.#e.changeState(A)),getIdleAgentList:A(A=>this.#e.getIdleAgentList(A)),getAgentState:A(A=>this.#e.getAgentState(A)),setAgentExplicit:A(A=>this.#e.setAgentExplicit(A))}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,out_display_data:s,out_display_select_switch:i,current_answer_device:r,current_state:o}=Ve.agentInfo,{stateObject:n}=Ve,a={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:o,default_device:r,out_display_data:s,out_display_select_switch:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:a[Number(A)]})),stateObject:n}}}exports.default=Hs;
@@ -911,4 +911,4 @@ const ms=A=>(e,t)=>{void 0!==t?t.addInitializer(()=>{customElements.define(A,e)}
911
911
  `:""}
912
912
  </div>
913
913
  </my-popover>
914
- `;ss(s,this.rttHTML)}}class xs{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const A=await navigator.mediaDevices.enumerateDevices();if(A.some(A=>"audioinput"===A.kind&&""!==A.label))return null;return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(A){return console.warn("获取音频权限失败:",A),null}}static show(A,e,t){if("Notification"in window&&"granted"===Notification.permission){const s=new Notification(A,{body:e,tag:"xy-global-notification",renotify:!0});s.onclick=()=>{window.focus(),s.close(),t?.()},setTimeout(()=>s.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(A=>"audioinput"===A.kind&&""!==A.label)}catch(A){return console.warn("无法检查设备权限:",A),!1}}}const Ks=console.log,Os=(...A)=>{Ve.logBuiltinEnabled&&Ks(...A)};let Ns=null;class bs{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Us,this.initWebSocket()}static getInstance(A){if(!Ns){if(!A)throw new Error("WebSocket 尚未初始化");Ns=new bs(A)}return Ns}stateIdleChange(){const{state:A}=Ve.stateObject;A!==Ae.IDLE&&this.apiClient._changeState({data:{...Ve.stateBeforeChange}})}async getCustomerInfo(A){try{await this.apiClient._getInCallCrmDetail({data:{phone:A},success:A=>{const{contact_count:e,customer_name:t,phone:s,city:i,province:r}=A.data;ae.emit(se.CUSTOMER_INFO,{customer_name:t||"未知客户",phone:s,city:i||"未知",province:r||"未知",contact_count:e||0})}})}catch(A){}}putAgentState(){Ve.sessionId="";const{post_call_process_time:A}=Ve.agentInfo,e=A||0;Ve.autoStateTimer&&(clearTimeout(Ve.autoStateTimer),Ve.autoStateTimer=null),ae.emit(se.CUSTOMER_INFO,void 0),e>0?Ve.autoStateTimer=setTimeout(()=>{Ve.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){const A=be(Le,We);this.ws=new WebSocket(this.url+A),this.ws.onopen=()=>{this.sendMessage({type:0}),this.startHeartbeat()},this.ws.onmessage=A=>{const e=JSON.parse(A.data),{type:t,data:s,code:i,msg:r}=e;if(0!==t&&Os("%cWebSocket 收到消息:","color: blue; font-weight: bold;",e),t===ie.OUT_CALL&&(0!==i?(he.reset(),ae.emit(se.OUT_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r),setTimeout(()=>{ae.emit(se.CUSTOMER_INFO,void 0)},500),this.stateIdleChange()):0===i&&ae.emit(se.OUT_SUCCESS)),t===ie.AGENT_STATE){Ve.stateObject.state!==Ae.IDLE&&Ve.stateObject.state!==Ae.BUSY||(Ve.stateBeforeChange=Ve.stateObject);const{state:A,state_name:e}=s;Ve.stateObject={state:A,state_name:e},"振铃中"===e&&he.updateDisplayText(oe.AGENT_RINGING),ae.emit(se.AGENT_STATE,{state:A,state_name:e})}if(t===ie.OUT_CALL_INCOMING_CALL&&(ae.emit(se.OUT_INCOMING_CALL),Ve.sessionId=s.session_id,he.updateActionConfigs(cs)),t===ie.OUT_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.OUT_HANGUP,s),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(se.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(hs)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(as)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(se.TRANSFER_END),he.updateActionConfigs(as))),t===ie.OUT_CALL_RINGING&&1===s.type&&(ae.emit(se.OUT_RINGING,s),he.updateDisplayText(oe.RINGING)),t===ie.OUT_CALL_ANSWER&&(ae.emit(se.OUT_OFF_ANSWER,s),he.updateOutCallIsAnswer(!0),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(hs)),t===ie.CONSULT_RINGING&&(ae.emit(se.CONSULT_RINGING),he.updateDisplayText(oe.AGENT_RINGING),he.updateActionConfigs([])),t===ie.CONSULT_ANSWER&&(ae.emit(se.CONSULT_OFF_HOOK,s),he.updateConsultIsAnswer(!0),he.updateDisplayText(oe.CONSULTING),he.updateActionConfigs(ls)),t===ie.CONSULT_FAIL&&(ae.emit(se.CONSULT_FAILED,{custom_reason:s.custom_reason}),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(hs)),t===ie.CONSULT_CALL_IN&&(ae.emit(se.CONSULT_INCOMING,s),he.updateIsCalling(!0),he.updateDirection(ee.CONSULT),he.updateDisplayText(oe.CONSULT_CALL_IN),he.updateActionConfigs(ds),Ve.enableBrowserAlert&&xs.show("📞 咨询来电",`坐席 [${s.agent_name}] 正在咨询...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{agent_mane:s.agent_name})})),t===ie.CONSULT_CALL_IN_SUCCESS&&(Ve.sessionId=s.session_id,ae.emit(se.CONSULT_CALL_IN_SUCCESS),he.updateConsultIsAnswer(!0),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(gs)),t===ie.CONSULT_RETURN_CALL_SUCCESS&&(he.updateConsultIsAnswer(!1),ae.emit(se.CONSULT_RETURN_CALL_SUCCESS),he.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(hs)),t===ie.MUTE&&(0===i?(he.updateIsMuted(!0),ae.emit(se.MUTE_SUCCESS),he.updateDisplayText(oe.MUTING)):(ae.emit(se.MUTE_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.UNMUTE&&(0===i?(he.updateIsMuted(!1),ae.emit(se.UNMUTE_SUCCESS),he.updateDisplayText(oe.CALLING)):(ae.emit(se.UNMUTE_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CALL_HOLD&&(0===i?(he.updateIsHold(!0),he.updateDisplayText(oe.HOLDING),ae.emit(se.HOLD_SUCCESS)):(ae.emit(se.HOLD_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CALL_UNHOLD&&(0===i?(he.updateDisplayText(oe.CALLING),he.updateIsHold(!1),ae.emit(se.UNHOLD_SUCCESS)):(ae.emit(se.UNHOLD_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CONSULT_TRANSFER&&(0===i?ae.emit(se.CONSULT_TRANSFER_SUCCESS):(ae.emit(se.CONSULT_TRANSFER_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CONSULT_TRANSFER_FAILED&&ae.emit(se.CONSULT_TRANSFER_FAILED,s.status),t===ie.CONSULT_TRANSFER_OFF_HOOK&&(he.updateDirection(ee.INCOMING),he.updateDisplayText(oe.CALLING),ae.emit(se.CONSULT_TRANSFER_OFF_HOOK),he.updateActionConfigs(us),he.updateIncomingIsAnswer(!0),he.updateConsultIsAnswer(!1)),t===ie.INCOMING_CALL&&(Ve.sessionId=s.session_id,he.updateIsCalling(!0),he.updateDirection(ee.INCOMING),he.updateDisplayText(oe.INCOMING_CALL),ae.emit(se.INCOMING_CALL,{customer_phone:s.customer_phone}),he.updateActionConfigs(ds),this.getCustomerInfo(s.customer_phone),Ve.enableBrowserAlert&&xs.show("📞 客户来电",`客户 [${s.customer_phone}] 正在呼入...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{customer_phone:s.customer_phone})})),t===ie.INCOMING_CALL_OFF_HOOK&&(he.updateIncomingIsAnswer(!0),ae.emit(se.INCOMING_CALL_OFF_HOOK),he.updateActionConfigs(us),he.updateDisplayText(oe.CALLING)),t===ie.INCOMING_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.INCOMING_CALL_END),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(se.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(hs)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(as)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(se.TRANSFER_END),he.updateActionConfigs(as))),t===ie.SATISFACTION_EVALUATION&&(0===i?ae.emit(se.SATISFACTION_EVALUATION_SUCCESS):(ae.emit(se.SATISFACTION_EVALUATION_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CONSULT_THREE_WAY&&(0!==i?(ae.emit(se.CONSULT_THREE_WAY_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r)):0===i&&he.updateIsMeeting(!0)),t===ie.CONSULT_THREE_WAY_RESULT&&("success"===s.status?(he.updateDirection(ee.MEETING),he.updateDisplayText(oe.MEETING),he.updateActionConfigs(qs),ae.emit(se.CONSULT_THREE_WAY_SUCCESS)):(ae.emit(se.CONSULT_THREE_WAY_FAILED,{conf_name:s.conf_name}),he.updateIsMeeting(!1))),t===ie.TRANSFER_INCOMING_CALL&&(s.agent_no===Ve.agentInfo.agent_no?(he.updateDisplayText(oe.TRANSFERRING),ae.emit(se.TRANSFER_PROGRESS),he.updateActionConfigs([]),he.updateTransferIsAnswer(!0)):(ae.emit(se.TRANSFER_INCOMING_CALL,s),he.updateIsCalling(!0),he.updateDirection(ee.TRANSFER),he.updateDisplayText(oe.TRANSFER_INCOMING_CALL),he.updateActionConfigs(ds),Ve.enableBrowserAlert&&xs.show("📞 转接来电",`坐席 [${s.agent_no}] 正在转接...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{agent_mane:s.agent_no})}))),t===ie.TRANSFER_OFF_HOOK&&(Ve.sessionId=s.session_id,ae.emit(se.TRANSFER_OFF_HOOK),he.updateTransferIsAnswer(!0),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(us)),t===ie.TRANSFER_FAILED&&"failed"===s.status){ae.emit(se.TRANSFER_FAILED,"未知原因");const A=he.get("direction");A===ee.OUTGOING?he.updateActionConfigs(hs):A===ee.INCOMING&&he.updateActionConfigs(us)}},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const A=new Blob(["\n let timer;\n self.onmessage = function (e) {\n if (e.data === 'start') {\n timer = setInterval(() => {\n self.postMessage('heartbeat');\n }, 14000);\n } else if (e.data === 'stop') {\n clearInterval(timer);\n }\n };\n "],{type:"application/javascript"}),e=URL.createObjectURL(A);this.heartbeatWorker=new Worker(e),this.heartbeatWorker.onmessage=()=>{this.sendMessage({type:0})},this.heartbeatWorker.postMessage("start")}stopHeartbeat(){this.heartbeatWorker&&(this.heartbeatWorker.postMessage("stop"),this.heartbeatWorker.terminate(),this.heartbeatWorker=null)}sendMessage(A){this.ws?.readyState===WebSocket.OPEN?(100===A.type&&this.getCustomerInfo(A.data.customer_phone),this.ws.send(JSON.stringify(A)),0!==A.type&&Os("%cWebSocket 发送消息:","color: green; font-weight: bold;",A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Ns&&(Ns.close(),Ns=null)}static __internalSend(A){if(!Ns)throw new Error("WebSocket 尚未初始化");Ns.sendMessage(A)}}class Js{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=he.get("isCalling"),e=Ve.sessionId;if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}))}holdCall(){this.roleMute();const A=he.get("isHold"),{sessionId:e}=Ve;if(!e)return;if(!he.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(A)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));bs.__internalSend({type:ie.CALL_HOLD,data:{session_id:e}})}unholdCall(){this.roleMute();const{isHold:A}=he.getState(),{sessionId:e}=Ve;if(!he.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(e){if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));bs.__internalSend({type:ie.CALL_UNHOLD,data:{session_id:e}})}}sendDTMF(A){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!he.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=he.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){this.hangup()}async consultCall(A){this.roleMute();const{isCalling:e,outCallIsAnswer:t,consultIsAnswer:s,incomingIsAnswer:i}=he.getState(),r=Ve.sessionId;if(!he.get("actionConfigs").includes("consult"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询"}));if(s)throw new Error(JSON.stringify({code:1,msg:"当前正在咨询"}));if(!(e||t||i))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!r)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));bs.__internalSend({type:ie.CONSULT_REQUEST,data:{session_id:r,consultation_agent_no:A}})}async answerCall(){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async rejectInCall(){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));const{isCalling:A}=he.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectInCall()}async makeCall(A){const e=he.get("isCalling"),t=he.get("selectOutNumber")||"";if(e)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));he.updateIsCalling(!0),he.updateDirection(ee.OUTGOING),bs.__internalSend({type:ie.OUT_CALL,data:{customer_phone:A,caller:t}})}async rejectOutCall(){const{isCalling:A}=he.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const e=Ve.sessionId;bs.__internalSend({type:ie.AGENT_HANGUP,data:{session_id:e}})}async hangup(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;bs.__internalSend({type:ie.AGENT_HANGUP,data:{session_id:A}})}mute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!A.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));bs.__internalSend({type:ie.MUTE,data:{session_id:t}})}unmute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!A.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));bs.__internalSend({type:ie.UNMUTE,data:{session_id:t}})}consultTransfer(){this.roleMute();const A=he.get("consultIsAnswer"),e=Ve.sessionId;if(!he.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:ie.CONSULT_TRANSFER,data:{session_id:e}})}satisfactionEvaluation(){this.roleMute();const A=Ve.sessionId;if(!he.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));bs.__internalSend({type:ie.SATISFACTION_EVALUATION,data:{session_id:A}})}startConference(){this.roleMute();if(!he.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:ie.CONSULT_THREE_WAY,data:{session_id:A}})}consultRetrieve(){this.roleMute();if(!he.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:ie.CONSULT_RETURN_CALL,data:{session_id:A}})}async transferAgent(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));bs.__internalSend({type:ie.TRANSFER,data:{session_id:t,transfer_type:0,transfer_dest:A}})}async transferOutline(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"号码不能为空"}));if(!/^\d+$/.test(A))throw new Error(JSON.stringify({code:1,msg:"号码格式错误"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));bs.__internalSend({type:ie.TRANSFER,data:{session_id:t,transfer_type:2,transfer_dest:A}})}}class Hs{static{this._instance=null}#A=null;#e=new Us;#t;#s=null;#i=!1;#r;#o=!1;constructor(){if(!Hs._creatingInstance)throw new Error("请使用 YSYTAgentSdk.getInstance() 获取实例");clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#n();Xe.updateRttObject(A)},2e3),xs.requestMediaPermissions(),this.#r=he.subscribeKey("answerDevice",A=>{1===A?this.initWebRtc():this.#A=null})}static get instance(){return this._instance}static async destroyInstance(){this._instance&&(await this._instance.destroy(),this._instance=null)}static getInstance(){return this._instance||(Hs._creatingInstance=!0,this._instance=new Hs,delete Hs._creatingInstance,window.addEventListener("beforeunload",()=>{this._instance?.destroy()})),this._instance}getInit(){return this.#o}async initWebRtc(){if(this.#A)return;const A=Ve.agentInfo.sip_account_list.find(A=>1===A.device_type);if(!A)throw new Error(JSON.stringify({code:1,msg:"未找到 sip_account_list"}));{const e=A.sip_register_addr;this.#A=new _e({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#a),await this.#A.start()}}async init({actionNodeParams:A,url:e,appKey:t,appSecret:s,agentNo:i,enableBrowserAlert:r,logBuiltinEnabled:o}){try{const{viewHtmlElement:n,rttHTML:a}=A||{},V=e||"https://aicc.yescloudy.com";je=V,Le=t,We=s,Ve.logBuiltinEnabled=o||!1,await this.#e._agentLogin(i);const{agent_no:c,current_answer_device:h,current_state:l,out_display_number:g,out_display_select_switch:q}=Ve.agentInfo;l===Ae.IDLE?(he.updateActionConfigs(as),Ve.stateObject={state:l,state_name:"空闲"}):l===Ae.BUSY&&(he.updateActionConfigs(Vs),Ve.stateObject={state:l,state_name:"忙碌"}),1===q?he.updateSelectOutNumber(g):he.updateSelectOutNumber("");let d="";const u=new URL(V).host;d=V.includes("https")?`wss://${u}`:`ws://${u}`,bs.getInstance(`${d}/ccs-ws/api/v1/ws/call/${c}?Authorization=`),he.updateAnswerDevice(h),1===h&&await this.initWebRtc(),this.#t=new Js(this.#A),A&&n&&(this.#i=!0,new vs({container:n,rttHTML:a,statusParams:{state:Ae.IDLE,statusName:"空闲"}},this,this.#t)),Ve.enableBrowserAlert=r,r&&xs.requestPermission(),ae.emit(re.AGENT_INIT_STATUS,!0),this.#o=!0}catch(A){this.#i&&Fs("初始化失败"),ae.emit(re.AGENT_INIT_STATUS,!1),this.#o=!1}}#a=A=>{const{type:e,data:t}=A;ae.emit(e,t)};on(A,e){return ae.on(A,e),this}off(A,e){ae.off(A,e)}offAll(){ae.clearAllListeners()}async destroyRtc(){await(this.#A?.destroy())}async destroy(){Hs._instance&&(await this.destroyRtc(),clearInterval(this.#s),bs.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#i=!1,Hs._instance=null)}async#n(){return this.#A?this.#A.getNetworkStats():{}}get call_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{answerCall:A(()=>this.#t.answerCall()),makeCall:A=>this.#t.makeCall(A),cancelCall:A(()=>this.#t.cancelCall()),hangup:A(()=>this.#t.hangup()),sendDTMF:A(A=>this.#t.sendDTMF(A)),holdCall:A(()=>this.#t.holdCall()),unholdCall:A(()=>this.#t.unholdCall()),consultCall:A(async A=>{try{await this.#t.consultCall(A)}catch(A){throw console.warn(A),A}}),consultRetrieve:A(()=>this.#t.consultRetrieve()),consultTransfer:A(()=>this.#t.consultTransfer()),mute:A(()=>this.#t.mute()),unmute:A(()=>this.#t.unmute()),satisfactionEvaluation:A(()=>this.#t.satisfactionEvaluation()),startConference:A(()=>this.#t.startConference()),transferAgent:A(A=>this.#t.transferAgent(A)),transferOutline:A(A=>this.#t.transferOutline(A))}}get agent_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{changeDevice:A(A=>this.#e.changeDevice(A)),changeState:A(A=>this.#e.changeState(A)),getIdleAgentList:A(A=>this.#e.getIdleAgentList(A)),getAgentState:A(A=>this.#e.getAgentState(A)),setAgentExplicit:A(A=>this.#e.setAgentExplicit(A))}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,out_display_data:s,out_display_select_switch:i,current_answer_device:r,current_state:o}=Ve.agentInfo,{stateObject:n}=Ve,a={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:o,default_device:r,out_display_data:s,out_display_select_switch:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:a[Number(A)]})),stateObject:n}}}import.meta.hot&&import.meta.hot.dispose(()=>{Hs.instance&&Hs.destroyInstance()});export{Ae as AgentStatus,se as CallSipCallEvent,ee as DirectionEnum,oe as DisplayTextEnum,re as EventName,te as WebRtcCallSipEventEnum,ie as WebsocketTypeEnum,Hs as default};
914
+ `;ss(s,this.rttHTML)}}class xs{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const A=await navigator.mediaDevices.enumerateDevices();if(A.some(A=>"audioinput"===A.kind&&""!==A.label))return null;return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(A){return console.warn("获取音频权限失败:",A),null}}static show(A,e,t){if("Notification"in window&&"granted"===Notification.permission){const s=new Notification(A,{body:e,tag:"xy-global-notification",renotify:!0});s.onclick=()=>{window.focus(),s.close(),t?.()},setTimeout(()=>s.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(A=>"audioinput"===A.kind&&""!==A.label)}catch(A){return console.warn("无法检查设备权限:",A),!1}}}const Ks=console.log,Os=(...A)=>{Ve.logBuiltinEnabled&&Ks(...A)};let Ns=null;class bs{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Us,this.initWebSocket()}static getInstance(A){if(!Ns){if(!A)throw new Error("WebSocket 尚未初始化");Ns=new bs(A)}return Ns}stateIdleChange(){const{state:A}=Ve.stateObject;A!==Ae.IDLE&&this.apiClient._changeState({data:{...Ve.stateBeforeChange}})}async getCustomerInfo(A){try{await this.apiClient._getInCallCrmDetail({data:{phone:A},success:A=>{const{contact_count:e,customer_name:t,phone:s,city:i,province:r}=A.data;ae.emit(se.CUSTOMER_INFO,{customer_name:t||"未知客户",phone:s,city:i||"未知",province:r||"未知",contact_count:e||0})}})}catch(A){}}putAgentState(){Ve.sessionId="";const{post_call_process_time:A}=Ve.agentInfo,e=A||0;Ve.autoStateTimer&&(clearTimeout(Ve.autoStateTimer),Ve.autoStateTimer=null),ae.emit(se.CUSTOMER_INFO,void 0),e>0?Ve.autoStateTimer=setTimeout(()=>{Ve.autoStateTimer=null,this.stateIdleChange()},e):this.stateIdleChange()}initWebSocket(){const A=be(Le,We);this.ws=new WebSocket(this.url+A),this.ws.onopen=()=>{this.sendMessage({type:0}),this.startHeartbeat()},this.ws.onmessage=A=>{const e=JSON.parse(A.data),{type:t,data:s,code:i,msg:r}=e;if(0!==t&&Os("%cWebSocket 收到消息:","color: blue; font-weight: bold;",e),t===ie.OUT_CALL&&(0!==i?(he.reset(),ae.emit(se.OUT_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r),setTimeout(()=>{ae.emit(se.CUSTOMER_INFO,void 0)},500),this.stateIdleChange()):0===i&&ae.emit(se.OUT_SUCCESS)),t===ie.AGENT_STATE){Ve.stateObject.state!==Ae.IDLE&&Ve.stateObject.state!==Ae.BUSY||(Ve.stateBeforeChange=Ve.stateObject);const{state:A,state_name:e}=s;Ve.stateObject={state:A,state_name:e},"振铃中"===e&&he.updateDisplayText(oe.AGENT_RINGING),ae.emit(se.AGENT_STATE,{state:A,state_name:e})}if(t===ie.OUT_CALL_INCOMING_CALL&&(ae.emit(se.OUT_INCOMING_CALL),Ve.sessionId=s.session_id,he.updateActionConfigs(cs)),t===ie.OUT_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.OUT_HANGUP,s),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(se.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(hs)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(as)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(se.TRANSFER_END),he.updateActionConfigs(as))),t===ie.OUT_CALL_RINGING&&1===s.type&&(ae.emit(se.OUT_RINGING,s),he.updateDisplayText(oe.RINGING)),t===ie.OUT_CALL_ANSWER&&(ae.emit(se.OUT_OFF_ANSWER,s),he.updateOutCallIsAnswer(!0),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(hs)),t===ie.CONSULT_RINGING&&(ae.emit(se.CONSULT_RINGING),he.updateDisplayText(oe.AGENT_RINGING),he.updateActionConfigs([])),t===ie.CONSULT_ANSWER&&(ae.emit(se.CONSULT_OFF_HOOK,s),he.updateConsultIsAnswer(!0),he.updateDisplayText(oe.CONSULTING),he.updateActionConfigs(ls)),t===ie.CONSULT_FAIL&&(ae.emit(se.CONSULT_FAILED,{custom_reason:s.custom_reason}),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(hs)),t===ie.CONSULT_CALL_IN&&(ae.emit(se.CONSULT_INCOMING,s),he.updateIsCalling(!0),he.updateDirection(ee.CONSULT),he.updateDisplayText(oe.CONSULT_CALL_IN),he.updateActionConfigs(ds),Ve.enableBrowserAlert&&xs.show("📞 咨询来电",`坐席 [${s.agent_name}] 正在咨询...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{agent_mane:s.agent_name})})),t===ie.CONSULT_CALL_IN_SUCCESS&&(Ve.sessionId=s.session_id,ae.emit(se.CONSULT_CALL_IN_SUCCESS),he.updateConsultIsAnswer(!0),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(gs)),t===ie.CONSULT_RETURN_CALL_SUCCESS&&(he.updateConsultIsAnswer(!1),ae.emit(se.CONSULT_RETURN_CALL_SUCCESS),he.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(hs)),t===ie.MUTE&&(0===i?(he.updateIsMuted(!0),ae.emit(se.MUTE_SUCCESS),he.updateDisplayText(oe.MUTING)):(ae.emit(se.MUTE_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.UNMUTE&&(0===i?(he.updateIsMuted(!1),ae.emit(se.UNMUTE_SUCCESS),he.updateDisplayText(oe.CALLING)):(ae.emit(se.UNMUTE_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CALL_HOLD&&(0===i?(he.updateIsHold(!0),he.updateDisplayText(oe.HOLDING),ae.emit(se.HOLD_SUCCESS)):(ae.emit(se.HOLD_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CALL_UNHOLD&&(0===i?(he.updateDisplayText(oe.CALLING),he.updateIsHold(!1),ae.emit(se.UNHOLD_SUCCESS)):(ae.emit(se.UNHOLD_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CONSULT_TRANSFER&&(0===i?ae.emit(se.CONSULT_TRANSFER_SUCCESS):(ae.emit(se.CONSULT_TRANSFER_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CONSULT_TRANSFER_FAILED&&ae.emit(se.CONSULT_TRANSFER_FAILED,s.status),t===ie.CONSULT_TRANSFER_OFF_HOOK&&(he.updateDirection(ee.INCOMING),he.updateDisplayText(oe.CALLING),ae.emit(se.CONSULT_TRANSFER_OFF_HOOK),he.updateActionConfigs(us),he.updateIncomingIsAnswer(!0),he.updateConsultIsAnswer(!1)),t===ie.INCOMING_CALL&&(Ve.sessionId=s.session_id,he.updateIsCalling(!0),he.updateDirection(ee.INCOMING),he.updateDisplayText(oe.INCOMING_CALL),ae.emit(se.INCOMING_CALL,{customer_phone:s.customer_phone}),he.updateActionConfigs(ds),this.getCustomerInfo(s.customer_phone),Ve.enableBrowserAlert&&xs.show("📞 客户来电",`客户 [${s.customer_phone}] 正在呼入...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{customer_phone:s.customer_phone})})),t===ie.INCOMING_CALL_OFF_HOOK&&(he.updateIncomingIsAnswer(!0),ae.emit(se.INCOMING_CALL_OFF_HOOK),he.updateActionConfigs(us),he.updateDisplayText(oe.CALLING)),t===ie.INCOMING_CALL_END&&(he.updateDisplayText(""),1===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.INCOMING_CALL_END),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(he.reset(),ae.emit(se.OUR_SIDE_CONSULT_HANGUP,s),this.putAgentState(),he.updateActionConfigs(as)):2===s.device_type&&s.agent_no!==Ve.agentInfo.agent_no?(he.updateDisplayText(oe.CALLING),ae.emit(se.OTHER_SIDE_CONSULT_HANGUP,s),he.updateActionConfigs(hs)):3===s.device_type&&s.agent_no===Ve.agentInfo.agent_no?(this.putAgentState(),he.reset(),ae.emit(se.THREE_WAY_OUR_SIDE_HANGUP),he.updateActionConfigs(as)):4===s.device_type&&s.agent_no===Ve.agentInfo.agent_no&&(this.putAgentState(),he.reset(),ae.emit(se.TRANSFER_END),he.updateActionConfigs(as))),t===ie.SATISFACTION_EVALUATION&&(0===i?ae.emit(se.SATISFACTION_EVALUATION_SUCCESS):(ae.emit(se.SATISFACTION_EVALUATION_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r))),t===ie.CONSULT_THREE_WAY&&(0!==i?(ae.emit(se.CONSULT_THREE_WAY_FAILED,r),ae.emit(re.FAIL_NOTIFICATION,r)):0===i&&he.updateIsMeeting(!0)),t===ie.CONSULT_THREE_WAY_RESULT&&("success"===s.status?(he.updateDirection(ee.MEETING),he.updateDisplayText(oe.MEETING),he.updateActionConfigs(qs),ae.emit(se.CONSULT_THREE_WAY_SUCCESS)):(ae.emit(se.CONSULT_THREE_WAY_FAILED,{conf_name:s.conf_name}),he.updateIsMeeting(!1))),t===ie.TRANSFER_INCOMING_CALL&&(s.agent_no===Ve.agentInfo.agent_no?(he.updateDisplayText(oe.TRANSFERRING),ae.emit(se.TRANSFER_PROGRESS),he.updateActionConfigs([]),he.updateTransferIsAnswer(!0)):(ae.emit(se.TRANSFER_INCOMING_CALL,s),he.updateIsCalling(!0),he.updateDirection(ee.TRANSFER),he.updateDisplayText(oe.TRANSFER_INCOMING_CALL),he.updateActionConfigs(ds),Ve.enableBrowserAlert&&xs.show("📞 转接来电",`坐席 [${s.agent_no}] 正在转接...`,()=>{ae.emit(re.NOTIFICATION_CLICK,{agent_mane:s.agent_no})}))),t===ie.TRANSFER_OFF_HOOK&&(Ve.sessionId=s.session_id,ae.emit(se.TRANSFER_OFF_HOOK),he.updateTransferIsAnswer(!0),he.updateDisplayText(oe.CALLING),he.updateActionConfigs(us)),t===ie.TRANSFER_FAILED&&"failed"===s.status){ae.emit(se.TRANSFER_FAILED,"未知原因");const A=he.get("direction");A===ee.OUTGOING?he.updateActionConfigs(hs):A===ee.INCOMING&&he.updateActionConfigs(us)}},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const A=new Blob(["\n let timer;\n self.onmessage = function (e) {\n if (e.data === 'start') {\n timer = setInterval(() => {\n self.postMessage('heartbeat');\n }, 14000);\n } else if (e.data === 'stop') {\n clearInterval(timer);\n }\n };\n "],{type:"application/javascript"}),e=URL.createObjectURL(A);this.heartbeatWorker=new Worker(e),this.heartbeatWorker.onmessage=()=>{this.sendMessage({type:0})},this.heartbeatWorker.postMessage("start")}stopHeartbeat(){this.heartbeatWorker&&(this.heartbeatWorker.postMessage("stop"),this.heartbeatWorker.terminate(),this.heartbeatWorker=null)}sendMessage(A){this.ws?.readyState===WebSocket.OPEN?(100===A.type&&this.getCustomerInfo(A.data.customer_phone),this.ws.send(JSON.stringify(A)),0!==A.type&&Os("%cWebSocket 发送消息:","color: green; font-weight: bold;",A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Ns&&(Ns.close(),Ns=null)}static __internalSend(A){if(!Ns)throw new Error("WebSocket 尚未初始化");Ns.sendMessage(A)}}class Js{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=he.get("isCalling"),e=Ve.sessionId;if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}))}holdCall(){this.roleMute();const A=he.get("isHold"),{sessionId:e}=Ve;if(!e)return;if(!he.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(A)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));bs.__internalSend({type:ie.CALL_HOLD,data:{session_id:e}})}unholdCall(){this.roleMute();const{isHold:A}=he.getState(),{sessionId:e}=Ve;if(!he.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(e){if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));bs.__internalSend({type:ie.CALL_UNHOLD,data:{session_id:e}})}}sendDTMF(A){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!he.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=he.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;bs.__internalSend({type:ie.AGENT_HANGUP,data:{session_id:A}})}async consultCall(A){this.roleMute();const{isCalling:e,outCallIsAnswer:t,consultIsAnswer:s,incomingIsAnswer:i}=he.getState(),r=Ve.sessionId;if(!he.get("actionConfigs").includes("consult"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询"}));if(s)throw new Error(JSON.stringify({code:1,msg:"当前正在咨询"}));if(!(e||t||i))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!r)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));bs.__internalSend({type:ie.CONSULT_REQUEST,data:{session_id:r,consultation_agent_no:A}})}async answerCall(){if(1!==he.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async makeCall(A){const e=he.get("isCalling"),t=he.get("selectOutNumber")||"";if(e)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));he.updateIsCalling(!0),he.updateDirection(ee.OUTGOING),bs.__internalSend({type:ie.OUT_CALL,data:{customer_phone:A,caller:t}})}async hangup(){if(!he.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const A=Ve.sessionId;bs.__internalSend({type:ie.AGENT_HANGUP,data:{session_id:A}})}mute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!A.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));bs.__internalSend({type:ie.MUTE,data:{session_id:t}})}unmute(){this.roleMute();const A=he.get("actionConfigs"),e=he.get("isMuted"),t=Ve.sessionId;if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!A.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));bs.__internalSend({type:ie.UNMUTE,data:{session_id:t}})}consultTransfer(){this.roleMute();const A=he.get("consultIsAnswer"),e=Ve.sessionId;if(!he.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:ie.CONSULT_TRANSFER,data:{session_id:e}})}satisfactionEvaluation(){this.roleMute();const A=Ve.sessionId;if(!he.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));bs.__internalSend({type:ie.SATISFACTION_EVALUATION,data:{session_id:A}})}startConference(){this.roleMute();if(!he.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:ie.CONSULT_THREE_WAY,data:{session_id:A}})}consultRetrieve(){this.roleMute();if(!he.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const A=Ve.sessionId;if(!he.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:ie.CONSULT_RETURN_CALL,data:{session_id:A}})}async transferAgent(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));bs.__internalSend({type:ie.TRANSFER,data:{session_id:t,transfer_type:0,transfer_dest:A}})}async transferOutline(A){this.roleMute();if(!he.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));if(!A)throw new Error(JSON.stringify({code:1,msg:"号码不能为空"}));if(!/^\d+$/.test(A))throw new Error(JSON.stringify({code:1,msg:"号码格式错误"}));const{transferIsAnswer:e}=he.getState(),t=Ve.sessionId;if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));bs.__internalSend({type:ie.TRANSFER,data:{session_id:t,transfer_type:2,transfer_dest:A}})}}class Hs{static{this._instance=null}#A=null;#e=new Us;#t;#s=null;#i=!1;#r;#o=!1;constructor(){if(!Hs._creatingInstance)throw new Error("请使用 YSYTAgentSdk.getInstance() 获取实例");clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#n();Xe.updateRttObject(A)},2e3),xs.requestMediaPermissions(),this.#r=he.subscribeKey("answerDevice",A=>{1===A?this.initWebRtc():this.#A=null})}static get instance(){return this._instance}static async destroyInstance(){this._instance&&(await this._instance.destroy(),this._instance=null)}static getInstance(){return this._instance||(Hs._creatingInstance=!0,this._instance=new Hs,delete Hs._creatingInstance,window.addEventListener("beforeunload",()=>{this._instance?.destroy()})),this._instance}getInit(){return this.#o}async initWebRtc(){if(this.#A)return;const A=Ve.agentInfo.sip_account_list.find(A=>1===A.device_type);if(!A)throw new Error(JSON.stringify({code:1,msg:"未找到 sip_account_list"}));{const e=A.sip_register_addr;this.#A=new _e({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#a),await this.#A.start()}}async init({actionNodeParams:A,url:e,appKey:t,appSecret:s,agentNo:i,enableBrowserAlert:r,logBuiltinEnabled:o}){try{const{viewHtmlElement:n,rttHTML:a}=A||{},V=e||"https://aicc.yescloudy.com";je=V,Le=t,We=s,Ve.logBuiltinEnabled=o||!1,await this.#e._agentLogin(i);const{agent_no:c,current_answer_device:h,current_state:l,out_display_number:g,out_display_select_switch:q}=Ve.agentInfo;l===Ae.IDLE?(he.updateActionConfigs(as),Ve.stateObject={state:l,state_name:"空闲"}):l===Ae.BUSY&&(he.updateActionConfigs(Vs),Ve.stateObject={state:l,state_name:"忙碌"}),1===q?he.updateSelectOutNumber(g):he.updateSelectOutNumber("");let d="";const u=new URL(V).host;d=V.includes("https")?`wss://${u}`:`ws://${u}`,bs.getInstance(`${d}/ccs-ws/api/v1/ws/call/${c}?Authorization=`),he.updateAnswerDevice(h),1===h&&await this.initWebRtc(),this.#t=new Js(this.#A),A&&n&&(this.#i=!0,new vs({container:n,rttHTML:a,statusParams:{state:Ae.IDLE,statusName:"空闲"}},this,this.#t)),Ve.enableBrowserAlert=r,r&&xs.requestPermission(),ae.emit(re.AGENT_INIT_STATUS,!0),this.#o=!0}catch(A){this.#i&&Fs("初始化失败"),ae.emit(re.AGENT_INIT_STATUS,!1),this.#o=!1}}#a=A=>{const{type:e,data:t}=A;ae.emit(e,t)};on(A,e){return ae.on(A,e),this}off(A,e){ae.off(A,e)}offAll(){ae.clearAllListeners()}async destroyRtc(){await(this.#A?.destroy())}async destroy(){Hs._instance&&(await this.destroyRtc(),clearInterval(this.#s),bs.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#i=!1,Hs._instance=null)}async#n(){return this.#A?this.#A.getNetworkStats():{}}get call_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{answerCall:A(()=>this.#t.answerCall()),makeCall:A=>this.#t.makeCall(A),cancelCall:A(()=>this.#t.cancelCall()),hangup:A(()=>this.#t.hangup()),sendDTMF:A(A=>this.#t.sendDTMF(A)),holdCall:A(()=>this.#t.holdCall()),unholdCall:A(()=>this.#t.unholdCall()),consultCall:A(async A=>{try{await this.#t.consultCall(A)}catch(A){throw console.warn(A),A}}),consultRetrieve:A(()=>this.#t.consultRetrieve()),consultTransfer:A(()=>this.#t.consultTransfer()),mute:A(()=>this.#t.mute()),unmute:A(()=>this.#t.unmute()),satisfactionEvaluation:A(()=>this.#t.satisfactionEvaluation()),startConference:A(()=>this.#t.startConference()),transferAgent:A(A=>this.#t.transferAgent(A)),transferOutline:A(A=>this.#t.transferOutline(A))}}get agent_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{changeDevice:A(A=>this.#e.changeDevice(A)),changeState:A(A=>this.#e.changeState(A)),getIdleAgentList:A(A=>this.#e.getIdleAgentList(A)),getAgentState:A(A=>this.#e.getAgentState(A)),setAgentExplicit:A(A=>this.#e.setAgentExplicit(A))}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,out_display_data:s,out_display_select_switch:i,current_answer_device:r,current_state:o}=Ve.agentInfo,{stateObject:n}=Ve,a={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:o,default_device:r,out_display_data:s,out_display_select_switch:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:a[Number(A)]})),stateObject:n}}}import.meta.hot&&import.meta.hot.dispose(()=>{Hs.instance&&Hs.destroyInstance()});export{Ae as AgentStatus,se as CallSipCallEvent,ee as DirectionEnum,oe as DisplayTextEnum,re as EventName,te as WebRtcCallSipEventEnum,ie as WebsocketTypeEnum,Hs as default};
@@ -911,4 +911,4 @@ const ms=A=>(e,t)=>{void 0!==t?t.addInitializer(()=>{customElements.define(A,e)}
911
911
  `:""}
912
912
  </div>
913
913
  </my-popover>
914
- `;ss(s,this.rttHTML)}}class xs{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const A=await navigator.mediaDevices.enumerateDevices();if(A.some(A=>"audioinput"===A.kind&&""!==A.label))return null;return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(A){return console.warn("获取音频权限失败:",A),null}}static show(A,e,t){if("Notification"in window&&"granted"===Notification.permission){const s=new Notification(A,{body:e,tag:"xy-global-notification",renotify:!0});s.onclick=()=>{window.focus(),s.close(),t?.()},setTimeout(()=>s.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(A=>"audioinput"===A.kind&&""!==A.label)}catch(A){return console.warn("无法检查设备权限:",A),!1}}}const Ks=console.log,Os=(...A)=>{ce.logBuiltinEnabled&&Ks(...A)};let Ns=null;class bs{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Us,this.initWebSocket()}static getInstance(A){if(!Ns){if(!A)throw new Error("WebSocket 尚未初始化");Ns=new bs(A)}return Ns}stateIdleChange(){const{state:e}=ce.stateObject;e!==A.AgentStatus.IDLE&&this.apiClient._changeState({data:{...ce.stateBeforeChange}})}async getCustomerInfo(e){try{await this.apiClient._getInCallCrmDetail({data:{phone:e},success:e=>{const{contact_count:t,customer_name:s,phone:i,city:r,province:n}=e.data;Ve.emit(A.CallSipCallEvent.CUSTOMER_INFO,{customer_name:s||"未知客户",phone:i,city:r||"未知",province:n||"未知",contact_count:t||0})}})}catch(A){}}putAgentState(){ce.sessionId="";const{post_call_process_time:e}=ce.agentInfo,t=e||0;ce.autoStateTimer&&(clearTimeout(ce.autoStateTimer),ce.autoStateTimer=null),Ve.emit(A.CallSipCallEvent.CUSTOMER_INFO,void 0),t>0?ce.autoStateTimer=setTimeout(()=>{ce.autoStateTimer=null,this.stateIdleChange()},t):this.stateIdleChange()}initWebSocket(){const e=be(Le,We);this.ws=new WebSocket(this.url+e),this.ws.onopen=()=>{this.sendMessage({type:0}),this.startHeartbeat()},this.ws.onmessage=e=>{const t=JSON.parse(e.data),{type:s,data:i,code:r,msg:n}=t;if(0!==s&&Os("%cWebSocket 收到消息:","color: blue; font-weight: bold;",t),s===A.WebsocketTypeEnum.OUT_CALL&&(0!==r?(le.reset(),Ve.emit(A.CallSipCallEvent.OUT_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n),setTimeout(()=>{Ve.emit(A.CallSipCallEvent.CUSTOMER_INFO,void 0)},500),this.stateIdleChange()):0===r&&Ve.emit(A.CallSipCallEvent.OUT_SUCCESS)),s===A.WebsocketTypeEnum.AGENT_STATE){ce.stateObject.state!==A.AgentStatus.IDLE&&ce.stateObject.state!==A.AgentStatus.BUSY||(ce.stateBeforeChange=ce.stateObject);const{state:e,state_name:t}=i;ce.stateObject={state:e,state_name:t},"振铃中"===t&&le.updateDisplayText(A.DisplayTextEnum.AGENT_RINGING),Ve.emit(A.CallSipCallEvent.AGENT_STATE,{state:e,state_name:t})}if(s===A.WebsocketTypeEnum.OUT_CALL_INCOMING_CALL&&(Ve.emit(A.CallSipCallEvent.OUT_INCOMING_CALL),ce.sessionId=i.session_id,le.updateActionConfigs(cs)),s===A.WebsocketTypeEnum.OUT_CALL_END&&(le.updateDisplayText(""),1===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.OUT_HANGUP,i),le.updateActionConfigs(as)):2===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(le.reset(),Ve.emit(A.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState(),le.updateActionConfigs(as)):2===i.device_type&&i.agent_no!==ce.agentInfo.agent_no?(le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),le.updateActionConfigs(hs)):3===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),le.updateActionConfigs(as)):4===i.device_type&&i.agent_no===ce.agentInfo.agent_no&&(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.TRANSFER_END),le.updateActionConfigs(as))),s===A.WebsocketTypeEnum.OUT_CALL_RINGING&&1===i.type&&(Ve.emit(A.CallSipCallEvent.OUT_RINGING,i),le.updateDisplayText(A.DisplayTextEnum.RINGING)),s===A.WebsocketTypeEnum.OUT_CALL_ANSWER&&(Ve.emit(A.CallSipCallEvent.OUT_OFF_ANSWER,i),le.updateOutCallIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(hs)),s===A.WebsocketTypeEnum.CONSULT_RINGING&&(Ve.emit(A.CallSipCallEvent.CONSULT_RINGING),le.updateDisplayText(A.DisplayTextEnum.AGENT_RINGING),le.updateActionConfigs([])),s===A.WebsocketTypeEnum.CONSULT_ANSWER&&(Ve.emit(A.CallSipCallEvent.CONSULT_OFF_HOOK,i),le.updateConsultIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CONSULTING),le.updateActionConfigs(ls)),s===A.WebsocketTypeEnum.CONSULT_FAIL&&(Ve.emit(A.CallSipCallEvent.CONSULT_FAILED,{custom_reason:i.custom_reason}),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(hs)),s===A.WebsocketTypeEnum.CONSULT_CALL_IN&&(Ve.emit(A.CallSipCallEvent.CONSULT_INCOMING,i),le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.CONSULT),le.updateDisplayText(A.DisplayTextEnum.CONSULT_CALL_IN),le.updateActionConfigs(ds),ce.enableBrowserAlert&&xs.show("📞 咨询来电",`坐席 [${i.agent_name}] 正在咨询...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{agent_mane:i.agent_name})})),s===A.WebsocketTypeEnum.CONSULT_CALL_IN_SUCCESS&&(ce.sessionId=i.session_id,Ve.emit(A.CallSipCallEvent.CONSULT_CALL_IN_SUCCESS),le.updateConsultIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(gs)),s===A.WebsocketTypeEnum.CONSULT_RETURN_CALL_SUCCESS&&(le.updateConsultIsAnswer(!1),Ve.emit(A.CallSipCallEvent.CONSULT_RETURN_CALL_SUCCESS),le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),le.updateActionConfigs(hs)),s===A.WebsocketTypeEnum.MUTE&&(0===r?(le.updateIsMuted(!0),Ve.emit(A.CallSipCallEvent.MUTE_SUCCESS),le.updateDisplayText(A.DisplayTextEnum.MUTING)):(Ve.emit(A.CallSipCallEvent.MUTE_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.UNMUTE&&(0===r?(le.updateIsMuted(!1),Ve.emit(A.CallSipCallEvent.UNMUTE_SUCCESS),le.updateDisplayText(A.DisplayTextEnum.CALLING)):(Ve.emit(A.CallSipCallEvent.UNMUTE_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CALL_HOLD&&(0===r?(le.updateIsHold(!0),le.updateDisplayText(A.DisplayTextEnum.HOLDING),Ve.emit(A.CallSipCallEvent.HOLD_SUCCESS)):(Ve.emit(A.CallSipCallEvent.HOLD_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CALL_UNHOLD&&(0===r?(le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateIsHold(!1),Ve.emit(A.CallSipCallEvent.UNHOLD_SUCCESS)):(Ve.emit(A.CallSipCallEvent.UNHOLD_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CONSULT_TRANSFER&&(0===r?Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_SUCCESS):(Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CONSULT_TRANSFER_FAILED&&Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_FAILED,i.status),s===A.WebsocketTypeEnum.CONSULT_TRANSFER_OFF_HOOK&&(le.updateDirection(A.DirectionEnum.INCOMING),le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_OFF_HOOK),le.updateActionConfigs(us),le.updateIncomingIsAnswer(!0),le.updateConsultIsAnswer(!1)),s===A.WebsocketTypeEnum.INCOMING_CALL&&(ce.sessionId=i.session_id,le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.INCOMING),le.updateDisplayText(A.DisplayTextEnum.INCOMING_CALL),Ve.emit(A.CallSipCallEvent.INCOMING_CALL,{customer_phone:i.customer_phone}),le.updateActionConfigs(ds),this.getCustomerInfo(i.customer_phone),ce.enableBrowserAlert&&xs.show("📞 客户来电",`客户 [${i.customer_phone}] 正在呼入...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{customer_phone:i.customer_phone})})),s===A.WebsocketTypeEnum.INCOMING_CALL_OFF_HOOK&&(le.updateIncomingIsAnswer(!0),Ve.emit(A.CallSipCallEvent.INCOMING_CALL_OFF_HOOK),le.updateActionConfigs(us),le.updateDisplayText(A.DisplayTextEnum.CALLING)),s===A.WebsocketTypeEnum.INCOMING_CALL_END&&(le.updateDisplayText(""),1===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.INCOMING_CALL_END),le.updateActionConfigs(as)):2===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(le.reset(),Ve.emit(A.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState(),le.updateActionConfigs(as)):2===i.device_type&&i.agent_no!==ce.agentInfo.agent_no?(le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),le.updateActionConfigs(hs)):3===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),le.updateActionConfigs(as)):4===i.device_type&&i.agent_no===ce.agentInfo.agent_no&&(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.TRANSFER_END),le.updateActionConfigs(as))),s===A.WebsocketTypeEnum.SATISFACTION_EVALUATION&&(0===r?Ve.emit(A.CallSipCallEvent.SATISFACTION_EVALUATION_SUCCESS):(Ve.emit(A.CallSipCallEvent.SATISFACTION_EVALUATION_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CONSULT_THREE_WAY&&(0!==r?(Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n)):0===r&&le.updateIsMeeting(!0)),s===A.WebsocketTypeEnum.CONSULT_THREE_WAY_RESULT&&("success"===i.status?(le.updateDirection(A.DirectionEnum.MEETING),le.updateDisplayText(A.DisplayTextEnum.MEETING),le.updateActionConfigs(qs),Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_SUCCESS)):(Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,{conf_name:i.conf_name}),le.updateIsMeeting(!1))),s===A.WebsocketTypeEnum.TRANSFER_INCOMING_CALL&&(i.agent_no===ce.agentInfo.agent_no?(le.updateDisplayText(A.DisplayTextEnum.TRANSFERRING),Ve.emit(A.CallSipCallEvent.TRANSFER_PROGRESS),le.updateActionConfigs([]),le.updateTransferIsAnswer(!0)):(Ve.emit(A.CallSipCallEvent.TRANSFER_INCOMING_CALL,i),le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.TRANSFER),le.updateDisplayText(A.DisplayTextEnum.TRANSFER_INCOMING_CALL),le.updateActionConfigs(ds),ce.enableBrowserAlert&&xs.show("📞 转接来电",`坐席 [${i.agent_no}] 正在转接...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{agent_mane:i.agent_no})}))),s===A.WebsocketTypeEnum.TRANSFER_OFF_HOOK&&(ce.sessionId=i.session_id,Ve.emit(A.CallSipCallEvent.TRANSFER_OFF_HOOK),le.updateTransferIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(us)),s===A.WebsocketTypeEnum.TRANSFER_FAILED&&"failed"===i.status){Ve.emit(A.CallSipCallEvent.TRANSFER_FAILED,"未知原因");const e=le.get("direction");e===A.DirectionEnum.OUTGOING?le.updateActionConfigs(hs):e===A.DirectionEnum.INCOMING&&le.updateActionConfigs(us)}},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const A=new Blob(["\n let timer;\n self.onmessage = function (e) {\n if (e.data === 'start') {\n timer = setInterval(() => {\n self.postMessage('heartbeat');\n }, 14000);\n } else if (e.data === 'stop') {\n clearInterval(timer);\n }\n };\n "],{type:"application/javascript"}),e=URL.createObjectURL(A);this.heartbeatWorker=new Worker(e),this.heartbeatWorker.onmessage=()=>{this.sendMessage({type:0})},this.heartbeatWorker.postMessage("start")}stopHeartbeat(){this.heartbeatWorker&&(this.heartbeatWorker.postMessage("stop"),this.heartbeatWorker.terminate(),this.heartbeatWorker=null)}sendMessage(A){this.ws?.readyState===WebSocket.OPEN?(100===A.type&&this.getCustomerInfo(A.data.customer_phone),this.ws.send(JSON.stringify(A)),0!==A.type&&Os("%cWebSocket 发送消息:","color: green; font-weight: bold;",A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Ns&&(Ns.close(),Ns=null)}static __internalSend(A){if(!Ns)throw new Error("WebSocket 尚未初始化");Ns.sendMessage(A)}}class Js{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=le.get("isCalling"),e=ce.sessionId;if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}))}holdCall(){this.roleMute();const e=le.get("isHold"),{sessionId:t}=ce;if(!t)return;if(!le.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));bs.__internalSend({type:A.WebsocketTypeEnum.CALL_HOLD,data:{session_id:t}})}unholdCall(){this.roleMute();const{isHold:e}=le.getState(),{sessionId:t}=ce;if(!le.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(t){if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));bs.__internalSend({type:A.WebsocketTypeEnum.CALL_UNHOLD,data:{session_id:t}})}}sendDTMF(A){if(1!==le.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!le.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=le.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){this.hangup()}async consultCall(e){this.roleMute();const{isCalling:t,outCallIsAnswer:s,consultIsAnswer:i,incomingIsAnswer:r}=le.getState(),n=ce.sessionId;if(!le.get("actionConfigs").includes("consult"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询"}));if(i)throw new Error(JSON.stringify({code:1,msg:"当前正在咨询"}));if(!(t||s||r))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!n)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));bs.__internalSend({type:A.WebsocketTypeEnum.CONSULT_REQUEST,data:{session_id:n,consultation_agent_no:e}})}async answerCall(){if(1!==le.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async rejectInCall(){if(1!==le.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));const{isCalling:A}=le.getState();if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));await this.sipClient.rejectInCall()}async makeCall(e){const t=le.get("isCalling"),s=le.get("selectOutNumber")||"";if(t)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.OUTGOING),bs.__internalSend({type:A.WebsocketTypeEnum.OUT_CALL,data:{customer_phone:e,caller:s}})}async rejectOutCall(){const{isCalling:e}=le.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const t=ce.sessionId;bs.__internalSend({type:A.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:t}})}async hangup(){if(!le.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const e=ce.sessionId;bs.__internalSend({type:A.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:e}})}mute(){this.roleMute();const e=le.get("actionConfigs"),t=le.get("isMuted"),s=ce.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!e.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));bs.__internalSend({type:A.WebsocketTypeEnum.MUTE,data:{session_id:s}})}unmute(){this.roleMute();const e=le.get("actionConfigs"),t=le.get("isMuted"),s=ce.sessionId;if(!t)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!e.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));bs.__internalSend({type:A.WebsocketTypeEnum.UNMUTE,data:{session_id:s}})}consultTransfer(){this.roleMute();const e=le.get("consultIsAnswer"),t=ce.sessionId;if(!le.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:A.WebsocketTypeEnum.CONSULT_TRANSFER,data:{session_id:t}})}satisfactionEvaluation(){this.roleMute();const e=ce.sessionId;if(!le.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));bs.__internalSend({type:A.WebsocketTypeEnum.SATISFACTION_EVALUATION,data:{session_id:e}})}startConference(){this.roleMute();if(!le.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const e=ce.sessionId;if(!le.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:A.WebsocketTypeEnum.CONSULT_THREE_WAY,data:{session_id:e}})}consultRetrieve(){this.roleMute();if(!le.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const e=ce.sessionId;if(!le.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:A.WebsocketTypeEnum.CONSULT_RETURN_CALL,data:{session_id:e}})}async transferAgent(e){this.roleMute();if(!le.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:t}=le.getState(),s=ce.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));bs.__internalSend({type:A.WebsocketTypeEnum.TRANSFER,data:{session_id:s,transfer_type:0,transfer_dest:e}})}async transferOutline(e){this.roleMute();if(!le.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"号码不能为空"}));if(!/^\d+$/.test(e))throw new Error(JSON.stringify({code:1,msg:"号码格式错误"}));const{transferIsAnswer:t}=le.getState(),s=ce.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));bs.__internalSend({type:A.WebsocketTypeEnum.TRANSFER,data:{session_id:s,transfer_type:2,transfer_dest:e}})}}class Hs{static{this._instance=null}#A=null;#e=new Us;#t;#s=null;#i=!1;#r;#n=!1;constructor(){if(!Hs._creatingInstance)throw new Error("请使用 YSYTAgentSdk.getInstance() 获取实例");clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#o();Xe.updateRttObject(A)},2e3),xs.requestMediaPermissions(),this.#r=le.subscribeKey("answerDevice",A=>{1===A?this.initWebRtc():this.#A=null})}static get instance(){return this._instance}static async destroyInstance(){this._instance&&(await this._instance.destroy(),this._instance=null)}static getInstance(){return this._instance||(Hs._creatingInstance=!0,this._instance=new Hs,delete Hs._creatingInstance,window.addEventListener("beforeunload",()=>{this._instance?.destroy()})),this._instance}getInit(){return this.#n}async initWebRtc(){if(this.#A)return;const A=ce.agentInfo.sip_account_list.find(A=>1===A.device_type);if(!A)throw new Error(JSON.stringify({code:1,msg:"未找到 sip_account_list"}));{const e=A.sip_register_addr;this.#A=new _e({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#a),await this.#A.start()}}async init({actionNodeParams:e,url:t,appKey:s,appSecret:i,agentNo:r,enableBrowserAlert:n,logBuiltinEnabled:o}){try{const{viewHtmlElement:a,rttHTML:V}=e||{},c=t||"https://aicc.yescloudy.com";je=c,Le=s,We=i,ce.logBuiltinEnabled=o||!1,await this.#e._agentLogin(r);const{agent_no:h,current_answer_device:l,current_state:g,out_display_number:q,out_display_select_switch:d}=ce.agentInfo;g===A.AgentStatus.IDLE?(le.updateActionConfigs(as),ce.stateObject={state:g,state_name:"空闲"}):g===A.AgentStatus.BUSY&&(le.updateActionConfigs(Vs),ce.stateObject={state:g,state_name:"忙碌"}),1===d?le.updateSelectOutNumber(q):le.updateSelectOutNumber("");let u="";const p=new URL(c).host;u=c.includes("https")?`wss://${p}`:`ws://${p}`,bs.getInstance(`${u}/ccs-ws/api/v1/ws/call/${h}?Authorization=`),le.updateAnswerDevice(l),1===l&&await this.initWebRtc(),this.#t=new Js(this.#A),e&&a&&(this.#i=!0,new Zs({container:a,rttHTML:V,statusParams:{state:A.AgentStatus.IDLE,statusName:"空闲"}},this,this.#t)),ce.enableBrowserAlert=n,n&&xs.requestPermission(),Ve.emit(A.EventName.AGENT_INIT_STATUS,!0),this.#n=!0}catch(e){this.#i&&Fs("初始化失败"),Ve.emit(A.EventName.AGENT_INIT_STATUS,!1),this.#n=!1}}#a=A=>{const{type:e,data:t}=A;Ve.emit(e,t)};on(A,e){return Ve.on(A,e),this}off(A,e){Ve.off(A,e)}offAll(){Ve.clearAllListeners()}async destroyRtc(){await(this.#A?.destroy())}async destroy(){Hs._instance&&(await this.destroyRtc(),clearInterval(this.#s),bs.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#i=!1,Hs._instance=null)}async#o(){return this.#A?this.#A.getNetworkStats():{}}get call_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{answerCall:A(()=>this.#t.answerCall()),makeCall:A=>this.#t.makeCall(A),cancelCall:A(()=>this.#t.cancelCall()),hangup:A(()=>this.#t.hangup()),sendDTMF:A(A=>this.#t.sendDTMF(A)),holdCall:A(()=>this.#t.holdCall()),unholdCall:A(()=>this.#t.unholdCall()),consultCall:A(async A=>{try{await this.#t.consultCall(A)}catch(A){throw console.warn(A),A}}),consultRetrieve:A(()=>this.#t.consultRetrieve()),consultTransfer:A(()=>this.#t.consultTransfer()),mute:A(()=>this.#t.mute()),unmute:A(()=>this.#t.unmute()),satisfactionEvaluation:A(()=>this.#t.satisfactionEvaluation()),startConference:A(()=>this.#t.startConference()),transferAgent:A(A=>this.#t.transferAgent(A)),transferOutline:A(A=>this.#t.transferOutline(A))}}get agent_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{changeDevice:A(A=>this.#e.changeDevice(A)),changeState:A(A=>this.#e.changeState(A)),getIdleAgentList:A(A=>this.#e.getIdleAgentList(A)),getAgentState:A(A=>this.#e.getAgentState(A)),setAgentExplicit:A(A=>this.#e.setAgentExplicit(A))}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,out_display_data:s,out_display_select_switch:i,current_answer_device:r,current_state:n}=ce.agentInfo,{stateObject:o}=ce,a={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:n,default_device:r,out_display_data:s,out_display_select_switch:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:a[Number(A)]})),stateObject:o}}}A.default=Hs,Object.defineProperty(A,"__esModule",{value:!0})});
914
+ `;ss(s,this.rttHTML)}}class xs{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const A=await navigator.mediaDevices.enumerateDevices();if(A.some(A=>"audioinput"===A.kind&&""!==A.label))return null;return await navigator.mediaDevices.getUserMedia({audio:!0})}catch(A){return console.warn("获取音频权限失败:",A),null}}static show(A,e,t){if("Notification"in window&&"granted"===Notification.permission){const s=new Notification(A,{body:e,tag:"xy-global-notification",renotify:!0});s.onclick=()=>{window.focus(),s.close(),t?.()},setTimeout(()=>s.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(A=>"audioinput"===A.kind&&""!==A.label)}catch(A){return console.warn("无法检查设备权限:",A),!1}}}const Ks=console.log,Os=(...A)=>{ce.logBuiltinEnabled&&Ks(...A)};let Ns=null;class bs{constructor(A){this.url=A,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Us,this.initWebSocket()}static getInstance(A){if(!Ns){if(!A)throw new Error("WebSocket 尚未初始化");Ns=new bs(A)}return Ns}stateIdleChange(){const{state:e}=ce.stateObject;e!==A.AgentStatus.IDLE&&this.apiClient._changeState({data:{...ce.stateBeforeChange}})}async getCustomerInfo(e){try{await this.apiClient._getInCallCrmDetail({data:{phone:e},success:e=>{const{contact_count:t,customer_name:s,phone:i,city:r,province:n}=e.data;Ve.emit(A.CallSipCallEvent.CUSTOMER_INFO,{customer_name:s||"未知客户",phone:i,city:r||"未知",province:n||"未知",contact_count:t||0})}})}catch(A){}}putAgentState(){ce.sessionId="";const{post_call_process_time:e}=ce.agentInfo,t=e||0;ce.autoStateTimer&&(clearTimeout(ce.autoStateTimer),ce.autoStateTimer=null),Ve.emit(A.CallSipCallEvent.CUSTOMER_INFO,void 0),t>0?ce.autoStateTimer=setTimeout(()=>{ce.autoStateTimer=null,this.stateIdleChange()},t):this.stateIdleChange()}initWebSocket(){const e=be(Le,We);this.ws=new WebSocket(this.url+e),this.ws.onopen=()=>{this.sendMessage({type:0}),this.startHeartbeat()},this.ws.onmessage=e=>{const t=JSON.parse(e.data),{type:s,data:i,code:r,msg:n}=t;if(0!==s&&Os("%cWebSocket 收到消息:","color: blue; font-weight: bold;",t),s===A.WebsocketTypeEnum.OUT_CALL&&(0!==r?(le.reset(),Ve.emit(A.CallSipCallEvent.OUT_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n),setTimeout(()=>{Ve.emit(A.CallSipCallEvent.CUSTOMER_INFO,void 0)},500),this.stateIdleChange()):0===r&&Ve.emit(A.CallSipCallEvent.OUT_SUCCESS)),s===A.WebsocketTypeEnum.AGENT_STATE){ce.stateObject.state!==A.AgentStatus.IDLE&&ce.stateObject.state!==A.AgentStatus.BUSY||(ce.stateBeforeChange=ce.stateObject);const{state:e,state_name:t}=i;ce.stateObject={state:e,state_name:t},"振铃中"===t&&le.updateDisplayText(A.DisplayTextEnum.AGENT_RINGING),Ve.emit(A.CallSipCallEvent.AGENT_STATE,{state:e,state_name:t})}if(s===A.WebsocketTypeEnum.OUT_CALL_INCOMING_CALL&&(Ve.emit(A.CallSipCallEvent.OUT_INCOMING_CALL),ce.sessionId=i.session_id,le.updateActionConfigs(cs)),s===A.WebsocketTypeEnum.OUT_CALL_END&&(le.updateDisplayText(""),1===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.OUT_HANGUP,i),le.updateActionConfigs(as)):2===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(le.reset(),Ve.emit(A.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState(),le.updateActionConfigs(as)):2===i.device_type&&i.agent_no!==ce.agentInfo.agent_no?(le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),le.updateActionConfigs(hs)):3===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),le.updateActionConfigs(as)):4===i.device_type&&i.agent_no===ce.agentInfo.agent_no&&(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.TRANSFER_END),le.updateActionConfigs(as))),s===A.WebsocketTypeEnum.OUT_CALL_RINGING&&1===i.type&&(Ve.emit(A.CallSipCallEvent.OUT_RINGING,i),le.updateDisplayText(A.DisplayTextEnum.RINGING)),s===A.WebsocketTypeEnum.OUT_CALL_ANSWER&&(Ve.emit(A.CallSipCallEvent.OUT_OFF_ANSWER,i),le.updateOutCallIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(hs)),s===A.WebsocketTypeEnum.CONSULT_RINGING&&(Ve.emit(A.CallSipCallEvent.CONSULT_RINGING),le.updateDisplayText(A.DisplayTextEnum.AGENT_RINGING),le.updateActionConfigs([])),s===A.WebsocketTypeEnum.CONSULT_ANSWER&&(Ve.emit(A.CallSipCallEvent.CONSULT_OFF_HOOK,i),le.updateConsultIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CONSULTING),le.updateActionConfigs(ls)),s===A.WebsocketTypeEnum.CONSULT_FAIL&&(Ve.emit(A.CallSipCallEvent.CONSULT_FAILED,{custom_reason:i.custom_reason}),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(hs)),s===A.WebsocketTypeEnum.CONSULT_CALL_IN&&(Ve.emit(A.CallSipCallEvent.CONSULT_INCOMING,i),le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.CONSULT),le.updateDisplayText(A.DisplayTextEnum.CONSULT_CALL_IN),le.updateActionConfigs(ds),ce.enableBrowserAlert&&xs.show("📞 咨询来电",`坐席 [${i.agent_name}] 正在咨询...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{agent_mane:i.agent_name})})),s===A.WebsocketTypeEnum.CONSULT_CALL_IN_SUCCESS&&(ce.sessionId=i.session_id,Ve.emit(A.CallSipCallEvent.CONSULT_CALL_IN_SUCCESS),le.updateConsultIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(gs)),s===A.WebsocketTypeEnum.CONSULT_RETURN_CALL_SUCCESS&&(le.updateConsultIsAnswer(!1),Ve.emit(A.CallSipCallEvent.CONSULT_RETURN_CALL_SUCCESS),le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),le.updateActionConfigs(hs)),s===A.WebsocketTypeEnum.MUTE&&(0===r?(le.updateIsMuted(!0),Ve.emit(A.CallSipCallEvent.MUTE_SUCCESS),le.updateDisplayText(A.DisplayTextEnum.MUTING)):(Ve.emit(A.CallSipCallEvent.MUTE_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.UNMUTE&&(0===r?(le.updateIsMuted(!1),Ve.emit(A.CallSipCallEvent.UNMUTE_SUCCESS),le.updateDisplayText(A.DisplayTextEnum.CALLING)):(Ve.emit(A.CallSipCallEvent.UNMUTE_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CALL_HOLD&&(0===r?(le.updateIsHold(!0),le.updateDisplayText(A.DisplayTextEnum.HOLDING),Ve.emit(A.CallSipCallEvent.HOLD_SUCCESS)):(Ve.emit(A.CallSipCallEvent.HOLD_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CALL_UNHOLD&&(0===r?(le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateIsHold(!1),Ve.emit(A.CallSipCallEvent.UNHOLD_SUCCESS)):(Ve.emit(A.CallSipCallEvent.UNHOLD_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CONSULT_TRANSFER&&(0===r?Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_SUCCESS):(Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CONSULT_TRANSFER_FAILED&&Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_FAILED,i.status),s===A.WebsocketTypeEnum.CONSULT_TRANSFER_OFF_HOOK&&(le.updateDirection(A.DirectionEnum.INCOMING),le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.CONSULT_TRANSFER_OFF_HOOK),le.updateActionConfigs(us),le.updateIncomingIsAnswer(!0),le.updateConsultIsAnswer(!1)),s===A.WebsocketTypeEnum.INCOMING_CALL&&(ce.sessionId=i.session_id,le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.INCOMING),le.updateDisplayText(A.DisplayTextEnum.INCOMING_CALL),Ve.emit(A.CallSipCallEvent.INCOMING_CALL,{customer_phone:i.customer_phone}),le.updateActionConfigs(ds),this.getCustomerInfo(i.customer_phone),ce.enableBrowserAlert&&xs.show("📞 客户来电",`客户 [${i.customer_phone}] 正在呼入...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{customer_phone:i.customer_phone})})),s===A.WebsocketTypeEnum.INCOMING_CALL_OFF_HOOK&&(le.updateIncomingIsAnswer(!0),Ve.emit(A.CallSipCallEvent.INCOMING_CALL_OFF_HOOK),le.updateActionConfigs(us),le.updateDisplayText(A.DisplayTextEnum.CALLING)),s===A.WebsocketTypeEnum.INCOMING_CALL_END&&(le.updateDisplayText(""),1===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.INCOMING_CALL_END),le.updateActionConfigs(as)):2===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(le.reset(),Ve.emit(A.CallSipCallEvent.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState(),le.updateActionConfigs(as)):2===i.device_type&&i.agent_no!==ce.agentInfo.agent_no?(le.updateDisplayText(A.DisplayTextEnum.CALLING),Ve.emit(A.CallSipCallEvent.OTHER_SIDE_CONSULT_HANGUP,i),le.updateActionConfigs(hs)):3===i.device_type&&i.agent_no===ce.agentInfo.agent_no?(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.THREE_WAY_OUR_SIDE_HANGUP),le.updateActionConfigs(as)):4===i.device_type&&i.agent_no===ce.agentInfo.agent_no&&(this.putAgentState(),le.reset(),Ve.emit(A.CallSipCallEvent.TRANSFER_END),le.updateActionConfigs(as))),s===A.WebsocketTypeEnum.SATISFACTION_EVALUATION&&(0===r?Ve.emit(A.CallSipCallEvent.SATISFACTION_EVALUATION_SUCCESS):(Ve.emit(A.CallSipCallEvent.SATISFACTION_EVALUATION_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n))),s===A.WebsocketTypeEnum.CONSULT_THREE_WAY&&(0!==r?(Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,n),Ve.emit(A.EventName.FAIL_NOTIFICATION,n)):0===r&&le.updateIsMeeting(!0)),s===A.WebsocketTypeEnum.CONSULT_THREE_WAY_RESULT&&("success"===i.status?(le.updateDirection(A.DirectionEnum.MEETING),le.updateDisplayText(A.DisplayTextEnum.MEETING),le.updateActionConfigs(qs),Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_SUCCESS)):(Ve.emit(A.CallSipCallEvent.CONSULT_THREE_WAY_FAILED,{conf_name:i.conf_name}),le.updateIsMeeting(!1))),s===A.WebsocketTypeEnum.TRANSFER_INCOMING_CALL&&(i.agent_no===ce.agentInfo.agent_no?(le.updateDisplayText(A.DisplayTextEnum.TRANSFERRING),Ve.emit(A.CallSipCallEvent.TRANSFER_PROGRESS),le.updateActionConfigs([]),le.updateTransferIsAnswer(!0)):(Ve.emit(A.CallSipCallEvent.TRANSFER_INCOMING_CALL,i),le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.TRANSFER),le.updateDisplayText(A.DisplayTextEnum.TRANSFER_INCOMING_CALL),le.updateActionConfigs(ds),ce.enableBrowserAlert&&xs.show("📞 转接来电",`坐席 [${i.agent_no}] 正在转接...`,()=>{Ve.emit(A.EventName.NOTIFICATION_CLICK,{agent_mane:i.agent_no})}))),s===A.WebsocketTypeEnum.TRANSFER_OFF_HOOK&&(ce.sessionId=i.session_id,Ve.emit(A.CallSipCallEvent.TRANSFER_OFF_HOOK),le.updateTransferIsAnswer(!0),le.updateDisplayText(A.DisplayTextEnum.CALLING),le.updateActionConfigs(us)),s===A.WebsocketTypeEnum.TRANSFER_FAILED&&"failed"===i.status){Ve.emit(A.CallSipCallEvent.TRANSFER_FAILED,"未知原因");const e=le.get("direction");e===A.DirectionEnum.OUTGOING?le.updateActionConfigs(hs):e===A.DirectionEnum.INCOMING&&le.updateActionConfigs(us)}},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const A=new Blob(["\n let timer;\n self.onmessage = function (e) {\n if (e.data === 'start') {\n timer = setInterval(() => {\n self.postMessage('heartbeat');\n }, 14000);\n } else if (e.data === 'stop') {\n clearInterval(timer);\n }\n };\n "],{type:"application/javascript"}),e=URL.createObjectURL(A);this.heartbeatWorker=new Worker(e),this.heartbeatWorker.onmessage=()=>{this.sendMessage({type:0})},this.heartbeatWorker.postMessage("start")}stopHeartbeat(){this.heartbeatWorker&&(this.heartbeatWorker.postMessage("stop"),this.heartbeatWorker.terminate(),this.heartbeatWorker=null)}sendMessage(A){this.ws?.readyState===WebSocket.OPEN?(100===A.type&&this.getCustomerInfo(A.data.customer_phone),this.ws.send(JSON.stringify(A)),0!==A.type&&Os("%cWebSocket 发送消息:","color: green; font-weight: bold;",A)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Ns&&(Ns.close(),Ns=null)}static __internalSend(A){if(!Ns)throw new Error("WebSocket 尚未初始化");Ns.sendMessage(A)}}class Js{constructor(A){this.sipClient=null,this.sipClient=A}roleMute(){const A=le.get("isCalling"),e=ce.sessionId;if(!A)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}))}holdCall(){this.roleMute();const e=le.get("isHold"),{sessionId:t}=ce;if(!t)return;if(!le.get("actionConfigs").includes("hold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿保持"}));if(e)throw new Error(JSON.stringify({code:1,msg:"当前已处于保持状态"}));bs.__internalSend({type:A.WebsocketTypeEnum.CALL_HOLD,data:{session_id:t}})}unholdCall(){this.roleMute();const{isHold:e}=le.getState(),{sessionId:t}=ce;if(!le.get("actionConfigs").includes("unhold"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取消保持"}));if(t){if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于保持状态"}));bs.__internalSend({type:A.WebsocketTypeEnum.CALL_UNHOLD,data:{session_id:t}})}}sendDTMF(A){if(1!==le.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));if(!le.get("actionConfigs").includes("dtmf"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿发送按键"}));const{isCalling:e}=le.getState();if(!e)throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));this.sipClient.sendDTMF(A)}cancelCall(){if(!le.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const e=ce.sessionId;bs.__internalSend({type:A.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:e}})}async consultCall(e){this.roleMute();const{isCalling:t,outCallIsAnswer:s,consultIsAnswer:i,incomingIsAnswer:r}=le.getState(),n=ce.sessionId;if(!le.get("actionConfigs").includes("consult"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询"}));if(i)throw new Error(JSON.stringify({code:1,msg:"当前正在咨询"}));if(!(t||s||r))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));if(!n)throw new Error(JSON.stringify({code:1,msg:"sessionId不存在"}));bs.__internalSend({type:A.WebsocketTypeEnum.CONSULT_REQUEST,data:{session_id:n,consultation_agent_no:e}})}async answerCall(){if(1!==le.get("answerDevice"))throw new Error(JSON.stringify({code:1,msg:"当前设备不支持此功能"}));await this.sipClient.answerCall()}async makeCall(e){const t=le.get("isCalling"),s=le.get("selectOutNumber")||"";if(t)throw new Error(JSON.stringify({code:1,msg:"正在呼叫中,请勿重复点击"}));le.updateIsCalling(!0),le.updateDirection(A.DirectionEnum.OUTGOING),bs.__internalSend({type:A.WebsocketTypeEnum.OUT_CALL,data:{customer_phone:e,caller:s}})}async hangup(){if(!le.get("isCalling"))throw new Error(JSON.stringify({code:1,msg:"当前没有通话"}));const e=ce.sessionId;bs.__internalSend({type:A.WebsocketTypeEnum.AGENT_HANGUP,data:{session_id:e}})}mute(){this.roleMute();const e=le.get("actionConfigs"),t=le.get("isMuted"),s=ce.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前未处于静音状态"}));if(!e.includes("mute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));bs.__internalSend({type:A.WebsocketTypeEnum.MUTE,data:{session_id:s}})}unmute(){this.roleMute();const e=le.get("actionConfigs"),t=le.get("isMuted"),s=ce.sessionId;if(!t)throw new Error(JSON.stringify({code:1,msg:"当前未处于未静音状态"}));if(!e.includes("unmute"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用静音"}));bs.__internalSend({type:A.WebsocketTypeEnum.UNMUTE,data:{session_id:s}})}consultTransfer(){this.roleMute();const e=le.get("consultIsAnswer"),t=ce.sessionId;if(!le.get("actionConfigs").includes("consult_transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用咨询转移"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:A.WebsocketTypeEnum.CONSULT_TRANSFER,data:{session_id:t}})}satisfactionEvaluation(){this.roleMute();const e=ce.sessionId;if(!le.get("actionConfigs").includes("satisfaction"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用满意度评价"}));bs.__internalSend({type:A.WebsocketTypeEnum.SATISFACTION_EVALUATION,data:{session_id:e}})}startConference(){this.roleMute();if(!le.get("actionConfigs").includes("conference"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿调用三方会议"}));const e=ce.sessionId;if(!le.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:A.WebsocketTypeEnum.CONSULT_THREE_WAY,data:{session_id:e}})}consultRetrieve(){this.roleMute();if(!le.get("actionConfigs").includes("consult_retrieve"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿取回通话"}));const e=ce.sessionId;if(!le.get("consultIsAnswer"))throw new Error(JSON.stringify({code:1,msg:"当前未处于咨询中"}));bs.__internalSend({type:A.WebsocketTypeEnum.CONSULT_RETURN_CALL,data:{session_id:e}})}async transferAgent(e){this.roleMute();if(!le.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));const{transferIsAnswer:t}=le.getState(),s=ce.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));bs.__internalSend({type:A.WebsocketTypeEnum.TRANSFER,data:{session_id:s,transfer_type:0,transfer_dest:e}})}async transferOutline(e){this.roleMute();if(!le.get("actionConfigs").includes("transfer"))throw new Error(JSON.stringify({code:1,msg:"当前状态请勿转接"}));if(!e)throw new Error(JSON.stringify({code:1,msg:"号码不能为空"}));if(!/^\d+$/.test(e))throw new Error(JSON.stringify({code:1,msg:"号码格式错误"}));const{transferIsAnswer:t}=le.getState(),s=ce.sessionId;if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));if(t)throw new Error(JSON.stringify({code:1,msg:"当前正在转接"}));bs.__internalSend({type:A.WebsocketTypeEnum.TRANSFER,data:{session_id:s,transfer_type:2,transfer_dest:e}})}}class Hs{static{this._instance=null}#A=null;#e=new Us;#t;#s=null;#i=!1;#r;#n=!1;constructor(){if(!Hs._creatingInstance)throw new Error("请使用 YSYTAgentSdk.getInstance() 获取实例");clearInterval(this.#s),this.#s=setInterval(async()=>{const A=await this.#o();Xe.updateRttObject(A)},2e3),xs.requestMediaPermissions(),this.#r=le.subscribeKey("answerDevice",A=>{1===A?this.initWebRtc():this.#A=null})}static get instance(){return this._instance}static async destroyInstance(){this._instance&&(await this._instance.destroy(),this._instance=null)}static getInstance(){return this._instance||(Hs._creatingInstance=!0,this._instance=new Hs,delete Hs._creatingInstance,window.addEventListener("beforeunload",()=>{this._instance?.destroy()})),this._instance}getInit(){return this.#n}async initWebRtc(){if(this.#A)return;const A=ce.agentInfo.sip_account_list.find(A=>1===A.device_type);if(!A)throw new Error(JSON.stringify({code:1,msg:"未找到 sip_account_list"}));{const e=A.sip_register_addr;this.#A=new _e({server:e.split(":")[0],user:A.sip_account,password:A.sip_password,webSocket:`wss://${e}`,callTimeout:3e4},this.#a),await this.#A.start()}}async init({actionNodeParams:e,url:t,appKey:s,appSecret:i,agentNo:r,enableBrowserAlert:n,logBuiltinEnabled:o}){try{const{viewHtmlElement:a,rttHTML:V}=e||{},c=t||"https://aicc.yescloudy.com";je=c,Le=s,We=i,ce.logBuiltinEnabled=o||!1,await this.#e._agentLogin(r);const{agent_no:h,current_answer_device:l,current_state:g,out_display_number:q,out_display_select_switch:d}=ce.agentInfo;g===A.AgentStatus.IDLE?(le.updateActionConfigs(as),ce.stateObject={state:g,state_name:"空闲"}):g===A.AgentStatus.BUSY&&(le.updateActionConfigs(Vs),ce.stateObject={state:g,state_name:"忙碌"}),1===d?le.updateSelectOutNumber(q):le.updateSelectOutNumber("");let u="";const p=new URL(c).host;u=c.includes("https")?`wss://${p}`:`ws://${p}`,bs.getInstance(`${u}/ccs-ws/api/v1/ws/call/${h}?Authorization=`),le.updateAnswerDevice(l),1===l&&await this.initWebRtc(),this.#t=new Js(this.#A),e&&a&&(this.#i=!0,new Zs({container:a,rttHTML:V,statusParams:{state:A.AgentStatus.IDLE,statusName:"空闲"}},this,this.#t)),ce.enableBrowserAlert=n,n&&xs.requestPermission(),Ve.emit(A.EventName.AGENT_INIT_STATUS,!0),this.#n=!0}catch(e){this.#i&&Fs("初始化失败"),Ve.emit(A.EventName.AGENT_INIT_STATUS,!1),this.#n=!1}}#a=A=>{const{type:e,data:t}=A;Ve.emit(e,t)};on(A,e){return Ve.on(A,e),this}off(A,e){Ve.off(A,e)}offAll(){Ve.clearAllListeners()}async destroyRtc(){await(this.#A?.destroy())}async destroy(){Hs._instance&&(await this.destroyRtc(),clearInterval(this.#s),bs.__internalClose(),this.offAll(),this.#r?.(),this.#A=null,this.#i=!1,Hs._instance=null)}async#o(){return this.#A?this.#A.getNetworkStats():{}}get call_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{answerCall:A(()=>this.#t.answerCall()),makeCall:A=>this.#t.makeCall(A),cancelCall:A(()=>this.#t.cancelCall()),hangup:A(()=>this.#t.hangup()),sendDTMF:A(A=>this.#t.sendDTMF(A)),holdCall:A(()=>this.#t.holdCall()),unholdCall:A(()=>this.#t.unholdCall()),consultCall:A(async A=>{try{await this.#t.consultCall(A)}catch(A){throw console.warn(A),A}}),consultRetrieve:A(()=>this.#t.consultRetrieve()),consultTransfer:A(()=>this.#t.consultTransfer()),mute:A(()=>this.#t.mute()),unmute:A(()=>this.#t.unmute()),satisfactionEvaluation:A(()=>this.#t.satisfactionEvaluation()),startConference:A(()=>this.#t.startConference()),transferAgent:A(A=>this.#t.transferAgent(A)),transferOutline:A(A=>this.#t.transferOutline(A))}}get agent_api(){const A=A=>(...e)=>{if(!this.#i)return A.apply(this,e);console.warn("当前未使用个人开发模式")};return{changeDevice:A(A=>this.#e.changeDevice(A)),changeState:A(A=>this.#e.changeState(A)),getIdleAgentList:A(A=>this.#e.getIdleAgentList(A)),getAgentState:A(A=>this.#e.getAgentState(A)),setAgentExplicit:A(A=>this.#e.setAgentExplicit(A))}}getAgentData(){const{agent_no:A,agent_name:e,answer_devices:t,out_display_data:s,out_display_select_switch:i,current_answer_device:r,current_state:n}=ce.agentInfo,{stateObject:o}=ce,a={1:"软电话",2:"手机模式",3:"SIP话机"};return{agent_no:A,agent_name:e,init_state:n,default_device:r,out_display_data:s,out_display_select_switch:i,answer_devices:(t||"").split(",").map(A=>({value:Number(A),label:a[Number(A)]})),stateObject:o}}}A.default=Hs,Object.defineProperty(A,"__esModule",{value:!0})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ysyt-agent-sdk",
3
- "version": "1.0.82",
3
+ "version": "1.0.83",
4
4
  "main": "dist/ysyt-agent-sdk.cjs.js",
5
5
  "module": "dist/ysyt-agent-sdk.esm.js",
6
6
  "types": "dist/src/index.d.ts",