Files
zyt/server/public/admin/assets/index-DKWTTvx4.js
T
2026-03-27 18:06:12 +08:00

2 lines
30 KiB
JavaScript

var Oe=Object.defineProperty;var He=(f,n,a)=>n in f?Oe(f,n,{enumerable:!0,configurable:!0,writable:!0,value:a}):f[n]=a;var A=(f,n,a)=>He(f,typeof n!="symbol"?n+"":n,a);import{d as Ke,i as We,K as ze}from"./element-plus-D9NzL5HE.js";import{q as Be,s as ft}from"./@vue/runtime-dom-iFk_KP8y.js";import{c as Xt,l as Fe,V as qe,W as je}from"./@element-plus/icons-vue-BZWa1PtL.js";import{u as Ge,i as $e}from"./file-BtSeeESa.js";import{j as At,t as Ye,q as Xe,M as Je,N as Qe,O as Ze,P as to}from"./tcm-9dTydv5E.js";import{u as eo,h as S,a as oo}from"./index-D54sWaXv.js";import{E as no}from"./@tencentcloud/chat-uikit-vue3-BidaUQ0g.js";import{T as It}from"./@tencentcloud/chat-AC2Y2r2A.js";import{u as ao,F as I,z as io,g as V,a as O,l as D}from"./@tencentcloud/call-uikit-vue-6oZM4bBc.js";import{c as Z}from"./@tencentcloud/call-engine-js-BX2W9Lhf.js";import{C as so,M as ro,a as lo,O as co,E as uo,N as fo,S as mo,A as ho,b as po}from"./tuikit-atomicx-vue3-BHPlbt3H.js";import{D as go}from"./@tencentcloud/uikit-base-component-vue3-k0EAtVKz.js";import{f as vo,b as yo,d as _o,w as wo,ak as U,G as mt,aP as So,J as b,a as y,aN as L,I as tt,H as et,O as Co,T as To,n as Rt,A as Jt}from"./@vue/runtime-core-C0pg79pw.js";import{Q as Qt,p as Zt}from"./@vue/shared-mAAVTE9n.js";import{y as R,o as p}from"./@vue/reactivity-BIbyPIZJ.js";import"./lodash-es-BADexyn7.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./lodash-D3kF6u-c.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-CYz6RFzi.js";import"./pinia-Ba_jX6-d.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-DIKi2bJB.js";import"./@vueuse/shared-D8934tfB.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-DYKKs4Al.js";import"./tslib-BDyQ-Jie.js";import"./zrender-CTTuYiLF.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./@tencentcloud/chat-uikit-engine-zx802ozq.js";import"./tim-upload-plugin-HO4N4AW9.js";import"./tim-profanity-filter-plugin-Dn_Cf-mP.js";import"./@tencentcloud/tui-core-8M7p1XHw.js";import"./rtc-detect-Chu-fZvE.js";import"./vue-tI-HfQaQ.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./@tencentcloud/tuiroom-engine-js-Br9swJyU.js";import"./tcplayer.js-qpFBCYzN.js";function Eo(){const f=["video/webm;codecs=vp9,opus","video/webm;codecs=vp8,opus","video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm"];for(const n of f)if(MediaRecorder.isTypeSupported(n))return n;return""}function Ao(){const f=window;return f.AudioContext||f.webkitAudioContext||null}function te(f,n,a,l,s,u){const m=n.videoWidth||n.clientWidth||1,r=n.videoHeight||n.clientHeight||1,c=Math.max(s/m,u/r),h=m*c,v=r*c,_=a+(s-h)/2,C=l+(u-v)/2;try{f.drawImage(n,_,C,h,v)}catch{}}function Io(f,n,a,l){f.fillStyle="#0b0b0b",f.fillRect(0,0,a,l);const s=n.filter(h=>h.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA);if(s.length===0)return;if(s.length===1){te(f,s[0],0,0,a,l);return}const u=Math.ceil(Math.sqrt(s.length)),m=Math.ceil(s.length/u),r=a/u,c=l/m;s.forEach((h,v)=>{const _=v%u,C=Math.floor(v/u);te(f,h,_*r,C*c,r,c)})}function Ro(f){const n=new Set,a=[];for(const l of f){const s=l.srcObject;if(s instanceof MediaStream)for(const u of s.getAudioTracks())u.kind!=="audio"||u.readyState==="ended"||!u.enabled||n.has(u.id)||(n.add(u.id),a.push(u))}return a}function ko(f){var l;const n=new Set,a=[];for(const s of f){if(s.readyState<HTMLMediaElement.HAVE_CURRENT_DATA)continue;const u=(l=s.captureStream)==null?void 0:l.call(s);if(u)for(const m of u.getAudioTracks())m.kind!=="audio"||m.readyState==="ended"||!m.enabled||n.has(m.id)||(n.add(m.id),a.push(m))}return a}function bo(f){const n=new Set,a=[],l=[...document.body.querySelectorAll("audio")];f&&l.push(...f.querySelectorAll("audio"));const s=document.getElementById("tuicallkit-id");s&&l.push(...s.querySelectorAll("audio"));const u=new Set;for(const m of l){if(u.has(m))continue;u.add(m);const r=m.srcObject;if(r instanceof MediaStream)for(const c of r.getAudioTracks())c.kind!=="audio"||c.readyState==="ended"||!c.enabled||n.has(c.id)||(n.add(c.id),a.push(c))}return a}function kt(f){const n=new Set,a=r=>{const c=[];for(const h of r)n.has(h)||(n.add(h),c.push(h));return c},l=[...f.querySelectorAll("video")];if(l.length>0)return a(l);const s=document.getElementById("tuicallkit-id");if(s){const r=[...s.querySelectorAll("video")];if(r.length>0)return a(r)}const m=[...document.body.querySelectorAll("video")].filter(r=>{const c=r.srcObject;return c instanceof MediaStream?c.getVideoTracks().some(h=>h.readyState==="live"):!1});return a(m)}class Lo{constructor(){A(this,"canvas",null);A(this,"ctx",null);A(this,"rafId",0);A(this,"container",null);A(this,"mediaRecorder",null);A(this,"chunks",[]);A(this,"mimeType","");A(this,"audioCtx",null);A(this,"audioDestination",null);A(this,"wiredTrackIds",new Set);A(this,"canvasVideoTrack",null);A(this,"silentOsc",null);A(this,"silentGain",null);A(this,"micStream",null);A(this,"stopResultPromise",null)}isRecording(){return this.mediaRecorder!==null&&this.mediaRecorder.state==="recording"}beginStopNow(){if(this.stopResultPromise)return;cancelAnimationFrame(this.rafId),this.rafId=0;const n=this.mediaRecorder,a=this.mimeType;!n||n.state==="inactive"||(this.stopResultPromise=new Promise(l=>{var s;n.onstop=()=>{this.teardownAudioGraph();const u=n.mimeType||a||"video/webm",m=this.chunks.length>0?new Blob(this.chunks,{type:u}):null;this.chunks=[],this.mediaRecorder=null,this.container=null,this.canvas=null,this.ctx=null,this.canvasVideoTrack=null,l(m&&m.size>0?m:null)};try{const u=n;(s=u.requestData)==null||s.call(u),n.stop()}catch{this.teardownAudioGraph(),this.chunks=[],this.mediaRecorder=null,this.container=null,this.canvas=null,this.ctx=null,this.canvasVideoTrack=null,l(null)}}))}teardownAudioGraph(){var n;try{(n=this.silentOsc)==null||n.stop()}catch{}if(this.silentOsc=null,this.silentGain=null,this.micStream){for(const a of this.micStream.getTracks())try{a.stop()}catch{}this.micStream=null}this.wiredTrackIds.clear(),this.audioDestination=null,this.audioCtx&&(this.audioCtx.close().catch(()=>{}),this.audioCtx=null)}connectTrackToMixer(n){if(!(n.kind!=="audio"||n.readyState==="ended"||!n.enabled)&&!(!this.audioCtx||!this.audioDestination)&&!this.wiredTrackIds.has(n.id))try{const a=this.audioCtx.createMediaStreamSource(new MediaStream([n])),l=this.audioCtx.createGain();l.gain.value=1.25,a.connect(l),l.connect(this.audioDestination),this.wiredTrackIds.add(n.id)}catch{}}attachMicForMixer(){if(!this.audioCtx||!this.audioDestination)return;const n=navigator.mediaDevices;n!=null&&n.getUserMedia&&n.getUserMedia({audio:!0,video:!1}).then(a=>{if(!this.audioDestination||!this.audioCtx){a.getTracks().forEach(l=>l.stop());return}if(this.micStream){a.getTracks().forEach(l=>l.stop());return}this.micStream=a;for(const l of a.getAudioTracks())this.connectTrackToMixer(l)}).catch(()=>{})}wireIncomingAudio(){var m;if(!this.audioCtx||!this.audioDestination||!this.container)return;this.audioCtx.state==="suspended"&&this.audioCtx.resume().catch(()=>{});const n=kt(this.container),a=document.getElementById("tuicallkit-id"),l=[...document.body.querySelectorAll("audio"),...this.container.querySelectorAll("audio"),...a?a.querySelectorAll("audio"):[]],s=new Set,u=[];for(const r of n)s.has(r)||(s.add(r),u.push(r));for(const r of l)s.has(r)||(s.add(r),u.push(r));for(const r of u){const c=r.srcObject;if(c instanceof MediaStream)for(const h of c.getAudioTracks())this.connectTrackToMixer(h);if(r instanceof HTMLVideoElement&&r.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){const h=(m=r.captureStream)==null?void 0:m.call(r);if(h)for(const v of h.getAudioTracks())this.connectTrackToMixer(v)}}}reset(){if(cancelAnimationFrame(this.rafId),this.rafId=0,this.stopResultPromise=null,this.canvasVideoTrack=null,this.mediaRecorder&&this.mediaRecorder.state!=="inactive")try{this.mediaRecorder.stop()}catch{}this.mediaRecorder=null,this.chunks=[],this.canvas=null,this.ctx=null,this.container=null,this.mimeType="",this.teardownAudioGraph()}start(n){if(typeof MediaRecorder>"u")return!1;this.reset(),this.container=n;const a=Eo();if(this.mimeType=a||"video/webm",this.canvas=document.createElement("canvas"),this.canvas.width=1280,this.canvas.height=720,this.ctx=this.canvas.getContext("2d",{alpha:!1}),!this.ctx)return!1;const s=this.canvas.captureStream(30).getVideoTracks();this.canvasVideoTrack=s[0]??null;const u=kt(n),m=Ao();let r;if(m)try{this.audioCtx=new m,this.audioDestination=this.audioCtx.createMediaStreamDestination(),this.audioCtx.resume().catch(()=>{}),this.wireIncomingAudio(),this.attachMicForMixer();const h=this.audioDestination.stream.getAudioTracks(),v=this.audioCtx.createOscillator(),_=this.audioCtx.createGain();_.gain.value=1e-5,v.frequency.value=20,v.connect(_),_.connect(this.audioDestination),v.start(),this.silentOsc=v,this.silentGain=_,r=new MediaStream([...s,...h])}catch{this.teardownAudioGraph(),r=this.buildStreamWithoutMixer(s,u)}else r=this.buildStreamWithoutMixer(s,u);try{this.mediaRecorder=a?new MediaRecorder(r,{mimeType:a}):new MediaRecorder(r)}catch{try{this.mediaRecorder=new MediaRecorder(r)}catch{return this.reset(),!1}}this.chunks=[],this.mediaRecorder.ondataavailable=h=>{h.data&&h.data.size>0&&this.chunks.push(h.data)},this.mediaRecorder.onerror=h=>{console.error("[call-local-recorder] MediaRecorder 错误",h)};const c=()=>{var v,_;if(!this.ctx||!this.canvas||!this.container)return;this.wireIncomingAudio();const h=kt(this.container);Io(this.ctx,h,this.canvas.width,this.canvas.height),(_=(v=this.canvasVideoTrack)==null?void 0:v.requestFrame)==null||_.call(v),this.rafId=requestAnimationFrame(c)};this.rafId=requestAnimationFrame(c);try{this.mediaRecorder.start(250)}catch{return this.reset(),!1}return!0}buildStreamWithoutMixer(n,a){const l=new Set,s=[],u=m=>{for(const r of m)l.has(r.id)||(l.add(r.id),s.push(r))};return u(Ro(a)),u(ko(a)),u(bo(this.container)),new MediaStream([...n,...s])}async stop(){this.beginStopNow();const n=this.stopResultPromise;return n||null}}async function Mo(f){const n=Array.from(f.querySelectorAll("video"));let a=null,l=0;for(const c of n){if(c.readyState<2)continue;const h=c.videoWidth||c.clientWidth,v=c.videoHeight||c.clientHeight,_=h*v;_>l&&(l=_,a=c)}if(!a)return null;const s=a.videoWidth||a.clientWidth,u=a.videoHeight||a.clientHeight;if(!s||!u)return null;const m=document.createElement("canvas");m.width=s,m.height=u;const r=m.getContext("2d");if(!r)return null;try{r.drawImage(a,0,0,s,u)}catch{return null}return new Promise(c=>{m.toBlob(h=>c(h),"image/jpeg",.92)})}function Do(f){const n=[];let a=f,l=0;for(;a!=null&&l<6;){if(typeof a=="string"){n.push(a);break}if(typeof a=="object"){const s=a;typeof s.message=="string"&&n.push(s.message),typeof s.name=="string"&&n.push(s.name),typeof s.code<"u"&&n.push(String(s.code)),a=s.cause}else{n.push(String(a));break}l++}return n.join(" ").toLowerCase()}const ee=-1001;function q(f){if(f&&typeof f=="object"){const a=f,l=a.code??a.error_code;if(l===ee||l===String(ee))return!0}const n=Do(f);return n.includes("does not support this ability")||n.includes("package you purchased")||n.includes("-1001")&&n.includes("does not support")}function ne(){return"套餐欠费或未开通该能力,请联系管理员在腾讯云续费或升级套餐。"}function xo(f,n="通话操作失败"){return q(f)?ne():f instanceof Error?f.message||n:typeof f=="string"&&f||n}const Uo={class:"chat-window-title"},No={class:"chat-container"},Po={key:0,class:"loading-container"},Vo={key:1,class:"error-container"},Oo={key:2,class:"chat-content"},Ho={class:"chat-layout"},Ko={class:"message-toolbar"},Wo={class:"call-kit-drag-handle-left"},zo={key:0,class:"call-local-recording-hint"},Bo={class:"call-kit-drag-handle-actions"},ot="idle",nt="calling",K="connected",oe=40,Fo=100,qo=2600,jo=vo({__name:"index",setup(f,{expose:n}){const a=p(""),l=p(!1),s=p(!1),u=p(""),m=p(""),r=p(null),c=p(null),h=p("正在初始化..."),v=p(""),_=p(""),C=p(!1),N=p(!1),{login:ae}=po(),{setActiveConversation:ie,createC2CConversation:se,activeConversation:re}=ho(),le=eo(),j=p("");let P=null,W=null,ht=0;const k=new Lo,pt=p(!1),G=p(!1);let gt=0,z=null,$=null,at=Promise.resolve(),bt=null;function B(){z&&(clearTimeout(z),z=null)}function vt(t){pt.value=!!(t!=null&&t.isLochostVod)}function it(){return $||($=(async()=>{if(B(),G.value=!1,!pt.value)return;k.beginStopNow();const t=bt??c.value;try{await at}catch{}const e=await k.stop();if(!e){console.warn("[chat-dialog] 本地录制无有效文件(若通话较长仍出现,请换 Chrome 并看控制台是否有 MediaRecorder 报错)");return}if(t==null){S.msgWarning("缺少诊单信息,本地录制无法保存到通话记录");return}try{const o=await $e(e,`call-rec-${t}-${Date.now()}.webm`),i=o.uri||o.url;if(!i){S.msgError("上传成功但未返回文件地址");return}await Je({diagnosis_id:t,file_url:i}),S.msgSuccess("本地录制已上传并关联到通话记录")}catch(o){const i=o instanceof Error?o.message:String(o);console.warn("[chat-dialog] 本地录制上传/关联失败",o),S.msgError(i||"本地录制上传失败")}})().finally(()=>{$=null}),$)}function ce(){const t=V.getData(O.CALL,D.ROOM_ID);if(t==null)return"";if(typeof t=="number")return t===0?"":String(t);const e=String(t).trim();return!e||e==="0"?"":e}function ue(){var t,e;try{const o=(e=(t=I).getTUICallEngineInstance)==null?void 0:e.call(t);if(!o)return"";const i=[o.roomId,o.roomID,o._roomId,o._roomID,o.strRoomID];for(const d of i){if(d==null||d==="")continue;const g=String(d).trim();if(g&&g!=="0")return g}}catch{}return""}function yt(){return ce()||ue()}function st(t,e){if(e!=null&&String(e).trim()!==""&&String(e)!=="0")return String(e).trim();if(typeof t=="number"&&t>0)return String(t);if(typeof t=="string"){const o=t.trim();if(o&&o!=="0")return o}return""}function Lt(t){if(t==null||typeof t!="object")return"";const e=t,o=st(e.roomID,e.strRoomID)||st(e.roomId,e.strRoomId);if(o)return o;const i=e.data;if(i&&typeof i=="object"){const d=i,g=st(d.roomID,d.strRoomID)||st(d.roomId,d.strRoomId);if(g)return g}return""}function F(){W&&(clearTimeout(W),W=null),ht=0}function de(){F();const t=()=>{W=null;const e=V.getData(O.CALL,D.CALL_STATUS);if(e===ot||e!==nt&&e!==K)return;const o=yt();if(o){X(o);return}if(ht++,ht>=oe){console.warn("[chat-dialog] 仍未解析到有效房间号(已重试",oe,"次)");return}W=setTimeout(t,Fo)};W=setTimeout(t,0)}async function Mt(t){if(!(r.value==null||c.value==null)){await Rt();for(let e=0;e<40;e++){const o=yt();if(o){await X(o);return}await new Promise(i=>setTimeout(i,50))}console.warn("[chat-dialog] 发起通话后仍未解析到房间号(API:",t,")")}}function fe(){var i,d;const t=window;if(t.__zytEngineRoomCapture__)return;const e=(d=(i=I).getTUICallEngineInstance)==null?void 0:d.call(i);if(!e||typeof e.calls!="function")return;t.__zytEngineRoomCapture__=!0,e.__zytEngineRoomCapture__=!0;const o=g=>{const w=e[g];typeof w=="function"&&(e[g]=async function(...T){const x=await w.apply(e,T),M=Lt(x);return M&&X(M),await Mt("engine."+g),x})};o("calls"),o("call"),o("groupCall")}function me(){const t=window;if(t.__zytHangupPreStop__)return;const e=I,o=e.hangup;typeof o=="function"&&(t.__zytHangupPreStop__=!0,e.hangup=function(...d){return k.beginStopNow(),o.apply(I,d)})}function Dt(){var g,w;const t=window;if(t.__zytTrtcPreStop__)return;const e=(w=(g=I).getTUICallEngineInstance)==null?void 0:w.call(g),o=e==null?void 0:e.trtcCloud;if(!o||typeof o!="object")return;let i=0;const d=["stopLocalVideo","stopLocalAudio"];for(const E of d){const T=o[E];typeof T=="function"&&(o[E]=function(...M){return k.beginStopNow(),T.apply(o,M)},i++)}i>0&&(t.__zytTrtcPreStop__=!0)}let Y=[];function he(){var t,e;try{const o=(e=(t=I).getTUICallEngineInstance)==null?void 0:e.call(t),i=o==null?void 0:o.on;if(!o||typeof i!="function"||o.__zytRoomEvents)return;o.__zytRoomEvents=!0;const d=T=>{const x=Lt(T);if(x){X(x);return}_t()},g=()=>{console.log("[chat-dialog] 检测到通话结束事件,立即停止录制"),k.isRecording()&&(console.log("[chat-dialog] 录制进行中,触发 beginStopNow"),k.beginStopNow())},w=[Z.TUICallEvent.CALL_END,Z.TUICallEvent.USER_LEAVE,Z.TUICallEvent.ON_CALL_NOT_CONNECTED];for(const T of w)i.call(o,T,g),Y.push({event:T,fn:g});const E=[Z.TUICallEvent.USER_ENTER,Z.TUICallEvent.ON_CALL_BEGIN];for(const T of E)i.call(o,T,d),Y.push({event:T,fn:d})}catch(o){console.warn("[chat-dialog] 绑定引擎房间事件失败",o)}}function pe(){var t,e;try{const o=(e=(t=I).getTUICallEngineInstance)==null?void 0:e.call(t);if(!(o!=null&&o.off)){Y=[];return}for(const{event:i,fn:d}of Y)o.off(i,d);o.__zytRoomEvents=!1}catch{}Y=[]}function ge(){const t=window;if(t.__zytTUICallRoomHooks__)return;t.__zytTUICallRoomHooks__=!0;const e=I,o=i=>{const d=e[i];typeof d=="function"&&(e[i]=async function(...w){const E=await d.apply(e,w);return await Mt(i),E})};o("calls"),o("call"),o("groupCall")}async function X(t){try{await at}catch{}if(r.value==null||c.value==null)return;const e=`${c.value}:${t}`;if(e===j.value){F();return}j.value=e;try{await Qe({diagnosis_id:c.value,room_id:t}),F(),console.log("[chat-dialog] bindCallRoom 成功",{room_id:t})}catch(o){console.warn("[chat-dialog] bindCallRoom 失败",o),j.value=""}}async function _t(){if(r.value==null||c.value==null)return;const t=V.getData(O.CALL,D.CALL_STATUS);if(t===ot){F(),j.value="";return}if(t!==nt&&t!==K)return;await Rt();const e=yt();if(e){await X(e);return}de()}async function ve(){if(!(r.value==null||c.value==null))try{await Ze({diagnosis_id:c.value,patient_id:r.value,call_type:2})}catch(t){console.warn("[chat-dialog] startCall 记录失败",t)}}async function wt(){if(c.value!=null)try{await to({diagnosis_id:c.value}),console.log("[chat-dialog] endCall 已同步")}catch(t){console.warn("[chat-dialog] endCall 失败",t)}}function ye(){P==null||P();let t=V.getData(O.CALL,D.CALL_STATUS)??ot;const e=i=>{const d=i??ot;if(d===ot){(t===nt||t===K)&&k.beginStopNow(),B(),G.value=!1,(t===nt||t===K)&&(async()=>(await it(),N.value=!1,await wt()))(),F(),j.value="",t=d;return}if(d===K){if(_t(),B(),!pt.value){t=d;return}const g=gt,w=(E=0)=>{if(g!==gt){console.log("[chat-dialog] 录制轮次已变化,取消启动");return}const T=Ct.value,x=V.getData(O.CALL,D.CALL_STATUS);if(!T||x!==K){console.warn("[chat-dialog] 录制启动条件不满足",{root:!!T,status:x});return}console.log(`[chat-dialog] 尝试启动本地录制(第 ${E+1} 次)`);let M=Array.from(T.querySelectorAll("video"));if(M.length===0&&(M=Array.from(document.body.querySelectorAll("video")).filter(Pe=>{const Yt=Pe.srcObject;return Yt instanceof MediaStream?Yt.getVideoTracks().some(Ve=>Ve.readyState==="live"):!1}),console.log("[chat-dialog] 在 body 中找到活跃视频:",M.length)),M.length===0){E<10?(console.warn("[chat-dialog] 未找到视频元素,300ms 后重试"),z=setTimeout(()=>w(E+1),300)):console.error("[chat-dialog] 重试 10 次后仍未找到视频元素,放弃录制");return}if(!M.some($t=>$t.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA)){E<10?(console.warn("[chat-dialog] 视频元素未就绪,300ms 后重试"),z=setTimeout(()=>w(E+1),300)):console.error("[chat-dialog] 重试 10 次后视频仍未就绪,放弃录制");return}console.log("[chat-dialog] 视频元素已就绪,立即启动录制");const Gt=k.start(T);G.value=Gt,Gt?console.log("[chat-dialog] ✅ 本地录制已成功启动"):console.error("[chat-dialog] 本地录制启动失败(MediaRecorder 或画布初始化失败)")};z=setTimeout(()=>w(0),500)}else B();t=d},o=()=>{_t()};V.watch(O.CALL,{[D.CALL_STATUS]:e,[D.ROOM_ID]:o}),P=()=>{try{V.unwatch(O.CALL,{[D.CALL_STATUS]:e,[D.ROOM_ID]:o})}catch{}F(),P=null}}let xt=0;function J(){const t=Date.now();t-xt<qo||(xt=t,S.msgError(ne()),N.value=!1)}let Q=null,rt=!1,H=null;function _e(){rt||(Q=console.error.bind(console),rt=!0,console.error=(...t)=>{if(Q(...t),!l.value||!C.value)return;const e=t.map(o=>{if(typeof o=="string")return o;if(o instanceof Error)return o.message;try{return JSON.stringify(o)}catch{return String(o)}}).join(" ");q(e)&&J()})}function we(){rt&&Q&&(console.error=Q),rt=!1,Q=null}function Se(){var t,e,o;try{const i=(e=(t=I).getTUICallEngineInstance)==null?void 0:e.call(t);if(!(i!=null&&i.on))return;H&&((o=i.off)==null||o.call(i,"error",H)),H=d=>{!l.value||!C.value||q(d)&&J()},i.on("error",H)}catch(i){console.warn("绑定 TUICallEngine error 监听失败:",i)}}function Ce(){var t,e;try{const o=(e=(t=I).getTUICallEngineInstance)==null?void 0:e.call(t);o!=null&&o.off&&H&&o.off("error",H)}catch{}H=null}async function Te(t,e){try{const o=It.create({SDKAppID:t}),i={businessID:"doctor_entered_consult_room",time:Date.now()},d=o.createCustomMessage({to:e,conversationType:It.TYPES.CONV_C2C,payload:{data:JSON.stringify(i)}});await o.sendMessage(d),console.log("已发送医生进入诊室信令(患者端聊天列表不展示)")}catch(o){console.warn("发送医生进入诊室信令失败:",o)}}const Ut=t=>{!l.value||!C.value||q(t.reason)&&J()};yo(()=>{_e(),window.addEventListener("unhandledrejection",Ut)}),_o(()=>{B(),k.reset(),P==null||P(),pe(),we(),Ce(),window.removeEventListener("unhandledrejection",Ut)});const Ee=async(t,e)=>{try{if(!t){console.warn("头像 URL 为空,跳过更新");return}console.log("开始更新头像到 IM:",t);const o=await new Promise((i,d)=>{setTimeout(async()=>{try{const w=await It.create({SDKAppID:e}).updateMyProfile({avatar:t});console.log("IM 头像更新成功:",w),i(w)}catch(g){console.error("更新头像异常:",g),i(null)}},500)})}catch(o){console.error("IM 头像更新失败:",o.message||o)}};wo(()=>re.value,async t=>{if(t){if(m.value=t.getShowName()||m.value,console.log("会话切换:",t.conversationID,"名称:",m.value,t),t.userProfile.userID.includes("doctor"))console.log("当前会话是医生,跳过获取 assistant_id");else try{const e=await At({patient_id:t.userProfile.userID.replace("patient_",""),diagnosis_id:c.value});vt(e),v.value=e.patientUserId,a.value=e.assistant_id,console.log("会话切换后获取到 assistant_id:",a.value,"完整响应:",e)}catch(e){console.error("获取 assistant_id 失败:",e)}console.log("会话切换完成,userID:",t.userProfile.userID)}});const Ae=async t=>{l.value=!0,lt.value=100,ct.value=80,ut.value=Math.max(0,(window.innerWidth-375)/2),dt.value=Math.max(0,(window.innerHeight-667)/2),m.value=t.patientName,r.value=t.patientId,c.value=t.diagnosisId||null,u.value="",s.value=!1,C.value=!1,N.value=!1,h.value="正在获取签名...";try{const e=await At({patient_id:t.patientId,diagnosis_id:t.diagnosisId||0});if(vt(e),a.value=e.assistant_id,console.log("后端返回的签名数据:",e),console.log("assistant_id:",a.value),!e||!e.userSig)throw new Error("获取签名失败");e.assistant_id||console.warn("警告:后端未返回 assistant_id,群视频通话可能无法正常工作"),v.value=e.patientUserId||`patient_${t.patientId}`,h.value="正在登录聊天...",await ae({sdkAppId:Number(e.sdkAppId),userId:e.userId,userSig:e.userSig,useUploadPlugin:!0});const o=Number(e.sdkAppId);if(!window.__TUICallKitInited__){h.value="正在初始化通话能力...";try{await I.init({userID:e.userId,userSig:e.userSig,SDKAppID:o}),window.__TUICallKitInited__=!0}catch(i){console.warn("TUICallKit 初始化失败,聊天仍可用,音视频通话不可用:",(i==null?void 0:i.message)||i),q(i)&&J()}}C.value=!!window.__TUICallKitInited__,C.value&&(I.setCallback({beforeCalling:()=>{Dt(),B(),k.reset(),G.value=!1,gt++,bt=c.value,N.value=!0,at=ve()},afterCalling:()=>{k.beginStopNow(),(async()=>(await it(),N.value=!1,await wt()))()}}),ge(),fe(),me(),Dt(),he(),ye(),Se()),console.log("Chat UIKit 登录成功,患者用户ID:",v.value),h.value="加载聊天界面...",setTimeout(async()=>{var d;s.value=!0,await Rt(),await new Promise(g=>setTimeout(g,1e3));const i=(d=le.userInfo)==null?void 0:d.avatar;console.log("准备更新头像,avatar:",i),i&&await Ee(i,o);try{const g=await se(v.value);_.value=g.conversationID,console.log("已创建/获取会话:",_.value),ie(_.value),console.log("已激活会话"),await Te(o,v.value)}catch(g){console.error("创建/激活会话失败:",g)}},800)}catch(e){console.error("初始化聊天失败:",e),u.value=e.message||"初始化聊天失败",S.msgError(u.value)}},Ie=async()=>{if(!C.value){S.msgWarning("通话服务初始化中,请稍后再试");return}if(!v.value){S.msgWarning("未找到患者通话ID,无法发起群视频");return}try{if(!a.value){console.warn("assistant_id 为空,尝试重新获取");const e=await At({patient_id:r.value,diagnosis_id:c.value});vt(e),a.value=e.assistant_id,console.log("重新获取 assistant_id:",a.value)}const t=[v.value,a.value].filter(e=>e);if(t.length<2){S.msgWarning("助理ID获取失败,无法发起群视频"),console.error("userIDList 不完整:",t,"assistant_ids:",a.value);return}console.log("发起群视频通话,参与者:",t),await I.calls({userIDList:t,type:io.VIDEO_CALL})}catch(t){console.error("发起群视频失败:",t),q(t)?J():S.msgError(xo(t,"发起群视频失败"))}},Re=p(),lt=p(100),ct=p(80),St=p(!1),Nt=p(0),Pt=p(0),Vt=p(0),Ot=p(0),ke=p(),Ct=p(),Tt=p(!1),ut=p(0),dt=p(0),Et=p(!1),Ht=p(0),Kt=p(0),Wt=p(0),zt=p(0),be=Jt(()=>({left:`${ut.value}px`,top:`${dt.value}px`})),Le=t=>{Et.value=!0,Ht.value=t.clientX,Kt.value=t.clientY,Wt.value=ut.value,zt.value=dt.value,document.addEventListener("mousemove",Bt),document.addEventListener("mouseup",Ft)},Bt=t=>{Et.value&&(ut.value=Math.max(0,Wt.value+t.clientX-Ht.value),dt.value=Math.max(0,zt.value+t.clientY-Kt.value))},Ft=()=>{Et.value=!1,document.removeEventListener("mousemove",Bt),document.removeEventListener("mouseup",Ft)},Me=async()=>{if(r.value==null){S.msgWarning("缺少患者信息,无法同步舌苔照片");return}const t=Ct.value;if(t){Tt.value=!0;try{const e=await Mo(t);if(!e){S.msgWarning("截屏失败,请确认视频画面已加载");return}const o=await Ge(e,`callshot-${Date.now()}.jpg`),i=o.url||o.uri;if(!i){S.msgError("上传未返回图片路径");return}if(c.value==null){S.msgWarning("请先保存诊单后再从视频同步舌苔照片");return}const d=await Ye({id:c.value});if(Number(d.patient_id)!==Number(r.value)){S.msgError("患者与当前诊单不匹配,无法同步");return}const g=[...d.tongue_images||[]];if(g.length>=9){S.msgWarning("舌苔照片已达上限 9 张");return}const w=[...g,i],E=JSON.parse(JSON.stringify(d));E.tongue_images=w,await Xe(E),S.msgSuccess("舌苔照片已同步到诊单")}catch(e){const o=e;console.error(o),S.msgError((o==null?void 0:o.message)||"上传失败")}finally{Tt.value=!1}}},De=async()=>{if(C.value)try{k.beginStopNow(),await it(),await I.hangup()}catch(t){console.warn("关闭视频窗口时挂断失败:",t)}N.value=!1},xe=Jt(()=>({left:`${lt.value}px`,top:`${ct.value}px`})),Ue=t=>{t.target.closest(".chat-close-btn")||(St.value=!0,Nt.value=t.clientX,Pt.value=t.clientY,Vt.value=lt.value,Ot.value=ct.value,document.addEventListener("mousemove",qt),document.addEventListener("mouseup",jt))},qt=t=>{St.value&&(lt.value=Math.max(0,Vt.value+t.clientX-Nt.value),ct.value=Math.max(0,Ot.value+t.clientY-Pt.value))},jt=()=>{St.value=!1,document.removeEventListener("mousemove",qt),document.removeEventListener("mouseup",jt)},Ne=async()=>{if(C.value){const t=V.getData(O.CALL,D.CALL_STATUS);if(t===nt||t===K)try{k.beginStopNow(),await it(),await I.hangup()}catch(e){console.warn("挂断通话时出错:",e)}}c.value!=null&&await wt(),l.value=!1,N.value=!1};return n({open:Ae}),(t,e)=>{const o=Ke,i=We,d=ze;return U(),mt(To,{to:"body"},[So(b("div",{ref_key:"chatWindowRef",ref:Re,class:"chat-floating-window",style:Zt(xe.value)},[b("div",{class:"chat-window-header",onMousedown:Ue},[b("span",Uo,"与 "+Qt(m.value)+" 聊天",1),y(i,{type:"danger",link:"",class:"chat-close-btn",onClick:Ne},{default:L(()=>[y(o,null,{default:L(()=>[y(R(Xt))]),_:1})]),_:1})],32),b("div",No,[s.value?u.value?(U(),tt("div",Vo,[y(d,{title:u.value,type:"error",closable:!1},null,8,["title"])])):(U(),tt("div",Oo,[y(R(go),{language:"zh-CN",theme:"light"},{default:L(()=>[b("div",Ho,[y(R(no),{class:"chat-area"},{default:L(()=>[y(R(so),{conversationID:_.value},null,8,["conversationID"]),y(R(ro),null,{headerToolbar:L(()=>[b("div",Ko,[y(R(lo)),y(R(co)),y(R(uo)),C.value?(U(),mt(R(fo),{key:0})):et("",!0),C.value?(U(),mt(R(mo),{key:1})):et("",!0),C.value?(U(),mt(i,{key:2,size:"small",type:"primary",onClick:Ie},{default:L(()=>[...e[2]||(e[2]=[Co(" 群视频 ",-1)])]),_:1})):et("",!0)])]),_:1})]),_:1})])]),_:1})])):(U(),tt("div",Po,[y(o,{class:"is-loading"},{default:L(()=>[y(R(Fe))]),_:1}),b("span",null,Qt(h.value),1)]))]),C.value&&N.value?(U(),tt("div",{key:0,ref_key:"callKitWrapperRef",ref:ke,class:"chat-dialog-call-kit-wrapper",style:Zt(be.value)},[b("div",{class:"call-kit-drag-handle",onMousedown:Le},[b("div",Wo,[e[3]||(e[3]=b("span",{class:"drag-handle-text"},"视频通话",-1)),G.value?(U(),tt("span",zo,"本地录制中")):et("",!0)]),b("div",Bo,[y(i,{type:"primary",link:"",class:"call-kit-screenshot-btn",loading:Tt.value,onMousedown:e[0]||(e[0]=ft(()=>{},["stop"])),onClick:ft(Me,["stop"])},{default:L(()=>[y(o,null,{default:L(()=>[y(R(qe))]),_:1}),e[4]||(e[4]=b("span",{class:"call-kit-screenshot-text"},"截屏",-1))]),_:1},8,["loading"]),y(i,{type:"danger",link:"",class:"call-kit-close-btn",onMousedown:e[1]||(e[1]=ft(()=>{},["stop"])),onClick:ft(De,["stop"])},{default:L(()=>[y(o,null,{default:L(()=>[y(R(Xt))]),_:1})]),_:1}),y(o,{class:"drag-handle-icon"},{default:L(()=>[y(R(je))]),_:1})])],32),b("div",{ref_key:"callKitContentRef",ref:Ct,class:"call-kit-content"},[y(R(ao),{allowedMinimized:!0,allowedFullScreen:!0,class:"chat-dialog-call-kit"})],512)],4)):et("",!0)],4),[[Be,l.value]])])}}}),Jn=oo(jo,[["__scopeId","data-v-e83e1dcd"]]);export{Jn as default};