ysyt-agent-sdk 1.0.14 → 1.0.16
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
@font-face{font-family:ysyt;src:url(../fonts/iconfont.woff2?t=1750839875481) format("woff2"),url(../fonts/iconfont.woff?t=1750839875481) format("woff"),url(../fonts/iconfont.ttf?t=1750839875481) format("truetype")}.ysyt{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:ysyt,serif!important;font-size:18px;font-style:normal}.icon-shouji:before{content:"\e692"}.icon-20gl-phoneSip:before{content:"\e924"}.icon-dianhua:before{content:"\e842"}.icon-quxiao:before{content:"\e676"}.icon-jieting:before{content:"\e60a"}.icon-boda:before{content:"\e679"}.icon-kaishi:before{content:"\e800"}.icon-guaji:before{content:"\e732"}.icon-manyidu:before{content:"\e600"}.icon-zixun:before{content:"\e71f"}.icon-zanting:before{content:"\ea81"}.icon-zhuanjie1:before{content:"\e601"}.icon-microphone:before{content:"\e661"}.icon-guanbimaikefeng:before{content:"\e603"}.icon-manglu:before{content:"\e65d"}.icon-shang:before{content:"\e60f"}.icon-xia:before{content:"\e64c"}.icon-kongxian:before{content:"\ed94"}#ysyt-body
|
|
1
|
+
@font-face{font-family:ysyt;src:url(../fonts/iconfont.woff2?t=1750839875481) format("woff2"),url(../fonts/iconfont.woff?t=1750839875481) format("woff"),url(../fonts/iconfont.ttf?t=1750839875481) format("truetype")}.ysyt{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:ysyt,serif!important;font-size:18px;font-style:normal}.icon-shouji:before{content:"\e692"}.icon-20gl-phoneSip:before{content:"\e924"}.icon-dianhua:before{content:"\e842"}.icon-quxiao:before{content:"\e676"}.icon-jieting:before{content:"\e60a"}.icon-boda:before{content:"\e679"}.icon-kaishi:before{content:"\e800"}.icon-guaji:before{content:"\e732"}.icon-manyidu:before{content:"\e600"}.icon-zixun:before{content:"\e71f"}.icon-zanting:before{content:"\ea81"}.icon-zhuanjie1:before{content:"\e601"}.icon-microphone:before{content:"\e661"}.icon-guanbimaikefeng:before{content:"\e603"}.icon-manglu:before{content:"\e65d"}.icon-shang:before{content:"\e60f"}.icon-xia:before{content:"\e64c"}.icon-kongxian:before{content:"\ed94"}#ysyt-body,.ysyt-phone-body{align-items:center;display:flex}.ysyt-phone-body{border-radius:30px 10px 0 30px;height:30px;padding:5px 15px;user-select:none}.ysyt-phone-body .ysyt-title{color:#fff;cursor:pointer;font-size:14px;padding-right:10px;position:relative;width:100px}.ysyt-phone-body .select-icon{color:#fff;display:none;font-size:10px;left:calc(50% - 4px);position:absolute;top:100%;z-index:9999999}.ysyt-select{background:#fff;border-radius:4px;box-shadow:0 4px 8px rgba(0,0,0,.1);height:0;overflow:hidden;position:absolute;top:calc(100% + 8px);transition:height .1s ease-in;width:100%;z-index:9999999}.ysyt-select-body{position:relative}.ysyt-select-body>div{color:rgba(0,0,0,.6);padding:5px 4px;text-align:center}.ysyt-select-body>div:hover{background:#ecf5ff;color:#2b96ea}.ysyt-action-body{align-items:center;color:#3356ec;display:flex;font-size:25px;gap:0 10px;height:30px;padding:0 10px}.ysyt-action-body>*{cursor:pointer}.content-call-key{color:rgba(0,0,0,.6);font-size:16px;padding:10px;width:250px}.content-call-key>my-input::part(wrapper){--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06);border:none;border-radius:30px;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);height:25px;width:220px}.content-call-key>my-input::part(wrapper-input){text-align:center}#wifi-body>img{width:18px}.network-body{color:rgba(0,0,0,.7);font-size:12px;padding:5px 10px}.network-body>div{align-items:center;display:flex;margin-bottom:5px}.network-body>div>div{color:#000;width:50px}.my-icon{font-size:22px}.agent-list-item{align-items:center;display:flex;justify-content:space-between;padding:10px}#ysyt-devices-body{align-items:center;display:flex;justify-content:center;margin-right:15px;position:relative;width:130px}
|
|
@@ -24,7 +24,6 @@ export declare class PhoneView {
|
|
|
24
24
|
private consultShow;
|
|
25
25
|
private modalRoot;
|
|
26
26
|
private agentStateData;
|
|
27
|
-
private devicesBodyShow;
|
|
28
27
|
constructor({ container, rttHTML, statusParams }: Props, VoiceSDKInstance: YSYTAgentSdk);
|
|
29
28
|
private eventHandle;
|
|
30
29
|
private handleNetworkInfoChange;
|
|
@@ -52,7 +51,6 @@ export declare class PhoneView {
|
|
|
52
51
|
private renderReject;
|
|
53
52
|
private renderConsultModalToBody;
|
|
54
53
|
private getActionConfigs;
|
|
55
|
-
private devicesMap;
|
|
56
54
|
private render;
|
|
57
55
|
private renderRtt;
|
|
58
56
|
}
|
|
@@ -110,7 +110,7 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
110
110
|
:host([type='loading']) {
|
|
111
111
|
background: #595959;
|
|
112
112
|
}
|
|
113
|
-
`}connectedCallback(){super.connectedCallback(),setTimeout(()=>{this.remove()},this.duration+300)}render(){return Ds`<div>${this.content}</div>`}};jt([ei({type:String})],ii.prototype,"type",void 0),jt([ei({type:String})],ii.prototype,"content",void 0),jt([ei({type:Number})],ii.prototype,"duration",void 0),ii=jt([Zs("my-message")],ii);const ri=(e,t,s=3e3)=>{let i=document.querySelector("#message-container");i||(i=document.createElement("div"),i.id="message-container",Object.assign(i.style,{position:"fixed",top:"14px",left:"50%",transform:"translateX(-50%)",zIndex:"9999"}),document.body.appendChild(i));const r=document.createElement("my-message");r.setAttribute("type",e),r.setAttribute("content",t),r.setAttribute("duration",String(s)),r.style.setProperty("--fade-delay",s/1e3+"s"),i.appendChild(r)},ni=(e,t=3e3)=>ri("success",e,t),oi=(e,t=3e3)=>ri("error",e,t),ai=(e,t=3e3)=>ri("warning",e,t),ci="/v1/aicc/bmserver",hi="/v1/aicc/ccs";let di="",li="",gi="";async function ui(e,t){const s=function(){const e=Ft(li,gi);return qt.create({prefixUrl:`${di}/api`,timeout:!1,headers:{Authorization:e},hooks:{afterResponse:[async(e,t,s)=>{const i=await s.clone().json();if(0!==i.code)throw oi(i.msg),new Error(JSON.stringify(i)||"请求失败");return s.json=async()=>i,s}]}})}(),i=e.replace(/^\/+/,"");return s.post(i,{json:t}).json()}const pi={agentInfo:{},isRtcReconnecting:!1,sessionId:"",enableBrowserAlert:!1,autoStateTimer:null};const fi=new class extends Qe{updateRttObject(e){this.setState({rttObject:e})}}({rttObject:{rtt:null,jitter:null,packetsLost:null,packetsReceived:null,packetsSent:null,sendBitrate:null,recvBitrate:null,codec:null}});class mi{constructor(e,t){this.config=e,this.eventCallback=t,this.userAgent=null,this.registerer=null,this.activeSession=null,this.callTimeoutTimer=null,this.incomingInvitation=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectTimer=null,this.isOffline=!1,this.autoAnswerTimer=null,this.handleMessage=e=>{},this.handleNetworkInfoChange=e=>{0===(e.rttObject?.rtt||0)?this.isOffline||(this.isOffline=!0,this.handleOffline()):this.isOffline&&(this.isOffline=!1,this.handleOnline())},this.handleOffline=()=>{console.warn("[SIPClient] 网络断开,准备销毁 SIP 客户端",(new Date).toLocaleString())
|
|
113
|
+
`}connectedCallback(){super.connectedCallback(),setTimeout(()=>{this.remove()},this.duration+300)}render(){return Ds`<div>${this.content}</div>`}};jt([ei({type:String})],ii.prototype,"type",void 0),jt([ei({type:String})],ii.prototype,"content",void 0),jt([ei({type:Number})],ii.prototype,"duration",void 0),ii=jt([Zs("my-message")],ii);const ri=(e,t,s=3e3)=>{let i=document.querySelector("#message-container");i||(i=document.createElement("div"),i.id="message-container",Object.assign(i.style,{position:"fixed",top:"14px",left:"50%",transform:"translateX(-50%)",zIndex:"9999"}),document.body.appendChild(i));const r=document.createElement("my-message");r.setAttribute("type",e),r.setAttribute("content",t),r.setAttribute("duration",String(s)),r.style.setProperty("--fade-delay",s/1e3+"s"),i.appendChild(r)},ni=(e,t=3e3)=>ri("success",e,t),oi=(e,t=3e3)=>ri("error",e,t),ai=(e,t=3e3)=>ri("warning",e,t),ci="/v1/aicc/bmserver",hi="/v1/aicc/ccs";let di="",li="",gi="";async function ui(e,t){const s=function(){const e=Ft(li,gi);return qt.create({prefixUrl:`${di}/api`,timeout:!1,headers:{Authorization:e},hooks:{afterResponse:[async(e,t,s)=>{const i=await s.clone().json();if(0!==i.code)throw oi(i.msg),new Error(JSON.stringify(i)||"请求失败");return s.json=async()=>i,s}]}})}(),i=e.replace(/^\/+/,"");return s.post(i,{json:t}).json()}const pi={agentInfo:{},isRtcReconnecting:!1,sessionId:"",enableBrowserAlert:!1,autoStateTimer:null};const fi=new class extends Qe{updateRttObject(e){this.setState({rttObject:e})}}({rttObject:{rtt:null,jitter:null,packetsLost:null,packetsReceived:null,packetsSent:null,sendBitrate:null,recvBitrate:null,codec:null}});class mi{constructor(e,t){this.config=e,this.eventCallback=t,this.userAgent=null,this.registerer=null,this.activeSession=null,this.callTimeoutTimer=null,this.incomingInvitation=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectTimer=null,this.isOffline=!1,this.autoAnswerTimer=null,this.handleMessage=e=>{},this.handleNetworkInfoChange=e=>{0===(e.rttObject?.rtt||0)?this.isOffline||(this.isOffline=!0,this.handleOffline()):this.isOffline&&(this.isOffline=!1,this.handleOnline())},this.handleOffline=()=>{console.warn("[SIPClient] 网络断开,准备销毁 SIP 客户端",(new Date).toLocaleString())},this.handleOnline=()=>{console.warn("[SIPClient] 网络恢复,准备重新启动 SIP 客户端",(new Date).toLocaleString())},fi.subscribe(this.handleNetworkInfoChange)}async start(){const e=Xe.makeURI(`sip:${this.config.user}@${this.config.server}`);if(!e)throw new Error("无效的SIP配置");const t={uri:e,authorizationUsername:this.config.user,authorizationPassword:this.config.password,transportOptions:{server:this.config.webSocket,connectionTimeout:30,keepAliveInterval:0},sessionDescriptionHandlerFactoryOptions:{alwaysAcquireMediaFirst:!0,peerConnectionConfiguration:{iceServers:[]},iceGatheringTimeout:400},logBuiltinEnabled:!1};this.userAgent=new Xe(t),this.setupEventListeners(),await this.userAgent.start(),await this.register()}setupEventListeners(){this.userAgent&&(this.userAgent.transport.stateChange.addListener(e=>{let t;switch(e){case ee.Connecting:t=st.WEB_RTC_CONNECTING;break;case ee.Connected:t=st.WEB_RTC_CONNECTED,this.reconnectAttempts=0,pi.isRtcReconnecting=!1,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null);break;case ee.Disconnecting:t=st.WEB_RTC_DISCONNECTING;break;case ee.Disconnected:{t=st.WEB_RTC_DISCONNECTED;const e=dt.get("answerDevice");if(!pi.isRtcReconnecting&&this.reconnectAttempts<this.maxReconnectAttempts&&1===e){this.reconnectAttempts++;const e=1e3*this.reconnectAttempts;console.warn(`SIP WebSocket 断开,第 ${this.reconnectAttempts} 次尝试重连,${e}ms 后重试...`),this.reconnectTimer=setTimeout(()=>{this.reconnect()},e)}else this.reconnectAttempts>=this.maxReconnectAttempts&&console.error("SIP 重连失败:已达到最大重试次数");break}default:t="unknown"}this.eventCallback?.({type:t})}),this.userAgent.transport.stateChange.addListener(e=>{}),this.userAgent.delegate={onInvite:e=>{this.handleIncomingCall(e)}})}async register(){if(this.userAgent){this.registerer=new ne(this.userAgent),this.registerer?.stateChange.addListener(e=>{let t;switch(e){case X.Initial:t="initial";break;case X.Registered:t=st.WEB_RTC_REGISTERED;break;case X.Unregistered:t=st.WEB_RTC_UNREGISTERED;break;case X.Terminated:t=st.WEB_RTC_TERMINATED;break;default:t="unknown"}this.eventCallback?.({type:t})});try{await this.registerer.register()}catch(e){this.eventCallback?.({type:st.WEB_RTC_REGISTER_FAILED,data:e})}}}attachRemoteAudio(e){const t=e.sessionDescriptionHandler;if(t){const e=t.peerConnection;if(!e)return;const s=new MediaStream;e.getReceivers().forEach(e=>{e.track&&"audio"===e.track.kind&&s.addTrack(e.track)});let i=document.getElementById("sip-remote-audio");i||(i=document.createElement("audio"),i.id="sip-remote-audio",i.autoplay=!0,i.style.display="none",document.body.appendChild(i)),i.srcObject=s,i.play().catch(e=>{console.error("音频播放失败,需要用户交互触发",e)})}}handleSessionState(e,t,s){e.stateChange.addListener(t=>{switch(t){case K.Established:clearTimeout(this.callTimeoutTimer),this.activeSession=e,this.attachRemoteAudio(e);break;case K.Terminating:break;case K.Terminated:this.activeSession=null,clearTimeout(this.callTimeoutTimer);case K.Establishing:}})}handleIncomingCall(e){this.incomingInvitation=e,this.handleSessionState(e,!1);const{soft_device_auto_answer:t,auto_answer_time:s}=pi.agentInfo,i=dt.get("direction"),r=1===t;if(i===tt.OUTGOING)this.answerCall();else if(r&&i===tt.INCOMING){const e=Number(s)||0;e>0?this.autoAnswerTimer=setTimeout(()=>{this.answerCall(),this.autoAnswerTimer=null},e):this.answerCall()}}async makeCall(e){if(dt.getState().isCalling)throw new Error("正在呼叫中,请勿重复点击");if(!this.userAgent)throw dt.updateIsCalling(!1),dt.updateDirection(null),new Error("SIP客户端未初始化");dt.updateIsCalling(!0),dt.updateDirection(tt.OUTGOING);const t=Xe.makeURI(`sip:${e}@${this.config.server}`);if(!t)throw new Error("无效的被叫号码");const s=new Z(this.userAgent,t);this.handleSessionState(s,!0,e);try{this.activeSession=s,await s.invite(),this.config.callTimeout&&(this.callTimeoutTimer=setTimeout(()=>{s.state!==K.Established&&(this.hangup(),this.eventCallback?.({type:"error",data:{message:"呼叫超时未接通"}}))},this.config.callTimeout))}catch(e){this.eventCallback?.({type:"error",data:{message:"呼叫失败",detail:e}}),dt.updateIsCalling(!1),dt.updateDirection(null)}}async answerCall(){if(!this.incomingInvitation)throw new Error("无来电可接听");this.autoAnswerTimer&&(clearTimeout(this.autoAnswerTimer),this.autoAnswerTimer=null);try{console.log((new Date).toLocaleString()),await this.incomingInvitation.accept(),console.log((new Date).toLocaleString()),this.activeSession=this.incomingInvitation,this.incomingInvitation=null}catch(e){this.eventCallback?.({type:st.WEB_RTC_ANSWER_FAILED,data:{detail:e}})}}async rejectInCall(){if(this.incomingInvitation)try{await this.incomingInvitation.reject(),this.incomingInvitation=null,dt.updateDirection(null),dt.updateIsCalling(!1),clearTimeout(this.callTimeoutTimer)}catch(e){this.eventCallback?.({type:"error",data:{message:"拒接失败",detail:e}})}}sendDTMF(e){if(!this.activeSession)throw new Error("当前没有活跃的通话");const t=this.activeSession.sessionDescriptionHandler;t&&"function"==typeof t.sendDtmf?(t.sendDtmf(e),this.eventCallback?.({type:st.WEB_RTC_SEND_DTMF,data:{tone:e}})):console.warn("DTMF发送不支持或未初始化")}async hangup(){if(this.activeSession){clearTimeout(this.callTimeoutTimer);const e=this.activeSession;if(!e)return;const t=e.state;try{t===K.Established?await e.bye():t===K.Establishing&&(e instanceof Z?await e.cancel():e instanceof J&&await e.reject()),clearTimeout(this.callTimeoutTimer)}catch(e){console.error("挂断失败",e)}finally{this.activeSession=null}}}async rejectOutCall(){this.activeSession instanceof J&&(await this.activeSession.reject(),this.activeSession=null)}async destroy(){if(clearTimeout(this.callTimeoutTimer),this.activeSession&&await this.hangup(),this.registerer){try{await this.registerer.unregister()}catch(e){console.warn("注销失败",e)}this.registerer=null}this.userAgent&&(await this.userAgent.stop(),this.userAgent=null)}async reconnect(){if(!pi.isRtcReconnecting){pi.isRtcReconnecting=!0;try{await this.destroy(),await this.start(),console.log("重连成功"),this.isOffline=!1}catch(e){console.error("重连失败",e)}finally{pi.isRtcReconnecting=!1}}}async getNetworkStats(){if(this.activeSession){const e=this.activeSession.sessionDescriptionHandler?.peerConnection;if(!e)return null;const t=await e.getStats(),s={};return t.forEach(e=>{"candidate-pair"===e.type&&"succeeded"===e.state&&null!=e.currentRoundTripTime&&(s.rtt=+(1e3*e.currentRoundTripTime).toFixed(2)),"inbound-rtp"===e.type&&"audio"===e.kind&&(s.jitter=+(1e3*e.jitter).toFixed(2),s.packetsLost=e.packetsLost,s.packetsReceived=e.packetsReceived,e.bytesReceived&&e.timestamp&&(s.recvBitrate=+(e.bytesReceived/1024).toFixed(2))),"outbound-rtp"===e.type&&"audio"===e.kind&&(s.packetsSent=e.packetsSent,e.bytesSent&&e.timestamp&&(s.sendBitrate=+(e.bytesSent/1024).toFixed(2))),"codec"===e.type&&e.mimeType&&(s.codec=e.mimeType)}),{...s,rtt:s?.rtt||40}}try{const e=Date.now();await ui(`${ci}/config/ping`,{});const t=Date.now();return{rtt:t-e||1}}catch(e){console.log(e)}}}const vi={statusColor:{[et.IDLE]:"#1D92E9",[et.BUSY]:"#F5212D",[et.OFFLINE]:"#8c8c8c",[et.RINGING]:"#e9b91d"}},wi=["call_number"],yi=[],bi=["hangup"],Ti=["hold","hangup","unhold","mute","unmute","transfer","consult","satisfaction","dtmf"],Si=["consult_transfer"],Ci=["hangup"],Ei=["answer","reject"],Ai=["hangup","consult","transfer","hold","unhold","mute","unmute","satisfaction","dtmf"];let _i=class extends zs{static{this.styles=Yt`
|
|
114
114
|
.timer-text {
|
|
115
115
|
width: 70px;
|
|
116
116
|
font-size: 14px;
|
|
@@ -173,6 +173,7 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
173
173
|
|
|
174
174
|
.trigger {
|
|
175
175
|
display: inline-block;
|
|
176
|
+
cursor: pointer;
|
|
176
177
|
}
|
|
177
178
|
|
|
178
179
|
.popover {
|
|
@@ -187,6 +188,8 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
187
188
|
opacity 0.2s ease,
|
|
188
189
|
transform 0.2s ease;
|
|
189
190
|
pointer-events: none;
|
|
191
|
+
min-width: 100px;
|
|
192
|
+
padding: 0px;
|
|
190
193
|
}
|
|
191
194
|
|
|
192
195
|
.popover.visible {
|
|
@@ -216,7 +219,6 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
216
219
|
|
|
217
220
|
.arrow[data-placement='top'] {
|
|
218
221
|
bottom: -6px;
|
|
219
|
-
left: 10px;
|
|
220
222
|
border-width: 6px 6px 0 6px;
|
|
221
223
|
border-color: #fff transparent transparent transparent;
|
|
222
224
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
|
|
@@ -224,26 +226,23 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
224
226
|
|
|
225
227
|
.arrow[data-placement='bottom'] {
|
|
226
228
|
top: -6px;
|
|
227
|
-
left: 10px;
|
|
228
229
|
border-width: 0 6px 6px 6px;
|
|
229
230
|
border-color: transparent transparent #fff transparent;
|
|
230
231
|
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.05);
|
|
231
232
|
}
|
|
232
233
|
|
|
233
234
|
.arrow[data-placement='left'] {
|
|
234
|
-
top: 10px;
|
|
235
235
|
right: -6px;
|
|
236
236
|
border-width: 6px 0 6px 6px;
|
|
237
237
|
border-color: transparent transparent transparent #fff;
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
.arrow[data-placement='right'] {
|
|
241
|
-
top: 10px;
|
|
242
241
|
left: -6px;
|
|
243
242
|
border-width: 6px 6px 6px 0;
|
|
244
243
|
border-color: transparent #fff transparent transparent;
|
|
245
244
|
}
|
|
246
|
-
`}firstUpdated(){this.triggerEl=this.renderRoot.querySelector(".trigger"),this.popoverEl=this.renderRoot.querySelector(".popover"),"click"===this.triggerType?(this.triggerEl.addEventListener("click",this.onTogglePopover),document.addEventListener("click",this.onOutsideClick)):(this.triggerEl.addEventListener("mouseenter",this.showPopover),this.triggerEl.addEventListener("mouseleave",this.hidePopoverDelayed),this.popoverEl.addEventListener("mouseenter",this.clearHideTimer),this.popoverEl.addEventListener("mouseleave",this.hidePopoverDelayed))}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.onOutsideClick)}updatePosition(){const e=this.triggerEl.getBoundingClientRect(),t=this.popoverEl;let s=0,i=0;switch(this.placement){case"top":s=e.top-t.offsetHeight-8,i=e.left;break;case"bottom":s=e.bottom+8,i=e.left;break;case"left":s=e.top,i=e.left-t.offsetWidth-8;break;case"right":s=e.top,i=e.right+8}t.style.top=`${s}px`,t.style.left=`${i}px`,t.setAttribute("data-placement",this.placement)}render(){return Ds`
|
|
245
|
+
`}firstUpdated(){this.triggerEl=this.renderRoot.querySelector(".trigger"),this.popoverEl=this.renderRoot.querySelector(".popover"),"click"===this.triggerType?(this.triggerEl.addEventListener("click",this.onTogglePopover),document.addEventListener("click",this.onOutsideClick)):(this.triggerEl.addEventListener("mouseenter",this.showPopover),this.triggerEl.addEventListener("mouseleave",this.hidePopoverDelayed),this.popoverEl.addEventListener("mouseenter",this.clearHideTimer),this.popoverEl.addEventListener("mouseleave",this.hidePopoverDelayed))}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.onOutsideClick),this.triggerEl&&("click"===this.triggerType?(this.triggerEl.removeEventListener("click",this.onTogglePopover),document.removeEventListener("click",this.onOutsideClick)):(this.triggerEl.removeEventListener("mouseenter",this.showPopover),this.triggerEl.removeEventListener("mouseleave",this.hidePopoverDelayed),this.popoverEl.removeEventListener("mouseenter",this.clearHideTimer),this.popoverEl.removeEventListener("mouseleave",this.hidePopoverDelayed)))}updatePosition(){const e=this.triggerEl.getBoundingClientRect(),t=this.popoverEl;let s=0,i=0;switch(this.placement){case"top":s=e.top-t.offsetHeight-8,i=e.left+(e.width-t.offsetWidth)/2;break;case"bottom":s=e.bottom+8,i=e.left+(e.width-t.offsetWidth)/2;break;case"left":s=e.top+(e.height-t.offsetHeight)/2,i=e.left-t.offsetWidth-8;break;case"right":s=e.top+(e.height-t.offsetHeight)/2,i=e.right+8}t.style.top=`${s}px`,t.style.left=`${i}px`,t.setAttribute("data-placement",this.placement);const r=this.renderRoot.querySelector(".arrow");if(r)if("top"===this.placement||"bottom"===this.placement){const s=e.left+e.width/2-i-6;r.style.left=`${Math.min(Math.max(s,10),t.offsetWidth-16)}px`,r.style.top=""}else{const i=e.top+e.height/2-s-6;r.style.top=`${Math.min(Math.max(i,10),t.offsetHeight-16)}px`,r.style.left=""}}render(){return Ds`
|
|
247
246
|
<div class="trigger">
|
|
248
247
|
<slot name="trigger"></slot>
|
|
249
248
|
</div>
|
|
@@ -554,7 +553,7 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
554
553
|
`:null}
|
|
555
554
|
</div>
|
|
556
555
|
</div>
|
|
557
|
-
`:Ds``}_onCancel(){this.dispatchEvent(new CustomEvent("cancel")),this.visible=!1}_onOk(){this.dispatchEvent(new CustomEvent("ok"))}_onMaskClick(){this._onCancel()}};jt([ei({type:Boolean})],ki.prototype,"visible",void 0),jt([ei({type:Boolean})],ki.prototype,"showFooter",void 0),jt([ei({type:String})],ki.prototype,"width",void 0),jt([ei({type:String})],ki.prototype,"title",void 0),ki=jt([Zs("my-modal-wrapper")],ki);class Ni{constructor(){this.roleData={agentInfo:()=>{if(!pi.agentInfo?.agent_no)throw new Error("请先登录")},requestInfo:e=>{if(!e.data)throw new Error("请传入参数")},changeDevice:e=>{if(!e)throw new Error('Parameter "device" is required');const{answer_devices:t}=pi.agentInfo;if(!t.split(",").map(e=>Number(e)).includes(e))throw new Error("当前设备不支持")},changeState:(e,t)=>{if(!e)throw new Error('Parameter "state" is required');if(!t)throw new Error('Parameter "state_name" is required');if(2===e&&"通话中"===t)throw new Error("当前状态不支持");if(![1,2].includes(e))throw new Error("当前状态不支持")}}}async _agentLogin(e){try{const s=await(t={agent_no:e},ui(`${hi}/agent/login`,t));pi.agentInfo=s.data}catch(e){throw console.log(e),new Error("登录失败")}var t}async changeDevice(e){try{this.roleData.agentInfo(),this.roleData.requestInfo(e);const{data:t,success:s}=e,{device:i}=t;this.roleData.changeDevice(i);const{agent_no:r}=pi.agentInfo;await(e=>ui(`${hi}/device/change`,e))({agent_no:r,answer_device:i}),dt.updateAnswerDevice(i),s?.({code:0,msg:"请求成功"})}catch(e){throw console.log(e),new Error("切换设备失败")}}async changeState(e){try{pi.autoStateTimer&&(clearTimeout(pi.autoStateTimer),pi.autoStateTimer=null),this.roleData.agentInfo(),this.roleData.requestInfo(e);const{data:t,success:s}=e,{state:i,state_name:r}=t;this.roleData.changeState(i,r);const{agent_no:n}=pi.agentInfo;await(e=>ui(`${hi}/state/change`,e))({agent_no:n,state_name:r,state:i}),i===et.IDLE?dt.updateActionConfigs(wi):i===et.BUSY&&dt.updateActionConfigs(yi),pi.stateObject={state:i,state_name:r},s?.({code:0,msg:"请求成功"})}catch(e){console.log(e)}}async getIdleAgentList(e){const{agent_no:t}=pi.agentInfo;try{this.roleData.agentInfo();const s=await(e=>ui(`${hi}/agent/free`,e))({agent_no:t});e.success?.(s)}catch(e){console.log(e)}}async getAgentState(e){try{const t=await ui(`${ci}/agent/statecfg/list`,{}),s=(t.data||[]).filter(e=>0===e.enable).filter(e=>0!==e.state&&3!==e.state).map(e=>({state:e.state,state_name:e.state_name})).reverse();e.success?.({...t,data:s})}catch(e){console.log(e)}}}class Hi{constructor({container:e,rttHTML:t,statusParams:s},i){this.VoiceSDKInstance=i,this.apiClient=new Ni,this.isOpenSelect=!1,this.statusParams={state:et.IDLE,statusName:"空闲"},this.consultShow=!1,this.modalRoot=null,this.agentStateData=[],this.
|
|
556
|
+
`:Ds``}_onCancel(){this.dispatchEvent(new CustomEvent("cancel")),this.visible=!1}_onOk(){this.dispatchEvent(new CustomEvent("ok"))}_onMaskClick(){this._onCancel()}};jt([ei({type:Boolean})],ki.prototype,"visible",void 0),jt([ei({type:Boolean})],ki.prototype,"showFooter",void 0),jt([ei({type:String})],ki.prototype,"width",void 0),jt([ei({type:String})],ki.prototype,"title",void 0),ki=jt([Zs("my-modal-wrapper")],ki);class Ni{constructor(){this.roleData={agentInfo:()=>{if(!pi.agentInfo?.agent_no)throw new Error("请先登录")},requestInfo:e=>{if(!e.data)throw new Error("请传入参数")},changeDevice:e=>{if(!e)throw new Error('Parameter "device" is required');const{answer_devices:t}=pi.agentInfo;if(!t.split(",").map(e=>Number(e)).includes(e))throw new Error("当前设备不支持")},changeState:(e,t)=>{if(!e)throw new Error('Parameter "state" is required');if(!t)throw new Error('Parameter "state_name" is required');if(2===e&&"通话中"===t)throw new Error("当前状态不支持");if(![1,2].includes(e))throw new Error("当前状态不支持")}}}async _agentLogin(e){try{const s=await(t={agent_no:e},ui(`${hi}/agent/login`,t));pi.agentInfo=s.data}catch(e){throw console.log(e),new Error("登录失败")}var t}async changeDevice(e){try{this.roleData.agentInfo(),this.roleData.requestInfo(e);const{data:t,success:s}=e,{device:i}=t;this.roleData.changeDevice(i);const{agent_no:r}=pi.agentInfo;await(e=>ui(`${hi}/device/change`,e))({agent_no:r,answer_device:i}),dt.updateAnswerDevice(i),s?.({code:0,msg:"请求成功"})}catch(e){throw console.log(e),new Error("切换设备失败")}}async changeState(e){try{pi.autoStateTimer&&(clearTimeout(pi.autoStateTimer),pi.autoStateTimer=null),this.roleData.agentInfo(),this.roleData.requestInfo(e);const{data:t,success:s}=e,{state:i,state_name:r}=t;this.roleData.changeState(i,r);const{agent_no:n}=pi.agentInfo;await(e=>ui(`${hi}/state/change`,e))({agent_no:n,state_name:r,state:i}),i===et.IDLE?dt.updateActionConfigs(wi):i===et.BUSY&&dt.updateActionConfigs(yi),pi.stateObject={state:i,state_name:r},s?.({code:0,msg:"请求成功"})}catch(e){console.log(e)}}async getIdleAgentList(e){const{agent_no:t}=pi.agentInfo;try{this.roleData.agentInfo();const s=await(e=>ui(`${hi}/agent/free`,e))({agent_no:t});e.success?.(s)}catch(e){console.log(e)}}async getAgentState(e){try{const t=await ui(`${ci}/agent/statecfg/list`,{}),s=(t.data||[]).filter(e=>0===e.enable).filter(e=>0!==e.state&&3!==e.state).map(e=>({state:e.state,state_name:e.state_name})).reverse();e.success?.({...t,data:s})}catch(e){console.log(e)}}}class Hi{constructor({container:e,rttHTML:t,statusParams:s},i){this.VoiceSDKInstance=i,this.apiClient=new Ni,this.isOpenSelect=!1,this.statusParams={state:et.IDLE,statusName:"空闲"},this.consultShow=!1,this.modalRoot=null,this.agentStateData=[],this.handleNetworkInfoChange=e=>{this.rttHTML&&this.renderRtt(e.rttObject)},this.handleCallInfoChange=e=>{this.render()},this.hiddenSelect=()=>{if(!this.isOpenSelect)return;const e=document.querySelector(".ysyt-select");e.style.height="0px",setTimeout(()=>{e.style.padding="0px"},100),this.isOpenSelect=!1,this.render()},this.toggle=e=>{e.stopPropagation(),this.isOpenSelect=!this.isOpenSelect;const t=document.querySelector(".ysyt-select");this.isOpenSelect?(t.style.height=t.scrollHeight+"px",t.style.padding="4px 0px",this.render()):this.hiddenSelect()},this.changeStatus=async e=>{const{state:t,statusName:s}=e;await this.apiClient.changeState({data:{state:t,state_name:s},success:()=>{this.statusParams=e;const t=document.getElementById("my-timer");t?.reset(),this.hiddenSelect()}})},this.onChangeDevices=async e=>{await this.apiClient.changeDevice({data:{device:e},success:({code:t})=>{0===t&&(1!==e&&this.VoiceSDKInstance.destroyRtc(),ni("切换成功"),this.render())}})},this.ruleCall=async e=>{if(e)try{await this.VoiceSDKInstance.call_api.makeCall(e)}catch(e){console.error(e)}},this.onCall=()=>{const e=document.querySelector("my-input");this.ruleCall(e.value)},this.renderCallPopover=()=>Ds`
|
|
558
557
|
<my-popover>
|
|
559
558
|
<div slot="trigger">
|
|
560
559
|
<my-tooltip content="拨打">
|
|
@@ -659,28 +658,16 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
659
658
|
</div>`}
|
|
660
659
|
</div>
|
|
661
660
|
</my-modal-wrapper>
|
|
662
|
-
`;Ws(i,this.modalRoot)}})}catch(e){oi(e)}}getActionConfigs(){const{show_satisfaction:e}=pi.agentInfo,t=dt.get("isHold"),s=dt.get("isMuted"),i=dt.get("actionConfigs").filter(i=>(0!==e||"satisfaction"!==i)&&(!(!t&&"unhold"===i)&&((!t||"hold"!==i)&&((!s||"mute"!==i)&&!(!s&&"unmute"===i)))));return[{render:this.renderCallPopover,type:"call_number"},{render:this.renderAnswer,type:"answer"},{render:this.renderReject,type:"reject"},{render:this.renderHangup,type:"hangup"},{render:this.renderDialer,type:"dtmf"},{render:this.renderUnhold,type:"unhold"},{render:this.renderHold,type:"hold"},{render:this.renderMute,type:"mute"},{render:this.renderUnmute,type:"unmute"},{render:this.renderSatisfaction,type:"satisfaction"},{render:this.renderConsult,type:"consult"},{render:this.renderTransfer,type:"transfer"},{render:this.renderConsultTransfer,type:"consult_transfer"}].filter(({type:e})=>i.includes(e))}
|
|
663
|
-
<div style="display: flex; align-items: center; gap: 8px;" @click="${()=>e&&this.onChangeDevices(1)}">
|
|
664
|
-
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAjhJREFUaEPtmM1WwjAQhWeAF0I34kZ5MuDJqBtxo7wQEE9CkzNNk8yktIl4YKOHRvPl9s5PBuEOP3iHzPCALvXWxEq/HBfvGmp2AfPz8/m0LQXp78NCa1gEtQF1hbUfVLirBZ6EXh3neweL0CjAnVZaodpoeIW4/lqemtKKB6E76rawFM48V2oPCM1heV7/CWircMoCr9+LrVa8hk16SufArH7mqoZNboKuZZMetLXG4enMZhatsl1fMij/F7RUuZwYGCvLRJWWQDtPA4DUTmOARwORg6bApdNeD1qaEWy6Kw2s31QwQxigRLWr4eNO3xPyGJfGLDRnoTH8G/of8d5DqX0MijvUVLCuwwxtwPmae14FWm/K+bZW3xENRKtUCsweqkZ7muwvODBJCzuFVdimiAu6GvmaheZKdY3KyELToIz5Nxe8d1lGaPCCH9KLsgia9s2xsk3BU8HprzOeb2/60pZADC0Bp2tMagqMGULBawJ+pt6k8FnQUhu4rNOmDg1vBG3BYorSv0upngXd8XdESZvi9AHpjMSlPmbs4I8vQiOKbOgccP8Alxk00uFOqkYMgh4CPqTIxFrkwdAlwCeBdj0KmflJ0xanfKphu0lpunEnY2QWi+BFJDG9Gg3a2cXLtznBZ+G5tnhUaH9TqqDUNvSNxcYSk0B34Iny5vvWOnaNfhP6d5PTydrU/XNS6F6h8Q8QMnNgHu4vKwLtb2qrJf3eKi4pPlWguXTHPX9AcwqN9fwulf4FD/s5TOGFiLYAAAAASUVORK5CYII="}" width="16" alt="" /><span style="font-size: 14px">软电话</span>
|
|
665
|
-
</div>
|
|
666
|
-
`,2:Ds`
|
|
667
|
-
<div style="display: flex; align-items: center; gap: 8px;" @click="${()=>e&&this.onChangeDevices(2)}">
|
|
668
|
-
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAWtJREFUaEPtWdFNAzEMdW6Ewgo3BzBOYYi2Q0DHKcxxK0BHaNA7cIVEVD0n8Uck31dVOfbLyzvn9JxkwCcNiFmqQd8fl8eWDX9u5/fa9WbQm9dlnyZ5yFmaQF8BZzmcX+a9ZQMm0HfH5QSwKcnKUr7Ih6XYv9gkO/yHfF/b+YnNRYMGw4IiFczcAlOTlwf9tmQUPz/P9BqWOZwgYlm2aQAbgO7Msm5KZccSQoFGp7hkOUF7SeTAMsjGZZEd3hUX0CyI2jgX0GC6uWMUdqQt1AX0kJoO0H9k4to9gulgutCS9HIJeYQ8Qh7cV0j0aeUpukdBMSGPkMeNRhLyCHmEPIibdujLJcyawgm7+R7T9GPz9nx8bTHSgNQpAev2u1wuYBWuKWt+q+fMxruBtnjIVqN8tZEN3jdl9a5MjzgJAHA9RvzWuUvrC6kzHHYKsNa2Fr0ybl1Ysnh/rWPX6VYHnF1SmJnuUrUxyZCgvwFf6/M9kuThSwAAAABJRU5ErkJggg=="}" width="16" alt="" /><span style="font-size: 14px">手机模式</span>
|
|
669
|
-
</div>
|
|
670
|
-
`,3:Ds`
|
|
671
|
-
<div style="display: flex; align-items: center; gap: 8px;" @click="${()=>e&&this.onChangeDevices(3)}">
|
|
672
|
-
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAq5JREFUaEPtmWFywiAQhcEr6Als79F6LdsZdab1WsZ7tJ7AXiF0lmYzC9mFDUGrM/qrmrB8PB7LQq25w4+9Q2bzgL7WrD2UvhmlF8/vr865jXXueD7tt1PAIBZtf/76aPA7PKPf4Xf6Pn2WtMdiud46YzZ9R9Y2P9+fqxLw+dPbwTgXQNvZbIUw8+XaGRJ/0LcxkDV2IJwIHTSytuk7LADnAGDgCOFns20P8NvPae+ZuEFiGxaadtIHpqqPBPcqEsh4plLQg/6tbVhoqZNYfY1VKBC1AwUfBf03+PDDBQg6KFCcTjUoB/Hoos7ag9gT2g+hESphgbGKUygUAKcds4TK0x1TEbTvqEBxaANtMSOhXZJKg4edO5rZrMFMUwxdCk4zgyZ70BkhsxR5WmEPyeOphUbboBXqQTM5M7eZ4ELjVPHKdikviEM3kkSeVilNO5GUE5Xudqx4kANoZpHDO8Hi7GZcD41bbmYT4Tah3KzUeM7viEqL5GxRA5CLIdYe/a5IiprBtHczorFRzQHI0AqL9DvdyFpk6gDkKo9YRMoKuS1/KpzUXl1PSxbIVXCXAM+eEft0JVjgPzJIFjooLYU8rAWvdXTLQsc1hmgTcpzi1kDNo5sKmhY58LdYY0RnSqydnbUv9Lg25ejm+9culKAm1tbaUfAaR7dR0HGxTk/O3MC9HUDh7mOt3QVXBgX1uFia5pQvKf6lmKWx1PaQKruc4pcQoQg6ziipxZmDHsRSlATF0AOPJ+41aoNPgu7BndtgGpPqlLHgqTiToREm3jxK4TWVYzVozuddTvWXhjeptJhdME/DzRK5u4gHEd9CpQZaVekYRLothTQZvEuugDW2uih04Hdafwhe0R7brgIdWAf+G9C2weV6yjbc+K4OrVmQuXce0DmFaj2/S6V/Ae/pt8oTAp/jAAAAAElFTkSuQmCC"}" width="16" alt="" /><span style="font-size: 14px">SIP话机</span>
|
|
673
|
-
</div>
|
|
674
|
-
`}}async render(){const{displayText:e,answerDevice:t}=dt.getState(),{answer_devices:s}=pi.agentInfo,i=(s||"").split(","),r=this.getActionConfigs(),n={...vi},{statusColor:o}=n,a=document.querySelector("head");if(a){const e=Ds`
|
|
661
|
+
`;Ws(i,this.modalRoot)}})}catch(e){oi(e)}}getActionConfigs(){const{show_satisfaction:e}=pi.agentInfo,t=dt.get("isHold"),s=dt.get("isMuted"),i=dt.get("actionConfigs").filter(i=>(0!==e||"satisfaction"!==i)&&(!(!t&&"unhold"===i)&&((!t||"hold"!==i)&&((!s||"mute"!==i)&&!(!s&&"unmute"===i)))));return[{render:this.renderCallPopover,type:"call_number"},{render:this.renderAnswer,type:"answer"},{render:this.renderReject,type:"reject"},{render:this.renderHangup,type:"hangup"},{render:this.renderDialer,type:"dtmf"},{render:this.renderUnhold,type:"unhold"},{render:this.renderHold,type:"hold"},{render:this.renderMute,type:"mute"},{render:this.renderUnmute,type:"unmute"},{render:this.renderSatisfaction,type:"satisfaction"},{render:this.renderConsult,type:"consult"},{render:this.renderTransfer,type:"transfer"},{render:this.renderConsultTransfer,type:"consult_transfer"}].filter(({type:e})=>i.includes(e))}async render(){const{displayText:e}=dt.getState(),{default_device:t,answer_devices:s,show_satisfaction:i}=pi.agentInfo,r=(s||"").split(","),n=this.getActionConfigs(),o={...vi},{statusColor:a}=o,c=document.querySelector("head");if(c){const e=Ds`
|
|
675
662
|
<style>
|
|
676
663
|
.ysyt-phone-body {
|
|
677
|
-
background: ${
|
|
664
|
+
background: ${a[this.statusParams.state]};
|
|
678
665
|
}
|
|
679
666
|
.ysyt-action-body {
|
|
680
|
-
border-bottom: 1px solid ${
|
|
667
|
+
border-bottom: 1px solid ${a[this.statusParams.state]};
|
|
681
668
|
}
|
|
682
669
|
</style>
|
|
683
|
-
`;Ws(e,
|
|
670
|
+
`;Ws(e,c)}const h=Ds`
|
|
684
671
|
<i class="ysyt icon-shang select-icon" style="${this.isOpenSelect?"display: block;":"display: none;"}"></i>
|
|
685
672
|
<div
|
|
686
673
|
class="ysyt-select"
|
|
@@ -697,21 +684,37 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
697
684
|
`)}
|
|
698
685
|
</div>
|
|
699
686
|
</div>
|
|
700
|
-
`,
|
|
687
|
+
`,d=Ds`
|
|
701
688
|
<div id="ysyt-body">
|
|
702
|
-
<div
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
689
|
+
<div id="ysyt-devices-body">
|
|
690
|
+
<my-select
|
|
691
|
+
width="100px"
|
|
692
|
+
value="${String(t)}"
|
|
693
|
+
placeholder=""
|
|
694
|
+
@change=${e=>this.onChangeDevices(Number(e.detail.value))}
|
|
695
|
+
>
|
|
696
|
+
${r.includes("1")?Ds`
|
|
697
|
+
<select-option value="1">
|
|
698
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
699
|
+
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAjhJREFUaEPtmM1WwjAQhWeAF0I34kZ5MuDJqBtxo7wQEE9CkzNNk8yktIl4YKOHRvPl9s5PBuEOP3iHzPCALvXWxEq/HBfvGmp2AfPz8/m0LQXp78NCa1gEtQF1hbUfVLirBZ6EXh3neweL0CjAnVZaodpoeIW4/lqemtKKB6E76rawFM48V2oPCM1heV7/CWircMoCr9+LrVa8hk16SufArH7mqoZNboKuZZMetLXG4enMZhatsl1fMij/F7RUuZwYGCvLRJWWQDtPA4DUTmOARwORg6bApdNeD1qaEWy6Kw2s31QwQxigRLWr4eNO3xPyGJfGLDRnoTH8G/of8d5DqX0MijvUVLCuwwxtwPmae14FWm/K+bZW3xENRKtUCsweqkZ7muwvODBJCzuFVdimiAu6GvmaheZKdY3KyELToIz5Nxe8d1lGaPCCH9KLsgia9s2xsk3BU8HprzOeb2/60pZADC0Bp2tMagqMGULBawJ+pt6k8FnQUhu4rNOmDg1vBG3BYorSv0upngXd8XdESZvi9AHpjMSlPmbs4I8vQiOKbOgccP8Alxk00uFOqkYMgh4CPqTIxFrkwdAlwCeBdj0KmflJ0xanfKphu0lpunEnY2QWi+BFJDG9Gg3a2cXLtznBZ+G5tnhUaH9TqqDUNvSNxcYSk0B34Iny5vvWOnaNfhP6d5PTydrU/XNS6F6h8Q8QMnNgHu4vKwLtb2qrJf3eKi4pPlWguXTHPX9AcwqN9fwulf4FD/s5TOGFiLYAAAAASUVORK5CYII="}" width="16" alt="" /><span style="font-size: 14px">软电话</span>
|
|
700
|
+
</div>
|
|
701
|
+
</select-option>
|
|
702
|
+
`:""}
|
|
703
|
+
${r.includes("2")?Ds`
|
|
704
|
+
<select-option value="2">
|
|
705
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
706
|
+
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAWtJREFUaEPtWdFNAzEMdW6Ewgo3BzBOYYi2Q0DHKcxxK0BHaNA7cIVEVD0n8Uck31dVOfbLyzvn9JxkwCcNiFmqQd8fl8eWDX9u5/fa9WbQm9dlnyZ5yFmaQF8BZzmcX+a9ZQMm0HfH5QSwKcnKUr7Ih6XYv9gkO/yHfF/b+YnNRYMGw4IiFczcAlOTlwf9tmQUPz/P9BqWOZwgYlm2aQAbgO7Msm5KZccSQoFGp7hkOUF7SeTAMsjGZZEd3hUX0CyI2jgX0GC6uWMUdqQt1AX0kJoO0H9k4to9gulgutCS9HIJeYQ8Qh7cV0j0aeUpukdBMSGPkMeNRhLyCHmEPIibdujLJcyawgm7+R7T9GPz9nx8bTHSgNQpAev2u1wuYBWuKWt+q+fMxruBtnjIVqN8tZEN3jdl9a5MjzgJAHA9RvzWuUvrC6kzHHYKsNa2Fr0ybl1Ysnh/rWPX6VYHnF1SmJnuUrUxyZCgvwFf6/M9kuThSwAAAABJRU5ErkJggg=="}" width="16" alt="" /><span style="font-size: 14px">手机模式</span>
|
|
707
|
+
</div>
|
|
708
|
+
</select-option>
|
|
709
|
+
`:""}
|
|
710
|
+
${r.includes("3")?Ds`
|
|
711
|
+
<select-option value="3">
|
|
712
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
713
|
+
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAq5JREFUaEPtmWFywiAQhcEr6Als79F6LdsZdab1WsZ7tJ7AXiF0lmYzC9mFDUGrM/qrmrB8PB7LQq25w4+9Q2bzgL7WrD2UvhmlF8/vr865jXXueD7tt1PAIBZtf/76aPA7PKPf4Xf6Pn2WtMdiud46YzZ9R9Y2P9+fqxLw+dPbwTgXQNvZbIUw8+XaGRJ/0LcxkDV2IJwIHTSytuk7LADnAGDgCOFns20P8NvPae+ZuEFiGxaadtIHpqqPBPcqEsh4plLQg/6tbVhoqZNYfY1VKBC1AwUfBf03+PDDBQg6KFCcTjUoB/Hoos7ag9gT2g+hESphgbGKUygUAKcds4TK0x1TEbTvqEBxaANtMSOhXZJKg4edO5rZrMFMUwxdCk4zgyZ70BkhsxR5WmEPyeOphUbboBXqQTM5M7eZ4ELjVPHKdikviEM3kkSeVilNO5GUE5Xudqx4kANoZpHDO8Hi7GZcD41bbmYT4Tah3KzUeM7viEqL5GxRA5CLIdYe/a5IiprBtHczorFRzQHI0AqL9DvdyFpk6gDkKo9YRMoKuS1/KpzUXl1PSxbIVXCXAM+eEft0JVjgPzJIFjooLYU8rAWvdXTLQsc1hmgTcpzi1kDNo5sKmhY58LdYY0RnSqydnbUv9Lg25ejm+9culKAm1tbaUfAaR7dR0HGxTk/O3MC9HUDh7mOt3QVXBgX1uFia5pQvKf6lmKWx1PaQKruc4pcQoQg6ziipxZmDHsRSlATF0AOPJ+41aoNPgu7BndtgGpPqlLHgqTiToREm3jxK4TWVYzVozuddTvWXhjeptJhdME/DzRK5u4gHEd9CpQZaVekYRLothTQZvEuugDW2uih04Hdafwhe0R7brgIdWAf+G9C2weV6yjbc+K4OrVmQuXce0DmFaj2/S6V/Ae/pt8oTAp/jAAAAAElFTkSuQmCC"}" width="16" alt="" /><span style="font-size: 14px">SIP话机</span>
|
|
714
|
+
</div>
|
|
715
|
+
</select-option>
|
|
716
|
+
`:""}
|
|
717
|
+
</my-select>
|
|
715
718
|
</div>
|
|
716
719
|
<div class="ysyt-phone-body">
|
|
717
720
|
<div class="ysyt-title" @click="${this.toggle}">
|
|
@@ -724,14 +727,14 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
724
727
|
<span>${t}</span>
|
|
725
728
|
`:void 0)(this.statusParams)}
|
|
726
729
|
<i class="ysyt icon-xia"></i>
|
|
727
|
-
${
|
|
730
|
+
${h}
|
|
728
731
|
`}
|
|
729
732
|
</div>
|
|
730
733
|
<timer-component id="my-timer"></timer-component>
|
|
731
734
|
</div>
|
|
732
|
-
<div class="ysyt-action-body">${
|
|
735
|
+
<div class="ysyt-action-body">${n.map(e=>e.render())}</div>
|
|
733
736
|
</div>
|
|
734
|
-
`;Ws(
|
|
737
|
+
`;Ws(d,this.container)}async renderRtt(e){const{outCallIsAnswer:t}=dt.getState(),s=e?.rtt||500,i=Ds`
|
|
735
738
|
<my-popover triggerType="hover">
|
|
736
739
|
<div slot="trigger" id="wifi-body">
|
|
737
740
|
${s>=250?Ds`<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAlVJREFUaEPtmGFuwyAMhU2PtU1qOVmbk5FKW4+1TCawkcQYG2i3aM2fqirBn83zc1IDO7zMDpnhCf2oU+teaefcKYW31o69k6mGTuDOAWoBmwGNCVwBYKxNSAUdQDWQkiIPuMhae5EsxjUi6ARWUk1pbGrdIIFnoZWwqXbx+NPrqJAQLmXhSWghLELGo1U1m3MuSiFKLXc6JPwGOmyY28yD1jYQRSZIYAP+DV2obnfYdQIF+EV8Dx2AHVGJu8Mq4X3VDSMHUSe3WAV3L8eF0BNxs9XoNpwU2mF0CdwSv6fDxIeRWFrkyYEjNMoi+q9YDkKHyRUT41wlCRBxhqhptCDRWC24S41aRDIMcT2jaCKGZsXESr6aQmM1NRNUBK8Z46mE1tWMumX9W+DHxUkYA7eMcbH+maFCnVxx3xI05SzFTTXCZnok62BZ6MxmYt11AM/G4qCxidIpqfJuDXSm0fWVTgz+pBk0E7wFx/gMn4fRwLv4KTC+EXExxZbHVW6ClwuAOQJMjMWZEWC6GriJ31ByMZug56pOZx6WDD20wFdDT/DqKmDTDKrBq6BnOVDTESXgZ5Z/owGIus5Jx4wGPqy2aWuhV/6NsGbgGm6Wkk9iMVAM3NQM6huwKj+V1jfX6pSqJFIFrT1Oaj1WXmOF6R6/Bt2S+N2gWypZSqg7NOEsVbrlwLtC560QuoL3hqYeZWfnrrC2u4zxdNPgw9R/J2HZwda6xRr+f1d6OXQ2B/t3NU2D1z1fPMw9thrHBpS/AJT8Of7eVdPSoK3rntCtFZTev8tKfwHUBxjzil9I5gAAAABJRU5ErkJggg=="}" alt="" />`:""}
|
|
@@ -771,4 +774,4 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
771
774
|
`:""}
|
|
772
775
|
</div>
|
|
773
776
|
</my-popover>
|
|
774
|
-
`;Ws(i,this.rttHTML)}}const Pi=new class{constructor(){this.events={}}on(e,t){this.events[e]=this.events[e]||[],this.events[e].push(t)}off(e,t){this.events[e]=(this.events[e]||[]).filter(e=>e!==t)}emit(e,...t){(this.events[e]||[]).forEach(e=>e(...t))}};class Oi{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const e=await navigator.mediaDevices.enumerateDevices();if(e.some(e=>"audioinput"===e.kind&&""!==e.label))return console.log("已授权麦克风权限,无需再次获取"),null;const t=await navigator.mediaDevices.getUserMedia({audio:!0});return console.log("获取音频权限成功"),t}catch(e){return console.warn("获取音频权限失败:",e),null}}static show(e,t,s){if("Notification"in window&&"granted"===Notification.permission){const i=new Notification(e,{body:t,tag:"xy-global-notification",renotify:!0});i.onclick=()=>{window.focus(),i.close(),s?.()},setTimeout(()=>i.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(e=>"audioinput"===e.kind&&""!==e.label)}catch(e){return console.warn("无法检查设备权限:",e),!1}}}let qi=null;class Li{constructor(e){this.url=e,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Ni,this.initWebSocket()}static getInstance(e){if(!qi){if(!e)throw new Error("WebSocket 尚未初始化");qi=new Li(e)}return qi}stateIdleChange(){const{state:e}=pi.stateObject;e!==et.IDLE&&this.apiClient.changeState({data:{state:et.IDLE,state_name:"空闲"}})}putAgentState(){pi.sessionId="";const{post_call_process_time:e}=pi.agentInfo,t=e||0;pi.autoStateTimer&&(clearTimeout(pi.autoStateTimer),pi.autoStateTimer=null),t>0?pi.autoStateTimer=setTimeout(()=>{pi.autoStateTimer=null,this.stateIdleChange()},t):this.stateIdleChange()}initWebSocket(){this.ws=new WebSocket(this.url),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&&console.warn(s),s===rt.OUT_CALL&&0!==r&&(ct.emit(it.OUT_FAILED,n),this.stateIdleChange()),s===rt.AGENT_STATE){const{state:e,state_name:t}=i;pi.stateObject={state:e,state_name:t},ct.emit(it.AGENT_STATE,{state:e,state_name:t})}s===rt.OUT_CALL_INCOMING_CALL&&(ct.emit(it.OUT_INCOMING_CALL,i),pi.sessionId=i.session_id,dt.updateActionConfigs(bi)),s===rt.OUT_CALL_END&&(0===i.device_type||1===i.device_type?(this.putAgentState(),dt.reset(),ct.emit(it.OUT_HANGUP,i)):2===i.device_type&&(dt.get("direction")===tt.CONSULT?(dt.reset(),ct.emit(it.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState()):dt.get("isCalling")&&(dt.updateDisplayText(ot.CALLING),ct.emit(it.OTHER_SIDE_CONSULT_HANGUP,i),dt.updateActionConfigs(Ti)))),s===rt.OUT_CALL_RINGING&&(ct.emit(it.OUT_RINGING,i),dt.updateDisplayText(ot.RINGING)),s===rt.OUT_CALL_ANSWER&&(ct.emit(it.OUT_OFF_ANSWER,i),dt.updateOutCallIsAnswer(!0),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ti)),s===rt.CONSULT_RINGING&&(ct.emit(it.CONSULT_RINGING,i),dt.updateDisplayText(ot.AGENT_RINGING),dt.updateActionConfigs([])),s===rt.CONSULT_ANSWER&&(ct.emit(it.CONSULT_OFF_HOOK,i),dt.updateConsultIsAnswer(!0),dt.updateDisplayText(ot.CONSULTING),dt.updateActionConfigs(Si)),s===rt.CONSULT_FAIL&&(ct.emit(it.CONSULT_FAILED),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ti)),s===rt.CONSULT_CALL_IN&&(ct.emit(it.CONSULT_INCOMING,i),dt.updateIsCalling(!0),dt.updateDirection(tt.CONSULT),dt.updateDisplayText(ot.CONSULT_CALL_IN),dt.updateActionConfigs(Ei),pi.enableBrowserAlert&&Oi.show("📞 咨询来电",`坐席 [${i.agent_name}] 正在咨询...`,()=>{ct.emit(nt.NOTIFICATION_CLICK,{agent_mane:i.agent_name})})),s===rt.CONSULT_CALL_IN_SUCCESS&&(pi.sessionId=i.session_id,ct.emit(it.CONSULT_CALL_IN_SUCCESS,i),dt.updateConsultIsAnswer(!0),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ci)),s===rt.MUTE&&(0===r?(dt.updateIsMuted(!0),ct.emit(it.MUTE_SUCCESS)):ct.emit(it.MUTE_FAILED,n)),s===rt.UNMUTE&&(0===r?(dt.updateIsMuted(!1),ct.emit(it.UNMUTE_SUCCESS)):ct.emit(it.UNMUTE_FAILED,n)),s===rt.CONSULT_TRANSFER&&(0===r?ct.emit(it.CONSULT_TRANSFER_SUCCESS):ct.emit(it.CONSULT_TRANSFER_FAILED,n)),s===rt.CONSULT_TRANSFER_FAILED&&ct.emit(it.CONSULT_TRANSFER_FAILED,i.status),s===rt.CONSULT_TRANSFER_OFF_HOOK&&(dt.updateDirection(tt.INCOMING),dt.updateDisplayText(ot.CALLING),ct.emit(it.CONSULT_TRANSFER_OFF_HOOK),dt.updateActionConfigs(Ai),dt.updateIncomingIsAnswer(!0),dt.updateConsultIsAnswer(!1)),s===rt.INCOMING_CALL&&(pi.sessionId=i.session_id,dt.updateIsCalling(!0),dt.updateDirection(tt.INCOMING),dt.updateDisplayText(ot.INCOMING_CALL),ct.emit(it.INCOMING_CALL,{customer_phone:i.customer_phone}),dt.updateActionConfigs(Ei),pi.enableBrowserAlert&&Oi.show("📞 客户来电",`客户 [${i.customer_phone}] 正在呼入...`,()=>{ct.emit(nt.NOTIFICATION_CLICK,{customer_phone:i.customer_phone})})),s===rt.INCOMING_CALL_OFF_HOOK&&(dt.updateIncomingIsAnswer(!0),ct.emit(it.INCOMING_CALL_OFF_HOOK),dt.updateActionConfigs(Ai),dt.updateDisplayText(ot.CALLING)),s===rt.INCOMING_CALL_END&&(ct.emit(it.INCOMING_CALL_END),dt.reset(),dt.updateActionConfigs(wi),this.putAgentState()),0!==s&&Pi.emit("ws-message",t)},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const e=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"}),t=URL.createObjectURL(e);this.heartbeatWorker=new Worker(t),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(e){this.ws?.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify(e)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){qi&&(qi.close(),qi=null)}static __internalSend(e){if(!qi)throw new Error("WebSocket 尚未初始化");qi.sendMessage(e)}}module.exports=class{#e=null;#t=new Ni;#s=null;#i=!1;#r;constructor(){clearInterval(this.#s),this.#s=setInterval(async()=>{const e=await this.#n();fi.updateRttObject(e)},2e3),Oi.requestMediaPermissions(),window.addEventListener("beforeunload",()=>{this.destroy()}),this.#r=dt.subscribeKey("answerDevice",e=>{1===e&&this.initWebRtc()})}async initWebRtc(){const e=pi.agentInfo.sip_account_list.find(e=>1===e.device_type);if(e){const t=e.sip_register_addr;this.#e=new mi({server:t.split(":")[0],user:e.sip_account,password:e.sip_password,webSocket:`wss://${t}`,callTimeout:3e4},this.#o),await this.#e.start()}}async init({actionNodeParams:e,url:t,appKey:s,appSecret:i,agentNo:r,enableBrowserAlert:n}){try{const{viewHtmlElement:o,rttHTML:a}=e;di=t||"https://aicc-api.yescloudy.com",li=s,gi=i;const c=Ft(s,i);await this.#t._agentLogin(r);const{agent_no:h,current_answer_device:d,init_state:l}=pi.agentInfo;l===et.IDLE?(dt.updateActionConfigs(wi),pi.stateObject={state:l,state_name:"空闲"}):l===et.BUSY&&(dt.updateActionConfigs(yi),pi.stateObject={state:l,state_name:"忙碌"}),Li.getInstance(`ws://112.90.183.54:8719/api/v1/ws/call/${h}?Authorization=${c}`),dt.updateAnswerDevice(d),1===d&&await this.initWebRtc(),e&&o&&(this.#i=!0,new Hi({container:o,rttHTML:a,statusParams:{state:et.IDLE,statusName:"空闲"}},this)),pi.enableBrowserAlert=n,n&&Oi.requestPermission()}catch(e){this.#i&&oi("初始化失败"),console.log(e)}}#o=e=>{const{type:t,data:s}=e;ct.emit(t,s)};#a=e=>{};on(e,t){return ct.on(e,t),this}off(e,t){ct.off(e,t)}offAll(){ct.clearAllListeners()}#c(){if(!this.#e)throw new Error("请先初始化SDK");const e=dt.get("isCalling"),t=pi.sessionId;if(!e)throw new Error("当前没有通话");if(!t)throw new Error("sessionId不存在")}#h(){const e=dt.get("isHold"),{sessionId:t}=pi;if(t){if(e)throw new Error("当前已处于保持状态");Li.__internalSend({type:rt.CALL_HOLD,data:{session_id:t}}),dt.updateDisplayText(ot.HOLD),dt.updateIsHold(!0)}}#d(){const{isHold:e}=dt.getState(),{sessionId:t}=pi;if(t){if(!e)throw new Error("当前未处于保持状态");Li.__internalSend({type:rt.CALL_UNHOLD,data:{session_id:t}}),dt.updateDisplayText(""),dt.updateIsHold(!1)}}#l(e){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:t}=dt.getState();if(!t)throw new Error("当前没有通话");this.#e.sendDTMF(e)}#g(){if(1!==dt.get("answerDevice"))throw new Error("当前设备不支持此功能");if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:e,direction:t,outCallIsAnswer:s}=dt.getState();if(!e)throw new Error("当前没有通话");s||(t===tt.INCOMING?this.#u():t===tt.OUTGOING&&this.#p())}async#f(e){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:t,outCallIsAnswer:s,consultIsAnswer:i,incomingIsAnswer:r}=dt.getState(),n=pi.sessionId;if(i)throw new Error("当前正在咨询");if(!(t||s||r))throw new Error("当前没有通话");if(!n)throw new Error("sessionId不存在");Li.__internalSend({type:rt.CONSULT_REQUEST,data:{session_id:n,consultation_agent_no:e}})}async#m(){if(1!==dt.get("answerDevice"))throw new Error("当前设备不支持此功能");if(!this.#e)throw new Error("请先初始化SDK");await this.#e.answerCall()}async#u(){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:e}=dt.getState();if(!e)throw new Error("当前没有通话");await this.#e.rejectInCall()}async#v(e){if(!this.#e)throw new Error("请先初始化SDK");if(dt.getState().isCalling)throw new Error("正在呼叫中,请勿重复点击");dt.updateIsCalling(!0),dt.updateDirection(tt.OUTGOING),Li.__internalSend({type:rt.OUT_CALL,data:{customer_phone:e}})}async#p(){const{isCalling:e}=dt.getState();if(!this.#e)throw new Error("请先初始化SDK");if(!e)throw new Error("当前没有通话");await this.#e.rejectOutCall()}async#w(){if(!this.#e)throw new Error("请先初始化SDK");if(!dt.get("isCalling"))throw new Error("当前没有通话");await this.#e.hangup()}#y(){this.#c();const e=dt.get("actionConfigs"),t=dt.get("isMuted"),s=pi.sessionId;if(t)throw new Error("当前未处于静音状态");if(!e.includes("mute"))throw new Error("当前状态请勿调用静音");Li.__internalSend({type:rt.MUTE,data:{session_id:s}})}#b(){this.#c();const e=dt.get("actionConfigs"),t=dt.get("isMuted"),s=pi.sessionId;if(!t)throw new Error("当前未处于未静音状态");if(!e.includes("unmute"))throw new Error("当前状态请勿调用静音");Li.__internalSend({type:rt.UNMUTE,data:{session_id:s}})}#T(){this.#c();const e=dt.get("consultIsAnswer"),t=pi.sessionId;if(!dt.get("actionConfigs").includes("consult_transfer"))throw new Error("当前状态请勿调用咨询转移");if(!e)throw new Error("当前未处于咨询中");Li.__internalSend({type:rt.CONSULT_TRANSFER,data:{session_id:t}})}async destroyRtc(){await(this.#e?.destroy())}destroy(){this.destroyRtc(),Pi.off("ws-message",this.#a),Li.__internalClose(),this.offAll(),this.#r?.()}async#n(){return this.#e?this.#e.getNetworkStats():{}}get call_api(){return this.#i?{answerCall:this.#m.bind(this),makeCall:this.#v.bind(this),cancelCall:this.#g.bind(this),hangup:this.#w.bind(this),sendDTMF:this.#l.bind(this),holdCall:this.#h.bind(this),unholdCall:this.#d.bind(this),consultCall:async e=>{try{await this.#f(e)}catch(e){throw console.warn(e),e}},consultTransfer:this.#T.bind(this),mute:this.#y.bind(this),unmute:this.#b.bind(this)}:{}}get agent_api(){return this.#i?{changeDevice:this.#t.changeDevice.bind(this.#t),changeState:this.#t.changeState.bind(this.#t),getIdleAgentList:e=>this.#t.getIdleAgentList(e),getAgentState:e=>this.#t.getAgentState(e)}:{}}};
|
|
777
|
+
`;Ws(i,this.rttHTML)}}const Pi=new class{constructor(){this.events={}}on(e,t){this.events[e]=this.events[e]||[],this.events[e].push(t)}off(e,t){this.events[e]=(this.events[e]||[]).filter(e=>e!==t)}emit(e,...t){(this.events[e]||[]).forEach(e=>e(...t))}};class Oi{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const e=await navigator.mediaDevices.enumerateDevices();if(e.some(e=>"audioinput"===e.kind&&""!==e.label))return console.log("已授权麦克风权限,无需再次获取"),null;const t=await navigator.mediaDevices.getUserMedia({audio:!0});return console.log("获取音频权限成功"),t}catch(e){return console.warn("获取音频权限失败:",e),null}}static show(e,t,s){if("Notification"in window&&"granted"===Notification.permission){const i=new Notification(e,{body:t,tag:"xy-global-notification",renotify:!0});i.onclick=()=>{window.focus(),i.close(),s?.()},setTimeout(()=>i.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(e=>"audioinput"===e.kind&&""!==e.label)}catch(e){return console.warn("无法检查设备权限:",e),!1}}}let qi=null;class Li{constructor(e){this.url=e,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Ni,this.initWebSocket()}static getInstance(e){if(!qi){if(!e)throw new Error("WebSocket 尚未初始化");qi=new Li(e)}return qi}stateIdleChange(){const{state:e}=pi.stateObject;e!==et.IDLE&&this.apiClient.changeState({data:{state:et.IDLE,state_name:"空闲"}})}putAgentState(){pi.sessionId="";const{post_call_process_time:e}=pi.agentInfo,t=e||0;pi.autoStateTimer&&(clearTimeout(pi.autoStateTimer),pi.autoStateTimer=null),t>0?pi.autoStateTimer=setTimeout(()=>{pi.autoStateTimer=null,this.stateIdleChange()},t):this.stateIdleChange()}initWebSocket(){this.ws=new WebSocket(this.url),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&&console.warn(s),s===rt.OUT_CALL&&0!==r&&(ct.emit(it.OUT_FAILED,n),this.stateIdleChange()),s===rt.AGENT_STATE){const{state:e,state_name:t}=i;pi.stateObject={state:e,state_name:t},ct.emit(it.AGENT_STATE,{state:e,state_name:t})}s===rt.OUT_CALL_INCOMING_CALL&&(ct.emit(it.OUT_INCOMING_CALL,i),pi.sessionId=i.session_id,dt.updateActionConfigs(bi)),s===rt.OUT_CALL_END&&(0===i.device_type||1===i.device_type?(this.putAgentState(),dt.reset(),ct.emit(it.OUT_HANGUP,i)):2===i.device_type&&(dt.get("direction")===tt.CONSULT?(dt.reset(),ct.emit(it.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState()):dt.get("isCalling")&&(dt.updateDisplayText(ot.CALLING),ct.emit(it.OTHER_SIDE_CONSULT_HANGUP,i),dt.updateActionConfigs(Ti)))),s===rt.OUT_CALL_RINGING&&(ct.emit(it.OUT_RINGING,i),dt.updateDisplayText(ot.RINGING)),s===rt.OUT_CALL_ANSWER&&(ct.emit(it.OUT_OFF_ANSWER,i),dt.updateOutCallIsAnswer(!0),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ti)),s===rt.CONSULT_RINGING&&(ct.emit(it.CONSULT_RINGING,i),dt.updateDisplayText(ot.AGENT_RINGING),dt.updateActionConfigs([])),s===rt.CONSULT_ANSWER&&(ct.emit(it.CONSULT_OFF_HOOK,i),dt.updateConsultIsAnswer(!0),dt.updateDisplayText(ot.CONSULTING),dt.updateActionConfigs(Si)),s===rt.CONSULT_FAIL&&(ct.emit(it.CONSULT_FAILED),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ti)),s===rt.CONSULT_CALL_IN&&(ct.emit(it.CONSULT_INCOMING,i),dt.updateIsCalling(!0),dt.updateDirection(tt.CONSULT),dt.updateDisplayText(ot.CONSULT_CALL_IN),dt.updateActionConfigs(Ei),pi.enableBrowserAlert&&Oi.show("📞 咨询来电",`坐席 [${i.agent_name}] 正在咨询...`,()=>{ct.emit(nt.NOTIFICATION_CLICK,{agent_mane:i.agent_name})})),s===rt.CONSULT_CALL_IN_SUCCESS&&(pi.sessionId=i.session_id,ct.emit(it.CONSULT_CALL_IN_SUCCESS,i),dt.updateConsultIsAnswer(!0),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ci)),s===rt.MUTE&&(0===r?(dt.updateIsMuted(!0),ct.emit(it.MUTE_SUCCESS)):ct.emit(it.MUTE_FAILED,n)),s===rt.UNMUTE&&(0===r?(dt.updateIsMuted(!1),ct.emit(it.UNMUTE_SUCCESS)):ct.emit(it.UNMUTE_FAILED,n)),s===rt.CONSULT_TRANSFER&&(0===r?ct.emit(it.CONSULT_TRANSFER_SUCCESS):ct.emit(it.CONSULT_TRANSFER_FAILED,n)),s===rt.CONSULT_TRANSFER_FAILED&&ct.emit(it.CONSULT_TRANSFER_FAILED,i.status),s===rt.CONSULT_TRANSFER_OFF_HOOK&&(dt.updateDirection(tt.INCOMING),dt.updateDisplayText(ot.CALLING),ct.emit(it.CONSULT_TRANSFER_OFF_HOOK),dt.updateActionConfigs(Ai),dt.updateIncomingIsAnswer(!0),dt.updateConsultIsAnswer(!1)),s===rt.INCOMING_CALL&&(pi.sessionId=i.session_id,dt.updateIsCalling(!0),dt.updateDirection(tt.INCOMING),dt.updateDisplayText(ot.INCOMING_CALL),ct.emit(it.INCOMING_CALL,{customer_phone:i.customer_phone}),dt.updateActionConfigs(Ei),pi.enableBrowserAlert&&Oi.show("📞 客户来电",`客户 [${i.customer_phone}] 正在呼入...`,()=>{ct.emit(nt.NOTIFICATION_CLICK,{customer_phone:i.customer_phone})})),s===rt.INCOMING_CALL_OFF_HOOK&&(dt.updateIncomingIsAnswer(!0),ct.emit(it.INCOMING_CALL_OFF_HOOK),dt.updateActionConfigs(Ai),dt.updateDisplayText(ot.CALLING)),s===rt.INCOMING_CALL_END&&(ct.emit(it.INCOMING_CALL_END),dt.reset(),dt.updateActionConfigs(wi),this.putAgentState()),0!==s&&Pi.emit("ws-message",t)},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const e=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"}),t=URL.createObjectURL(e);this.heartbeatWorker=new Worker(t),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(e){this.ws?.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify(e)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){qi&&(qi.close(),qi=null)}static __internalSend(e){if(!qi)throw new Error("WebSocket 尚未初始化");qi.sendMessage(e)}}module.exports=class{#e=null;#t=new Ni;#s=null;#i=!1;#r;constructor(){clearInterval(this.#s),this.#s=setInterval(async()=>{const e=await this.#n();fi.updateRttObject(e)},2e3),Oi.requestMediaPermissions(),window.addEventListener("beforeunload",()=>{this.destroy()}),this.#r=dt.subscribeKey("answerDevice",e=>{1===e&&this.initWebRtc()})}async initWebRtc(){const e=pi.agentInfo.sip_account_list.find(e=>1===e.device_type);if(e){const t=e.sip_register_addr;this.#e=new mi({server:t.split(":")[0],user:e.sip_account,password:e.sip_password,webSocket:`wss://${t}`,callTimeout:3e4},this.#o),await this.#e.start()}}async init({actionNodeParams:e,url:t,appKey:s,appSecret:i,agentNo:r,enableBrowserAlert:n}){try{const{viewHtmlElement:o,rttHTML:a}=e;di=t||"https://aicc-api.yescloudy.com",li=s,gi=i;const c=Ft(s,i);await this.#t._agentLogin(r);const{agent_no:h,current_answer_device:d,init_state:l}=pi.agentInfo;l===et.IDLE?(dt.updateActionConfigs(wi),pi.stateObject={state:l,state_name:"空闲"}):l===et.BUSY&&(dt.updateActionConfigs(yi),pi.stateObject={state:l,state_name:"忙碌"}),Li.getInstance(`ws://112.90.183.54:8719/api/v1/ws/call/${h}?Authorization=${c}`),dt.updateAnswerDevice(d),1===d&&await this.initWebRtc(),e&&o&&(this.#i=!0,new Hi({container:o,rttHTML:a,statusParams:{state:et.IDLE,statusName:"空闲"}},this)),pi.enableBrowserAlert=n,n&&Oi.requestPermission()}catch(e){this.#i&&oi("初始化失败"),console.log(e)}}#o=e=>{const{type:t,data:s}=e;ct.emit(t,s)};#a=e=>{};on(e,t){return ct.on(e,t),this}off(e,t){ct.off(e,t)}offAll(){ct.clearAllListeners()}#c(){if(!this.#e)throw new Error("请先初始化SDK");const e=dt.get("isCalling"),t=pi.sessionId;if(!e)throw new Error("当前没有通话");if(!t)throw new Error("sessionId不存在")}#h(){const e=dt.get("isHold"),{sessionId:t}=pi;if(t){if(e)throw new Error("当前已处于保持状态");Li.__internalSend({type:rt.CALL_HOLD,data:{session_id:t}}),dt.updateDisplayText(ot.HOLD),dt.updateIsHold(!0)}}#d(){const{isHold:e}=dt.getState(),{sessionId:t}=pi;if(t){if(!e)throw new Error("当前未处于保持状态");Li.__internalSend({type:rt.CALL_UNHOLD,data:{session_id:t}}),dt.updateDisplayText(""),dt.updateIsHold(!1)}}#l(e){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:t}=dt.getState();if(!t)throw new Error("当前没有通话");this.#e.sendDTMF(e)}#g(){if(1!==dt.get("answerDevice"))throw new Error("当前设备不支持此功能");if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:e,direction:t,outCallIsAnswer:s}=dt.getState();if(!e)throw new Error("当前没有通话");s||(t===tt.INCOMING?this.#u():t===tt.OUTGOING&&this.#p())}async#f(e){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:t,outCallIsAnswer:s,consultIsAnswer:i,incomingIsAnswer:r}=dt.getState(),n=pi.sessionId;if(i)throw new Error("当前正在咨询");if(!(t||s||r))throw new Error("当前没有通话");if(!n)throw new Error("sessionId不存在");Li.__internalSend({type:rt.CONSULT_REQUEST,data:{session_id:n,consultation_agent_no:e}})}async#m(){if(1!==dt.get("answerDevice"))throw new Error("当前设备不支持此功能");if(!this.#e)throw new Error("请先初始化SDK");await this.#e.answerCall()}async#u(){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:e}=dt.getState();if(!e)throw new Error("当前没有通话");await this.#e.rejectInCall()}async#v(e){if(!this.#e)throw new Error("请先初始化SDK");if(dt.getState().isCalling)throw new Error("正在呼叫中,请勿重复点击");dt.updateIsCalling(!0),dt.updateDirection(tt.OUTGOING),Li.__internalSend({type:rt.OUT_CALL,data:{customer_phone:e}})}async#p(){const{isCalling:e}=dt.getState();if(!this.#e)throw new Error("请先初始化SDK");if(!e)throw new Error("当前没有通话");await this.#e.rejectOutCall()}async#w(){if(!this.#e)throw new Error("请先初始化SDK");if(!dt.get("isCalling"))throw new Error("当前没有通话");await this.#e.hangup()}#y(){this.#c();const e=dt.get("actionConfigs"),t=dt.get("isMuted"),s=pi.sessionId;if(t)throw new Error("当前未处于静音状态");if(!e.includes("mute"))throw new Error("当前状态请勿调用静音");Li.__internalSend({type:rt.MUTE,data:{session_id:s}})}#b(){this.#c();const e=dt.get("actionConfigs"),t=dt.get("isMuted"),s=pi.sessionId;if(!t)throw new Error("当前未处于未静音状态");if(!e.includes("unmute"))throw new Error("当前状态请勿调用静音");Li.__internalSend({type:rt.UNMUTE,data:{session_id:s}})}#T(){this.#c();const e=dt.get("consultIsAnswer"),t=pi.sessionId;if(!dt.get("actionConfigs").includes("consult_transfer"))throw new Error("当前状态请勿调用咨询转移");if(!e)throw new Error("当前未处于咨询中");Li.__internalSend({type:rt.CONSULT_TRANSFER,data:{session_id:t}})}async destroyRtc(){await(this.#e?.destroy())}destroy(){this.destroyRtc(),clearInterval(this.#s),Pi.off("ws-message",this.#a),Li.__internalClose(),this.offAll(),this.#r?.()}async#n(){return this.#e?this.#e.getNetworkStats():{}}get call_api(){return this.#i?{answerCall:this.#m.bind(this),makeCall:this.#v.bind(this),cancelCall:this.#g.bind(this),hangup:this.#w.bind(this),sendDTMF:this.#l.bind(this),holdCall:this.#h.bind(this),unholdCall:this.#d.bind(this),consultCall:async e=>{try{await this.#f(e)}catch(e){throw console.warn(e),e}},consultTransfer:this.#T.bind(this),mute:this.#y.bind(this),unmute:this.#b.bind(this)}:{}}get agent_api(){return this.#i?{changeDevice:this.#t.changeDevice.bind(this.#t),changeState:this.#t.changeState.bind(this.#t),getIdleAgentList:e=>this.#t.getIdleAgentList(e),getAgentState:e=>this.#t.getAgentState(e)}:{}}};
|
|
@@ -110,7 +110,7 @@ const Xs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
110
110
|
:host([type='loading']) {
|
|
111
111
|
background: #595959;
|
|
112
112
|
}
|
|
113
|
-
`}connectedCallback(){super.connectedCallback(),setTimeout(()=>{this.remove()},this.duration+300)}render(){return xs`<div>${this.content}</div>`}};Bt([ti({type:String})],ri.prototype,"type",void 0),Bt([ti({type:String})],ri.prototype,"content",void 0),Bt([ti({type:Number})],ri.prototype,"duration",void 0),ri=Bt([Xs("my-message")],ri);const ni=(e,t,s=3e3)=>{let i=document.querySelector("#message-container");i||(i=document.createElement("div"),i.id="message-container",Object.assign(i.style,{position:"fixed",top:"14px",left:"50%",transform:"translateX(-50%)",zIndex:"9999"}),document.body.appendChild(i));const r=document.createElement("my-message");r.setAttribute("type",e),r.setAttribute("content",t),r.setAttribute("duration",String(s)),r.style.setProperty("--fade-delay",s/1e3+"s"),i.appendChild(r)},oi=(e,t=3e3)=>ni("success",e,t),ai=(e,t=3e3)=>ni("error",e,t),ci=(e,t=3e3)=>ni("warning",e,t),hi="/v1/aicc/bmserver",di="/v1/aicc/ccs";let li="",gi="",ui="";async function pi(e,t){const s=function(){const e=jt(gi,ui);return Lt.create({prefixUrl:`${li}/api`,timeout:!1,headers:{Authorization:e},hooks:{afterResponse:[async(e,t,s)=>{const i=await s.clone().json();if(0!==i.code)throw ai(i.msg),new Error(JSON.stringify(i)||"请求失败");return s.json=async()=>i,s}]}})}(),i=e.replace(/^\/+/,"");return s.post(i,{json:t}).json()}const fi={agentInfo:{},isRtcReconnecting:!1,sessionId:"",enableBrowserAlert:!1,autoStateTimer:null};const mi=new class extends Qe{updateRttObject(e){this.setState({rttObject:e})}}({rttObject:{rtt:null,jitter:null,packetsLost:null,packetsReceived:null,packetsSent:null,sendBitrate:null,recvBitrate:null,codec:null}});class vi{constructor(e,t){this.config=e,this.eventCallback=t,this.userAgent=null,this.registerer=null,this.activeSession=null,this.callTimeoutTimer=null,this.incomingInvitation=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectTimer=null,this.isOffline=!1,this.autoAnswerTimer=null,this.handleMessage=e=>{},this.handleNetworkInfoChange=e=>{0===(e.rttObject?.rtt||0)?this.isOffline||(this.isOffline=!0,this.handleOffline()):this.isOffline&&(this.isOffline=!1,this.handleOnline())},this.handleOffline=()=>{console.warn("[SIPClient] 网络断开,准备销毁 SIP 客户端",(new Date).toLocaleString())
|
|
113
|
+
`}connectedCallback(){super.connectedCallback(),setTimeout(()=>{this.remove()},this.duration+300)}render(){return xs`<div>${this.content}</div>`}};Bt([ti({type:String})],ri.prototype,"type",void 0),Bt([ti({type:String})],ri.prototype,"content",void 0),Bt([ti({type:Number})],ri.prototype,"duration",void 0),ri=Bt([Xs("my-message")],ri);const ni=(e,t,s=3e3)=>{let i=document.querySelector("#message-container");i||(i=document.createElement("div"),i.id="message-container",Object.assign(i.style,{position:"fixed",top:"14px",left:"50%",transform:"translateX(-50%)",zIndex:"9999"}),document.body.appendChild(i));const r=document.createElement("my-message");r.setAttribute("type",e),r.setAttribute("content",t),r.setAttribute("duration",String(s)),r.style.setProperty("--fade-delay",s/1e3+"s"),i.appendChild(r)},oi=(e,t=3e3)=>ni("success",e,t),ai=(e,t=3e3)=>ni("error",e,t),ci=(e,t=3e3)=>ni("warning",e,t),hi="/v1/aicc/bmserver",di="/v1/aicc/ccs";let li="",gi="",ui="";async function pi(e,t){const s=function(){const e=jt(gi,ui);return Lt.create({prefixUrl:`${li}/api`,timeout:!1,headers:{Authorization:e},hooks:{afterResponse:[async(e,t,s)=>{const i=await s.clone().json();if(0!==i.code)throw ai(i.msg),new Error(JSON.stringify(i)||"请求失败");return s.json=async()=>i,s}]}})}(),i=e.replace(/^\/+/,"");return s.post(i,{json:t}).json()}const fi={agentInfo:{},isRtcReconnecting:!1,sessionId:"",enableBrowserAlert:!1,autoStateTimer:null};const mi=new class extends Qe{updateRttObject(e){this.setState({rttObject:e})}}({rttObject:{rtt:null,jitter:null,packetsLost:null,packetsReceived:null,packetsSent:null,sendBitrate:null,recvBitrate:null,codec:null}});class vi{constructor(e,t){this.config=e,this.eventCallback=t,this.userAgent=null,this.registerer=null,this.activeSession=null,this.callTimeoutTimer=null,this.incomingInvitation=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectTimer=null,this.isOffline=!1,this.autoAnswerTimer=null,this.handleMessage=e=>{},this.handleNetworkInfoChange=e=>{0===(e.rttObject?.rtt||0)?this.isOffline||(this.isOffline=!0,this.handleOffline()):this.isOffline&&(this.isOffline=!1,this.handleOnline())},this.handleOffline=()=>{console.warn("[SIPClient] 网络断开,准备销毁 SIP 客户端",(new Date).toLocaleString())},this.handleOnline=()=>{console.warn("[SIPClient] 网络恢复,准备重新启动 SIP 客户端",(new Date).toLocaleString())},mi.subscribe(this.handleNetworkInfoChange)}async start(){const e=Xe.makeURI(`sip:${this.config.user}@${this.config.server}`);if(!e)throw new Error("无效的SIP配置");const t={uri:e,authorizationUsername:this.config.user,authorizationPassword:this.config.password,transportOptions:{server:this.config.webSocket,connectionTimeout:30,keepAliveInterval:0},sessionDescriptionHandlerFactoryOptions:{alwaysAcquireMediaFirst:!0,peerConnectionConfiguration:{iceServers:[]},iceGatheringTimeout:400},logBuiltinEnabled:!1};this.userAgent=new Xe(t),this.setupEventListeners(),await this.userAgent.start(),await this.register()}setupEventListeners(){this.userAgent&&(this.userAgent.transport.stateChange.addListener(e=>{let t;switch(e){case ee.Connecting:t=st.WEB_RTC_CONNECTING;break;case ee.Connected:t=st.WEB_RTC_CONNECTED,this.reconnectAttempts=0,fi.isRtcReconnecting=!1,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null);break;case ee.Disconnecting:t=st.WEB_RTC_DISCONNECTING;break;case ee.Disconnected:{t=st.WEB_RTC_DISCONNECTED;const e=dt.get("answerDevice");if(!fi.isRtcReconnecting&&this.reconnectAttempts<this.maxReconnectAttempts&&1===e){this.reconnectAttempts++;const e=1e3*this.reconnectAttempts;console.warn(`SIP WebSocket 断开,第 ${this.reconnectAttempts} 次尝试重连,${e}ms 后重试...`),this.reconnectTimer=setTimeout(()=>{this.reconnect()},e)}else this.reconnectAttempts>=this.maxReconnectAttempts&&console.error("SIP 重连失败:已达到最大重试次数");break}default:t="unknown"}this.eventCallback?.({type:t})}),this.userAgent.transport.stateChange.addListener(e=>{}),this.userAgent.delegate={onInvite:e=>{this.handleIncomingCall(e)}})}async register(){if(this.userAgent){this.registerer=new ne(this.userAgent),this.registerer?.stateChange.addListener(e=>{let t;switch(e){case X.Initial:t="initial";break;case X.Registered:t=st.WEB_RTC_REGISTERED;break;case X.Unregistered:t=st.WEB_RTC_UNREGISTERED;break;case X.Terminated:t=st.WEB_RTC_TERMINATED;break;default:t="unknown"}this.eventCallback?.({type:t})});try{await this.registerer.register()}catch(e){this.eventCallback?.({type:st.WEB_RTC_REGISTER_FAILED,data:e})}}}attachRemoteAudio(e){const t=e.sessionDescriptionHandler;if(t){const e=t.peerConnection;if(!e)return;const s=new MediaStream;e.getReceivers().forEach(e=>{e.track&&"audio"===e.track.kind&&s.addTrack(e.track)});let i=document.getElementById("sip-remote-audio");i||(i=document.createElement("audio"),i.id="sip-remote-audio",i.autoplay=!0,i.style.display="none",document.body.appendChild(i)),i.srcObject=s,i.play().catch(e=>{console.error("音频播放失败,需要用户交互触发",e)})}}handleSessionState(e,t,s){e.stateChange.addListener(t=>{switch(t){case K.Established:clearTimeout(this.callTimeoutTimer),this.activeSession=e,this.attachRemoteAudio(e);break;case K.Terminating:break;case K.Terminated:this.activeSession=null,clearTimeout(this.callTimeoutTimer);case K.Establishing:}})}handleIncomingCall(e){this.incomingInvitation=e,this.handleSessionState(e,!1);const{soft_device_auto_answer:t,auto_answer_time:s}=fi.agentInfo,i=dt.get("direction"),r=1===t;if(i===tt.OUTGOING)this.answerCall();else if(r&&i===tt.INCOMING){const e=Number(s)||0;e>0?this.autoAnswerTimer=setTimeout(()=>{this.answerCall(),this.autoAnswerTimer=null},e):this.answerCall()}}async makeCall(e){if(dt.getState().isCalling)throw new Error("正在呼叫中,请勿重复点击");if(!this.userAgent)throw dt.updateIsCalling(!1),dt.updateDirection(null),new Error("SIP客户端未初始化");dt.updateIsCalling(!0),dt.updateDirection(tt.OUTGOING);const t=Xe.makeURI(`sip:${e}@${this.config.server}`);if(!t)throw new Error("无效的被叫号码");const s=new Z(this.userAgent,t);this.handleSessionState(s,!0,e);try{this.activeSession=s,await s.invite(),this.config.callTimeout&&(this.callTimeoutTimer=setTimeout(()=>{s.state!==K.Established&&(this.hangup(),this.eventCallback?.({type:"error",data:{message:"呼叫超时未接通"}}))},this.config.callTimeout))}catch(e){this.eventCallback?.({type:"error",data:{message:"呼叫失败",detail:e}}),dt.updateIsCalling(!1),dt.updateDirection(null)}}async answerCall(){if(!this.incomingInvitation)throw new Error("无来电可接听");this.autoAnswerTimer&&(clearTimeout(this.autoAnswerTimer),this.autoAnswerTimer=null);try{console.log((new Date).toLocaleString()),await this.incomingInvitation.accept(),console.log((new Date).toLocaleString()),this.activeSession=this.incomingInvitation,this.incomingInvitation=null}catch(e){this.eventCallback?.({type:st.WEB_RTC_ANSWER_FAILED,data:{detail:e}})}}async rejectInCall(){if(this.incomingInvitation)try{await this.incomingInvitation.reject(),this.incomingInvitation=null,dt.updateDirection(null),dt.updateIsCalling(!1),clearTimeout(this.callTimeoutTimer)}catch(e){this.eventCallback?.({type:"error",data:{message:"拒接失败",detail:e}})}}sendDTMF(e){if(!this.activeSession)throw new Error("当前没有活跃的通话");const t=this.activeSession.sessionDescriptionHandler;t&&"function"==typeof t.sendDtmf?(t.sendDtmf(e),this.eventCallback?.({type:st.WEB_RTC_SEND_DTMF,data:{tone:e}})):console.warn("DTMF发送不支持或未初始化")}async hangup(){if(this.activeSession){clearTimeout(this.callTimeoutTimer);const e=this.activeSession;if(!e)return;const t=e.state;try{t===K.Established?await e.bye():t===K.Establishing&&(e instanceof Z?await e.cancel():e instanceof J&&await e.reject()),clearTimeout(this.callTimeoutTimer)}catch(e){console.error("挂断失败",e)}finally{this.activeSession=null}}}async rejectOutCall(){this.activeSession instanceof J&&(await this.activeSession.reject(),this.activeSession=null)}async destroy(){if(clearTimeout(this.callTimeoutTimer),this.activeSession&&await this.hangup(),this.registerer){try{await this.registerer.unregister()}catch(e){console.warn("注销失败",e)}this.registerer=null}this.userAgent&&(await this.userAgent.stop(),this.userAgent=null)}async reconnect(){if(!fi.isRtcReconnecting){fi.isRtcReconnecting=!0;try{await this.destroy(),await this.start(),console.log("重连成功"),this.isOffline=!1}catch(e){console.error("重连失败",e)}finally{fi.isRtcReconnecting=!1}}}async getNetworkStats(){if(this.activeSession){const e=this.activeSession.sessionDescriptionHandler?.peerConnection;if(!e)return null;const t=await e.getStats(),s={};return t.forEach(e=>{"candidate-pair"===e.type&&"succeeded"===e.state&&null!=e.currentRoundTripTime&&(s.rtt=+(1e3*e.currentRoundTripTime).toFixed(2)),"inbound-rtp"===e.type&&"audio"===e.kind&&(s.jitter=+(1e3*e.jitter).toFixed(2),s.packetsLost=e.packetsLost,s.packetsReceived=e.packetsReceived,e.bytesReceived&&e.timestamp&&(s.recvBitrate=+(e.bytesReceived/1024).toFixed(2))),"outbound-rtp"===e.type&&"audio"===e.kind&&(s.packetsSent=e.packetsSent,e.bytesSent&&e.timestamp&&(s.sendBitrate=+(e.bytesSent/1024).toFixed(2))),"codec"===e.type&&e.mimeType&&(s.codec=e.mimeType)}),{...s,rtt:s?.rtt||40}}try{const e=Date.now();await pi(`${hi}/config/ping`,{});const t=Date.now();return{rtt:t-e||1}}catch(e){console.log(e)}}}const wi={statusColor:{[et.IDLE]:"#1D92E9",[et.BUSY]:"#F5212D",[et.OFFLINE]:"#8c8c8c",[et.RINGING]:"#e9b91d"}},yi=["call_number"],bi=[],Ti=["hangup"],Si=["hold","hangup","unhold","mute","unmute","transfer","consult","satisfaction","dtmf"],Ci=["consult_transfer"],Ei=["hangup"],Ai=["answer","reject"],_i=["hangup","consult","transfer","hold","unhold","mute","unmute","satisfaction","dtmf"];let Ii=class extends Js{static{this.styles=zt`
|
|
114
114
|
.timer-text {
|
|
115
115
|
width: 70px;
|
|
116
116
|
font-size: 14px;
|
|
@@ -173,6 +173,7 @@ const Xs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
173
173
|
|
|
174
174
|
.trigger {
|
|
175
175
|
display: inline-block;
|
|
176
|
+
cursor: pointer;
|
|
176
177
|
}
|
|
177
178
|
|
|
178
179
|
.popover {
|
|
@@ -187,6 +188,8 @@ const Xs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
187
188
|
opacity 0.2s ease,
|
|
188
189
|
transform 0.2s ease;
|
|
189
190
|
pointer-events: none;
|
|
191
|
+
min-width: 100px;
|
|
192
|
+
padding: 0px;
|
|
190
193
|
}
|
|
191
194
|
|
|
192
195
|
.popover.visible {
|
|
@@ -216,7 +219,6 @@ const Xs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
216
219
|
|
|
217
220
|
.arrow[data-placement='top'] {
|
|
218
221
|
bottom: -6px;
|
|
219
|
-
left: 10px;
|
|
220
222
|
border-width: 6px 6px 0 6px;
|
|
221
223
|
border-color: #fff transparent transparent transparent;
|
|
222
224
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
|
|
@@ -224,26 +226,23 @@ const Xs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
224
226
|
|
|
225
227
|
.arrow[data-placement='bottom'] {
|
|
226
228
|
top: -6px;
|
|
227
|
-
left: 10px;
|
|
228
229
|
border-width: 0 6px 6px 6px;
|
|
229
230
|
border-color: transparent transparent #fff transparent;
|
|
230
231
|
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.05);
|
|
231
232
|
}
|
|
232
233
|
|
|
233
234
|
.arrow[data-placement='left'] {
|
|
234
|
-
top: 10px;
|
|
235
235
|
right: -6px;
|
|
236
236
|
border-width: 6px 0 6px 6px;
|
|
237
237
|
border-color: transparent transparent transparent #fff;
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
.arrow[data-placement='right'] {
|
|
241
|
-
top: 10px;
|
|
242
241
|
left: -6px;
|
|
243
242
|
border-width: 6px 6px 6px 0;
|
|
244
243
|
border-color: transparent #fff transparent transparent;
|
|
245
244
|
}
|
|
246
|
-
`}firstUpdated(){this.triggerEl=this.renderRoot.querySelector(".trigger"),this.popoverEl=this.renderRoot.querySelector(".popover"),"click"===this.triggerType?(this.triggerEl.addEventListener("click",this.onTogglePopover),document.addEventListener("click",this.onOutsideClick)):(this.triggerEl.addEventListener("mouseenter",this.showPopover),this.triggerEl.addEventListener("mouseleave",this.hidePopoverDelayed),this.popoverEl.addEventListener("mouseenter",this.clearHideTimer),this.popoverEl.addEventListener("mouseleave",this.hidePopoverDelayed))}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.onOutsideClick)}updatePosition(){const e=this.triggerEl.getBoundingClientRect(),t=this.popoverEl;let s=0,i=0;switch(this.placement){case"top":s=e.top-t.offsetHeight-8,i=e.left;break;case"bottom":s=e.bottom+8,i=e.left;break;case"left":s=e.top,i=e.left-t.offsetWidth-8;break;case"right":s=e.top,i=e.right+8}t.style.top=`${s}px`,t.style.left=`${i}px`,t.setAttribute("data-placement",this.placement)}render(){return xs`
|
|
245
|
+
`}firstUpdated(){this.triggerEl=this.renderRoot.querySelector(".trigger"),this.popoverEl=this.renderRoot.querySelector(".popover"),"click"===this.triggerType?(this.triggerEl.addEventListener("click",this.onTogglePopover),document.addEventListener("click",this.onOutsideClick)):(this.triggerEl.addEventListener("mouseenter",this.showPopover),this.triggerEl.addEventListener("mouseleave",this.hidePopoverDelayed),this.popoverEl.addEventListener("mouseenter",this.clearHideTimer),this.popoverEl.addEventListener("mouseleave",this.hidePopoverDelayed))}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.onOutsideClick),this.triggerEl&&("click"===this.triggerType?(this.triggerEl.removeEventListener("click",this.onTogglePopover),document.removeEventListener("click",this.onOutsideClick)):(this.triggerEl.removeEventListener("mouseenter",this.showPopover),this.triggerEl.removeEventListener("mouseleave",this.hidePopoverDelayed),this.popoverEl.removeEventListener("mouseenter",this.clearHideTimer),this.popoverEl.removeEventListener("mouseleave",this.hidePopoverDelayed)))}updatePosition(){const e=this.triggerEl.getBoundingClientRect(),t=this.popoverEl;let s=0,i=0;switch(this.placement){case"top":s=e.top-t.offsetHeight-8,i=e.left+(e.width-t.offsetWidth)/2;break;case"bottom":s=e.bottom+8,i=e.left+(e.width-t.offsetWidth)/2;break;case"left":s=e.top+(e.height-t.offsetHeight)/2,i=e.left-t.offsetWidth-8;break;case"right":s=e.top+(e.height-t.offsetHeight)/2,i=e.right+8}t.style.top=`${s}px`,t.style.left=`${i}px`,t.setAttribute("data-placement",this.placement);const r=this.renderRoot.querySelector(".arrow");if(r)if("top"===this.placement||"bottom"===this.placement){const s=e.left+e.width/2-i-6;r.style.left=`${Math.min(Math.max(s,10),t.offsetWidth-16)}px`,r.style.top=""}else{const i=e.top+e.height/2-s-6;r.style.top=`${Math.min(Math.max(i,10),t.offsetHeight-16)}px`,r.style.left=""}}render(){return xs`
|
|
247
246
|
<div class="trigger">
|
|
248
247
|
<slot name="trigger"></slot>
|
|
249
248
|
</div>
|
|
@@ -554,7 +553,7 @@ const Xs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
554
553
|
`:null}
|
|
555
554
|
</div>
|
|
556
555
|
</div>
|
|
557
|
-
`:xs``}_onCancel(){this.dispatchEvent(new CustomEvent("cancel")),this.visible=!1}_onOk(){this.dispatchEvent(new CustomEvent("ok"))}_onMaskClick(){this._onCancel()}};Bt([ti({type:Boolean})],Ni.prototype,"visible",void 0),Bt([ti({type:Boolean})],Ni.prototype,"showFooter",void 0),Bt([ti({type:String})],Ni.prototype,"width",void 0),Bt([ti({type:String})],Ni.prototype,"title",void 0),Ni=Bt([Xs("my-modal-wrapper")],Ni);class Hi{constructor(){this.roleData={agentInfo:()=>{if(!fi.agentInfo?.agent_no)throw new Error("请先登录")},requestInfo:e=>{if(!e.data)throw new Error("请传入参数")},changeDevice:e=>{if(!e)throw new Error('Parameter "device" is required');const{answer_devices:t}=fi.agentInfo;if(!t.split(",").map(e=>Number(e)).includes(e))throw new Error("当前设备不支持")},changeState:(e,t)=>{if(!e)throw new Error('Parameter "state" is required');if(!t)throw new Error('Parameter "state_name" is required');if(2===e&&"通话中"===t)throw new Error("当前状态不支持");if(![1,2].includes(e))throw new Error("当前状态不支持")}}}async _agentLogin(e){try{const s=await(t={agent_no:e},pi(`${di}/agent/login`,t));fi.agentInfo=s.data}catch(e){throw console.log(e),new Error("登录失败")}var t}async changeDevice(e){try{this.roleData.agentInfo(),this.roleData.requestInfo(e);const{data:t,success:s}=e,{device:i}=t;this.roleData.changeDevice(i);const{agent_no:r}=fi.agentInfo;await(e=>pi(`${di}/device/change`,e))({agent_no:r,answer_device:i}),dt.updateAnswerDevice(i),s?.({code:0,msg:"请求成功"})}catch(e){throw console.log(e),new Error("切换设备失败")}}async changeState(e){try{fi.autoStateTimer&&(clearTimeout(fi.autoStateTimer),fi.autoStateTimer=null),this.roleData.agentInfo(),this.roleData.requestInfo(e);const{data:t,success:s}=e,{state:i,state_name:r}=t;this.roleData.changeState(i,r);const{agent_no:n}=fi.agentInfo;await(e=>pi(`${di}/state/change`,e))({agent_no:n,state_name:r,state:i}),i===et.IDLE?dt.updateActionConfigs(yi):i===et.BUSY&&dt.updateActionConfigs(bi),fi.stateObject={state:i,state_name:r},s?.({code:0,msg:"请求成功"})}catch(e){console.log(e)}}async getIdleAgentList(e){const{agent_no:t}=fi.agentInfo;try{this.roleData.agentInfo();const s=await(e=>pi(`${di}/agent/free`,e))({agent_no:t});e.success?.(s)}catch(e){console.log(e)}}async getAgentState(e){try{const t=await pi(`${hi}/agent/statecfg/list`,{}),s=(t.data||[]).filter(e=>0===e.enable).filter(e=>0!==e.state&&3!==e.state).map(e=>({state:e.state,state_name:e.state_name})).reverse();e.success?.({...t,data:s})}catch(e){console.log(e)}}}class Pi{constructor({container:e,rttHTML:t,statusParams:s},i){this.VoiceSDKInstance=i,this.apiClient=new Hi,this.isOpenSelect=!1,this.statusParams={state:et.IDLE,statusName:"空闲"},this.consultShow=!1,this.modalRoot=null,this.agentStateData=[],this.
|
|
556
|
+
`:xs``}_onCancel(){this.dispatchEvent(new CustomEvent("cancel")),this.visible=!1}_onOk(){this.dispatchEvent(new CustomEvent("ok"))}_onMaskClick(){this._onCancel()}};Bt([ti({type:Boolean})],Ni.prototype,"visible",void 0),Bt([ti({type:Boolean})],Ni.prototype,"showFooter",void 0),Bt([ti({type:String})],Ni.prototype,"width",void 0),Bt([ti({type:String})],Ni.prototype,"title",void 0),Ni=Bt([Xs("my-modal-wrapper")],Ni);class Hi{constructor(){this.roleData={agentInfo:()=>{if(!fi.agentInfo?.agent_no)throw new Error("请先登录")},requestInfo:e=>{if(!e.data)throw new Error("请传入参数")},changeDevice:e=>{if(!e)throw new Error('Parameter "device" is required');const{answer_devices:t}=fi.agentInfo;if(!t.split(",").map(e=>Number(e)).includes(e))throw new Error("当前设备不支持")},changeState:(e,t)=>{if(!e)throw new Error('Parameter "state" is required');if(!t)throw new Error('Parameter "state_name" is required');if(2===e&&"通话中"===t)throw new Error("当前状态不支持");if(![1,2].includes(e))throw new Error("当前状态不支持")}}}async _agentLogin(e){try{const s=await(t={agent_no:e},pi(`${di}/agent/login`,t));fi.agentInfo=s.data}catch(e){throw console.log(e),new Error("登录失败")}var t}async changeDevice(e){try{this.roleData.agentInfo(),this.roleData.requestInfo(e);const{data:t,success:s}=e,{device:i}=t;this.roleData.changeDevice(i);const{agent_no:r}=fi.agentInfo;await(e=>pi(`${di}/device/change`,e))({agent_no:r,answer_device:i}),dt.updateAnswerDevice(i),s?.({code:0,msg:"请求成功"})}catch(e){throw console.log(e),new Error("切换设备失败")}}async changeState(e){try{fi.autoStateTimer&&(clearTimeout(fi.autoStateTimer),fi.autoStateTimer=null),this.roleData.agentInfo(),this.roleData.requestInfo(e);const{data:t,success:s}=e,{state:i,state_name:r}=t;this.roleData.changeState(i,r);const{agent_no:n}=fi.agentInfo;await(e=>pi(`${di}/state/change`,e))({agent_no:n,state_name:r,state:i}),i===et.IDLE?dt.updateActionConfigs(yi):i===et.BUSY&&dt.updateActionConfigs(bi),fi.stateObject={state:i,state_name:r},s?.({code:0,msg:"请求成功"})}catch(e){console.log(e)}}async getIdleAgentList(e){const{agent_no:t}=fi.agentInfo;try{this.roleData.agentInfo();const s=await(e=>pi(`${di}/agent/free`,e))({agent_no:t});e.success?.(s)}catch(e){console.log(e)}}async getAgentState(e){try{const t=await pi(`${hi}/agent/statecfg/list`,{}),s=(t.data||[]).filter(e=>0===e.enable).filter(e=>0!==e.state&&3!==e.state).map(e=>({state:e.state,state_name:e.state_name})).reverse();e.success?.({...t,data:s})}catch(e){console.log(e)}}}class Pi{constructor({container:e,rttHTML:t,statusParams:s},i){this.VoiceSDKInstance=i,this.apiClient=new Hi,this.isOpenSelect=!1,this.statusParams={state:et.IDLE,statusName:"空闲"},this.consultShow=!1,this.modalRoot=null,this.agentStateData=[],this.handleNetworkInfoChange=e=>{this.rttHTML&&this.renderRtt(e.rttObject)},this.handleCallInfoChange=e=>{this.render()},this.hiddenSelect=()=>{if(!this.isOpenSelect)return;const e=document.querySelector(".ysyt-select");e.style.height="0px",setTimeout(()=>{e.style.padding="0px"},100),this.isOpenSelect=!1,this.render()},this.toggle=e=>{e.stopPropagation(),this.isOpenSelect=!this.isOpenSelect;const t=document.querySelector(".ysyt-select");this.isOpenSelect?(t.style.height=t.scrollHeight+"px",t.style.padding="4px 0px",this.render()):this.hiddenSelect()},this.changeStatus=async e=>{const{state:t,statusName:s}=e;await this.apiClient.changeState({data:{state:t,state_name:s},success:()=>{this.statusParams=e;const t=document.getElementById("my-timer");t?.reset(),this.hiddenSelect()}})},this.onChangeDevices=async e=>{await this.apiClient.changeDevice({data:{device:e},success:({code:t})=>{0===t&&(1!==e&&this.VoiceSDKInstance.destroyRtc(),oi("切换成功"),this.render())}})},this.ruleCall=async e=>{if(e)try{await this.VoiceSDKInstance.call_api.makeCall(e)}catch(e){console.error(e)}},this.onCall=()=>{const e=document.querySelector("my-input");this.ruleCall(e.value)},this.renderCallPopover=()=>xs`
|
|
558
557
|
<my-popover>
|
|
559
558
|
<div slot="trigger">
|
|
560
559
|
<my-tooltip content="拨打">
|
|
@@ -659,28 +658,16 @@ const Xs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
659
658
|
</div>`}
|
|
660
659
|
</div>
|
|
661
660
|
</my-modal-wrapper>
|
|
662
|
-
`;Ys(i,this.modalRoot)}})}catch(e){ai(e)}}getActionConfigs(){const{show_satisfaction:e}=fi.agentInfo,t=dt.get("isHold"),s=dt.get("isMuted"),i=dt.get("actionConfigs").filter(i=>(0!==e||"satisfaction"!==i)&&(!(!t&&"unhold"===i)&&((!t||"hold"!==i)&&((!s||"mute"!==i)&&!(!s&&"unmute"===i)))));return[{render:this.renderCallPopover,type:"call_number"},{render:this.renderAnswer,type:"answer"},{render:this.renderReject,type:"reject"},{render:this.renderHangup,type:"hangup"},{render:this.renderDialer,type:"dtmf"},{render:this.renderUnhold,type:"unhold"},{render:this.renderHold,type:"hold"},{render:this.renderMute,type:"mute"},{render:this.renderUnmute,type:"unmute"},{render:this.renderSatisfaction,type:"satisfaction"},{render:this.renderConsult,type:"consult"},{render:this.renderTransfer,type:"transfer"},{render:this.renderConsultTransfer,type:"consult_transfer"}].filter(({type:e})=>i.includes(e))}
|
|
663
|
-
<div style="display: flex; align-items: center; gap: 8px;" @click="${()=>e&&this.onChangeDevices(1)}">
|
|
664
|
-
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAjhJREFUaEPtmM1WwjAQhWeAF0I34kZ5MuDJqBtxo7wQEE9CkzNNk8yktIl4YKOHRvPl9s5PBuEOP3iHzPCALvXWxEq/HBfvGmp2AfPz8/m0LQXp78NCa1gEtQF1hbUfVLirBZ6EXh3neweL0CjAnVZaodpoeIW4/lqemtKKB6E76rawFM48V2oPCM1heV7/CWircMoCr9+LrVa8hk16SufArH7mqoZNboKuZZMetLXG4enMZhatsl1fMij/F7RUuZwYGCvLRJWWQDtPA4DUTmOARwORg6bApdNeD1qaEWy6Kw2s31QwQxigRLWr4eNO3xPyGJfGLDRnoTH8G/of8d5DqX0MijvUVLCuwwxtwPmae14FWm/K+bZW3xENRKtUCsweqkZ7muwvODBJCzuFVdimiAu6GvmaheZKdY3KyELToIz5Nxe8d1lGaPCCH9KLsgia9s2xsk3BU8HprzOeb2/60pZADC0Bp2tMagqMGULBawJ+pt6k8FnQUhu4rNOmDg1vBG3BYorSv0upngXd8XdESZvi9AHpjMSlPmbs4I8vQiOKbOgccP8Alxk00uFOqkYMgh4CPqTIxFrkwdAlwCeBdj0KmflJ0xanfKphu0lpunEnY2QWi+BFJDG9Gg3a2cXLtznBZ+G5tnhUaH9TqqDUNvSNxcYSk0B34Iny5vvWOnaNfhP6d5PTydrU/XNS6F6h8Q8QMnNgHu4vKwLtb2qrJf3eKi4pPlWguXTHPX9AcwqN9fwulf4FD/s5TOGFiLYAAAAASUVORK5CYII="}" width="16" alt="" /><span style="font-size: 14px">软电话</span>
|
|
665
|
-
</div>
|
|
666
|
-
`,2:xs`
|
|
667
|
-
<div style="display: flex; align-items: center; gap: 8px;" @click="${()=>e&&this.onChangeDevices(2)}">
|
|
668
|
-
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAWtJREFUaEPtWdFNAzEMdW6Ewgo3BzBOYYi2Q0DHKcxxK0BHaNA7cIVEVD0n8Uck31dVOfbLyzvn9JxkwCcNiFmqQd8fl8eWDX9u5/fa9WbQm9dlnyZ5yFmaQF8BZzmcX+a9ZQMm0HfH5QSwKcnKUr7Ih6XYv9gkO/yHfF/b+YnNRYMGw4IiFczcAlOTlwf9tmQUPz/P9BqWOZwgYlm2aQAbgO7Msm5KZccSQoFGp7hkOUF7SeTAMsjGZZEd3hUX0CyI2jgX0GC6uWMUdqQt1AX0kJoO0H9k4to9gulgutCS9HIJeYQ8Qh7cV0j0aeUpukdBMSGPkMeNRhLyCHmEPIibdujLJcyawgm7+R7T9GPz9nx8bTHSgNQpAev2u1wuYBWuKWt+q+fMxruBtnjIVqN8tZEN3jdl9a5MjzgJAHA9RvzWuUvrC6kzHHYKsNa2Fr0ybl1Ysnh/rWPX6VYHnF1SmJnuUrUxyZCgvwFf6/M9kuThSwAAAABJRU5ErkJggg=="}" width="16" alt="" /><span style="font-size: 14px">手机模式</span>
|
|
669
|
-
</div>
|
|
670
|
-
`,3:xs`
|
|
671
|
-
<div style="display: flex; align-items: center; gap: 8px;" @click="${()=>e&&this.onChangeDevices(3)}">
|
|
672
|
-
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAq5JREFUaEPtmWFywiAQhcEr6Als79F6LdsZdab1WsZ7tJ7AXiF0lmYzC9mFDUGrM/qrmrB8PB7LQq25w4+9Q2bzgL7WrD2UvhmlF8/vr865jXXueD7tt1PAIBZtf/76aPA7PKPf4Xf6Pn2WtMdiud46YzZ9R9Y2P9+fqxLw+dPbwTgXQNvZbIUw8+XaGRJ/0LcxkDV2IJwIHTSytuk7LADnAGDgCOFns20P8NvPae+ZuEFiGxaadtIHpqqPBPcqEsh4plLQg/6tbVhoqZNYfY1VKBC1AwUfBf03+PDDBQg6KFCcTjUoB/Hoos7ag9gT2g+hESphgbGKUygUAKcds4TK0x1TEbTvqEBxaANtMSOhXZJKg4edO5rZrMFMUwxdCk4zgyZ70BkhsxR5WmEPyeOphUbboBXqQTM5M7eZ4ELjVPHKdikviEM3kkSeVilNO5GUE5Xudqx4kANoZpHDO8Hi7GZcD41bbmYT4Tah3KzUeM7viEqL5GxRA5CLIdYe/a5IiprBtHczorFRzQHI0AqL9DvdyFpk6gDkKo9YRMoKuS1/KpzUXl1PSxbIVXCXAM+eEft0JVjgPzJIFjooLYU8rAWvdXTLQsc1hmgTcpzi1kDNo5sKmhY58LdYY0RnSqydnbUv9Lg25ejm+9culKAm1tbaUfAaR7dR0HGxTk/O3MC9HUDh7mOt3QVXBgX1uFia5pQvKf6lmKWx1PaQKruc4pcQoQg6ziipxZmDHsRSlATF0AOPJ+41aoNPgu7BndtgGpPqlLHgqTiToREm3jxK4TWVYzVozuddTvWXhjeptJhdME/DzRK5u4gHEd9CpQZaVekYRLothTQZvEuugDW2uih04Hdafwhe0R7brgIdWAf+G9C2weV6yjbc+K4OrVmQuXce0DmFaj2/S6V/Ae/pt8oTAp/jAAAAAElFTkSuQmCC"}" width="16" alt="" /><span style="font-size: 14px">SIP话机</span>
|
|
673
|
-
</div>
|
|
674
|
-
`}}async render(){const{displayText:e,answerDevice:t}=dt.getState(),{answer_devices:s}=fi.agentInfo,i=(s||"").split(","),r=this.getActionConfigs(),n={...wi},{statusColor:o}=n,a=document.querySelector("head");if(a){const e=xs`
|
|
661
|
+
`;Ys(i,this.modalRoot)}})}catch(e){ai(e)}}getActionConfigs(){const{show_satisfaction:e}=fi.agentInfo,t=dt.get("isHold"),s=dt.get("isMuted"),i=dt.get("actionConfigs").filter(i=>(0!==e||"satisfaction"!==i)&&(!(!t&&"unhold"===i)&&((!t||"hold"!==i)&&((!s||"mute"!==i)&&!(!s&&"unmute"===i)))));return[{render:this.renderCallPopover,type:"call_number"},{render:this.renderAnswer,type:"answer"},{render:this.renderReject,type:"reject"},{render:this.renderHangup,type:"hangup"},{render:this.renderDialer,type:"dtmf"},{render:this.renderUnhold,type:"unhold"},{render:this.renderHold,type:"hold"},{render:this.renderMute,type:"mute"},{render:this.renderUnmute,type:"unmute"},{render:this.renderSatisfaction,type:"satisfaction"},{render:this.renderConsult,type:"consult"},{render:this.renderTransfer,type:"transfer"},{render:this.renderConsultTransfer,type:"consult_transfer"}].filter(({type:e})=>i.includes(e))}async render(){const{displayText:e}=dt.getState(),{default_device:t,answer_devices:s,show_satisfaction:i}=fi.agentInfo,r=(s||"").split(","),n=this.getActionConfigs(),o={...wi},{statusColor:a}=o,c=document.querySelector("head");if(c){const e=xs`
|
|
675
662
|
<style>
|
|
676
663
|
.ysyt-phone-body {
|
|
677
|
-
background: ${
|
|
664
|
+
background: ${a[this.statusParams.state]};
|
|
678
665
|
}
|
|
679
666
|
.ysyt-action-body {
|
|
680
|
-
border-bottom: 1px solid ${
|
|
667
|
+
border-bottom: 1px solid ${a[this.statusParams.state]};
|
|
681
668
|
}
|
|
682
669
|
</style>
|
|
683
|
-
`;Ys(e,
|
|
670
|
+
`;Ys(e,c)}const h=xs`
|
|
684
671
|
<i class="ysyt icon-shang select-icon" style="${this.isOpenSelect?"display: block;":"display: none;"}"></i>
|
|
685
672
|
<div
|
|
686
673
|
class="ysyt-select"
|
|
@@ -697,21 +684,37 @@ const Xs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
697
684
|
`)}
|
|
698
685
|
</div>
|
|
699
686
|
</div>
|
|
700
|
-
`,
|
|
687
|
+
`,d=xs`
|
|
701
688
|
<div id="ysyt-body">
|
|
702
|
-
<div
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
689
|
+
<div id="ysyt-devices-body">
|
|
690
|
+
<my-select
|
|
691
|
+
width="100px"
|
|
692
|
+
value="${String(t)}"
|
|
693
|
+
placeholder=""
|
|
694
|
+
@change=${e=>this.onChangeDevices(Number(e.detail.value))}
|
|
695
|
+
>
|
|
696
|
+
${r.includes("1")?xs`
|
|
697
|
+
<select-option value="1">
|
|
698
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
699
|
+
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAjhJREFUaEPtmM1WwjAQhWeAF0I34kZ5MuDJqBtxo7wQEE9CkzNNk8yktIl4YKOHRvPl9s5PBuEOP3iHzPCALvXWxEq/HBfvGmp2AfPz8/m0LQXp78NCa1gEtQF1hbUfVLirBZ6EXh3neweL0CjAnVZaodpoeIW4/lqemtKKB6E76rawFM48V2oPCM1heV7/CWircMoCr9+LrVa8hk16SufArH7mqoZNboKuZZMetLXG4enMZhatsl1fMij/F7RUuZwYGCvLRJWWQDtPA4DUTmOARwORg6bApdNeD1qaEWy6Kw2s31QwQxigRLWr4eNO3xPyGJfGLDRnoTH8G/of8d5DqX0MijvUVLCuwwxtwPmae14FWm/K+bZW3xENRKtUCsweqkZ7muwvODBJCzuFVdimiAu6GvmaheZKdY3KyELToIz5Nxe8d1lGaPCCH9KLsgia9s2xsk3BU8HprzOeb2/60pZADC0Bp2tMagqMGULBawJ+pt6k8FnQUhu4rNOmDg1vBG3BYorSv0upngXd8XdESZvi9AHpjMSlPmbs4I8vQiOKbOgccP8Alxk00uFOqkYMgh4CPqTIxFrkwdAlwCeBdj0KmflJ0xanfKphu0lpunEnY2QWi+BFJDG9Gg3a2cXLtznBZ+G5tnhUaH9TqqDUNvSNxcYSk0B34Iny5vvWOnaNfhP6d5PTydrU/XNS6F6h8Q8QMnNgHu4vKwLtb2qrJf3eKi4pPlWguXTHPX9AcwqN9fwulf4FD/s5TOGFiLYAAAAASUVORK5CYII="}" width="16" alt="" /><span style="font-size: 14px">软电话</span>
|
|
700
|
+
</div>
|
|
701
|
+
</select-option>
|
|
702
|
+
`:""}
|
|
703
|
+
${r.includes("2")?xs`
|
|
704
|
+
<select-option value="2">
|
|
705
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
706
|
+
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAWtJREFUaEPtWdFNAzEMdW6Ewgo3BzBOYYi2Q0DHKcxxK0BHaNA7cIVEVD0n8Uck31dVOfbLyzvn9JxkwCcNiFmqQd8fl8eWDX9u5/fa9WbQm9dlnyZ5yFmaQF8BZzmcX+a9ZQMm0HfH5QSwKcnKUr7Ih6XYv9gkO/yHfF/b+YnNRYMGw4IiFczcAlOTlwf9tmQUPz/P9BqWOZwgYlm2aQAbgO7Msm5KZccSQoFGp7hkOUF7SeTAMsjGZZEd3hUX0CyI2jgX0GC6uWMUdqQt1AX0kJoO0H9k4to9gulgutCS9HIJeYQ8Qh7cV0j0aeUpukdBMSGPkMeNRhLyCHmEPIibdujLJcyawgm7+R7T9GPz9nx8bTHSgNQpAev2u1wuYBWuKWt+q+fMxruBtnjIVqN8tZEN3jdl9a5MjzgJAHA9RvzWuUvrC6kzHHYKsNa2Fr0ybl1Ysnh/rWPX6VYHnF1SmJnuUrUxyZCgvwFf6/M9kuThSwAAAABJRU5ErkJggg=="}" width="16" alt="" /><span style="font-size: 14px">手机模式</span>
|
|
707
|
+
</div>
|
|
708
|
+
</select-option>
|
|
709
|
+
`:""}
|
|
710
|
+
${r.includes("3")?xs`
|
|
711
|
+
<select-option value="3">
|
|
712
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
713
|
+
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAq5JREFUaEPtmWFywiAQhcEr6Als79F6LdsZdab1WsZ7tJ7AXiF0lmYzC9mFDUGrM/qrmrB8PB7LQq25w4+9Q2bzgL7WrD2UvhmlF8/vr865jXXueD7tt1PAIBZtf/76aPA7PKPf4Xf6Pn2WtMdiud46YzZ9R9Y2P9+fqxLw+dPbwTgXQNvZbIUw8+XaGRJ/0LcxkDV2IJwIHTSytuk7LADnAGDgCOFns20P8NvPae+ZuEFiGxaadtIHpqqPBPcqEsh4plLQg/6tbVhoqZNYfY1VKBC1AwUfBf03+PDDBQg6KFCcTjUoB/Hoos7ag9gT2g+hESphgbGKUygUAKcds4TK0x1TEbTvqEBxaANtMSOhXZJKg4edO5rZrMFMUwxdCk4zgyZ70BkhsxR5WmEPyeOphUbboBXqQTM5M7eZ4ELjVPHKdikviEM3kkSeVilNO5GUE5Xudqx4kANoZpHDO8Hi7GZcD41bbmYT4Tah3KzUeM7viEqL5GxRA5CLIdYe/a5IiprBtHczorFRzQHI0AqL9DvdyFpk6gDkKo9YRMoKuS1/KpzUXl1PSxbIVXCXAM+eEft0JVjgPzJIFjooLYU8rAWvdXTLQsc1hmgTcpzi1kDNo5sKmhY58LdYY0RnSqydnbUv9Lg25ejm+9culKAm1tbaUfAaR7dR0HGxTk/O3MC9HUDh7mOt3QVXBgX1uFia5pQvKf6lmKWx1PaQKruc4pcQoQg6ziipxZmDHsRSlATF0AOPJ+41aoNPgu7BndtgGpPqlLHgqTiToREm3jxK4TWVYzVozuddTvWXhjeptJhdME/DzRK5u4gHEd9CpQZaVekYRLothTQZvEuugDW2uih04Hdafwhe0R7brgIdWAf+G9C2weV6yjbc+K4OrVmQuXce0DmFaj2/S6V/Ae/pt8oTAp/jAAAAAElFTkSuQmCC"}" width="16" alt="" /><span style="font-size: 14px">SIP话机</span>
|
|
714
|
+
</div>
|
|
715
|
+
</select-option>
|
|
716
|
+
`:""}
|
|
717
|
+
</my-select>
|
|
715
718
|
</div>
|
|
716
719
|
<div class="ysyt-phone-body">
|
|
717
720
|
<div class="ysyt-title" @click="${this.toggle}">
|
|
@@ -724,14 +727,14 @@ const Xs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
724
727
|
<span>${t}</span>
|
|
725
728
|
`:void 0)(this.statusParams)}
|
|
726
729
|
<i class="ysyt icon-xia"></i>
|
|
727
|
-
${
|
|
730
|
+
${h}
|
|
728
731
|
`}
|
|
729
732
|
</div>
|
|
730
733
|
<timer-component id="my-timer"></timer-component>
|
|
731
734
|
</div>
|
|
732
|
-
<div class="ysyt-action-body">${
|
|
735
|
+
<div class="ysyt-action-body">${n.map(e=>e.render())}</div>
|
|
733
736
|
</div>
|
|
734
|
-
`;Ys(
|
|
737
|
+
`;Ys(d,this.container)}async renderRtt(e){const{outCallIsAnswer:t}=dt.getState(),s=e?.rtt||500,i=xs`
|
|
735
738
|
<my-popover triggerType="hover">
|
|
736
739
|
<div slot="trigger" id="wifi-body">
|
|
737
740
|
${s>=250?xs`<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAlVJREFUaEPtmGFuwyAMhU2PtU1qOVmbk5FKW4+1TCawkcQYG2i3aM2fqirBn83zc1IDO7zMDpnhCf2oU+teaefcKYW31o69k6mGTuDOAWoBmwGNCVwBYKxNSAUdQDWQkiIPuMhae5EsxjUi6ARWUk1pbGrdIIFnoZWwqXbx+NPrqJAQLmXhSWghLELGo1U1m3MuSiFKLXc6JPwGOmyY28yD1jYQRSZIYAP+DV2obnfYdQIF+EV8Dx2AHVGJu8Mq4X3VDSMHUSe3WAV3L8eF0BNxs9XoNpwU2mF0CdwSv6fDxIeRWFrkyYEjNMoi+q9YDkKHyRUT41wlCRBxhqhptCDRWC24S41aRDIMcT2jaCKGZsXESr6aQmM1NRNUBK8Z46mE1tWMumX9W+DHxUkYA7eMcbH+maFCnVxx3xI05SzFTTXCZnok62BZ6MxmYt11AM/G4qCxidIpqfJuDXSm0fWVTgz+pBk0E7wFx/gMn4fRwLv4KTC+EXExxZbHVW6ClwuAOQJMjMWZEWC6GriJ31ByMZug56pOZx6WDD20wFdDT/DqKmDTDKrBq6BnOVDTESXgZ5Z/owGIus5Jx4wGPqy2aWuhV/6NsGbgGm6Wkk9iMVAM3NQM6huwKj+V1jfX6pSqJFIFrT1Oaj1WXmOF6R6/Bt2S+N2gWypZSqg7NOEsVbrlwLtC560QuoL3hqYeZWfnrrC2u4zxdNPgw9R/J2HZwda6xRr+f1d6OXQ2B/t3NU2D1z1fPMw9thrHBpS/AJT8Of7eVdPSoK3rntCtFZTev8tKfwHUBxjzil9I5gAAAABJRU5ErkJggg=="}" alt="" />`:""}
|
|
@@ -771,4 +774,4 @@ const Xs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
771
774
|
`:""}
|
|
772
775
|
</div>
|
|
773
776
|
</my-popover>
|
|
774
|
-
`;Ys(i,this.rttHTML)}}const Oi=new class{constructor(){this.events={}}on(e,t){this.events[e]=this.events[e]||[],this.events[e].push(t)}off(e,t){this.events[e]=(this.events[e]||[]).filter(e=>e!==t)}emit(e,...t){(this.events[e]||[]).forEach(e=>e(...t))}};class qi{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const e=await navigator.mediaDevices.enumerateDevices();if(e.some(e=>"audioinput"===e.kind&&""!==e.label))return console.log("已授权麦克风权限,无需再次获取"),null;const t=await navigator.mediaDevices.getUserMedia({audio:!0});return console.log("获取音频权限成功"),t}catch(e){return console.warn("获取音频权限失败:",e),null}}static show(e,t,s){if("Notification"in window&&"granted"===Notification.permission){const i=new Notification(e,{body:t,tag:"xy-global-notification",renotify:!0});i.onclick=()=>{window.focus(),i.close(),s?.()},setTimeout(()=>i.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(e=>"audioinput"===e.kind&&""!==e.label)}catch(e){return console.warn("无法检查设备权限:",e),!1}}}let Li=null;class Ui{constructor(e){this.url=e,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Hi,this.initWebSocket()}static getInstance(e){if(!Li){if(!e)throw new Error("WebSocket 尚未初始化");Li=new Ui(e)}return Li}stateIdleChange(){const{state:e}=fi.stateObject;e!==et.IDLE&&this.apiClient.changeState({data:{state:et.IDLE,state_name:"空闲"}})}putAgentState(){fi.sessionId="";const{post_call_process_time:e}=fi.agentInfo,t=e||0;fi.autoStateTimer&&(clearTimeout(fi.autoStateTimer),fi.autoStateTimer=null),t>0?fi.autoStateTimer=setTimeout(()=>{fi.autoStateTimer=null,this.stateIdleChange()},t):this.stateIdleChange()}initWebSocket(){this.ws=new WebSocket(this.url),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&&console.warn(s),s===rt.OUT_CALL&&0!==r&&(ct.emit(it.OUT_FAILED,n),this.stateIdleChange()),s===rt.AGENT_STATE){const{state:e,state_name:t}=i;fi.stateObject={state:e,state_name:t},ct.emit(it.AGENT_STATE,{state:e,state_name:t})}s===rt.OUT_CALL_INCOMING_CALL&&(ct.emit(it.OUT_INCOMING_CALL,i),fi.sessionId=i.session_id,dt.updateActionConfigs(Ti)),s===rt.OUT_CALL_END&&(0===i.device_type||1===i.device_type?(this.putAgentState(),dt.reset(),ct.emit(it.OUT_HANGUP,i)):2===i.device_type&&(dt.get("direction")===tt.CONSULT?(dt.reset(),ct.emit(it.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState()):dt.get("isCalling")&&(dt.updateDisplayText(ot.CALLING),ct.emit(it.OTHER_SIDE_CONSULT_HANGUP,i),dt.updateActionConfigs(Si)))),s===rt.OUT_CALL_RINGING&&(ct.emit(it.OUT_RINGING,i),dt.updateDisplayText(ot.RINGING)),s===rt.OUT_CALL_ANSWER&&(ct.emit(it.OUT_OFF_ANSWER,i),dt.updateOutCallIsAnswer(!0),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Si)),s===rt.CONSULT_RINGING&&(ct.emit(it.CONSULT_RINGING,i),dt.updateDisplayText(ot.AGENT_RINGING),dt.updateActionConfigs([])),s===rt.CONSULT_ANSWER&&(ct.emit(it.CONSULT_OFF_HOOK,i),dt.updateConsultIsAnswer(!0),dt.updateDisplayText(ot.CONSULTING),dt.updateActionConfigs(Ci)),s===rt.CONSULT_FAIL&&(ct.emit(it.CONSULT_FAILED),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Si)),s===rt.CONSULT_CALL_IN&&(ct.emit(it.CONSULT_INCOMING,i),dt.updateIsCalling(!0),dt.updateDirection(tt.CONSULT),dt.updateDisplayText(ot.CONSULT_CALL_IN),dt.updateActionConfigs(Ai),fi.enableBrowserAlert&&qi.show("📞 咨询来电",`坐席 [${i.agent_name}] 正在咨询...`,()=>{ct.emit(nt.NOTIFICATION_CLICK,{agent_mane:i.agent_name})})),s===rt.CONSULT_CALL_IN_SUCCESS&&(fi.sessionId=i.session_id,ct.emit(it.CONSULT_CALL_IN_SUCCESS,i),dt.updateConsultIsAnswer(!0),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ei)),s===rt.MUTE&&(0===r?(dt.updateIsMuted(!0),ct.emit(it.MUTE_SUCCESS)):ct.emit(it.MUTE_FAILED,n)),s===rt.UNMUTE&&(0===r?(dt.updateIsMuted(!1),ct.emit(it.UNMUTE_SUCCESS)):ct.emit(it.UNMUTE_FAILED,n)),s===rt.CONSULT_TRANSFER&&(0===r?ct.emit(it.CONSULT_TRANSFER_SUCCESS):ct.emit(it.CONSULT_TRANSFER_FAILED,n)),s===rt.CONSULT_TRANSFER_FAILED&&ct.emit(it.CONSULT_TRANSFER_FAILED,i.status),s===rt.CONSULT_TRANSFER_OFF_HOOK&&(dt.updateDirection(tt.INCOMING),dt.updateDisplayText(ot.CALLING),ct.emit(it.CONSULT_TRANSFER_OFF_HOOK),dt.updateActionConfigs(_i),dt.updateIncomingIsAnswer(!0),dt.updateConsultIsAnswer(!1)),s===rt.INCOMING_CALL&&(fi.sessionId=i.session_id,dt.updateIsCalling(!0),dt.updateDirection(tt.INCOMING),dt.updateDisplayText(ot.INCOMING_CALL),ct.emit(it.INCOMING_CALL,{customer_phone:i.customer_phone}),dt.updateActionConfigs(Ai),fi.enableBrowserAlert&&qi.show("📞 客户来电",`客户 [${i.customer_phone}] 正在呼入...`,()=>{ct.emit(nt.NOTIFICATION_CLICK,{customer_phone:i.customer_phone})})),s===rt.INCOMING_CALL_OFF_HOOK&&(dt.updateIncomingIsAnswer(!0),ct.emit(it.INCOMING_CALL_OFF_HOOK),dt.updateActionConfigs(_i),dt.updateDisplayText(ot.CALLING)),s===rt.INCOMING_CALL_END&&(ct.emit(it.INCOMING_CALL_END),dt.reset(),dt.updateActionConfigs(yi),this.putAgentState()),0!==s&&Oi.emit("ws-message",t)},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const e=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"}),t=URL.createObjectURL(e);this.heartbeatWorker=new Worker(t),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(e){this.ws?.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify(e)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Li&&(Li.close(),Li=null)}static __internalSend(e){if(!Li)throw new Error("WebSocket 尚未初始化");Li.sendMessage(e)}}class Mi{#e=null;#t=new Hi;#s=null;#i=!1;#r;constructor(){clearInterval(this.#s),this.#s=setInterval(async()=>{const e=await this.#n();mi.updateRttObject(e)},2e3),qi.requestMediaPermissions(),window.addEventListener("beforeunload",()=>{this.destroy()}),this.#r=dt.subscribeKey("answerDevice",e=>{1===e&&this.initWebRtc()})}async initWebRtc(){const e=fi.agentInfo.sip_account_list.find(e=>1===e.device_type);if(e){const t=e.sip_register_addr;this.#e=new vi({server:t.split(":")[0],user:e.sip_account,password:e.sip_password,webSocket:`wss://${t}`,callTimeout:3e4},this.#o),await this.#e.start()}}async init({actionNodeParams:e,url:t,appKey:s,appSecret:i,agentNo:r,enableBrowserAlert:n}){try{const{viewHtmlElement:o,rttHTML:a}=e;li=t||"https://aicc-api.yescloudy.com",gi=s,ui=i;const c=jt(s,i);await this.#t._agentLogin(r);const{agent_no:h,current_answer_device:d,init_state:l}=fi.agentInfo;l===et.IDLE?(dt.updateActionConfigs(yi),fi.stateObject={state:l,state_name:"空闲"}):l===et.BUSY&&(dt.updateActionConfigs(bi),fi.stateObject={state:l,state_name:"忙碌"}),Ui.getInstance(`ws://112.90.183.54:8719/api/v1/ws/call/${h}?Authorization=${c}`),dt.updateAnswerDevice(d),1===d&&await this.initWebRtc(),e&&o&&(this.#i=!0,new Pi({container:o,rttHTML:a,statusParams:{state:et.IDLE,statusName:"空闲"}},this)),fi.enableBrowserAlert=n,n&&qi.requestPermission()}catch(e){this.#i&&ai("初始化失败"),console.log(e)}}#o=e=>{const{type:t,data:s}=e;ct.emit(t,s)};#a=e=>{};on(e,t){return ct.on(e,t),this}off(e,t){ct.off(e,t)}offAll(){ct.clearAllListeners()}#c(){if(!this.#e)throw new Error("请先初始化SDK");const e=dt.get("isCalling"),t=fi.sessionId;if(!e)throw new Error("当前没有通话");if(!t)throw new Error("sessionId不存在")}#h(){const e=dt.get("isHold"),{sessionId:t}=fi;if(t){if(e)throw new Error("当前已处于保持状态");Ui.__internalSend({type:rt.CALL_HOLD,data:{session_id:t}}),dt.updateDisplayText(ot.HOLD),dt.updateIsHold(!0)}}#d(){const{isHold:e}=dt.getState(),{sessionId:t}=fi;if(t){if(!e)throw new Error("当前未处于保持状态");Ui.__internalSend({type:rt.CALL_UNHOLD,data:{session_id:t}}),dt.updateDisplayText(""),dt.updateIsHold(!1)}}#l(e){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:t}=dt.getState();if(!t)throw new Error("当前没有通话");this.#e.sendDTMF(e)}#g(){if(1!==dt.get("answerDevice"))throw new Error("当前设备不支持此功能");if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:e,direction:t,outCallIsAnswer:s}=dt.getState();if(!e)throw new Error("当前没有通话");s||(t===tt.INCOMING?this.#u():t===tt.OUTGOING&&this.#p())}async#f(e){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:t,outCallIsAnswer:s,consultIsAnswer:i,incomingIsAnswer:r}=dt.getState(),n=fi.sessionId;if(i)throw new Error("当前正在咨询");if(!(t||s||r))throw new Error("当前没有通话");if(!n)throw new Error("sessionId不存在");Ui.__internalSend({type:rt.CONSULT_REQUEST,data:{session_id:n,consultation_agent_no:e}})}async#m(){if(1!==dt.get("answerDevice"))throw new Error("当前设备不支持此功能");if(!this.#e)throw new Error("请先初始化SDK");await this.#e.answerCall()}async#u(){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:e}=dt.getState();if(!e)throw new Error("当前没有通话");await this.#e.rejectInCall()}async#v(e){if(!this.#e)throw new Error("请先初始化SDK");if(dt.getState().isCalling)throw new Error("正在呼叫中,请勿重复点击");dt.updateIsCalling(!0),dt.updateDirection(tt.OUTGOING),Ui.__internalSend({type:rt.OUT_CALL,data:{customer_phone:e}})}async#p(){const{isCalling:e}=dt.getState();if(!this.#e)throw new Error("请先初始化SDK");if(!e)throw new Error("当前没有通话");await this.#e.rejectOutCall()}async#w(){if(!this.#e)throw new Error("请先初始化SDK");if(!dt.get("isCalling"))throw new Error("当前没有通话");await this.#e.hangup()}#y(){this.#c();const e=dt.get("actionConfigs"),t=dt.get("isMuted"),s=fi.sessionId;if(t)throw new Error("当前未处于静音状态");if(!e.includes("mute"))throw new Error("当前状态请勿调用静音");Ui.__internalSend({type:rt.MUTE,data:{session_id:s}})}#b(){this.#c();const e=dt.get("actionConfigs"),t=dt.get("isMuted"),s=fi.sessionId;if(!t)throw new Error("当前未处于未静音状态");if(!e.includes("unmute"))throw new Error("当前状态请勿调用静音");Ui.__internalSend({type:rt.UNMUTE,data:{session_id:s}})}#T(){this.#c();const e=dt.get("consultIsAnswer"),t=fi.sessionId;if(!dt.get("actionConfigs").includes("consult_transfer"))throw new Error("当前状态请勿调用咨询转移");if(!e)throw new Error("当前未处于咨询中");Ui.__internalSend({type:rt.CONSULT_TRANSFER,data:{session_id:t}})}async destroyRtc(){await(this.#e?.destroy())}destroy(){this.destroyRtc(),Oi.off("ws-message",this.#a),Ui.__internalClose(),this.offAll(),this.#r?.()}async#n(){return this.#e?this.#e.getNetworkStats():{}}get call_api(){return this.#i?{answerCall:this.#m.bind(this),makeCall:this.#v.bind(this),cancelCall:this.#g.bind(this),hangup:this.#w.bind(this),sendDTMF:this.#l.bind(this),holdCall:this.#h.bind(this),unholdCall:this.#d.bind(this),consultCall:async e=>{try{await this.#f(e)}catch(e){throw console.warn(e),e}},consultTransfer:this.#T.bind(this),mute:this.#y.bind(this),unmute:this.#b.bind(this)}:{}}get agent_api(){return this.#i?{changeDevice:this.#t.changeDevice.bind(this.#t),changeState:this.#t.changeState.bind(this.#t),getIdleAgentList:e=>this.#t.getIdleAgentList(e),getAgentState:e=>this.#t.getAgentState(e)}:{}}}export{Mi as default};
|
|
777
|
+
`;Ys(i,this.rttHTML)}}const Oi=new class{constructor(){this.events={}}on(e,t){this.events[e]=this.events[e]||[],this.events[e].push(t)}off(e,t){this.events[e]=(this.events[e]||[]).filter(e=>e!==t)}emit(e,...t){(this.events[e]||[]).forEach(e=>e(...t))}};class qi{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const e=await navigator.mediaDevices.enumerateDevices();if(e.some(e=>"audioinput"===e.kind&&""!==e.label))return console.log("已授权麦克风权限,无需再次获取"),null;const t=await navigator.mediaDevices.getUserMedia({audio:!0});return console.log("获取音频权限成功"),t}catch(e){return console.warn("获取音频权限失败:",e),null}}static show(e,t,s){if("Notification"in window&&"granted"===Notification.permission){const i=new Notification(e,{body:t,tag:"xy-global-notification",renotify:!0});i.onclick=()=>{window.focus(),i.close(),s?.()},setTimeout(()=>i.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(e=>"audioinput"===e.kind&&""!==e.label)}catch(e){return console.warn("无法检查设备权限:",e),!1}}}let Li=null;class Ui{constructor(e){this.url=e,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Hi,this.initWebSocket()}static getInstance(e){if(!Li){if(!e)throw new Error("WebSocket 尚未初始化");Li=new Ui(e)}return Li}stateIdleChange(){const{state:e}=fi.stateObject;e!==et.IDLE&&this.apiClient.changeState({data:{state:et.IDLE,state_name:"空闲"}})}putAgentState(){fi.sessionId="";const{post_call_process_time:e}=fi.agentInfo,t=e||0;fi.autoStateTimer&&(clearTimeout(fi.autoStateTimer),fi.autoStateTimer=null),t>0?fi.autoStateTimer=setTimeout(()=>{fi.autoStateTimer=null,this.stateIdleChange()},t):this.stateIdleChange()}initWebSocket(){this.ws=new WebSocket(this.url),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&&console.warn(s),s===rt.OUT_CALL&&0!==r&&(ct.emit(it.OUT_FAILED,n),this.stateIdleChange()),s===rt.AGENT_STATE){const{state:e,state_name:t}=i;fi.stateObject={state:e,state_name:t},ct.emit(it.AGENT_STATE,{state:e,state_name:t})}s===rt.OUT_CALL_INCOMING_CALL&&(ct.emit(it.OUT_INCOMING_CALL,i),fi.sessionId=i.session_id,dt.updateActionConfigs(Ti)),s===rt.OUT_CALL_END&&(0===i.device_type||1===i.device_type?(this.putAgentState(),dt.reset(),ct.emit(it.OUT_HANGUP,i)):2===i.device_type&&(dt.get("direction")===tt.CONSULT?(dt.reset(),ct.emit(it.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState()):dt.get("isCalling")&&(dt.updateDisplayText(ot.CALLING),ct.emit(it.OTHER_SIDE_CONSULT_HANGUP,i),dt.updateActionConfigs(Si)))),s===rt.OUT_CALL_RINGING&&(ct.emit(it.OUT_RINGING,i),dt.updateDisplayText(ot.RINGING)),s===rt.OUT_CALL_ANSWER&&(ct.emit(it.OUT_OFF_ANSWER,i),dt.updateOutCallIsAnswer(!0),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Si)),s===rt.CONSULT_RINGING&&(ct.emit(it.CONSULT_RINGING,i),dt.updateDisplayText(ot.AGENT_RINGING),dt.updateActionConfigs([])),s===rt.CONSULT_ANSWER&&(ct.emit(it.CONSULT_OFF_HOOK,i),dt.updateConsultIsAnswer(!0),dt.updateDisplayText(ot.CONSULTING),dt.updateActionConfigs(Ci)),s===rt.CONSULT_FAIL&&(ct.emit(it.CONSULT_FAILED),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Si)),s===rt.CONSULT_CALL_IN&&(ct.emit(it.CONSULT_INCOMING,i),dt.updateIsCalling(!0),dt.updateDirection(tt.CONSULT),dt.updateDisplayText(ot.CONSULT_CALL_IN),dt.updateActionConfigs(Ai),fi.enableBrowserAlert&&qi.show("📞 咨询来电",`坐席 [${i.agent_name}] 正在咨询...`,()=>{ct.emit(nt.NOTIFICATION_CLICK,{agent_mane:i.agent_name})})),s===rt.CONSULT_CALL_IN_SUCCESS&&(fi.sessionId=i.session_id,ct.emit(it.CONSULT_CALL_IN_SUCCESS,i),dt.updateConsultIsAnswer(!0),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ei)),s===rt.MUTE&&(0===r?(dt.updateIsMuted(!0),ct.emit(it.MUTE_SUCCESS)):ct.emit(it.MUTE_FAILED,n)),s===rt.UNMUTE&&(0===r?(dt.updateIsMuted(!1),ct.emit(it.UNMUTE_SUCCESS)):ct.emit(it.UNMUTE_FAILED,n)),s===rt.CONSULT_TRANSFER&&(0===r?ct.emit(it.CONSULT_TRANSFER_SUCCESS):ct.emit(it.CONSULT_TRANSFER_FAILED,n)),s===rt.CONSULT_TRANSFER_FAILED&&ct.emit(it.CONSULT_TRANSFER_FAILED,i.status),s===rt.CONSULT_TRANSFER_OFF_HOOK&&(dt.updateDirection(tt.INCOMING),dt.updateDisplayText(ot.CALLING),ct.emit(it.CONSULT_TRANSFER_OFF_HOOK),dt.updateActionConfigs(_i),dt.updateIncomingIsAnswer(!0),dt.updateConsultIsAnswer(!1)),s===rt.INCOMING_CALL&&(fi.sessionId=i.session_id,dt.updateIsCalling(!0),dt.updateDirection(tt.INCOMING),dt.updateDisplayText(ot.INCOMING_CALL),ct.emit(it.INCOMING_CALL,{customer_phone:i.customer_phone}),dt.updateActionConfigs(Ai),fi.enableBrowserAlert&&qi.show("📞 客户来电",`客户 [${i.customer_phone}] 正在呼入...`,()=>{ct.emit(nt.NOTIFICATION_CLICK,{customer_phone:i.customer_phone})})),s===rt.INCOMING_CALL_OFF_HOOK&&(dt.updateIncomingIsAnswer(!0),ct.emit(it.INCOMING_CALL_OFF_HOOK),dt.updateActionConfigs(_i),dt.updateDisplayText(ot.CALLING)),s===rt.INCOMING_CALL_END&&(ct.emit(it.INCOMING_CALL_END),dt.reset(),dt.updateActionConfigs(yi),this.putAgentState()),0!==s&&Oi.emit("ws-message",t)},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const e=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"}),t=URL.createObjectURL(e);this.heartbeatWorker=new Worker(t),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(e){this.ws?.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify(e)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){Li&&(Li.close(),Li=null)}static __internalSend(e){if(!Li)throw new Error("WebSocket 尚未初始化");Li.sendMessage(e)}}class Mi{#e=null;#t=new Hi;#s=null;#i=!1;#r;constructor(){clearInterval(this.#s),this.#s=setInterval(async()=>{const e=await this.#n();mi.updateRttObject(e)},2e3),qi.requestMediaPermissions(),window.addEventListener("beforeunload",()=>{this.destroy()}),this.#r=dt.subscribeKey("answerDevice",e=>{1===e&&this.initWebRtc()})}async initWebRtc(){const e=fi.agentInfo.sip_account_list.find(e=>1===e.device_type);if(e){const t=e.sip_register_addr;this.#e=new vi({server:t.split(":")[0],user:e.sip_account,password:e.sip_password,webSocket:`wss://${t}`,callTimeout:3e4},this.#o),await this.#e.start()}}async init({actionNodeParams:e,url:t,appKey:s,appSecret:i,agentNo:r,enableBrowserAlert:n}){try{const{viewHtmlElement:o,rttHTML:a}=e;li=t||"https://aicc-api.yescloudy.com",gi=s,ui=i;const c=jt(s,i);await this.#t._agentLogin(r);const{agent_no:h,current_answer_device:d,init_state:l}=fi.agentInfo;l===et.IDLE?(dt.updateActionConfigs(yi),fi.stateObject={state:l,state_name:"空闲"}):l===et.BUSY&&(dt.updateActionConfigs(bi),fi.stateObject={state:l,state_name:"忙碌"}),Ui.getInstance(`ws://112.90.183.54:8719/api/v1/ws/call/${h}?Authorization=${c}`),dt.updateAnswerDevice(d),1===d&&await this.initWebRtc(),e&&o&&(this.#i=!0,new Pi({container:o,rttHTML:a,statusParams:{state:et.IDLE,statusName:"空闲"}},this)),fi.enableBrowserAlert=n,n&&qi.requestPermission()}catch(e){this.#i&&ai("初始化失败"),console.log(e)}}#o=e=>{const{type:t,data:s}=e;ct.emit(t,s)};#a=e=>{};on(e,t){return ct.on(e,t),this}off(e,t){ct.off(e,t)}offAll(){ct.clearAllListeners()}#c(){if(!this.#e)throw new Error("请先初始化SDK");const e=dt.get("isCalling"),t=fi.sessionId;if(!e)throw new Error("当前没有通话");if(!t)throw new Error("sessionId不存在")}#h(){const e=dt.get("isHold"),{sessionId:t}=fi;if(t){if(e)throw new Error("当前已处于保持状态");Ui.__internalSend({type:rt.CALL_HOLD,data:{session_id:t}}),dt.updateDisplayText(ot.HOLD),dt.updateIsHold(!0)}}#d(){const{isHold:e}=dt.getState(),{sessionId:t}=fi;if(t){if(!e)throw new Error("当前未处于保持状态");Ui.__internalSend({type:rt.CALL_UNHOLD,data:{session_id:t}}),dt.updateDisplayText(""),dt.updateIsHold(!1)}}#l(e){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:t}=dt.getState();if(!t)throw new Error("当前没有通话");this.#e.sendDTMF(e)}#g(){if(1!==dt.get("answerDevice"))throw new Error("当前设备不支持此功能");if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:e,direction:t,outCallIsAnswer:s}=dt.getState();if(!e)throw new Error("当前没有通话");s||(t===tt.INCOMING?this.#u():t===tt.OUTGOING&&this.#p())}async#f(e){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:t,outCallIsAnswer:s,consultIsAnswer:i,incomingIsAnswer:r}=dt.getState(),n=fi.sessionId;if(i)throw new Error("当前正在咨询");if(!(t||s||r))throw new Error("当前没有通话");if(!n)throw new Error("sessionId不存在");Ui.__internalSend({type:rt.CONSULT_REQUEST,data:{session_id:n,consultation_agent_no:e}})}async#m(){if(1!==dt.get("answerDevice"))throw new Error("当前设备不支持此功能");if(!this.#e)throw new Error("请先初始化SDK");await this.#e.answerCall()}async#u(){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:e}=dt.getState();if(!e)throw new Error("当前没有通话");await this.#e.rejectInCall()}async#v(e){if(!this.#e)throw new Error("请先初始化SDK");if(dt.getState().isCalling)throw new Error("正在呼叫中,请勿重复点击");dt.updateIsCalling(!0),dt.updateDirection(tt.OUTGOING),Ui.__internalSend({type:rt.OUT_CALL,data:{customer_phone:e}})}async#p(){const{isCalling:e}=dt.getState();if(!this.#e)throw new Error("请先初始化SDK");if(!e)throw new Error("当前没有通话");await this.#e.rejectOutCall()}async#w(){if(!this.#e)throw new Error("请先初始化SDK");if(!dt.get("isCalling"))throw new Error("当前没有通话");await this.#e.hangup()}#y(){this.#c();const e=dt.get("actionConfigs"),t=dt.get("isMuted"),s=fi.sessionId;if(t)throw new Error("当前未处于静音状态");if(!e.includes("mute"))throw new Error("当前状态请勿调用静音");Ui.__internalSend({type:rt.MUTE,data:{session_id:s}})}#b(){this.#c();const e=dt.get("actionConfigs"),t=dt.get("isMuted"),s=fi.sessionId;if(!t)throw new Error("当前未处于未静音状态");if(!e.includes("unmute"))throw new Error("当前状态请勿调用静音");Ui.__internalSend({type:rt.UNMUTE,data:{session_id:s}})}#T(){this.#c();const e=dt.get("consultIsAnswer"),t=fi.sessionId;if(!dt.get("actionConfigs").includes("consult_transfer"))throw new Error("当前状态请勿调用咨询转移");if(!e)throw new Error("当前未处于咨询中");Ui.__internalSend({type:rt.CONSULT_TRANSFER,data:{session_id:t}})}async destroyRtc(){await(this.#e?.destroy())}destroy(){this.destroyRtc(),clearInterval(this.#s),Oi.off("ws-message",this.#a),Ui.__internalClose(),this.offAll(),this.#r?.()}async#n(){return this.#e?this.#e.getNetworkStats():{}}get call_api(){return this.#i?{answerCall:this.#m.bind(this),makeCall:this.#v.bind(this),cancelCall:this.#g.bind(this),hangup:this.#w.bind(this),sendDTMF:this.#l.bind(this),holdCall:this.#h.bind(this),unholdCall:this.#d.bind(this),consultCall:async e=>{try{await this.#f(e)}catch(e){throw console.warn(e),e}},consultTransfer:this.#T.bind(this),mute:this.#y.bind(this),unmute:this.#b.bind(this)}:{}}get agent_api(){return this.#i?{changeDevice:this.#t.changeDevice.bind(this.#t),changeState:this.#t.changeState.bind(this.#t),getIdleAgentList:e=>this.#t.getIdleAgentList(e),getAgentState:e=>this.#t.getAgentState(e)}:{}}}export{Mi as default};
|
|
@@ -110,7 +110,7 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
110
110
|
:host([type='loading']) {
|
|
111
111
|
background: #595959;
|
|
112
112
|
}
|
|
113
|
-
`}connectedCallback(){super.connectedCallback(),setTimeout(()=>{this.remove()},this.duration+300)}render(){return Ds`<div>${this.content}</div>`}};jt([ei({type:String})],ii.prototype,"type",void 0),jt([ei({type:String})],ii.prototype,"content",void 0),jt([ei({type:Number})],ii.prototype,"duration",void 0),ii=jt([Zs("my-message")],ii);const ri=(e,t,s=3e3)=>{let i=document.querySelector("#message-container");i||(i=document.createElement("div"),i.id="message-container",Object.assign(i.style,{position:"fixed",top:"14px",left:"50%",transform:"translateX(-50%)",zIndex:"9999"}),document.body.appendChild(i));const r=document.createElement("my-message");r.setAttribute("type",e),r.setAttribute("content",t),r.setAttribute("duration",String(s)),r.style.setProperty("--fade-delay",s/1e3+"s"),i.appendChild(r)},ni=(e,t=3e3)=>ri("success",e,t),oi=(e,t=3e3)=>ri("error",e,t),ai=(e,t=3e3)=>ri("warning",e,t),ci="/v1/aicc/bmserver",hi="/v1/aicc/ccs";let di="",li="",gi="";async function ui(e,t){const s=function(){const e=Ft(li,gi);return qt.create({prefixUrl:`${di}/api`,timeout:!1,headers:{Authorization:e},hooks:{afterResponse:[async(e,t,s)=>{const i=await s.clone().json();if(0!==i.code)throw oi(i.msg),new Error(JSON.stringify(i)||"请求失败");return s.json=async()=>i,s}]}})}(),i=e.replace(/^\/+/,"");return s.post(i,{json:t}).json()}const pi={agentInfo:{},isRtcReconnecting:!1,sessionId:"",enableBrowserAlert:!1,autoStateTimer:null};const fi=new class extends Qe{updateRttObject(e){this.setState({rttObject:e})}}({rttObject:{rtt:null,jitter:null,packetsLost:null,packetsReceived:null,packetsSent:null,sendBitrate:null,recvBitrate:null,codec:null}});class mi{constructor(e,t){this.config=e,this.eventCallback=t,this.userAgent=null,this.registerer=null,this.activeSession=null,this.callTimeoutTimer=null,this.incomingInvitation=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectTimer=null,this.isOffline=!1,this.autoAnswerTimer=null,this.handleMessage=e=>{},this.handleNetworkInfoChange=e=>{0===(e.rttObject?.rtt||0)?this.isOffline||(this.isOffline=!0,this.handleOffline()):this.isOffline&&(this.isOffline=!1,this.handleOnline())},this.handleOffline=()=>{console.warn("[SIPClient] 网络断开,准备销毁 SIP 客户端",(new Date).toLocaleString())
|
|
113
|
+
`}connectedCallback(){super.connectedCallback(),setTimeout(()=>{this.remove()},this.duration+300)}render(){return Ds`<div>${this.content}</div>`}};jt([ei({type:String})],ii.prototype,"type",void 0),jt([ei({type:String})],ii.prototype,"content",void 0),jt([ei({type:Number})],ii.prototype,"duration",void 0),ii=jt([Zs("my-message")],ii);const ri=(e,t,s=3e3)=>{let i=document.querySelector("#message-container");i||(i=document.createElement("div"),i.id="message-container",Object.assign(i.style,{position:"fixed",top:"14px",left:"50%",transform:"translateX(-50%)",zIndex:"9999"}),document.body.appendChild(i));const r=document.createElement("my-message");r.setAttribute("type",e),r.setAttribute("content",t),r.setAttribute("duration",String(s)),r.style.setProperty("--fade-delay",s/1e3+"s"),i.appendChild(r)},ni=(e,t=3e3)=>ri("success",e,t),oi=(e,t=3e3)=>ri("error",e,t),ai=(e,t=3e3)=>ri("warning",e,t),ci="/v1/aicc/bmserver",hi="/v1/aicc/ccs";let di="",li="",gi="";async function ui(e,t){const s=function(){const e=Ft(li,gi);return qt.create({prefixUrl:`${di}/api`,timeout:!1,headers:{Authorization:e},hooks:{afterResponse:[async(e,t,s)=>{const i=await s.clone().json();if(0!==i.code)throw oi(i.msg),new Error(JSON.stringify(i)||"请求失败");return s.json=async()=>i,s}]}})}(),i=e.replace(/^\/+/,"");return s.post(i,{json:t}).json()}const pi={agentInfo:{},isRtcReconnecting:!1,sessionId:"",enableBrowserAlert:!1,autoStateTimer:null};const fi=new class extends Qe{updateRttObject(e){this.setState({rttObject:e})}}({rttObject:{rtt:null,jitter:null,packetsLost:null,packetsReceived:null,packetsSent:null,sendBitrate:null,recvBitrate:null,codec:null}});class mi{constructor(e,t){this.config=e,this.eventCallback=t,this.userAgent=null,this.registerer=null,this.activeSession=null,this.callTimeoutTimer=null,this.incomingInvitation=null,this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.reconnectTimer=null,this.isOffline=!1,this.autoAnswerTimer=null,this.handleMessage=e=>{},this.handleNetworkInfoChange=e=>{0===(e.rttObject?.rtt||0)?this.isOffline||(this.isOffline=!0,this.handleOffline()):this.isOffline&&(this.isOffline=!1,this.handleOnline())},this.handleOffline=()=>{console.warn("[SIPClient] 网络断开,准备销毁 SIP 客户端",(new Date).toLocaleString())},this.handleOnline=()=>{console.warn("[SIPClient] 网络恢复,准备重新启动 SIP 客户端",(new Date).toLocaleString())},fi.subscribe(this.handleNetworkInfoChange)}async start(){const e=Xe.makeURI(`sip:${this.config.user}@${this.config.server}`);if(!e)throw new Error("无效的SIP配置");const t={uri:e,authorizationUsername:this.config.user,authorizationPassword:this.config.password,transportOptions:{server:this.config.webSocket,connectionTimeout:30,keepAliveInterval:0},sessionDescriptionHandlerFactoryOptions:{alwaysAcquireMediaFirst:!0,peerConnectionConfiguration:{iceServers:[]},iceGatheringTimeout:400},logBuiltinEnabled:!1};this.userAgent=new Xe(t),this.setupEventListeners(),await this.userAgent.start(),await this.register()}setupEventListeners(){this.userAgent&&(this.userAgent.transport.stateChange.addListener(e=>{let t;switch(e){case ee.Connecting:t=st.WEB_RTC_CONNECTING;break;case ee.Connected:t=st.WEB_RTC_CONNECTED,this.reconnectAttempts=0,pi.isRtcReconnecting=!1,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null);break;case ee.Disconnecting:t=st.WEB_RTC_DISCONNECTING;break;case ee.Disconnected:{t=st.WEB_RTC_DISCONNECTED;const e=dt.get("answerDevice");if(!pi.isRtcReconnecting&&this.reconnectAttempts<this.maxReconnectAttempts&&1===e){this.reconnectAttempts++;const e=1e3*this.reconnectAttempts;console.warn(`SIP WebSocket 断开,第 ${this.reconnectAttempts} 次尝试重连,${e}ms 后重试...`),this.reconnectTimer=setTimeout(()=>{this.reconnect()},e)}else this.reconnectAttempts>=this.maxReconnectAttempts&&console.error("SIP 重连失败:已达到最大重试次数");break}default:t="unknown"}this.eventCallback?.({type:t})}),this.userAgent.transport.stateChange.addListener(e=>{}),this.userAgent.delegate={onInvite:e=>{this.handleIncomingCall(e)}})}async register(){if(this.userAgent){this.registerer=new ne(this.userAgent),this.registerer?.stateChange.addListener(e=>{let t;switch(e){case X.Initial:t="initial";break;case X.Registered:t=st.WEB_RTC_REGISTERED;break;case X.Unregistered:t=st.WEB_RTC_UNREGISTERED;break;case X.Terminated:t=st.WEB_RTC_TERMINATED;break;default:t="unknown"}this.eventCallback?.({type:t})});try{await this.registerer.register()}catch(e){this.eventCallback?.({type:st.WEB_RTC_REGISTER_FAILED,data:e})}}}attachRemoteAudio(e){const t=e.sessionDescriptionHandler;if(t){const e=t.peerConnection;if(!e)return;const s=new MediaStream;e.getReceivers().forEach(e=>{e.track&&"audio"===e.track.kind&&s.addTrack(e.track)});let i=document.getElementById("sip-remote-audio");i||(i=document.createElement("audio"),i.id="sip-remote-audio",i.autoplay=!0,i.style.display="none",document.body.appendChild(i)),i.srcObject=s,i.play().catch(e=>{console.error("音频播放失败,需要用户交互触发",e)})}}handleSessionState(e,t,s){e.stateChange.addListener(t=>{switch(t){case K.Established:clearTimeout(this.callTimeoutTimer),this.activeSession=e,this.attachRemoteAudio(e);break;case K.Terminating:break;case K.Terminated:this.activeSession=null,clearTimeout(this.callTimeoutTimer);case K.Establishing:}})}handleIncomingCall(e){this.incomingInvitation=e,this.handleSessionState(e,!1);const{soft_device_auto_answer:t,auto_answer_time:s}=pi.agentInfo,i=dt.get("direction"),r=1===t;if(i===tt.OUTGOING)this.answerCall();else if(r&&i===tt.INCOMING){const e=Number(s)||0;e>0?this.autoAnswerTimer=setTimeout(()=>{this.answerCall(),this.autoAnswerTimer=null},e):this.answerCall()}}async makeCall(e){if(dt.getState().isCalling)throw new Error("正在呼叫中,请勿重复点击");if(!this.userAgent)throw dt.updateIsCalling(!1),dt.updateDirection(null),new Error("SIP客户端未初始化");dt.updateIsCalling(!0),dt.updateDirection(tt.OUTGOING);const t=Xe.makeURI(`sip:${e}@${this.config.server}`);if(!t)throw new Error("无效的被叫号码");const s=new Z(this.userAgent,t);this.handleSessionState(s,!0,e);try{this.activeSession=s,await s.invite(),this.config.callTimeout&&(this.callTimeoutTimer=setTimeout(()=>{s.state!==K.Established&&(this.hangup(),this.eventCallback?.({type:"error",data:{message:"呼叫超时未接通"}}))},this.config.callTimeout))}catch(e){this.eventCallback?.({type:"error",data:{message:"呼叫失败",detail:e}}),dt.updateIsCalling(!1),dt.updateDirection(null)}}async answerCall(){if(!this.incomingInvitation)throw new Error("无来电可接听");this.autoAnswerTimer&&(clearTimeout(this.autoAnswerTimer),this.autoAnswerTimer=null);try{console.log((new Date).toLocaleString()),await this.incomingInvitation.accept(),console.log((new Date).toLocaleString()),this.activeSession=this.incomingInvitation,this.incomingInvitation=null}catch(e){this.eventCallback?.({type:st.WEB_RTC_ANSWER_FAILED,data:{detail:e}})}}async rejectInCall(){if(this.incomingInvitation)try{await this.incomingInvitation.reject(),this.incomingInvitation=null,dt.updateDirection(null),dt.updateIsCalling(!1),clearTimeout(this.callTimeoutTimer)}catch(e){this.eventCallback?.({type:"error",data:{message:"拒接失败",detail:e}})}}sendDTMF(e){if(!this.activeSession)throw new Error("当前没有活跃的通话");const t=this.activeSession.sessionDescriptionHandler;t&&"function"==typeof t.sendDtmf?(t.sendDtmf(e),this.eventCallback?.({type:st.WEB_RTC_SEND_DTMF,data:{tone:e}})):console.warn("DTMF发送不支持或未初始化")}async hangup(){if(this.activeSession){clearTimeout(this.callTimeoutTimer);const e=this.activeSession;if(!e)return;const t=e.state;try{t===K.Established?await e.bye():t===K.Establishing&&(e instanceof Z?await e.cancel():e instanceof J&&await e.reject()),clearTimeout(this.callTimeoutTimer)}catch(e){console.error("挂断失败",e)}finally{this.activeSession=null}}}async rejectOutCall(){this.activeSession instanceof J&&(await this.activeSession.reject(),this.activeSession=null)}async destroy(){if(clearTimeout(this.callTimeoutTimer),this.activeSession&&await this.hangup(),this.registerer){try{await this.registerer.unregister()}catch(e){console.warn("注销失败",e)}this.registerer=null}this.userAgent&&(await this.userAgent.stop(),this.userAgent=null)}async reconnect(){if(!pi.isRtcReconnecting){pi.isRtcReconnecting=!0;try{await this.destroy(),await this.start(),console.log("重连成功"),this.isOffline=!1}catch(e){console.error("重连失败",e)}finally{pi.isRtcReconnecting=!1}}}async getNetworkStats(){if(this.activeSession){const e=this.activeSession.sessionDescriptionHandler?.peerConnection;if(!e)return null;const t=await e.getStats(),s={};return t.forEach(e=>{"candidate-pair"===e.type&&"succeeded"===e.state&&null!=e.currentRoundTripTime&&(s.rtt=+(1e3*e.currentRoundTripTime).toFixed(2)),"inbound-rtp"===e.type&&"audio"===e.kind&&(s.jitter=+(1e3*e.jitter).toFixed(2),s.packetsLost=e.packetsLost,s.packetsReceived=e.packetsReceived,e.bytesReceived&&e.timestamp&&(s.recvBitrate=+(e.bytesReceived/1024).toFixed(2))),"outbound-rtp"===e.type&&"audio"===e.kind&&(s.packetsSent=e.packetsSent,e.bytesSent&&e.timestamp&&(s.sendBitrate=+(e.bytesSent/1024).toFixed(2))),"codec"===e.type&&e.mimeType&&(s.codec=e.mimeType)}),{...s,rtt:s?.rtt||40}}try{const e=Date.now();await ui(`${ci}/config/ping`,{});const t=Date.now();return{rtt:t-e||1}}catch(e){console.log(e)}}}const vi={statusColor:{[et.IDLE]:"#1D92E9",[et.BUSY]:"#F5212D",[et.OFFLINE]:"#8c8c8c",[et.RINGING]:"#e9b91d"}},wi=["call_number"],yi=[],bi=["hangup"],Ti=["hold","hangup","unhold","mute","unmute","transfer","consult","satisfaction","dtmf"],Si=["consult_transfer"],Ci=["hangup"],Ei=["answer","reject"],Ai=["hangup","consult","transfer","hold","unhold","mute","unmute","satisfaction","dtmf"];let _i=class extends zs{static{this.styles=Yt`
|
|
114
114
|
.timer-text {
|
|
115
115
|
width: 70px;
|
|
116
116
|
font-size: 14px;
|
|
@@ -173,6 +173,7 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
173
173
|
|
|
174
174
|
.trigger {
|
|
175
175
|
display: inline-block;
|
|
176
|
+
cursor: pointer;
|
|
176
177
|
}
|
|
177
178
|
|
|
178
179
|
.popover {
|
|
@@ -187,6 +188,8 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
187
188
|
opacity 0.2s ease,
|
|
188
189
|
transform 0.2s ease;
|
|
189
190
|
pointer-events: none;
|
|
191
|
+
min-width: 100px;
|
|
192
|
+
padding: 0px;
|
|
190
193
|
}
|
|
191
194
|
|
|
192
195
|
.popover.visible {
|
|
@@ -216,7 +219,6 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
216
219
|
|
|
217
220
|
.arrow[data-placement='top'] {
|
|
218
221
|
bottom: -6px;
|
|
219
|
-
left: 10px;
|
|
220
222
|
border-width: 6px 6px 0 6px;
|
|
221
223
|
border-color: #fff transparent transparent transparent;
|
|
222
224
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
|
|
@@ -224,26 +226,23 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
224
226
|
|
|
225
227
|
.arrow[data-placement='bottom'] {
|
|
226
228
|
top: -6px;
|
|
227
|
-
left: 10px;
|
|
228
229
|
border-width: 0 6px 6px 6px;
|
|
229
230
|
border-color: transparent transparent #fff transparent;
|
|
230
231
|
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.05);
|
|
231
232
|
}
|
|
232
233
|
|
|
233
234
|
.arrow[data-placement='left'] {
|
|
234
|
-
top: 10px;
|
|
235
235
|
right: -6px;
|
|
236
236
|
border-width: 6px 0 6px 6px;
|
|
237
237
|
border-color: transparent transparent transparent #fff;
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
.arrow[data-placement='right'] {
|
|
241
|
-
top: 10px;
|
|
242
241
|
left: -6px;
|
|
243
242
|
border-width: 6px 6px 6px 0;
|
|
244
243
|
border-color: transparent #fff transparent transparent;
|
|
245
244
|
}
|
|
246
|
-
`}firstUpdated(){this.triggerEl=this.renderRoot.querySelector(".trigger"),this.popoverEl=this.renderRoot.querySelector(".popover"),"click"===this.triggerType?(this.triggerEl.addEventListener("click",this.onTogglePopover),document.addEventListener("click",this.onOutsideClick)):(this.triggerEl.addEventListener("mouseenter",this.showPopover),this.triggerEl.addEventListener("mouseleave",this.hidePopoverDelayed),this.popoverEl.addEventListener("mouseenter",this.clearHideTimer),this.popoverEl.addEventListener("mouseleave",this.hidePopoverDelayed))}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.onOutsideClick)}updatePosition(){const e=this.triggerEl.getBoundingClientRect(),t=this.popoverEl;let s=0,i=0;switch(this.placement){case"top":s=e.top-t.offsetHeight-8,i=e.left;break;case"bottom":s=e.bottom+8,i=e.left;break;case"left":s=e.top,i=e.left-t.offsetWidth-8;break;case"right":s=e.top,i=e.right+8}t.style.top=`${s}px`,t.style.left=`${i}px`,t.setAttribute("data-placement",this.placement)}render(){return Ds`
|
|
245
|
+
`}firstUpdated(){this.triggerEl=this.renderRoot.querySelector(".trigger"),this.popoverEl=this.renderRoot.querySelector(".popover"),"click"===this.triggerType?(this.triggerEl.addEventListener("click",this.onTogglePopover),document.addEventListener("click",this.onOutsideClick)):(this.triggerEl.addEventListener("mouseenter",this.showPopover),this.triggerEl.addEventListener("mouseleave",this.hidePopoverDelayed),this.popoverEl.addEventListener("mouseenter",this.clearHideTimer),this.popoverEl.addEventListener("mouseleave",this.hidePopoverDelayed))}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.onOutsideClick),this.triggerEl&&("click"===this.triggerType?(this.triggerEl.removeEventListener("click",this.onTogglePopover),document.removeEventListener("click",this.onOutsideClick)):(this.triggerEl.removeEventListener("mouseenter",this.showPopover),this.triggerEl.removeEventListener("mouseleave",this.hidePopoverDelayed),this.popoverEl.removeEventListener("mouseenter",this.clearHideTimer),this.popoverEl.removeEventListener("mouseleave",this.hidePopoverDelayed)))}updatePosition(){const e=this.triggerEl.getBoundingClientRect(),t=this.popoverEl;let s=0,i=0;switch(this.placement){case"top":s=e.top-t.offsetHeight-8,i=e.left+(e.width-t.offsetWidth)/2;break;case"bottom":s=e.bottom+8,i=e.left+(e.width-t.offsetWidth)/2;break;case"left":s=e.top+(e.height-t.offsetHeight)/2,i=e.left-t.offsetWidth-8;break;case"right":s=e.top+(e.height-t.offsetHeight)/2,i=e.right+8}t.style.top=`${s}px`,t.style.left=`${i}px`,t.setAttribute("data-placement",this.placement);const r=this.renderRoot.querySelector(".arrow");if(r)if("top"===this.placement||"bottom"===this.placement){const s=e.left+e.width/2-i-6;r.style.left=`${Math.min(Math.max(s,10),t.offsetWidth-16)}px`,r.style.top=""}else{const i=e.top+e.height/2-s-6;r.style.top=`${Math.min(Math.max(i,10),t.offsetHeight-16)}px`,r.style.left=""}}render(){return Ds`
|
|
247
246
|
<div class="trigger">
|
|
248
247
|
<slot name="trigger"></slot>
|
|
249
248
|
</div>
|
|
@@ -554,7 +553,7 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
554
553
|
`:null}
|
|
555
554
|
</div>
|
|
556
555
|
</div>
|
|
557
|
-
`:Ds``}_onCancel(){this.dispatchEvent(new CustomEvent("cancel")),this.visible=!1}_onOk(){this.dispatchEvent(new CustomEvent("ok"))}_onMaskClick(){this._onCancel()}};jt([ei({type:Boolean})],ki.prototype,"visible",void 0),jt([ei({type:Boolean})],ki.prototype,"showFooter",void 0),jt([ei({type:String})],ki.prototype,"width",void 0),jt([ei({type:String})],ki.prototype,"title",void 0),ki=jt([Zs("my-modal-wrapper")],ki);class Ni{constructor(){this.roleData={agentInfo:()=>{if(!pi.agentInfo?.agent_no)throw new Error("请先登录")},requestInfo:e=>{if(!e.data)throw new Error("请传入参数")},changeDevice:e=>{if(!e)throw new Error('Parameter "device" is required');const{answer_devices:t}=pi.agentInfo;if(!t.split(",").map(e=>Number(e)).includes(e))throw new Error("当前设备不支持")},changeState:(e,t)=>{if(!e)throw new Error('Parameter "state" is required');if(!t)throw new Error('Parameter "state_name" is required');if(2===e&&"通话中"===t)throw new Error("当前状态不支持");if(![1,2].includes(e))throw new Error("当前状态不支持")}}}async _agentLogin(e){try{const s=await(t={agent_no:e},ui(`${hi}/agent/login`,t));pi.agentInfo=s.data}catch(e){throw console.log(e),new Error("登录失败")}var t}async changeDevice(e){try{this.roleData.agentInfo(),this.roleData.requestInfo(e);const{data:t,success:s}=e,{device:i}=t;this.roleData.changeDevice(i);const{agent_no:r}=pi.agentInfo;await(e=>ui(`${hi}/device/change`,e))({agent_no:r,answer_device:i}),dt.updateAnswerDevice(i),s?.({code:0,msg:"请求成功"})}catch(e){throw console.log(e),new Error("切换设备失败")}}async changeState(e){try{pi.autoStateTimer&&(clearTimeout(pi.autoStateTimer),pi.autoStateTimer=null),this.roleData.agentInfo(),this.roleData.requestInfo(e);const{data:t,success:s}=e,{state:i,state_name:r}=t;this.roleData.changeState(i,r);const{agent_no:n}=pi.agentInfo;await(e=>ui(`${hi}/state/change`,e))({agent_no:n,state_name:r,state:i}),i===et.IDLE?dt.updateActionConfigs(wi):i===et.BUSY&&dt.updateActionConfigs(yi),pi.stateObject={state:i,state_name:r},s?.({code:0,msg:"请求成功"})}catch(e){console.log(e)}}async getIdleAgentList(e){const{agent_no:t}=pi.agentInfo;try{this.roleData.agentInfo();const s=await(e=>ui(`${hi}/agent/free`,e))({agent_no:t});e.success?.(s)}catch(e){console.log(e)}}async getAgentState(e){try{const t=await ui(`${ci}/agent/statecfg/list`,{}),s=(t.data||[]).filter(e=>0===e.enable).filter(e=>0!==e.state&&3!==e.state).map(e=>({state:e.state,state_name:e.state_name})).reverse();e.success?.({...t,data:s})}catch(e){console.log(e)}}}class Hi{constructor({container:e,rttHTML:t,statusParams:s},i){this.VoiceSDKInstance=i,this.apiClient=new Ni,this.isOpenSelect=!1,this.statusParams={state:et.IDLE,statusName:"空闲"},this.consultShow=!1,this.modalRoot=null,this.agentStateData=[],this.
|
|
556
|
+
`:Ds``}_onCancel(){this.dispatchEvent(new CustomEvent("cancel")),this.visible=!1}_onOk(){this.dispatchEvent(new CustomEvent("ok"))}_onMaskClick(){this._onCancel()}};jt([ei({type:Boolean})],ki.prototype,"visible",void 0),jt([ei({type:Boolean})],ki.prototype,"showFooter",void 0),jt([ei({type:String})],ki.prototype,"width",void 0),jt([ei({type:String})],ki.prototype,"title",void 0),ki=jt([Zs("my-modal-wrapper")],ki);class Ni{constructor(){this.roleData={agentInfo:()=>{if(!pi.agentInfo?.agent_no)throw new Error("请先登录")},requestInfo:e=>{if(!e.data)throw new Error("请传入参数")},changeDevice:e=>{if(!e)throw new Error('Parameter "device" is required');const{answer_devices:t}=pi.agentInfo;if(!t.split(",").map(e=>Number(e)).includes(e))throw new Error("当前设备不支持")},changeState:(e,t)=>{if(!e)throw new Error('Parameter "state" is required');if(!t)throw new Error('Parameter "state_name" is required');if(2===e&&"通话中"===t)throw new Error("当前状态不支持");if(![1,2].includes(e))throw new Error("当前状态不支持")}}}async _agentLogin(e){try{const s=await(t={agent_no:e},ui(`${hi}/agent/login`,t));pi.agentInfo=s.data}catch(e){throw console.log(e),new Error("登录失败")}var t}async changeDevice(e){try{this.roleData.agentInfo(),this.roleData.requestInfo(e);const{data:t,success:s}=e,{device:i}=t;this.roleData.changeDevice(i);const{agent_no:r}=pi.agentInfo;await(e=>ui(`${hi}/device/change`,e))({agent_no:r,answer_device:i}),dt.updateAnswerDevice(i),s?.({code:0,msg:"请求成功"})}catch(e){throw console.log(e),new Error("切换设备失败")}}async changeState(e){try{pi.autoStateTimer&&(clearTimeout(pi.autoStateTimer),pi.autoStateTimer=null),this.roleData.agentInfo(),this.roleData.requestInfo(e);const{data:t,success:s}=e,{state:i,state_name:r}=t;this.roleData.changeState(i,r);const{agent_no:n}=pi.agentInfo;await(e=>ui(`${hi}/state/change`,e))({agent_no:n,state_name:r,state:i}),i===et.IDLE?dt.updateActionConfigs(wi):i===et.BUSY&&dt.updateActionConfigs(yi),pi.stateObject={state:i,state_name:r},s?.({code:0,msg:"请求成功"})}catch(e){console.log(e)}}async getIdleAgentList(e){const{agent_no:t}=pi.agentInfo;try{this.roleData.agentInfo();const s=await(e=>ui(`${hi}/agent/free`,e))({agent_no:t});e.success?.(s)}catch(e){console.log(e)}}async getAgentState(e){try{const t=await ui(`${ci}/agent/statecfg/list`,{}),s=(t.data||[]).filter(e=>0===e.enable).filter(e=>0!==e.state&&3!==e.state).map(e=>({state:e.state,state_name:e.state_name})).reverse();e.success?.({...t,data:s})}catch(e){console.log(e)}}}class Hi{constructor({container:e,rttHTML:t,statusParams:s},i){this.VoiceSDKInstance=i,this.apiClient=new Ni,this.isOpenSelect=!1,this.statusParams={state:et.IDLE,statusName:"空闲"},this.consultShow=!1,this.modalRoot=null,this.agentStateData=[],this.handleNetworkInfoChange=e=>{this.rttHTML&&this.renderRtt(e.rttObject)},this.handleCallInfoChange=e=>{this.render()},this.hiddenSelect=()=>{if(!this.isOpenSelect)return;const e=document.querySelector(".ysyt-select");e.style.height="0px",setTimeout(()=>{e.style.padding="0px"},100),this.isOpenSelect=!1,this.render()},this.toggle=e=>{e.stopPropagation(),this.isOpenSelect=!this.isOpenSelect;const t=document.querySelector(".ysyt-select");this.isOpenSelect?(t.style.height=t.scrollHeight+"px",t.style.padding="4px 0px",this.render()):this.hiddenSelect()},this.changeStatus=async e=>{const{state:t,statusName:s}=e;await this.apiClient.changeState({data:{state:t,state_name:s},success:()=>{this.statusParams=e;const t=document.getElementById("my-timer");t?.reset(),this.hiddenSelect()}})},this.onChangeDevices=async e=>{await this.apiClient.changeDevice({data:{device:e},success:({code:t})=>{0===t&&(1!==e&&this.VoiceSDKInstance.destroyRtc(),ni("切换成功"),this.render())}})},this.ruleCall=async e=>{if(e)try{await this.VoiceSDKInstance.call_api.makeCall(e)}catch(e){console.error(e)}},this.onCall=()=>{const e=document.querySelector("my-input");this.ruleCall(e.value)},this.renderCallPopover=()=>Ds`
|
|
558
557
|
<my-popover>
|
|
559
558
|
<div slot="trigger">
|
|
560
559
|
<my-tooltip content="拨打">
|
|
@@ -659,28 +658,16 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
659
658
|
</div>`}
|
|
660
659
|
</div>
|
|
661
660
|
</my-modal-wrapper>
|
|
662
|
-
`;Ws(i,this.modalRoot)}})}catch(e){oi(e)}}getActionConfigs(){const{show_satisfaction:e}=pi.agentInfo,t=dt.get("isHold"),s=dt.get("isMuted"),i=dt.get("actionConfigs").filter(i=>(0!==e||"satisfaction"!==i)&&(!(!t&&"unhold"===i)&&((!t||"hold"!==i)&&((!s||"mute"!==i)&&!(!s&&"unmute"===i)))));return[{render:this.renderCallPopover,type:"call_number"},{render:this.renderAnswer,type:"answer"},{render:this.renderReject,type:"reject"},{render:this.renderHangup,type:"hangup"},{render:this.renderDialer,type:"dtmf"},{render:this.renderUnhold,type:"unhold"},{render:this.renderHold,type:"hold"},{render:this.renderMute,type:"mute"},{render:this.renderUnmute,type:"unmute"},{render:this.renderSatisfaction,type:"satisfaction"},{render:this.renderConsult,type:"consult"},{render:this.renderTransfer,type:"transfer"},{render:this.renderConsultTransfer,type:"consult_transfer"}].filter(({type:e})=>i.includes(e))}
|
|
663
|
-
<div style="display: flex; align-items: center; gap: 8px;" @click="${()=>e&&this.onChangeDevices(1)}">
|
|
664
|
-
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAjhJREFUaEPtmM1WwjAQhWeAF0I34kZ5MuDJqBtxo7wQEE9CkzNNk8yktIl4YKOHRvPl9s5PBuEOP3iHzPCALvXWxEq/HBfvGmp2AfPz8/m0LQXp78NCa1gEtQF1hbUfVLirBZ6EXh3neweL0CjAnVZaodpoeIW4/lqemtKKB6E76rawFM48V2oPCM1heV7/CWircMoCr9+LrVa8hk16SufArH7mqoZNboKuZZMetLXG4enMZhatsl1fMij/F7RUuZwYGCvLRJWWQDtPA4DUTmOARwORg6bApdNeD1qaEWy6Kw2s31QwQxigRLWr4eNO3xPyGJfGLDRnoTH8G/of8d5DqX0MijvUVLCuwwxtwPmae14FWm/K+bZW3xENRKtUCsweqkZ7muwvODBJCzuFVdimiAu6GvmaheZKdY3KyELToIz5Nxe8d1lGaPCCH9KLsgia9s2xsk3BU8HprzOeb2/60pZADC0Bp2tMagqMGULBawJ+pt6k8FnQUhu4rNOmDg1vBG3BYorSv0upngXd8XdESZvi9AHpjMSlPmbs4I8vQiOKbOgccP8Alxk00uFOqkYMgh4CPqTIxFrkwdAlwCeBdj0KmflJ0xanfKphu0lpunEnY2QWi+BFJDG9Gg3a2cXLtznBZ+G5tnhUaH9TqqDUNvSNxcYSk0B34Iny5vvWOnaNfhP6d5PTydrU/XNS6F6h8Q8QMnNgHu4vKwLtb2qrJf3eKi4pPlWguXTHPX9AcwqN9fwulf4FD/s5TOGFiLYAAAAASUVORK5CYII="}" width="16" alt="" /><span style="font-size: 14px">软电话</span>
|
|
665
|
-
</div>
|
|
666
|
-
`,2:Ds`
|
|
667
|
-
<div style="display: flex; align-items: center; gap: 8px;" @click="${()=>e&&this.onChangeDevices(2)}">
|
|
668
|
-
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAWtJREFUaEPtWdFNAzEMdW6Ewgo3BzBOYYi2Q0DHKcxxK0BHaNA7cIVEVD0n8Uck31dVOfbLyzvn9JxkwCcNiFmqQd8fl8eWDX9u5/fa9WbQm9dlnyZ5yFmaQF8BZzmcX+a9ZQMm0HfH5QSwKcnKUr7Ih6XYv9gkO/yHfF/b+YnNRYMGw4IiFczcAlOTlwf9tmQUPz/P9BqWOZwgYlm2aQAbgO7Msm5KZccSQoFGp7hkOUF7SeTAMsjGZZEd3hUX0CyI2jgX0GC6uWMUdqQt1AX0kJoO0H9k4to9gulgutCS9HIJeYQ8Qh7cV0j0aeUpukdBMSGPkMeNRhLyCHmEPIibdujLJcyawgm7+R7T9GPz9nx8bTHSgNQpAev2u1wuYBWuKWt+q+fMxruBtnjIVqN8tZEN3jdl9a5MjzgJAHA9RvzWuUvrC6kzHHYKsNa2Fr0ybl1Ysnh/rWPX6VYHnF1SmJnuUrUxyZCgvwFf6/M9kuThSwAAAABJRU5ErkJggg=="}" width="16" alt="" /><span style="font-size: 14px">手机模式</span>
|
|
669
|
-
</div>
|
|
670
|
-
`,3:Ds`
|
|
671
|
-
<div style="display: flex; align-items: center; gap: 8px;" @click="${()=>e&&this.onChangeDevices(3)}">
|
|
672
|
-
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAq5JREFUaEPtmWFywiAQhcEr6Als79F6LdsZdab1WsZ7tJ7AXiF0lmYzC9mFDUGrM/qrmrB8PB7LQq25w4+9Q2bzgL7WrD2UvhmlF8/vr865jXXueD7tt1PAIBZtf/76aPA7PKPf4Xf6Pn2WtMdiud46YzZ9R9Y2P9+fqxLw+dPbwTgXQNvZbIUw8+XaGRJ/0LcxkDV2IJwIHTSytuk7LADnAGDgCOFns20P8NvPae+ZuEFiGxaadtIHpqqPBPcqEsh4plLQg/6tbVhoqZNYfY1VKBC1AwUfBf03+PDDBQg6KFCcTjUoB/Hoos7ag9gT2g+hESphgbGKUygUAKcds4TK0x1TEbTvqEBxaANtMSOhXZJKg4edO5rZrMFMUwxdCk4zgyZ70BkhsxR5WmEPyeOphUbboBXqQTM5M7eZ4ELjVPHKdikviEM3kkSeVilNO5GUE5Xudqx4kANoZpHDO8Hi7GZcD41bbmYT4Tah3KzUeM7viEqL5GxRA5CLIdYe/a5IiprBtHczorFRzQHI0AqL9DvdyFpk6gDkKo9YRMoKuS1/KpzUXl1PSxbIVXCXAM+eEft0JVjgPzJIFjooLYU8rAWvdXTLQsc1hmgTcpzi1kDNo5sKmhY58LdYY0RnSqydnbUv9Lg25ejm+9culKAm1tbaUfAaR7dR0HGxTk/O3MC9HUDh7mOt3QVXBgX1uFia5pQvKf6lmKWx1PaQKruc4pcQoQg6ziipxZmDHsRSlATF0AOPJ+41aoNPgu7BndtgGpPqlLHgqTiToREm3jxK4TWVYzVozuddTvWXhjeptJhdME/DzRK5u4gHEd9CpQZaVekYRLothTQZvEuugDW2uih04Hdafwhe0R7brgIdWAf+G9C2weV6yjbc+K4OrVmQuXce0DmFaj2/S6V/Ae/pt8oTAp/jAAAAAElFTkSuQmCC"}" width="16" alt="" /><span style="font-size: 14px">SIP话机</span>
|
|
673
|
-
</div>
|
|
674
|
-
`}}async render(){const{displayText:e,answerDevice:t}=dt.getState(),{answer_devices:s}=pi.agentInfo,i=(s||"").split(","),r=this.getActionConfigs(),n={...vi},{statusColor:o}=n,a=document.querySelector("head");if(a){const e=Ds`
|
|
661
|
+
`;Ws(i,this.modalRoot)}})}catch(e){oi(e)}}getActionConfigs(){const{show_satisfaction:e}=pi.agentInfo,t=dt.get("isHold"),s=dt.get("isMuted"),i=dt.get("actionConfigs").filter(i=>(0!==e||"satisfaction"!==i)&&(!(!t&&"unhold"===i)&&((!t||"hold"!==i)&&((!s||"mute"!==i)&&!(!s&&"unmute"===i)))));return[{render:this.renderCallPopover,type:"call_number"},{render:this.renderAnswer,type:"answer"},{render:this.renderReject,type:"reject"},{render:this.renderHangup,type:"hangup"},{render:this.renderDialer,type:"dtmf"},{render:this.renderUnhold,type:"unhold"},{render:this.renderHold,type:"hold"},{render:this.renderMute,type:"mute"},{render:this.renderUnmute,type:"unmute"},{render:this.renderSatisfaction,type:"satisfaction"},{render:this.renderConsult,type:"consult"},{render:this.renderTransfer,type:"transfer"},{render:this.renderConsultTransfer,type:"consult_transfer"}].filter(({type:e})=>i.includes(e))}async render(){const{displayText:e}=dt.getState(),{default_device:t,answer_devices:s,show_satisfaction:i}=pi.agentInfo,r=(s||"").split(","),n=this.getActionConfigs(),o={...vi},{statusColor:a}=o,c=document.querySelector("head");if(c){const e=Ds`
|
|
675
662
|
<style>
|
|
676
663
|
.ysyt-phone-body {
|
|
677
|
-
background: ${
|
|
664
|
+
background: ${a[this.statusParams.state]};
|
|
678
665
|
}
|
|
679
666
|
.ysyt-action-body {
|
|
680
|
-
border-bottom: 1px solid ${
|
|
667
|
+
border-bottom: 1px solid ${a[this.statusParams.state]};
|
|
681
668
|
}
|
|
682
669
|
</style>
|
|
683
|
-
`;Ws(e,
|
|
670
|
+
`;Ws(e,c)}const h=Ds`
|
|
684
671
|
<i class="ysyt icon-shang select-icon" style="${this.isOpenSelect?"display: block;":"display: none;"}"></i>
|
|
685
672
|
<div
|
|
686
673
|
class="ysyt-select"
|
|
@@ -697,21 +684,37 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
697
684
|
`)}
|
|
698
685
|
</div>
|
|
699
686
|
</div>
|
|
700
|
-
`,
|
|
687
|
+
`,d=Ds`
|
|
701
688
|
<div id="ysyt-body">
|
|
702
|
-
<div
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
689
|
+
<div id="ysyt-devices-body">
|
|
690
|
+
<my-select
|
|
691
|
+
width="100px"
|
|
692
|
+
value="${String(t)}"
|
|
693
|
+
placeholder=""
|
|
694
|
+
@change=${e=>this.onChangeDevices(Number(e.detail.value))}
|
|
695
|
+
>
|
|
696
|
+
${r.includes("1")?Ds`
|
|
697
|
+
<select-option value="1">
|
|
698
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
699
|
+
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAjhJREFUaEPtmM1WwjAQhWeAF0I34kZ5MuDJqBtxo7wQEE9CkzNNk8yktIl4YKOHRvPl9s5PBuEOP3iHzPCALvXWxEq/HBfvGmp2AfPz8/m0LQXp78NCa1gEtQF1hbUfVLirBZ6EXh3neweL0CjAnVZaodpoeIW4/lqemtKKB6E76rawFM48V2oPCM1heV7/CWircMoCr9+LrVa8hk16SufArH7mqoZNboKuZZMetLXG4enMZhatsl1fMij/F7RUuZwYGCvLRJWWQDtPA4DUTmOARwORg6bApdNeD1qaEWy6Kw2s31QwQxigRLWr4eNO3xPyGJfGLDRnoTH8G/of8d5DqX0MijvUVLCuwwxtwPmae14FWm/K+bZW3xENRKtUCsweqkZ7muwvODBJCzuFVdimiAu6GvmaheZKdY3KyELToIz5Nxe8d1lGaPCCH9KLsgia9s2xsk3BU8HprzOeb2/60pZADC0Bp2tMagqMGULBawJ+pt6k8FnQUhu4rNOmDg1vBG3BYorSv0upngXd8XdESZvi9AHpjMSlPmbs4I8vQiOKbOgccP8Alxk00uFOqkYMgh4CPqTIxFrkwdAlwCeBdj0KmflJ0xanfKphu0lpunEnY2QWi+BFJDG9Gg3a2cXLtznBZ+G5tnhUaH9TqqDUNvSNxcYSk0B34Iny5vvWOnaNfhP6d5PTydrU/XNS6F6h8Q8QMnNgHu4vKwLtb2qrJf3eKi4pPlWguXTHPX9AcwqN9fwulf4FD/s5TOGFiLYAAAAASUVORK5CYII="}" width="16" alt="" /><span style="font-size: 14px">软电话</span>
|
|
700
|
+
</div>
|
|
701
|
+
</select-option>
|
|
702
|
+
`:""}
|
|
703
|
+
${r.includes("2")?Ds`
|
|
704
|
+
<select-option value="2">
|
|
705
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
706
|
+
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAWtJREFUaEPtWdFNAzEMdW6Ewgo3BzBOYYi2Q0DHKcxxK0BHaNA7cIVEVD0n8Uck31dVOfbLyzvn9JxkwCcNiFmqQd8fl8eWDX9u5/fa9WbQm9dlnyZ5yFmaQF8BZzmcX+a9ZQMm0HfH5QSwKcnKUr7Ih6XYv9gkO/yHfF/b+YnNRYMGw4IiFczcAlOTlwf9tmQUPz/P9BqWOZwgYlm2aQAbgO7Msm5KZccSQoFGp7hkOUF7SeTAMsjGZZEd3hUX0CyI2jgX0GC6uWMUdqQt1AX0kJoO0H9k4to9gulgutCS9HIJeYQ8Qh7cV0j0aeUpukdBMSGPkMeNRhLyCHmEPIibdujLJcyawgm7+R7T9GPz9nx8bTHSgNQpAev2u1wuYBWuKWt+q+fMxruBtnjIVqN8tZEN3jdl9a5MjzgJAHA9RvzWuUvrC6kzHHYKsNa2Fr0ybl1Ysnh/rWPX6VYHnF1SmJnuUrUxyZCgvwFf6/M9kuThSwAAAABJRU5ErkJggg=="}" width="16" alt="" /><span style="font-size: 14px">手机模式</span>
|
|
707
|
+
</div>
|
|
708
|
+
</select-option>
|
|
709
|
+
`:""}
|
|
710
|
+
${r.includes("3")?Ds`
|
|
711
|
+
<select-option value="3">
|
|
712
|
+
<div style="display: flex; align-items: center; gap: 8px;">
|
|
713
|
+
<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAq5JREFUaEPtmWFywiAQhcEr6Als79F6LdsZdab1WsZ7tJ7AXiF0lmYzC9mFDUGrM/qrmrB8PB7LQq25w4+9Q2bzgL7WrD2UvhmlF8/vr865jXXueD7tt1PAIBZtf/76aPA7PKPf4Xf6Pn2WtMdiud46YzZ9R9Y2P9+fqxLw+dPbwTgXQNvZbIUw8+XaGRJ/0LcxkDV2IJwIHTSytuk7LADnAGDgCOFns20P8NvPae+ZuEFiGxaadtIHpqqPBPcqEsh4plLQg/6tbVhoqZNYfY1VKBC1AwUfBf03+PDDBQg6KFCcTjUoB/Hoos7ag9gT2g+hESphgbGKUygUAKcds4TK0x1TEbTvqEBxaANtMSOhXZJKg4edO5rZrMFMUwxdCk4zgyZ70BkhsxR5WmEPyeOphUbboBXqQTM5M7eZ4ELjVPHKdikviEM3kkSeVilNO5GUE5Xudqx4kANoZpHDO8Hi7GZcD41bbmYT4Tah3KzUeM7viEqL5GxRA5CLIdYe/a5IiprBtHczorFRzQHI0AqL9DvdyFpk6gDkKo9YRMoKuS1/KpzUXl1PSxbIVXCXAM+eEft0JVjgPzJIFjooLYU8rAWvdXTLQsc1hmgTcpzi1kDNo5sKmhY58LdYY0RnSqydnbUv9Lg25ejm+9culKAm1tbaUfAaR7dR0HGxTk/O3MC9HUDh7mOt3QVXBgX1uFia5pQvKf6lmKWx1PaQKruc4pcQoQg6ziipxZmDHsRSlATF0AOPJ+41aoNPgu7BndtgGpPqlLHgqTiToREm3jxK4TWVYzVozuddTvWXhjeptJhdME/DzRK5u4gHEd9CpQZaVekYRLothTQZvEuugDW2uih04Hdafwhe0R7brgIdWAf+G9C2weV6yjbc+K4OrVmQuXce0DmFaj2/S6V/Ae/pt8oTAp/jAAAAAElFTkSuQmCC"}" width="16" alt="" /><span style="font-size: 14px">SIP话机</span>
|
|
714
|
+
</div>
|
|
715
|
+
</select-option>
|
|
716
|
+
`:""}
|
|
717
|
+
</my-select>
|
|
715
718
|
</div>
|
|
716
719
|
<div class="ysyt-phone-body">
|
|
717
720
|
<div class="ysyt-title" @click="${this.toggle}">
|
|
@@ -724,14 +727,14 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
724
727
|
<span>${t}</span>
|
|
725
728
|
`:void 0)(this.statusParams)}
|
|
726
729
|
<i class="ysyt icon-xia"></i>
|
|
727
|
-
${
|
|
730
|
+
${h}
|
|
728
731
|
`}
|
|
729
732
|
</div>
|
|
730
733
|
<timer-component id="my-timer"></timer-component>
|
|
731
734
|
</div>
|
|
732
|
-
<div class="ysyt-action-body">${
|
|
735
|
+
<div class="ysyt-action-body">${n.map(e=>e.render())}</div>
|
|
733
736
|
</div>
|
|
734
|
-
`;Ws(
|
|
737
|
+
`;Ws(d,this.container)}async renderRtt(e){const{outCallIsAnswer:t}=dt.getState(),s=e?.rtt||500,i=Ds`
|
|
735
738
|
<my-popover triggerType="hover">
|
|
736
739
|
<div slot="trigger" id="wifi-body">
|
|
737
740
|
${s>=250?Ds`<img src="${"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAAXNSR0IArs4c6QAAAlVJREFUaEPtmGFuwyAMhU2PtU1qOVmbk5FKW4+1TCawkcQYG2i3aM2fqirBn83zc1IDO7zMDpnhCf2oU+teaefcKYW31o69k6mGTuDOAWoBmwGNCVwBYKxNSAUdQDWQkiIPuMhae5EsxjUi6ARWUk1pbGrdIIFnoZWwqXbx+NPrqJAQLmXhSWghLELGo1U1m3MuSiFKLXc6JPwGOmyY28yD1jYQRSZIYAP+DV2obnfYdQIF+EV8Dx2AHVGJu8Mq4X3VDSMHUSe3WAV3L8eF0BNxs9XoNpwU2mF0CdwSv6fDxIeRWFrkyYEjNMoi+q9YDkKHyRUT41wlCRBxhqhptCDRWC24S41aRDIMcT2jaCKGZsXESr6aQmM1NRNUBK8Z46mE1tWMumX9W+DHxUkYA7eMcbH+maFCnVxx3xI05SzFTTXCZnok62BZ6MxmYt11AM/G4qCxidIpqfJuDXSm0fWVTgz+pBk0E7wFx/gMn4fRwLv4KTC+EXExxZbHVW6ClwuAOQJMjMWZEWC6GriJ31ByMZug56pOZx6WDD20wFdDT/DqKmDTDKrBq6BnOVDTESXgZ5Z/owGIus5Jx4wGPqy2aWuhV/6NsGbgGm6Wkk9iMVAM3NQM6huwKj+V1jfX6pSqJFIFrT1Oaj1WXmOF6R6/Bt2S+N2gWypZSqg7NOEsVbrlwLtC560QuoL3hqYeZWfnrrC2u4zxdNPgw9R/J2HZwda6xRr+f1d6OXQ2B/t3NU2D1z1fPMw9thrHBpS/AJT8Of7eVdPSoK3rntCtFZTev8tKfwHUBxjzil9I5gAAAABJRU5ErkJggg=="}" alt="" />`:""}
|
|
@@ -771,4 +774,4 @@ const Zs=e=>(t,s)=>{void 0!==s?s.addInitializer(()=>{customElements.define(e,t)}
|
|
|
771
774
|
`:""}
|
|
772
775
|
</div>
|
|
773
776
|
</my-popover>
|
|
774
|
-
`;Ws(i,this.rttHTML)}}const Pi=new class{constructor(){this.events={}}on(e,t){this.events[e]=this.events[e]||[],this.events[e].push(t)}off(e,t){this.events[e]=(this.events[e]||[]).filter(e=>e!==t)}emit(e,...t){(this.events[e]||[]).forEach(e=>e(...t))}};class Oi{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const e=await navigator.mediaDevices.enumerateDevices();if(e.some(e=>"audioinput"===e.kind&&""!==e.label))return console.log("已授权麦克风权限,无需再次获取"),null;const t=await navigator.mediaDevices.getUserMedia({audio:!0});return console.log("获取音频权限成功"),t}catch(e){return console.warn("获取音频权限失败:",e),null}}static show(e,t,s){if("Notification"in window&&"granted"===Notification.permission){const i=new Notification(e,{body:t,tag:"xy-global-notification",renotify:!0});i.onclick=()=>{window.focus(),i.close(),s?.()},setTimeout(()=>i.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(e=>"audioinput"===e.kind&&""!==e.label)}catch(e){return console.warn("无法检查设备权限:",e),!1}}}let qi=null;class Li{constructor(e){this.url=e,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Ni,this.initWebSocket()}static getInstance(e){if(!qi){if(!e)throw new Error("WebSocket 尚未初始化");qi=new Li(e)}return qi}stateIdleChange(){const{state:e}=pi.stateObject;e!==et.IDLE&&this.apiClient.changeState({data:{state:et.IDLE,state_name:"空闲"}})}putAgentState(){pi.sessionId="";const{post_call_process_time:e}=pi.agentInfo,t=e||0;pi.autoStateTimer&&(clearTimeout(pi.autoStateTimer),pi.autoStateTimer=null),t>0?pi.autoStateTimer=setTimeout(()=>{pi.autoStateTimer=null,this.stateIdleChange()},t):this.stateIdleChange()}initWebSocket(){this.ws=new WebSocket(this.url),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&&console.warn(s),s===rt.OUT_CALL&&0!==r&&(ct.emit(it.OUT_FAILED,n),this.stateIdleChange()),s===rt.AGENT_STATE){const{state:e,state_name:t}=i;pi.stateObject={state:e,state_name:t},ct.emit(it.AGENT_STATE,{state:e,state_name:t})}s===rt.OUT_CALL_INCOMING_CALL&&(ct.emit(it.OUT_INCOMING_CALL,i),pi.sessionId=i.session_id,dt.updateActionConfigs(bi)),s===rt.OUT_CALL_END&&(0===i.device_type||1===i.device_type?(this.putAgentState(),dt.reset(),ct.emit(it.OUT_HANGUP,i)):2===i.device_type&&(dt.get("direction")===tt.CONSULT?(dt.reset(),ct.emit(it.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState()):dt.get("isCalling")&&(dt.updateDisplayText(ot.CALLING),ct.emit(it.OTHER_SIDE_CONSULT_HANGUP,i),dt.updateActionConfigs(Ti)))),s===rt.OUT_CALL_RINGING&&(ct.emit(it.OUT_RINGING,i),dt.updateDisplayText(ot.RINGING)),s===rt.OUT_CALL_ANSWER&&(ct.emit(it.OUT_OFF_ANSWER,i),dt.updateOutCallIsAnswer(!0),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ti)),s===rt.CONSULT_RINGING&&(ct.emit(it.CONSULT_RINGING,i),dt.updateDisplayText(ot.AGENT_RINGING),dt.updateActionConfigs([])),s===rt.CONSULT_ANSWER&&(ct.emit(it.CONSULT_OFF_HOOK,i),dt.updateConsultIsAnswer(!0),dt.updateDisplayText(ot.CONSULTING),dt.updateActionConfigs(Si)),s===rt.CONSULT_FAIL&&(ct.emit(it.CONSULT_FAILED),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ti)),s===rt.CONSULT_CALL_IN&&(ct.emit(it.CONSULT_INCOMING,i),dt.updateIsCalling(!0),dt.updateDirection(tt.CONSULT),dt.updateDisplayText(ot.CONSULT_CALL_IN),dt.updateActionConfigs(Ei),pi.enableBrowserAlert&&Oi.show("📞 咨询来电",`坐席 [${i.agent_name}] 正在咨询...`,()=>{ct.emit(nt.NOTIFICATION_CLICK,{agent_mane:i.agent_name})})),s===rt.CONSULT_CALL_IN_SUCCESS&&(pi.sessionId=i.session_id,ct.emit(it.CONSULT_CALL_IN_SUCCESS,i),dt.updateConsultIsAnswer(!0),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ci)),s===rt.MUTE&&(0===r?(dt.updateIsMuted(!0),ct.emit(it.MUTE_SUCCESS)):ct.emit(it.MUTE_FAILED,n)),s===rt.UNMUTE&&(0===r?(dt.updateIsMuted(!1),ct.emit(it.UNMUTE_SUCCESS)):ct.emit(it.UNMUTE_FAILED,n)),s===rt.CONSULT_TRANSFER&&(0===r?ct.emit(it.CONSULT_TRANSFER_SUCCESS):ct.emit(it.CONSULT_TRANSFER_FAILED,n)),s===rt.CONSULT_TRANSFER_FAILED&&ct.emit(it.CONSULT_TRANSFER_FAILED,i.status),s===rt.CONSULT_TRANSFER_OFF_HOOK&&(dt.updateDirection(tt.INCOMING),dt.updateDisplayText(ot.CALLING),ct.emit(it.CONSULT_TRANSFER_OFF_HOOK),dt.updateActionConfigs(Ai),dt.updateIncomingIsAnswer(!0),dt.updateConsultIsAnswer(!1)),s===rt.INCOMING_CALL&&(pi.sessionId=i.session_id,dt.updateIsCalling(!0),dt.updateDirection(tt.INCOMING),dt.updateDisplayText(ot.INCOMING_CALL),ct.emit(it.INCOMING_CALL,{customer_phone:i.customer_phone}),dt.updateActionConfigs(Ei),pi.enableBrowserAlert&&Oi.show("📞 客户来电",`客户 [${i.customer_phone}] 正在呼入...`,()=>{ct.emit(nt.NOTIFICATION_CLICK,{customer_phone:i.customer_phone})})),s===rt.INCOMING_CALL_OFF_HOOK&&(dt.updateIncomingIsAnswer(!0),ct.emit(it.INCOMING_CALL_OFF_HOOK),dt.updateActionConfigs(Ai),dt.updateDisplayText(ot.CALLING)),s===rt.INCOMING_CALL_END&&(ct.emit(it.INCOMING_CALL_END),dt.reset(),dt.updateActionConfigs(wi),this.putAgentState()),0!==s&&Pi.emit("ws-message",t)},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const e=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"}),t=URL.createObjectURL(e);this.heartbeatWorker=new Worker(t),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(e){this.ws?.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify(e)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){qi&&(qi.close(),qi=null)}static __internalSend(e){if(!qi)throw new Error("WebSocket 尚未初始化");qi.sendMessage(e)}}return class{#e=null;#t=new Ni;#s=null;#i=!1;#r;constructor(){clearInterval(this.#s),this.#s=setInterval(async()=>{const e=await this.#n();fi.updateRttObject(e)},2e3),Oi.requestMediaPermissions(),window.addEventListener("beforeunload",()=>{this.destroy()}),this.#r=dt.subscribeKey("answerDevice",e=>{1===e&&this.initWebRtc()})}async initWebRtc(){const e=pi.agentInfo.sip_account_list.find(e=>1===e.device_type);if(e){const t=e.sip_register_addr;this.#e=new mi({server:t.split(":")[0],user:e.sip_account,password:e.sip_password,webSocket:`wss://${t}`,callTimeout:3e4},this.#o),await this.#e.start()}}async init({actionNodeParams:e,url:t,appKey:s,appSecret:i,agentNo:r,enableBrowserAlert:n}){try{const{viewHtmlElement:o,rttHTML:a}=e;di=t||"https://aicc-api.yescloudy.com",li=s,gi=i;const c=Ft(s,i);await this.#t._agentLogin(r);const{agent_no:h,current_answer_device:d,init_state:l}=pi.agentInfo;l===et.IDLE?(dt.updateActionConfigs(wi),pi.stateObject={state:l,state_name:"空闲"}):l===et.BUSY&&(dt.updateActionConfigs(yi),pi.stateObject={state:l,state_name:"忙碌"}),Li.getInstance(`ws://112.90.183.54:8719/api/v1/ws/call/${h}?Authorization=${c}`),dt.updateAnswerDevice(d),1===d&&await this.initWebRtc(),e&&o&&(this.#i=!0,new Hi({container:o,rttHTML:a,statusParams:{state:et.IDLE,statusName:"空闲"}},this)),pi.enableBrowserAlert=n,n&&Oi.requestPermission()}catch(e){this.#i&&oi("初始化失败"),console.log(e)}}#o=e=>{const{type:t,data:s}=e;ct.emit(t,s)};#a=e=>{};on(e,t){return ct.on(e,t),this}off(e,t){ct.off(e,t)}offAll(){ct.clearAllListeners()}#c(){if(!this.#e)throw new Error("请先初始化SDK");const e=dt.get("isCalling"),t=pi.sessionId;if(!e)throw new Error("当前没有通话");if(!t)throw new Error("sessionId不存在")}#h(){const e=dt.get("isHold"),{sessionId:t}=pi;if(t){if(e)throw new Error("当前已处于保持状态");Li.__internalSend({type:rt.CALL_HOLD,data:{session_id:t}}),dt.updateDisplayText(ot.HOLD),dt.updateIsHold(!0)}}#d(){const{isHold:e}=dt.getState(),{sessionId:t}=pi;if(t){if(!e)throw new Error("当前未处于保持状态");Li.__internalSend({type:rt.CALL_UNHOLD,data:{session_id:t}}),dt.updateDisplayText(""),dt.updateIsHold(!1)}}#l(e){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:t}=dt.getState();if(!t)throw new Error("当前没有通话");this.#e.sendDTMF(e)}#g(){if(1!==dt.get("answerDevice"))throw new Error("当前设备不支持此功能");if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:e,direction:t,outCallIsAnswer:s}=dt.getState();if(!e)throw new Error("当前没有通话");s||(t===tt.INCOMING?this.#u():t===tt.OUTGOING&&this.#p())}async#f(e){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:t,outCallIsAnswer:s,consultIsAnswer:i,incomingIsAnswer:r}=dt.getState(),n=pi.sessionId;if(i)throw new Error("当前正在咨询");if(!(t||s||r))throw new Error("当前没有通话");if(!n)throw new Error("sessionId不存在");Li.__internalSend({type:rt.CONSULT_REQUEST,data:{session_id:n,consultation_agent_no:e}})}async#m(){if(1!==dt.get("answerDevice"))throw new Error("当前设备不支持此功能");if(!this.#e)throw new Error("请先初始化SDK");await this.#e.answerCall()}async#u(){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:e}=dt.getState();if(!e)throw new Error("当前没有通话");await this.#e.rejectInCall()}async#v(e){if(!this.#e)throw new Error("请先初始化SDK");if(dt.getState().isCalling)throw new Error("正在呼叫中,请勿重复点击");dt.updateIsCalling(!0),dt.updateDirection(tt.OUTGOING),Li.__internalSend({type:rt.OUT_CALL,data:{customer_phone:e}})}async#p(){const{isCalling:e}=dt.getState();if(!this.#e)throw new Error("请先初始化SDK");if(!e)throw new Error("当前没有通话");await this.#e.rejectOutCall()}async#w(){if(!this.#e)throw new Error("请先初始化SDK");if(!dt.get("isCalling"))throw new Error("当前没有通话");await this.#e.hangup()}#y(){this.#c();const e=dt.get("actionConfigs"),t=dt.get("isMuted"),s=pi.sessionId;if(t)throw new Error("当前未处于静音状态");if(!e.includes("mute"))throw new Error("当前状态请勿调用静音");Li.__internalSend({type:rt.MUTE,data:{session_id:s}})}#b(){this.#c();const e=dt.get("actionConfigs"),t=dt.get("isMuted"),s=pi.sessionId;if(!t)throw new Error("当前未处于未静音状态");if(!e.includes("unmute"))throw new Error("当前状态请勿调用静音");Li.__internalSend({type:rt.UNMUTE,data:{session_id:s}})}#T(){this.#c();const e=dt.get("consultIsAnswer"),t=pi.sessionId;if(!dt.get("actionConfigs").includes("consult_transfer"))throw new Error("当前状态请勿调用咨询转移");if(!e)throw new Error("当前未处于咨询中");Li.__internalSend({type:rt.CONSULT_TRANSFER,data:{session_id:t}})}async destroyRtc(){await(this.#e?.destroy())}destroy(){this.destroyRtc(),Pi.off("ws-message",this.#a),Li.__internalClose(),this.offAll(),this.#r?.()}async#n(){return this.#e?this.#e.getNetworkStats():{}}get call_api(){return this.#i?{answerCall:this.#m.bind(this),makeCall:this.#v.bind(this),cancelCall:this.#g.bind(this),hangup:this.#w.bind(this),sendDTMF:this.#l.bind(this),holdCall:this.#h.bind(this),unholdCall:this.#d.bind(this),consultCall:async e=>{try{await this.#f(e)}catch(e){throw console.warn(e),e}},consultTransfer:this.#T.bind(this),mute:this.#y.bind(this),unmute:this.#b.bind(this)}:{}}get agent_api(){return this.#i?{changeDevice:this.#t.changeDevice.bind(this.#t),changeState:this.#t.changeState.bind(this.#t),getIdleAgentList:e=>this.#t.getIdleAgentList(e),getAgentState:e=>this.#t.getAgentState(e)}:{}}}});
|
|
777
|
+
`;Ws(i,this.rttHTML)}}const Pi=new class{constructor(){this.events={}}on(e,t){this.events[e]=this.events[e]||[],this.events[e].push(t)}off(e,t){this.events[e]=(this.events[e]||[]).filter(e=>e!==t)}emit(e,...t){(this.events[e]||[]).forEach(e=>e(...t))}};class Oi{static requestPermission(){"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission()}static async requestMediaPermissions(){try{const e=await navigator.mediaDevices.enumerateDevices();if(e.some(e=>"audioinput"===e.kind&&""!==e.label))return console.log("已授权麦克风权限,无需再次获取"),null;const t=await navigator.mediaDevices.getUserMedia({audio:!0});return console.log("获取音频权限成功"),t}catch(e){return console.warn("获取音频权限失败:",e),null}}static show(e,t,s){if("Notification"in window&&"granted"===Notification.permission){const i=new Notification(e,{body:t,tag:"xy-global-notification",renotify:!0});i.onclick=()=>{window.focus(),i.close(),s?.()},setTimeout(()=>i.close(),5e3)}}static async checkMediaPermissions(){try{return(await navigator.mediaDevices.enumerateDevices()).some(e=>"audioinput"===e.kind&&""!==e.label)}catch(e){return console.warn("无法检查设备权限:",e),!1}}}let qi=null;class Li{constructor(e){this.url=e,this.ws=null,this.heartbeatWorker=null,this.reconnectDelay=3e3,this.manualClose=!1,this.apiClient=new Ni,this.initWebSocket()}static getInstance(e){if(!qi){if(!e)throw new Error("WebSocket 尚未初始化");qi=new Li(e)}return qi}stateIdleChange(){const{state:e}=pi.stateObject;e!==et.IDLE&&this.apiClient.changeState({data:{state:et.IDLE,state_name:"空闲"}})}putAgentState(){pi.sessionId="";const{post_call_process_time:e}=pi.agentInfo,t=e||0;pi.autoStateTimer&&(clearTimeout(pi.autoStateTimer),pi.autoStateTimer=null),t>0?pi.autoStateTimer=setTimeout(()=>{pi.autoStateTimer=null,this.stateIdleChange()},t):this.stateIdleChange()}initWebSocket(){this.ws=new WebSocket(this.url),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&&console.warn(s),s===rt.OUT_CALL&&0!==r&&(ct.emit(it.OUT_FAILED,n),this.stateIdleChange()),s===rt.AGENT_STATE){const{state:e,state_name:t}=i;pi.stateObject={state:e,state_name:t},ct.emit(it.AGENT_STATE,{state:e,state_name:t})}s===rt.OUT_CALL_INCOMING_CALL&&(ct.emit(it.OUT_INCOMING_CALL,i),pi.sessionId=i.session_id,dt.updateActionConfigs(bi)),s===rt.OUT_CALL_END&&(0===i.device_type||1===i.device_type?(this.putAgentState(),dt.reset(),ct.emit(it.OUT_HANGUP,i)):2===i.device_type&&(dt.get("direction")===tt.CONSULT?(dt.reset(),ct.emit(it.OUR_SIDE_CONSULT_HANGUP,i),this.putAgentState()):dt.get("isCalling")&&(dt.updateDisplayText(ot.CALLING),ct.emit(it.OTHER_SIDE_CONSULT_HANGUP,i),dt.updateActionConfigs(Ti)))),s===rt.OUT_CALL_RINGING&&(ct.emit(it.OUT_RINGING,i),dt.updateDisplayText(ot.RINGING)),s===rt.OUT_CALL_ANSWER&&(ct.emit(it.OUT_OFF_ANSWER,i),dt.updateOutCallIsAnswer(!0),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ti)),s===rt.CONSULT_RINGING&&(ct.emit(it.CONSULT_RINGING,i),dt.updateDisplayText(ot.AGENT_RINGING),dt.updateActionConfigs([])),s===rt.CONSULT_ANSWER&&(ct.emit(it.CONSULT_OFF_HOOK,i),dt.updateConsultIsAnswer(!0),dt.updateDisplayText(ot.CONSULTING),dt.updateActionConfigs(Si)),s===rt.CONSULT_FAIL&&(ct.emit(it.CONSULT_FAILED),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ti)),s===rt.CONSULT_CALL_IN&&(ct.emit(it.CONSULT_INCOMING,i),dt.updateIsCalling(!0),dt.updateDirection(tt.CONSULT),dt.updateDisplayText(ot.CONSULT_CALL_IN),dt.updateActionConfigs(Ei),pi.enableBrowserAlert&&Oi.show("📞 咨询来电",`坐席 [${i.agent_name}] 正在咨询...`,()=>{ct.emit(nt.NOTIFICATION_CLICK,{agent_mane:i.agent_name})})),s===rt.CONSULT_CALL_IN_SUCCESS&&(pi.sessionId=i.session_id,ct.emit(it.CONSULT_CALL_IN_SUCCESS,i),dt.updateConsultIsAnswer(!0),dt.updateDisplayText(ot.CALLING),dt.updateActionConfigs(Ci)),s===rt.MUTE&&(0===r?(dt.updateIsMuted(!0),ct.emit(it.MUTE_SUCCESS)):ct.emit(it.MUTE_FAILED,n)),s===rt.UNMUTE&&(0===r?(dt.updateIsMuted(!1),ct.emit(it.UNMUTE_SUCCESS)):ct.emit(it.UNMUTE_FAILED,n)),s===rt.CONSULT_TRANSFER&&(0===r?ct.emit(it.CONSULT_TRANSFER_SUCCESS):ct.emit(it.CONSULT_TRANSFER_FAILED,n)),s===rt.CONSULT_TRANSFER_FAILED&&ct.emit(it.CONSULT_TRANSFER_FAILED,i.status),s===rt.CONSULT_TRANSFER_OFF_HOOK&&(dt.updateDirection(tt.INCOMING),dt.updateDisplayText(ot.CALLING),ct.emit(it.CONSULT_TRANSFER_OFF_HOOK),dt.updateActionConfigs(Ai),dt.updateIncomingIsAnswer(!0),dt.updateConsultIsAnswer(!1)),s===rt.INCOMING_CALL&&(pi.sessionId=i.session_id,dt.updateIsCalling(!0),dt.updateDirection(tt.INCOMING),dt.updateDisplayText(ot.INCOMING_CALL),ct.emit(it.INCOMING_CALL,{customer_phone:i.customer_phone}),dt.updateActionConfigs(Ei),pi.enableBrowserAlert&&Oi.show("📞 客户来电",`客户 [${i.customer_phone}] 正在呼入...`,()=>{ct.emit(nt.NOTIFICATION_CLICK,{customer_phone:i.customer_phone})})),s===rt.INCOMING_CALL_OFF_HOOK&&(dt.updateIncomingIsAnswer(!0),ct.emit(it.INCOMING_CALL_OFF_HOOK),dt.updateActionConfigs(Ai),dt.updateDisplayText(ot.CALLING)),s===rt.INCOMING_CALL_END&&(ct.emit(it.INCOMING_CALL_END),dt.reset(),dt.updateActionConfigs(wi),this.putAgentState()),0!==s&&Pi.emit("ws-message",t)},this.ws.onclose=()=>{this.stopHeartbeat(),this.manualClose||setTimeout(()=>this.initWebSocket(),this.reconnectDelay)},this.ws.onerror=()=>{this.ws?.close()}}startHeartbeat(){const e=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"}),t=URL.createObjectURL(e);this.heartbeatWorker=new Worker(t),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(e){this.ws?.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify(e)):console.warn("WebSocket 未连接,消息未发送")}close(){this.manualClose=!0,this.stopHeartbeat(),this.ws?.close()}static __internalClose(){qi&&(qi.close(),qi=null)}static __internalSend(e){if(!qi)throw new Error("WebSocket 尚未初始化");qi.sendMessage(e)}}return class{#e=null;#t=new Ni;#s=null;#i=!1;#r;constructor(){clearInterval(this.#s),this.#s=setInterval(async()=>{const e=await this.#n();fi.updateRttObject(e)},2e3),Oi.requestMediaPermissions(),window.addEventListener("beforeunload",()=>{this.destroy()}),this.#r=dt.subscribeKey("answerDevice",e=>{1===e&&this.initWebRtc()})}async initWebRtc(){const e=pi.agentInfo.sip_account_list.find(e=>1===e.device_type);if(e){const t=e.sip_register_addr;this.#e=new mi({server:t.split(":")[0],user:e.sip_account,password:e.sip_password,webSocket:`wss://${t}`,callTimeout:3e4},this.#o),await this.#e.start()}}async init({actionNodeParams:e,url:t,appKey:s,appSecret:i,agentNo:r,enableBrowserAlert:n}){try{const{viewHtmlElement:o,rttHTML:a}=e;di=t||"https://aicc-api.yescloudy.com",li=s,gi=i;const c=Ft(s,i);await this.#t._agentLogin(r);const{agent_no:h,current_answer_device:d,init_state:l}=pi.agentInfo;l===et.IDLE?(dt.updateActionConfigs(wi),pi.stateObject={state:l,state_name:"空闲"}):l===et.BUSY&&(dt.updateActionConfigs(yi),pi.stateObject={state:l,state_name:"忙碌"}),Li.getInstance(`ws://112.90.183.54:8719/api/v1/ws/call/${h}?Authorization=${c}`),dt.updateAnswerDevice(d),1===d&&await this.initWebRtc(),e&&o&&(this.#i=!0,new Hi({container:o,rttHTML:a,statusParams:{state:et.IDLE,statusName:"空闲"}},this)),pi.enableBrowserAlert=n,n&&Oi.requestPermission()}catch(e){this.#i&&oi("初始化失败"),console.log(e)}}#o=e=>{const{type:t,data:s}=e;ct.emit(t,s)};#a=e=>{};on(e,t){return ct.on(e,t),this}off(e,t){ct.off(e,t)}offAll(){ct.clearAllListeners()}#c(){if(!this.#e)throw new Error("请先初始化SDK");const e=dt.get("isCalling"),t=pi.sessionId;if(!e)throw new Error("当前没有通话");if(!t)throw new Error("sessionId不存在")}#h(){const e=dt.get("isHold"),{sessionId:t}=pi;if(t){if(e)throw new Error("当前已处于保持状态");Li.__internalSend({type:rt.CALL_HOLD,data:{session_id:t}}),dt.updateDisplayText(ot.HOLD),dt.updateIsHold(!0)}}#d(){const{isHold:e}=dt.getState(),{sessionId:t}=pi;if(t){if(!e)throw new Error("当前未处于保持状态");Li.__internalSend({type:rt.CALL_UNHOLD,data:{session_id:t}}),dt.updateDisplayText(""),dt.updateIsHold(!1)}}#l(e){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:t}=dt.getState();if(!t)throw new Error("当前没有通话");this.#e.sendDTMF(e)}#g(){if(1!==dt.get("answerDevice"))throw new Error("当前设备不支持此功能");if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:e,direction:t,outCallIsAnswer:s}=dt.getState();if(!e)throw new Error("当前没有通话");s||(t===tt.INCOMING?this.#u():t===tt.OUTGOING&&this.#p())}async#f(e){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:t,outCallIsAnswer:s,consultIsAnswer:i,incomingIsAnswer:r}=dt.getState(),n=pi.sessionId;if(i)throw new Error("当前正在咨询");if(!(t||s||r))throw new Error("当前没有通话");if(!n)throw new Error("sessionId不存在");Li.__internalSend({type:rt.CONSULT_REQUEST,data:{session_id:n,consultation_agent_no:e}})}async#m(){if(1!==dt.get("answerDevice"))throw new Error("当前设备不支持此功能");if(!this.#e)throw new Error("请先初始化SDK");await this.#e.answerCall()}async#u(){if(!this.#e)throw new Error("请先初始化SDK");const{isCalling:e}=dt.getState();if(!e)throw new Error("当前没有通话");await this.#e.rejectInCall()}async#v(e){if(!this.#e)throw new Error("请先初始化SDK");if(dt.getState().isCalling)throw new Error("正在呼叫中,请勿重复点击");dt.updateIsCalling(!0),dt.updateDirection(tt.OUTGOING),Li.__internalSend({type:rt.OUT_CALL,data:{customer_phone:e}})}async#p(){const{isCalling:e}=dt.getState();if(!this.#e)throw new Error("请先初始化SDK");if(!e)throw new Error("当前没有通话");await this.#e.rejectOutCall()}async#w(){if(!this.#e)throw new Error("请先初始化SDK");if(!dt.get("isCalling"))throw new Error("当前没有通话");await this.#e.hangup()}#y(){this.#c();const e=dt.get("actionConfigs"),t=dt.get("isMuted"),s=pi.sessionId;if(t)throw new Error("当前未处于静音状态");if(!e.includes("mute"))throw new Error("当前状态请勿调用静音");Li.__internalSend({type:rt.MUTE,data:{session_id:s}})}#b(){this.#c();const e=dt.get("actionConfigs"),t=dt.get("isMuted"),s=pi.sessionId;if(!t)throw new Error("当前未处于未静音状态");if(!e.includes("unmute"))throw new Error("当前状态请勿调用静音");Li.__internalSend({type:rt.UNMUTE,data:{session_id:s}})}#T(){this.#c();const e=dt.get("consultIsAnswer"),t=pi.sessionId;if(!dt.get("actionConfigs").includes("consult_transfer"))throw new Error("当前状态请勿调用咨询转移");if(!e)throw new Error("当前未处于咨询中");Li.__internalSend({type:rt.CONSULT_TRANSFER,data:{session_id:t}})}async destroyRtc(){await(this.#e?.destroy())}destroy(){this.destroyRtc(),clearInterval(this.#s),Pi.off("ws-message",this.#a),Li.__internalClose(),this.offAll(),this.#r?.()}async#n(){return this.#e?this.#e.getNetworkStats():{}}get call_api(){return this.#i?{answerCall:this.#m.bind(this),makeCall:this.#v.bind(this),cancelCall:this.#g.bind(this),hangup:this.#w.bind(this),sendDTMF:this.#l.bind(this),holdCall:this.#h.bind(this),unholdCall:this.#d.bind(this),consultCall:async e=>{try{await this.#f(e)}catch(e){throw console.warn(e),e}},consultTransfer:this.#T.bind(this),mute:this.#y.bind(this),unmute:this.#b.bind(this)}:{}}get agent_api(){return this.#i?{changeDevice:this.#t.changeDevice.bind(this.#t),changeState:this.#t.changeState.bind(this.#t),getIdleAgentList:e=>this.#t.getIdleAgentList(e),getAgentState:e=>this.#t.getAgentState(e)}:{}}}});
|