2 lines
37 KiB
JavaScript
2 lines
37 KiB
JavaScript
var en=Object.defineProperty;var nn=(i,n,a)=>n in i?en(i,n,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[n]=a;var L=(i,n,a)=>nn(i,typeof n!="symbol"?n+"":n,a);import{d as on,i as an,r as sn,K as rn}from"./element-plus-Bolc0EfP.js";import{q as Pt,s as dt}from"./@vue/runtime-dom-DDAG46FW.js";import{c as ue,ai as ln,aj as cn,l as un,ak as dn,al as fn}from"./@element-plus/icons-vue-B0jSCQ-G.js";import{u as mn,l as hn}from"./file-DVLJj-JF.js";import{a as pn}from"./patient-B8mLd3BT.js";import{Q as Vt,ae as gn,aA as vn,aB as yn,aC as _n}from"./tcm-4eHdADUG.js";import{_ as we,u as wn,i as M}from"./index-DsiMl32K.js";import{E as Sn}from"./@tencentcloud/chat-uikit-vue3-CLQ__Wr9.js";import{p as Cn}from"./im-business-message-parse-QKjFLn3X.js";import{g as Tn,G as En,C as An,M as In,a as kn,O as bn,E as Rn,N as Mn,S as Ln,A as Dn,b as xn}from"./tuikit-atomicx-vue3-Dln8Zi6e.js";import{f as Se,aB as Un,ak as R,I as H,H as B,J as A,G as F,ab as Pn,A as q,b as Vn,d as Hn,w as Nn,aP as Ht,a as S,aN as b,O as On,T as Kn,n as Nt}from"./@vue/runtime-core-C6bnekPw.js";import{Q as G,p as de,o as $n}from"./@vue/shared-mAAVTE9n.js";import{y as E,n as y}from"./@vue/reactivity-DiY1c2vO.js";import{T as Z}from"./@tencentcloud/chat-AC2Y2r2A.js";import{X as fe}from"./@tencentcloud/chat-uikit-engine-zx802ozq.js";import{u as zn,F as x,z as Bn,g as $,a as z,l as N}from"./@tencentcloud/call-uikit-vue-DB7vt9Ht.js";import{c as ft}from"./@tencentcloud/call-engine-js-BX2W9Lhf.js";import{D as jn}from"./@tencentcloud/uikit-base-component-vue3-YgTqL4da.js";import"./lodash-es-C2A-Pj28.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-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.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-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./@tencentcloud/tui-core-8M7p1XHw.js";import"./tim-upload-plugin-HO4N4AW9.js";import"./tim-profanity-filter-plugin-Dn_Cf-mP.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./@tencentcloud/tuiroom-engine-js-Br9swJyU.js";import"./rtc-detect-Chu-fZvE.js";import"./tcplayer.js-qpFBCYzN.js";function Wn(){const i=["video/webm;codecs=vp9,opus","video/webm;codecs=vp8,opus","video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm"];for(const n of i)if(MediaRecorder.isTypeSupported(n))return n;return""}function Fn(){const i=window;return i.AudioContext||i.webkitAudioContext||null}function me(i,n,a,s,r,u){const f=n.videoWidth||n.clientWidth||1,d=n.videoHeight||n.clientHeight||1,p=Math.max(r/f,u/d),c=f*p,m=d*p,_=a+(r-c)/2,D=s+(u-m)/2;try{i.drawImage(n,_,D,c,m)}catch{}}function qn(i,n,a,s){i.fillStyle="#0b0b0b",i.fillRect(0,0,a,s);const r=n.filter(c=>c.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA);if(r.length===0)return;if(r.length===1){me(i,r[0],0,0,a,s);return}const u=Math.ceil(Math.sqrt(r.length)),f=Math.ceil(r.length/u),d=a/u,p=s/f;r.forEach((c,m)=>{const _=m%u,D=Math.floor(m/u);me(i,c,_*d,D*p,d,p)})}function Gn(i){const n=new Set,a=[];for(const s of i){const r=s.srcObject;if(r instanceof MediaStream)for(const u of r.getAudioTracks())u.kind!=="audio"||u.readyState==="ended"||!u.enabled||n.has(u.id)||(n.add(u.id),a.push(u))}return a}function Xn(i){var s;const n=new Set,a=[];for(const r of i){if(r.readyState<HTMLMediaElement.HAVE_CURRENT_DATA)continue;const u=(s=r.captureStream)==null?void 0:s.call(r);if(u)for(const f of u.getAudioTracks())f.kind!=="audio"||f.readyState==="ended"||!f.enabled||n.has(f.id)||(n.add(f.id),a.push(f))}return a}function Yn(i){const n=new Set,a=[],s=[...document.body.querySelectorAll("audio")];i&&s.push(...i.querySelectorAll("audio"));const r=document.getElementById("tuicallkit-id");r&&s.push(...r.querySelectorAll("audio"));const u=new Set;for(const f of s){if(u.has(f))continue;u.add(f);const d=f.srcObject;if(d instanceof MediaStream)for(const p of d.getAudioTracks())p.kind!=="audio"||p.readyState==="ended"||!p.enabled||n.has(p.id)||(n.add(p.id),a.push(p))}return a}function Ot(i){const n=new Set,a=d=>{const p=[];for(const c of d)n.has(c)||(n.add(c),p.push(c));return p},s=[...i.querySelectorAll("video")];if(s.length>0)return a(s);const r=document.getElementById("tuicallkit-id");if(r){const d=[...r.querySelectorAll("video")];if(d.length>0)return a(d)}const f=[...document.body.querySelectorAll("video")].filter(d=>{const p=d.srcObject;return p instanceof MediaStream?p.getVideoTracks().some(c=>c.readyState==="live"):!1});return a(f)}class Jn{constructor(){L(this,"canvas",null);L(this,"ctx",null);L(this,"rafId",0);L(this,"container",null);L(this,"mediaRecorder",null);L(this,"chunks",[]);L(this,"mimeType","");L(this,"audioCtx",null);L(this,"audioDestination",null);L(this,"wiredTrackIds",new Set);L(this,"canvasVideoTrack",null);L(this,"silentOsc",null);L(this,"silentGain",null);L(this,"micStream",null);L(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(s=>{var r;n.onstop=()=>{this.teardownAudioGraph();const u=n.mimeType||a||"video/webm",f=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,s(f&&f.size>0?f:null)};try{const u=n;(r=u.requestData)==null||r.call(u),n.stop()}catch{this.teardownAudioGraph(),this.chunks=[],this.mediaRecorder=null,this.container=null,this.canvas=null,this.ctx=null,this.canvasVideoTrack=null,s(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])),s=this.audioCtx.createGain();s.gain.value=1.25,a.connect(s),s.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(s=>s.stop());return}if(this.micStream){a.getTracks().forEach(s=>s.stop());return}this.micStream=a;for(const s of a.getAudioTracks())this.connectTrackToMixer(s)}).catch(()=>{})}wireIncomingAudio(){var f;if(!this.audioCtx||!this.audioDestination||!this.container)return;this.audioCtx.state==="suspended"&&this.audioCtx.resume().catch(()=>{});const n=Ot(this.container),a=document.getElementById("tuicallkit-id"),s=[...document.body.querySelectorAll("audio"),...this.container.querySelectorAll("audio"),...a?a.querySelectorAll("audio"):[]],r=new Set,u=[];for(const d of n)r.has(d)||(r.add(d),u.push(d));for(const d of s)r.has(d)||(r.add(d),u.push(d));for(const d of u){const p=d.srcObject;if(p instanceof MediaStream)for(const c of p.getAudioTracks())this.connectTrackToMixer(c);if(d instanceof HTMLVideoElement&&d.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){const c=(f=d.captureStream)==null?void 0:f.call(d);if(c)for(const m of c.getAudioTracks())this.connectTrackToMixer(m)}}}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=Wn();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 r=this.canvas.captureStream(30).getVideoTracks();this.canvasVideoTrack=r[0]??null;const u=Ot(n),f=Fn();let d;if(f)try{this.audioCtx=new f,this.audioDestination=this.audioCtx.createMediaStreamDestination(),this.audioCtx.resume().catch(()=>{}),this.wireIncomingAudio(),this.attachMicForMixer();const c=this.audioDestination.stream.getAudioTracks(),m=this.audioCtx.createOscillator(),_=this.audioCtx.createGain();_.gain.value=1e-5,m.frequency.value=20,m.connect(_),_.connect(this.audioDestination),m.start(),this.silentOsc=m,this.silentGain=_,d=new MediaStream([...r,...c])}catch{this.teardownAudioGraph(),d=this.buildStreamWithoutMixer(r,u)}else d=this.buildStreamWithoutMixer(r,u);try{this.mediaRecorder=a?new MediaRecorder(d,{mimeType:a}):new MediaRecorder(d)}catch{try{this.mediaRecorder=new MediaRecorder(d)}catch{return this.reset(),!1}}this.chunks=[],this.mediaRecorder.ondataavailable=c=>{c.data&&c.data.size>0&&this.chunks.push(c.data)},this.mediaRecorder.onerror=c=>{console.error("[call-local-recorder] MediaRecorder 错误",c)};const p=()=>{var m,_;if(!this.ctx||!this.canvas||!this.container)return;this.wireIncomingAudio();const c=Ot(this.container);qn(this.ctx,c,this.canvas.width,this.canvas.height),(_=(m=this.canvasVideoTrack)==null?void 0:m.requestFrame)==null||_.call(m),this.rafId=requestAnimationFrame(p)};this.rafId=requestAnimationFrame(p);try{this.mediaRecorder.start(250)}catch{return this.reset(),!1}return!0}buildStreamWithoutMixer(n,a){const s=new Set,r=[],u=f=>{for(const d of f)s.has(d.id)||(s.add(d.id),r.push(d))};return u(Gn(a)),u(Xn(a)),u(Yn(this.container)),new MediaStream([...n,...r])}async stop(){this.beginStopNow();const n=this.stopResultPromise;return n||null}}function he(i){const n=i.srcObject;return n instanceof MediaStream?n.getVideoTracks().some(a=>a.readyState==="live"):!1}function et(i){const n=i.getBoundingClientRect();return Math.max(0,n.width)*Math.max(0,n.height)}function pe(i){const n=i.videoWidth||i.clientWidth,a=i.videoHeight||i.clientHeight;return n*a}function Qn(i){const n=new Map,a=new Map;for(const s of i){const r=s.srcObject;if(!(r instanceof MediaStream))continue;const u=r.getVideoTracks(),f=r.id&&String(r.id)||u.map(c=>c.id).filter(Boolean).join("|")||`${u.length}`,d=et(s),p=a.get(f)??0;d>=p&&(n.set(f,s),a.set(f,d))}return n.size===0?i:Array.from(n.values())}function Zn(i){if(i.length<2)return i;let n=0;for(const s of i)n=Math.max(n,et(s));return n<=1||Math.min(...i.map(s=>et(s)))/n>=.25?i:i.filter(s=>et(s)>=n*.25)}function to(i){let n=i;for(let a=0;a<12&&n;a++){const s=getComputedStyle(n).transform;if(s&&s!=="none"&&(/matrix\(\s*-1\s*,/.test(s)||/scaleX\(\s*-1/.test(s)))return!0;n=n.parentElement}return!1}function eo(i){const n=/local|self|pusher|mini[_-]?stream|preview[_-]?self|own[_-]?camera|tui-local|tencent-local|stream-local|publisher|send|pip|picture[_-]?in[_-]?picture/i,a=/remote|subscriber|peer|other|tui-remote|stream-remote|big-stream|play[_-]?stream|receiver|pull|substream/i;let s=i;for(let r=0;r<20&&s;r++){const u=`${s.className||""} ${s.id||""} ${s.getAttribute("data-type")||""}`;if(a.test(u))return!1;if(n.test(u))return!0;s=s.parentElement}return!1}async function no(i,n){const a=(n==null?void 0:n.preferRemote)!==!1,s=[i,...(n==null?void 0:n.extraRoots)||[]].filter(g=>!!g),r=new Set;for(const g of s)for(const w of g.querySelectorAll("video"))w instanceof HTMLVideoElement&&r.add(w);if(r.size===0){const g=document.querySelector(".chat-dialog-call-kit-wrapper");if(g)for(const w of g.querySelectorAll("video"))w instanceof HTMLVideoElement&&r.add(w)}r.size===0&&document.body.querySelectorAll("video").forEach(g=>{g instanceof HTMLVideoElement&&he(g)&&r.add(g)});let u=Array.from(r).filter(g=>g.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA&&he(g));if(u.length===0&&(u=Array.from(r).filter(g=>g.readyState>=2)),u.length===0)return null;u=Qn(u);let f=null,d=0,p=0;if(a){const g=u.map(C=>({v:C,layout:et(C),pixel:pe(C),localClass:eo(C),mirror:to(C)}));let w=g.filter(C=>!C.localClass&&!C.mirror);w.length===0&&(w=g.filter(C=>!C.localClass)),w.length===0&&(w=g.filter(C=>!C.mirror)),w.length===0&&(w=g);let O=w.map(C=>C.v);O=Zn(O),w=w.filter(C=>O.includes(C.v));for(const C of w)(C.layout>d||C.layout===d&&C.pixel>p)&&(d=C.layout,p=C.pixel,f=C.v)}else for(const g of u){const w=et(g),O=pe(g);(w>d||w===d&&O>p)&&(d=w,p=O,f=g)}if(!f)return null;const c=f.videoWidth||f.clientWidth,m=f.videoHeight||f.clientHeight;if(!c||!m)return null;const _=document.createElement("canvas");_.width=c,_.height=m;const D=_.getContext("2d");if(!D)return null;try{D.drawImage(f,0,0,c,m)}catch{return null}return new Promise(g=>{_.toBlob(w=>g(w),"image/jpeg",.92)})}function oo(i){const n=[];let a=i,s=0;for(;a!=null&&s<6;){if(typeof a=="string"){n.push(a);break}if(typeof a=="object"){const r=a;typeof r.message=="string"&&n.push(r.message),typeof r.name=="string"&&n.push(r.name),typeof r.code<"u"&&n.push(String(r.code)),a=r.cause}else{n.push(String(a));break}s++}return n.join(" ").toLowerCase()}const ge=-1001;function tt(i){if(i&&typeof i=="object"){const a=i,s=a.code??a.error_code;if(s===ge||s===String(ge))return!0}const n=oo(i);return n.includes("does not support this ability")||n.includes("package you purchased")||n.includes("-1001")&&n.includes("does not support")}function Ce(){return"套餐欠费或未开通该能力,请联系管理员在腾讯云续费或升级套餐。"}function ao(i,n="通话操作失败"){return tt(i)?Ce():i instanceof Error?i.message||n:typeof i=="string"&&i||n}const io={key:0,class:"chat-uikit-custom-msg"},so={key:0,class:"chat-uikit-custom-msg__tag"},ro={class:"chat-uikit-custom-msg__main"},lo={key:1,class:"chat-uikit-custom-msg__sub"},co={key:1,class:"chat-uikit-custom-msg chat-uikit-custom-msg--plain"},uo={class:"chat-uikit-custom-msg__main"},fo={key:2,class:"chat-uikit-custom-msg chat-uikit-custom-msg--plain"},mo={key:0,class:"chat-uikit-custom-msg__sub"},ho=Se({inheritAttrs:!1,__name:"ChatMessageItem",props:{message:{}},setup(i){const n=i,a=Un();function s(c){if(!c||typeof c!="object")return null;const m=c,_=m.data;if(typeof _=="string")return _;if(_&&typeof _=="object")return JSON.stringify(_);const D=m.extension;return typeof D=="string"&&D.trim().startsWith("{")?D:null}const r=q(()=>{var m;const c=(m=n.message)==null?void 0:m.type;return!!(c===En.CUSTOM||typeof c=="string"&&/custom/i.test(c))}),u=q(()=>{var m;if(!r.value)return null;const c=(m=s(n.message.payload))==null?void 0:m.trim();return c?Cn(c):null}),f=q(()=>r.value&&!!u.value),d=q(()=>{const c=n.message.payload,m=c==null?void 0:c.description;return typeof m=="string"&&m.trim()?m.trim():""}),p=q(()=>{var m;const c=(m=s(n.message.payload))==null?void 0:m.trim();return!c||c.length<2?"":c.length<=120?c:`${c.slice(0,117)}…`});return(c,m)=>f.value?(R(),H("div",io,[u.value.tag?(R(),H("span",so,G(u.value.tag),1)):B("",!0),A("div",ro,G(u.value.main),1),u.value.sub?(R(),H("div",lo,G(u.value.sub),1)):B("",!0)])):r.value&&d.value?(R(),H("div",co,[A("div",uo,G(d.value),1)])):r.value?(R(),H("div",fo,[m[0]||(m[0]=A("div",{class:"chat-uikit-custom-msg__main"},"系统消息",-1)),p.value?(R(),H("div",mo,G(p.value),1)):B("",!0)])):(R(),F(E(Tn),Pn({key:3},E(a),{message:i.message}),null,16,["message"]))}}),po=we(ho,[["__scopeId","data-v-1c506f55"]]);function go(i){if(i==null)return null;if(typeof i=="object"&&!Array.isArray(i))return i;if(typeof i!="string")return null;const n=i.trim();if(!n.startsWith("{"))return null;try{return JSON.parse(n)}catch{return null}}function ve(i){const n=i.toLowerCase();return["hangup","cancel","reject","timeout","linebusy","end"].includes(n)}function vo(i){const n=i.trim();if(!n)return!1;if(/\bcall_end\b/i.test(n)&&(/call_engine|call_record|rtc/i.test(n)||/"reason"\s*:\s*\d/.test(n))||/call_engine_srv\.[a-z_]*call[a-z_]*/i.test(n)&&/hangup|end|leave|reject|cancel/i.test(n))return!0;if(!n.startsWith("{"))return!1;let a;try{a=JSON.parse(n)}catch{return!1}if(a.businessID===1||a.businessID==="1"){const r=go(a.data);if(r){const u=String(r.cmd??"");if(ve(u))return!0}}if((a.businessID==="rtc_call"||typeof a.cmd=="string")&&ve(String(a.cmd??"")))return!0;const s=JSON.stringify(a);return!!(s.includes("call_engine_srv")&&/hangup|call_end|CALL_END|reject|cancel/i.test(s))}const yo=["title"],_o={class:"chat-container"},wo={key:0,class:"loading-container"},So={key:1,class:"error-container"},Co={key:2,class:"chat-content"},To={class:"chat-layout"},Eo={class:"message-toolbar"},Ao={class:"call-kit-drag-handle-left"},Io={key:0,class:"call-local-recording-hint"},ko={class:"call-kit-drag-handle-actions"},mt="idle",ht="calling",W="connected",ye=40,bo=100,Ro=1500,Mo=2600,Lo=667,_e=16,Do=Se({__name:"index",setup(i,{expose:n}){const a=y(""),s=y(!1),r=y(!1),u=y(!1),f=y(""),d=y(""),p=y(null),c=y(null),m=y("正在初始化..."),_=y(""),D=y(""),g=y(!1),w=y(!1),{login:O}=xn(),{setActiveConversation:C,createC2CConversation:Te,activeConversation:Ee}=Dn(),Ae=wn(),nt=y("");let K=null,X=null,Et=0;const P=new Jn,At=y(!1),ot=y(!1);let It=0,Y=null,at=null,pt=Promise.resolve(),kt=null;function J(){Y&&(clearTimeout(Y),Y=null)}function bt(e){At.value=!!(e!=null&&e.isLochostVod)}function gt(){return at||(at=(async()=>{if(J(),ot.value=!1,!At.value)return;P.beginStopNow();const e=kt??c.value;try{await pt}catch{}const t=await P.stop();if(!t){console.warn("[chat-dialog] 本地录制无有效文件(若通话较长仍出现,请换 Chrome 并看控制台是否有 MediaRecorder 报错)");return}if(e==null){M.msgWarning("缺少诊单信息,本地录制无法保存到通话记录");return}try{const o=await hn(t,`call-rec-${e}-${Date.now()}.webm`),l=o.uri||o.url;if(!l){M.msgError("上传成功但未返回文件地址");return}await gn({diagnosis_id:e,file_url:l}),M.msgSuccess("本地录制已上传并关联到通话记录")}catch(o){const l=o instanceof Error?o.message:String(o);console.warn("[chat-dialog] 本地录制上传/关联失败",o),M.msgError(l||"本地录制上传失败")}})().finally(()=>{at=null}),at)}function Ie(){const e=$.getData(z.CALL,N.ROOM_ID);if(e==null)return"";if(typeof e=="number")return e===0?"":String(e);const t=String(e).trim();return!t||t==="0"?"":t}function ke(){var e,t;try{const o=(t=(e=x).getTUICallEngineInstance)==null?void 0:t.call(e);if(!o)return"";const l=[o.roomId,o.roomID,o._roomId,o._roomID,o.strRoomID];for(const h of l){if(h==null||h==="")continue;const v=String(h).trim();if(v&&v!=="0")return v}}catch{}return""}function Rt(){return Ie()||ke()}function vt(e,t){if(t!=null&&String(t).trim()!==""&&String(t)!=="0")return String(t).trim();if(typeof e=="number"&&e>0)return String(e);if(typeof e=="string"){const o=e.trim();if(o&&o!=="0")return o}return""}function Kt(e){if(e==null||typeof e!="object")return"";const t=e,o=vt(t.roomID,t.strRoomID)||vt(t.roomId,t.strRoomId);if(o)return o;const l=t.data;if(l&&typeof l=="object"){const h=l,v=vt(h.roomID,h.strRoomID)||vt(h.roomId,h.strRoomId);if(v)return v}return""}function Q(){X&&(clearTimeout(X),X=null),Et=0}function be(){Q();const e=()=>{X=null;const t=$.getData(z.CALL,N.CALL_STATUS);if(t===mt||t!==ht&&t!==W)return;const o=Rt();if(o){rt(o);return}if(Et++,Et>=ye){console.warn("[chat-dialog] 仍未解析到有效房间号(已重试",ye,"次)");return}X=setTimeout(e,bo)};X=setTimeout(e,0)}async function $t(e){if(!(p.value==null||c.value==null)){await Nt();for(let t=0;t<40;t++){const o=Rt();if(o){await rt(o);return}await new Promise(l=>setTimeout(l,50))}console.warn("[chat-dialog] 发起通话后仍未解析到房间号(API:",e,")")}}function Re(){var l,h;const e=window;if(e.__zytEngineRoomCapture__)return;const t=(h=(l=x).getTUICallEngineInstance)==null?void 0:h.call(l);if(!t||typeof t.calls!="function")return;e.__zytEngineRoomCapture__=!0,t.__zytEngineRoomCapture__=!0;const o=v=>{const T=t[v];typeof T=="function"&&(t[v]=async function(...k){const U=await T.apply(t,k),V=Kt(U);return V&&rt(V),await $t("engine."+v),U})};o("calls"),o("call"),o("groupCall")}function Me(){const e=window;if(e.__zytHangupPreStop__)return;const t=x,o=t.hangup;typeof o=="function"&&(e.__zytHangupPreStop__=!0,t.hangup=function(...h){return P.beginStopNow(),o.apply(x,h)})}function zt(){var v,T;const e=window;if(e.__zytTrtcPreStop__)return;const t=(T=(v=x).getTUICallEngineInstance)==null?void 0:T.call(v),o=t==null?void 0:t.trtcCloud;if(!o||typeof o!="object")return;let l=0;const h=["stopLocalVideo","stopLocalAudio"];for(const I of h){const k=o[I];typeof k=="function"&&(o[I]=function(...V){return P.beginStopNow(),k.apply(o,V)},l++)}l>0&&(e.__zytTrtcPreStop__=!0)}let it=[],st=null,Bt=0;async function yt(){const e=kt??c.value;if(e==null){console.warn("[chat-dialog] endCall 跳过:无诊单 ID(快照与当前均为空)");return}try{await vn({diagnosis_id:e}),console.log("[chat-dialog] endCall 已同步",{diagnosis_id:e})}catch(t){console.warn("[chat-dialog] endCall 失败",t)}}function jt(e){const t=Date.now();t-Bt<Ro||(Bt=t,console.log("[chat-dialog] 挂断停合流:",e),P.isRecording()&&P.beginStopNow(),yt())}function Le(){var e;Mt();try{const t=(e=fe)==null?void 0:e.chat;if(!(t!=null&&t.on)){console.warn("[chat-dialog] TUIChatEngine.chat 不可用,无法监听 IM 视频挂断信令");return}st=o=>{if(!r.value)return;const l=_.value;if(!l)return;const h=l.startsWith("C2C")?l:`C2C${l}`,v=Array.isArray(o.data)?o.data:[];for(const T of v){if(!T||T.conversationID!==h)continue;const I=T.type;if(!(I===Z.TYPES.MSG_CUSTOM||I==="TIMCustomElem"||typeof I=="string"&&/custom/i.test(I)))continue;const U=T.payload,V=typeof(U==null?void 0:U.data)=="string"?U.data:"";if(!(!V||!vo(V))){jt("IM");break}}},t.on(Z.EVENT.MESSAGE_RECEIVED,st)}catch(t){console.warn("[chat-dialog] 绑定 IM 挂断监听失败",t)}}function Mt(){var e,t;if(st){try{const o=(e=fe)==null?void 0:e.chat;(t=o==null?void 0:o.off)==null||t.call(o,Z.EVENT.MESSAGE_RECEIVED,st)}catch{}st=null}}function De(){var e,t;try{const o=(t=(e=x).getTUICallEngineInstance)==null?void 0:t.call(e),l=o==null?void 0:o.on;if(!o||typeof l!="function"||o.__zytRoomEvents)return;o.__zytRoomEvents=!0;const h=k=>{const U=Kt(k);if(U){rt(U);return}Lt()},v=()=>{jt("TUICallEngine")},T=[ft.TUICallEvent.CALL_END,ft.TUICallEvent.USER_LEAVE,ft.TUICallEvent.ON_CALL_NOT_CONNECTED];for(const k of T)l.call(o,k,v),it.push({event:k,fn:v});const I=[ft.TUICallEvent.USER_ENTER,ft.TUICallEvent.ON_CALL_BEGIN];for(const k of I)l.call(o,k,h),it.push({event:k,fn:h})}catch(o){console.warn("[chat-dialog] 绑定引擎房间事件失败",o)}}function xe(){var e,t;try{const o=(t=(e=x).getTUICallEngineInstance)==null?void 0:t.call(e);if(!(o!=null&&o.off)){it=[];return}for(const{event:l,fn:h}of it)o.off(l,h);o.__zytRoomEvents=!1}catch{}it=[]}function Ue(){const e=window;if(e.__zytTUICallRoomHooks__)return;e.__zytTUICallRoomHooks__=!0;const t=x,o=l=>{const h=t[l];typeof h=="function"&&(t[l]=async function(...T){const I=await h.apply(t,T);return await $t(l),I})};o("calls"),o("call"),o("groupCall")}async function rt(e){try{await pt}catch{}if(p.value==null||c.value==null)return;const t=`${c.value}:${e}`;if(t===nt.value){Q();return}nt.value=t;try{const o=await yn({diagnosis_id:c.value,room_id:e});Q(),console.log("[chat-dialog] bindCallRoom 成功",{room_id:e,bindRes:o});const l=o==null?void 0:o.cloud_recording;l&&l.started===!1&&l.message&&M.msgWarning(`云端合流录制未启动(关闭控制台全局录制后仅依赖 API):${l.message}`)}catch(o){console.warn("[chat-dialog] bindCallRoom 失败",o),nt.value=""}}async function Lt(){if(p.value==null||c.value==null)return;const e=$.getData(z.CALL,N.CALL_STATUS);if(e===mt){Q(),nt.value="";return}if(e!==ht&&e!==W)return;await Nt();const t=Rt();if(t){await rt(t);return}be()}async function Pe(){if(!(p.value==null||c.value==null))try{await _n({diagnosis_id:c.value,patient_id:p.value,call_type:2})}catch(e){console.warn("[chat-dialog] startCall 记录失败",e)}}function Ve(){K==null||K();let e=$.getData(z.CALL,N.CALL_STATUS)??mt;const t=l=>{const h=l??mt;if(h===mt){(e===ht||e===W)&&P.beginStopNow(),J(),ot.value=!1,(e===ht||e===W)&&(async()=>(await yt(),w.value=!1,await gt()))(),Q(),nt.value="",e=h;return}if(h===W){if(Lt(),J(),!At.value){e=h;return}const v=It,T=(I=0)=>{if(v!==It){console.log("[chat-dialog] 录制轮次已变化,取消启动");return}const k=xt.value,U=$.getData(z.CALL,N.CALL_STATUS);if(!k||U!==W){console.warn("[chat-dialog] 录制启动条件不满足",{root:!!k,status:U});return}console.log(`[chat-dialog] 尝试启动本地录制(第 ${I+1} 次)`);let V=Array.from(k.querySelectorAll("video"));if(V.length===0&&(V=Array.from(document.body.querySelectorAll("video")).filter(Ze=>{const ce=Ze.srcObject;return ce instanceof MediaStream?ce.getVideoTracks().some(tn=>tn.readyState==="live"):!1}),console.log("[chat-dialog] 在 body 中找到活跃视频:",V.length)),V.length===0){I<10?(console.warn("[chat-dialog] 未找到视频元素,300ms 后重试"),Y=setTimeout(()=>T(I+1),300)):console.error("[chat-dialog] 重试 10 次后仍未找到视频元素,放弃录制");return}if(!V.some(le=>le.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA)){I<10?(console.warn("[chat-dialog] 视频元素未就绪,300ms 后重试"),Y=setTimeout(()=>T(I+1),300)):console.error("[chat-dialog] 重试 10 次后视频仍未就绪,放弃录制");return}console.log("[chat-dialog] 视频元素已就绪,立即启动录制");const re=P.start(k);ot.value=re,re?console.log("[chat-dialog] ✅ 本地录制已成功启动"):console.error("[chat-dialog] 本地录制启动失败(MediaRecorder 或画布初始化失败)")};Y=setTimeout(()=>T(0),500)}else J();e=h},o=()=>{Lt()};$.watch(z.CALL,{[N.CALL_STATUS]:t,[N.ROOM_ID]:o}),K=()=>{try{$.unwatch(z.CALL,{[N.CALL_STATUS]:t,[N.ROOM_ID]:o})}catch{}Q(),K=null}}let Wt=0;function lt(){const e=Date.now();e-Wt<Mo||(Wt=e,M.msgError(Ce()),w.value=!1)}let ct=null,_t=!1,j=null;function He(){_t||(ct=console.error.bind(console),_t=!0,console.error=(...e)=>{if(ct(...e),!r.value||!g.value)return;const t=e.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(" ");tt(t)&<()})}function Ne(){_t&&ct&&(console.error=ct),_t=!1,ct=null}function Oe(){var e,t,o;try{const l=(t=(e=x).getTUICallEngineInstance)==null?void 0:t.call(e);if(!(l!=null&&l.on))return;j&&((o=l.off)==null||o.call(l,"error",j)),j=h=>{!r.value||!g.value||tt(h)&<()},l.on("error",j)}catch(l){console.warn("绑定 TUICallEngine error 监听失败:",l)}}function Ke(){var e,t;try{const o=(t=(e=x).getTUICallEngineInstance)==null?void 0:t.call(e);o!=null&&o.off&&j&&o.off("error",j)}catch{}j=null}async function $e(e,t){try{const o=Z.create({SDKAppID:e}),l={businessID:"doctor_entered_consult_room",time:Date.now()},h=o.createCustomMessage({to:t,conversationType:Z.TYPES.CONV_C2C,payload:{data:JSON.stringify(l)}});await o.sendMessage(h),console.log("已发送医生进入诊室信令(患者端聊天列表不展示)")}catch(o){console.warn("发送医生进入诊室信令失败:",o)}}const Ft=e=>{!r.value||!g.value||tt(e.reason)&<()};Vn(()=>{He(),window.addEventListener("unhandledrejection",Ft)}),Hn(()=>{J(),P.reset(),K==null||K(),xe(),Mt(),Ne(),Ke(),window.removeEventListener("unhandledrejection",Ft)});const ze=async(e,t)=>{try{if(!e){console.warn("头像 URL 为空,跳过更新");return}console.log("开始更新头像到 IM:",e);const o=await new Promise((l,h)=>{setTimeout(async()=>{try{const T=await Z.create({SDKAppID:t}).updateMyProfile({avatar:e});console.log("IM 头像更新成功:",T),l(T)}catch(v){console.error("更新头像异常:",v),l(null)}},500)})}catch(o){console.error("IM 头像更新失败:",o.message||o)}};Nn(()=>Ee.value,async e=>{if(e){if(d.value=e.getShowName()||d.value,console.log("会话切换:",e.conversationID,"名称:",d.value,e),e.userProfile.userID.includes("doctor"))console.log("当前会话是医生,跳过获取 assistant_id");else try{const t=await Vt({patient_id:e.userProfile.userID.replace("patient_",""),diagnosis_id:c.value});bt(t),_.value=t.patientUserId,a.value=t.assistant_id,console.log("会话切换后获取到 assistant_id:",a.value,"完整响应:",t)}catch(t){console.error("获取 assistant_id 失败:",t)}console.log("会话切换完成,userID:",e.userProfile.userID)}});const Be=async e=>{r.value=!0,s.value=!1,wt.value=100,St.value=80,Qt(),d.value=e.patientName,p.value=e.patientId,c.value=e.diagnosisId||null,f.value="",u.value=!1,g.value=!1,w.value=!1,m.value="正在获取签名...";try{const t=await Vt({patient_id:e.patientId,diagnosis_id:e.diagnosisId||0});if(bt(t),a.value=t.assistant_id,console.log("后端返回的签名数据:",t),console.log("assistant_id:",a.value),!t||!t.userSig)throw new Error("获取签名失败");t.assistant_id||console.warn("警告:后端未返回 assistant_id,群视频通话可能无法正常工作"),_.value=t.patientUserId||`patient_${e.patientId}`,m.value="正在登录聊天...",await O({sdkAppId:Number(t.sdkAppId),userId:t.userId,userSig:t.userSig,useUploadPlugin:!0}),Le();const o=Number(t.sdkAppId);if(!window.__TUICallKitInited__){m.value="正在初始化通话能力...";try{await x.init({userID:t.userId,userSig:t.userSig,SDKAppID:o}),window.__TUICallKitInited__=!0}catch(l){console.warn("TUICallKit 初始化失败,聊天仍可用,音视频通话不可用:",(l==null?void 0:l.message)||l),tt(l)&<()}}g.value=!!window.__TUICallKitInited__,g.value&&(x.setCallback({beforeCalling:()=>{zt(),J(),P.reset(),ot.value=!1,It++,kt=c.value,Qt(),w.value=!0,pt=Pe()},afterCalling:()=>{P.beginStopNow(),(async()=>(await yt(),w.value=!1,await gt()))()}}),Ue(),Re(),Me(),zt(),De(),Ve(),Oe()),console.log("Chat UIKit 登录成功,患者用户ID:",_.value),m.value="加载聊天界面...",setTimeout(async()=>{var h;u.value=!0,await Nt(),await new Promise(v=>setTimeout(v,1e3));const l=(h=Ae.userInfo)==null?void 0:h.avatar;console.log("准备更新头像,avatar:",l),l&&await ze(l,o);try{const v=await Te(_.value);D.value=v.conversationID,console.log("已创建/获取会话:",D.value),C(D.value),console.log("已激活会话"),await $e(o,_.value)}catch(v){console.error("创建/激活会话失败:",v)}},800)}catch(t){console.error("初始化聊天失败:",t),f.value=t.message||"初始化聊天失败",M.msgError(f.value)}},je=async()=>{if(!g.value){M.msgWarning("通话服务初始化中,请稍后再试");return}if(!_.value){M.msgWarning("未找到患者通话ID,无法发起群视频");return}try{if(!a.value){console.warn("assistant_id 为空,尝试重新获取");const t=await Vt({patient_id:p.value,diagnosis_id:c.value});bt(t),a.value=t.assistant_id,console.log("重新获取 assistant_id:",a.value)}const e=[_.value,a.value].filter(t=>t);if(e.length<2){M.msgWarning("助理ID获取失败,无法发起群视频"),console.error("userIDList 不完整:",e,"assistant_ids:",a.value);return}console.log("发起群视频通话,参与者:",e),await x.calls({userIDList:e,type:Bn.VIDEO_CALL})}catch(e){console.error("发起群视频失败:",e),tt(e)?lt():M.msgError(ao(e,"发起群视频失败"))}},We=y(),wt=y(100),St=y(80),Dt=y(!1),qt=y(0),Gt=y(0),Xt=y(0),Yt=y(0),Jt=y(),xt=y(),ut=y(!1),Ct=y(0),Tt=y(0);function Qt(){Ct.value=_e,Tt.value=Math.max(_e,Math.floor((window.innerHeight-Lo)/2))}const Ut=y(!1),Zt=y(0),te=y(0),ee=y(0),ne=y(0),Fe=q(()=>({left:`${Ct.value}px`,top:`${Tt.value}px`})),qe=e=>{Ut.value=!0,Zt.value=e.clientX,te.value=e.clientY,ee.value=Ct.value,ne.value=Tt.value,document.addEventListener("mousemove",oe),document.addEventListener("mouseup",ae)},oe=e=>{Ut.value&&(Ct.value=Math.max(0,ee.value+e.clientX-Zt.value),Tt.value=Math.max(0,ne.value+e.clientY-te.value))},ae=()=>{Ut.value=!1,document.removeEventListener("mousemove",oe),document.removeEventListener("mouseup",ae)},Ge=async()=>{if(!ut.value){ut.value=!0;try{if(p.value==null){M.msgWarning("缺少患者信息,无法同步舌苔照片");return}const e=Jt.value,t=xt.value,o=e||t;if(!o)return;const l=await no(o,{extraRoots:[t].filter(Boolean)});if(!l){M.msgWarning("截屏失败,请确认视频画面已加载");return}const h=await mn(l,`callshot-${Date.now()}.jpg`),v=h.url||h.uri;if(!v){M.msgError("上传未返回图片路径");return}if(c.value==null){M.msgWarning("请先保存诊单后再从视频同步舌苔照片");return}await pn({diagnosis_id:c.value,tongue_images:[v]}),M.msgSuccess("舌苔照片已保存")}catch(e){const t=e;console.error(t),M.msgError((t==null?void 0:t.message)||"上传失败")}finally{ut.value=!1}}},Xe=async()=>{if(g.value)try{P.beginStopNow(),await gt(),await x.hangup()}catch(e){console.warn("关闭视频窗口时挂断失败:",e)}w.value=!1},Ye=q(()=>({left:`${wt.value}px`,top:`${St.value}px`})),Je=e=>{const t=e.target;t.closest(".chat-close-btn")||t.closest(".chat-header-actions")||(Dt.value=!0,qt.value=e.clientX,Gt.value=e.clientY,Xt.value=wt.value,Yt.value=St.value,document.addEventListener("mousemove",ie),document.addEventListener("mouseup",se))},ie=e=>{Dt.value&&(wt.value=Math.max(0,Xt.value+e.clientX-qt.value),St.value=Math.max(0,Yt.value+e.clientY-Gt.value))},se=()=>{Dt.value=!1,document.removeEventListener("mousemove",ie),document.removeEventListener("mouseup",se)},Qe=async()=>{if(Mt(),g.value){const e=$.getData(z.CALL,N.CALL_STATUS);if(e===ht||e===W)try{P.beginStopNow(),await gt(),await x.hangup()}catch(t){console.warn("挂断通话时出错:",t)}}c.value!=null&&await yt(),r.value=!1,w.value=!1};return n({open:Be}),(e,t)=>{const o=on,l=an,h=sn,v=rn;return R(),F(Kn,{to:"body"},[Ht(A("div",{ref_key:"chatWindowRef",ref:We,class:$n(["chat-floating-window",{"chat-floating-window--minimized":s.value}]),style:de(Ye.value)},[A("div",{class:"chat-window-header",onMousedown:Je},[A("span",{class:"chat-window-title",title:d.value},"与 "+G(d.value)+" 通讯",9,yo),A("div",{class:"chat-header-actions",onMousedown:t[2]||(t[2]=dt(()=>{},["stop"]))},[S(l,{type:"danger",link:"",class:"chat-close-btn",onClick:Qe},{default:b(()=>[S(o,null,{default:b(()=>[S(E(ue))]),_:1})]),_:1}),s.value?(R(),F(h,{key:1,content:"展开聊天窗口",placement:"top"},{default:b(()=>[S(l,{type:"primary",link:"",class:"chat-expand-btn",onClick:t[1]||(t[1]=T=>s.value=!1)},{default:b(()=>[S(o,null,{default:b(()=>[S(E(cn))]),_:1}),t[6]||(t[6]=A("span",{class:"chat-header-btn-text"},"展开",-1))]),_:1})]),_:1})):(R(),F(h,{key:0,content:"缩小为标题条,不关闭会话",placement:"top"},{default:b(()=>[S(l,{type:"primary",link:"",class:"chat-minimize-btn",onClick:t[0]||(t[0]=T=>s.value=!0)},{default:b(()=>[S(o,null,{default:b(()=>[S(E(ln))]),_:1}),t[5]||(t[5]=A("span",{class:"chat-header-btn-text"},"缩小",-1))]),_:1})]),_:1}))],32)],32),Ht(A("div",_o,[u.value?f.value?(R(),H("div",So,[S(v,{title:f.value,type:"error",closable:!1},null,8,["title"])])):(R(),H("div",Co,[S(E(jn),{language:"zh-CN",theme:"light"},{default:b(()=>[A("div",To,[S(E(Sn),{class:"chat-area"},{default:b(()=>[S(E(An),{conversationID:D.value,Message:po},null,8,["conversationID"]),S(E(In),null,{headerToolbar:b(()=>[A("div",Eo,[S(E(kn)),S(E(bn)),S(E(Rn)),g.value?(R(),F(E(Mn),{key:0})):B("",!0),g.value?(R(),F(E(Ln),{key:1})):B("",!0),g.value?(R(),F(l,{key:2,size:"small",type:"primary",onClick:je},{default:b(()=>[...t[7]||(t[7]=[On(" 群视频 ",-1)])]),_:1})):B("",!0)])]),_:1})]),_:1})])]),_:1})])):(R(),H("div",wo,[S(o,{class:"is-loading"},{default:b(()=>[S(E(un))]),_:1}),A("span",null,G(m.value),1)]))],512),[[Pt,!s.value]]),g.value?Ht((R(),H("div",{key:0,ref_key:"callKitWrapperRef",ref:Jt,class:"chat-dialog-call-kit-wrapper",style:de(Fe.value)},[A("div",{class:"call-kit-drag-handle",onMousedown:qe},[A("div",Ao,[t[8]||(t[8]=A("span",{class:"drag-handle-text"},"视频通话",-1)),ot.value?(R(),H("span",Io,"本地录制中")):B("",!0)]),A("div",ko,[S(l,{type:"primary",link:"",class:"call-kit-screenshot-btn",loading:ut.value,disabled:ut.value,onMousedown:t[3]||(t[3]=dt(()=>{},["stop"])),onClick:dt(Ge,["stop","prevent"])},{default:b(()=>[S(o,null,{default:b(()=>[S(E(dn))]),_:1}),t[9]||(t[9]=A("span",{class:"call-kit-screenshot-text"},"截屏",-1))]),_:1},8,["loading","disabled"]),S(l,{type:"danger",link:"",class:"call-kit-close-btn",onMousedown:t[4]||(t[4]=dt(()=>{},["stop"])),onClick:dt(Xe,["stop"])},{default:b(()=>[S(o,null,{default:b(()=>[S(E(ue))]),_:1})]),_:1}),S(o,{class:"drag-handle-icon"},{default:b(()=>[S(E(fn))]),_:1})])],32),A("div",{ref_key:"callKitContentRef",ref:xt,class:"call-kit-content"},[S(E(zn),{allowedMinimized:!0,allowedFullScreen:!0,class:"chat-dialog-call-kit"})],512)],4)),[[Pt,w.value]]):B("",!0)],6),[[Pt,r.value]])])}}}),Na=we(Do,[["__scopeId","data-v-09c808b4"]]);export{Na as default};
|