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 D=(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-DCRlGjqn.js";import{q as Nt,s as dt}from"./@vue/runtime-dom-iFk_KP8y.js";import{c as ue,_ as ln,$ as cn,l as un,a0 as dn,a1 as fn}from"./@element-plus/icons-vue-jYCthPJY.js";import{u as mn,i as hn}from"./file-CNY42yWf.js";import{E as Pt,H as pn,L as gn,ad as vn,ae as yn,af as _n,ag as wn}from"./tcm-BU23xs5N.js";import{D as Sn}from"./diagnosis-sync-events-Bb57o6Fi.js";import{_ as we,u as Cn,i as I}from"./index-uyUH29BJ.js";import{E as Tn}from"./@tencentcloud/chat-uikit-vue3-CXQYzAFr.js";import{p as En}from"./im-business-message-parse-ClZDqEhB.js";import{g as An,G as In,C as kn,M as bn,a as Rn,O as Mn,E as Ln,N as Dn,S as xn,A as Un,b as Nn}from"./tuikit-atomicx-vue3-CZgu16-k.js";import{f as Se,aB as Pn,ak as M,I as V,H as B,J as b,G,ab as Vn,A as F,b as Hn,d as On,w as Kn,aP as Vt,a as S,aN as R,O as $n,T as zn,n as Ht}from"./@vue/runtime-core-C0pg79pw.js";import{Q as q,p as de,o as Bn}from"./@vue/shared-mAAVTE9n.js";import{y as k,o as y}from"./@vue/reactivity-BIbyPIZJ.js";import{T as Z}from"./@tencentcloud/chat-AC2Y2r2A.js";import{X as fe}from"./@tencentcloud/chat-uikit-engine-zx802ozq.js";import{u as Wn,F as U,z as jn,g as $,a as z,l as H}from"./@tencentcloud/call-uikit-vue-6oZM4bBc.js";import{c as ft}from"./@tencentcloud/call-engine-js-BX2W9Lhf.js";import{D as Gn}from"./@tencentcloud/uikit-base-component-vue3-DdfqV_bd.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-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-CZvD9OL_.js";import"./tslib-BDyQ-Jie.js";import"./zrender-BQyIY4j9.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-BVMzZUvF.js";import"./@tencentcloud/tui-core-8M7p1XHw.js";import"./tim-upload-plugin-HO4N4AW9.js";import"./tim-profanity-filter-plugin-Dn_Cf-mP.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"./rtc-detect-Chu-fZvE.js";import"./tcplayer.js-qpFBCYzN.js";function Fn(){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 qn(){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,x=s+(u-m)/2;try{i.drawImage(n,_,x,c,m)}catch{}}function Xn(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,x=Math.floor(m/u);me(i,c,_*d,x*p,d,p)})}function Yn(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 Jn(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 Qn(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 Zn{constructor(){D(this,"canvas",null);D(this,"ctx",null);D(this,"rafId",0);D(this,"container",null);D(this,"mediaRecorder",null);D(this,"chunks",[]);D(this,"mimeType","");D(this,"audioCtx",null);D(this,"audioDestination",null);D(this,"wiredTrackIds",new Set);D(this,"canvasVideoTrack",null);D(this,"silentOsc",null);D(this,"silentGain",null);D(this,"micStream",null);D(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=Fn();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=qn();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);Xn(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(Yn(a)),u(Jn(a)),u(Qn(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 to(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 eo(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 no(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 oo(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 ao(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=to(u);let f=null,d=0,p=0;if(a){const g=u.map(T=>({v:T,layout:et(T),pixel:pe(T),localClass:oo(T),mirror:no(T)}));let w=g.filter(T=>!T.localClass&&!T.mirror);w.length===0&&(w=g.filter(T=>!T.localClass)),w.length===0&&(w=g.filter(T=>!T.mirror)),w.length===0&&(w=g);let O=w.map(T=>T.v);O=eo(O),w=w.filter(T=>O.includes(T.v));for(const T of w)(T.layout>d||T.layout===d&&T.pixel>p)&&(d=T.layout,p=T.pixel,f=T.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 x=_.getContext("2d");if(!x)return null;try{x.drawImage(f,0,0,c,m)}catch{return null}return new Promise(g=>{_.toBlob(w=>g(w),"image/jpeg",.92)})}function io(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=io(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 so(i,n="通话操作失败"){return tt(i)?Ce():i instanceof Error?i.message||n:typeof i=="string"&&i||n}const ro={key:0,class:"chat-uikit-custom-msg"},lo={key:0,class:"chat-uikit-custom-msg__tag"},co={class:"chat-uikit-custom-msg__main"},uo={key:1,class:"chat-uikit-custom-msg__sub"},fo={key:1,class:"chat-uikit-custom-msg chat-uikit-custom-msg--plain"},mo={class:"chat-uikit-custom-msg__main"},ho={key:2,class:"chat-uikit-custom-msg chat-uikit-custom-msg--plain"},po={key:0,class:"chat-uikit-custom-msg__sub"},go=Se({inheritAttrs:!1,__name:"ChatMessageItem",props:{message:{}},setup(i){const n=i,a=Pn();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 x=m.extension;return typeof x=="string"&&x.trim().startsWith("{")?x:null}const r=F(()=>{var m;const c=(m=n.message)==null?void 0:m.type;return!!(c===In.CUSTOM||typeof c=="string"&&/custom/i.test(c))}),u=F(()=>{var m;if(!r.value)return null;const c=(m=s(n.message.payload))==null?void 0:m.trim();return c?En(c):null}),f=F(()=>r.value&&!!u.value),d=F(()=>{const c=n.message.payload,m=c==null?void 0:c.description;return typeof m=="string"&&m.trim()?m.trim():""}),p=F(()=>{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?(M(),V("div",ro,[u.value.tag?(M(),V("span",lo,q(u.value.tag),1)):B("",!0),b("div",co,q(u.value.main),1),u.value.sub?(M(),V("div",uo,q(u.value.sub),1)):B("",!0)])):r.value&&d.value?(M(),V("div",fo,[b("div",mo,q(d.value),1)])):r.value?(M(),V("div",ho,[m[0]||(m[0]=b("div",{class:"chat-uikit-custom-msg__main"},"系统消息",-1)),p.value?(M(),V("div",po,q(p.value),1)):B("",!0)])):(M(),G(k(An),Vn({key:3},k(a),{message:i.message}),null,16,["message"]))}}),vo=we(go,[["__scopeId","data-v-1c506f55"]]);function yo(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 _o(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=yo(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 wo=["title"],So={class:"chat-container"},Co={key:0,class:"loading-container"},To={key:1,class:"error-container"},Eo={key:2,class:"chat-content"},Ao={class:"chat-layout"},Io={class:"message-toolbar"},ko={class:"call-kit-drag-handle-left"},bo={key:0,class:"call-local-recording-hint"},Ro={class:"call-kit-drag-handle-actions"},mt="idle",ht="calling",j="connected",ye=40,Mo=100,Lo=1500,Do=2600,xo=667,_e=16,Uo=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(""),x=y(""),g=y(!1),w=y(!1),{login:O}=Nn(),{setActiveConversation:T,createC2CConversation:Te,activeConversation:Ee}=Un(),Ae=Cn(),nt=y("");let K=null,X=null,Et=0;const N=new Zn,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;N.beginStopNow();const e=kt??c.value;try{await pt}catch{}const t=await N.stop();if(!t){console.warn("[chat-dialog] 本地录制无有效文件(若通话较长仍出现,请换 Chrome 并看控制台是否有 MediaRecorder 报错)");return}if(e==null){I.msgWarning("缺少诊单信息,本地录制无法保存到通话记录");return}try{const o=await hn(t,`call-rec-${e}-${Date.now()}.webm`),l=o.uri||o.url;if(!l){I.msgError("上传成功但未返回文件地址");return}await vn({diagnosis_id:e,file_url:l}),I.msgSuccess("本地录制已上传并关联到通话记录")}catch(o){const l=o instanceof Error?o.message:String(o);console.warn("[chat-dialog] 本地录制上传/关联失败",o),I.msgError(l||"本地录制上传失败")}})().finally(()=>{at=null}),at)}function Ie(){const e=$.getData(z.CALL,H.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=U).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,H.CALL_STATUS);if(t===mt||t!==ht&&t!==j)return;const o=Rt();if(o){rt(o);return}if(Et++,Et>=ye){console.warn("[chat-dialog] 仍未解析到有效房间号(已重试",ye,"次)");return}X=setTimeout(e,Mo)};X=setTimeout(e,0)}async function $t(e){if(!(p.value==null||c.value==null)){await Ht();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=U).getTUICallEngineInstance)==null?void 0:h.call(l);if(!t||typeof t.calls!="function")return;e.__zytEngineRoomCapture__=!0,t.__zytEngineRoomCapture__=!0;const o=v=>{const C=t[v];typeof C=="function"&&(t[v]=async function(...A){const L=await C.apply(t,A),P=Kt(L);return P&&rt(P),await $t("engine."+v),L})};o("calls"),o("call"),o("groupCall")}function Me(){const e=window;if(e.__zytHangupPreStop__)return;const t=U,o=t.hangup;typeof o=="function"&&(e.__zytHangupPreStop__=!0,t.hangup=function(...h){return N.beginStopNow(),o.apply(U,h)})}function zt(){var v,C;const e=window;if(e.__zytTrtcPreStop__)return;const t=(C=(v=U).getTUICallEngineInstance)==null?void 0:C.call(v),o=t==null?void 0:t.trtcCloud;if(!o||typeof o!="object")return;let l=0;const h=["stopLocalVideo","stopLocalAudio"];for(const E of h){const A=o[E];typeof A=="function"&&(o[E]=function(...P){return N.beginStopNow(),A.apply(o,P)},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 yn({diagnosis_id:e}),console.log("[chat-dialog] endCall 已同步",{diagnosis_id:e})}catch(t){console.warn("[chat-dialog] endCall 失败",t)}}function Wt(e){const t=Date.now();t-Bt<Lo||(Bt=t,console.log("[chat-dialog] 挂断停合流:",e),N.isRecording()&&N.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 C of v){if(!C||C.conversationID!==h)continue;const E=C.type;if(!(E===Z.TYPES.MSG_CUSTOM||E==="TIMCustomElem"||typeof E=="string"&&/custom/i.test(E)))continue;const L=C.payload,P=typeof(L==null?void 0:L.data)=="string"?L.data:"";if(!(!P||!_o(P))){Wt("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=U).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=A=>{const L=Kt(A);if(L){rt(L);return}Lt()},v=()=>{Wt("TUICallEngine")},C=[ft.TUICallEvent.CALL_END,ft.TUICallEvent.USER_LEAVE,ft.TUICallEvent.ON_CALL_NOT_CONNECTED];for(const A of C)l.call(o,A,v),it.push({event:A,fn:v});const E=[ft.TUICallEvent.USER_ENTER,ft.TUICallEvent.ON_CALL_BEGIN];for(const A of E)l.call(o,A,h),it.push({event:A,fn:h})}catch(o){console.warn("[chat-dialog] 绑定引擎房间事件失败",o)}}function xe(){var e,t;try{const o=(t=(e=U).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=U,o=l=>{const h=t[l];typeof h=="function"&&(t[l]=async function(...C){const E=await h.apply(t,C);return await $t(l),E})};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 _n({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&&I.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,H.CALL_STATUS);if(e===mt){Q(),nt.value="";return}if(e!==ht&&e!==j)return;await Ht();const t=Rt();if(t){await rt(t);return}be()}async function Ne(){if(!(p.value==null||c.value==null))try{await wn({diagnosis_id:c.value,patient_id:p.value,call_type:2})}catch(e){console.warn("[chat-dialog] startCall 记录失败",e)}}function Pe(){K==null||K();let e=$.getData(z.CALL,H.CALL_STATUS)??mt;const t=l=>{const h=l??mt;if(h===mt){(e===ht||e===j)&&N.beginStopNow(),J(),ot.value=!1,(e===ht||e===j)&&(async()=>(await yt(),w.value=!1,await gt()))(),Q(),nt.value="",e=h;return}if(h===j){if(Lt(),J(),!At.value){e=h;return}const v=It,C=(E=0)=>{if(v!==It){console.log("[chat-dialog] 录制轮次已变化,取消启动");return}const A=xt.value,L=$.getData(z.CALL,H.CALL_STATUS);if(!A||L!==j){console.warn("[chat-dialog] 录制启动条件不满足",{root:!!A,status:L});return}console.log(`[chat-dialog] 尝试启动本地录制(第 ${E+1} 次)`);let P=Array.from(A.querySelectorAll("video"));if(P.length===0&&(P=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 中找到活跃视频:",P.length)),P.length===0){E<10?(console.warn("[chat-dialog] 未找到视频元素,300ms 后重试"),Y=setTimeout(()=>C(E+1),300)):console.error("[chat-dialog] 重试 10 次后仍未找到视频元素,放弃录制");return}if(!P.some(le=>le.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA)){E<10?(console.warn("[chat-dialog] 视频元素未就绪,300ms 后重试"),Y=setTimeout(()=>C(E+1),300)):console.error("[chat-dialog] 重试 10 次后视频仍未就绪,放弃录制");return}console.log("[chat-dialog] 视频元素已就绪,立即启动录制");const re=N.start(A);ot.value=re,re?console.log("[chat-dialog] ✅ 本地录制已成功启动"):console.error("[chat-dialog] 本地录制启动失败(MediaRecorder 或画布初始化失败)")};Y=setTimeout(()=>C(0),500)}else J();e=h},o=()=>{Lt()};$.watch(z.CALL,{[H.CALL_STATUS]:t,[H.ROOM_ID]:o}),K=()=>{try{$.unwatch(z.CALL,{[H.CALL_STATUS]:t,[H.ROOM_ID]:o})}catch{}Q(),K=null}}let jt=0;function lt(){const e=Date.now();e-jt<Do||(jt=e,I.msgError(Ce()),w.value=!1)}let ct=null,_t=!1,W=null;function Ve(){_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 He(){_t&&ct&&(console.error=ct),_t=!1,ct=null}function Oe(){var e,t,o;try{const l=(t=(e=U).getTUICallEngineInstance)==null?void 0:t.call(e);if(!(l!=null&&l.on))return;W&&((o=l.off)==null||o.call(l,"error",W)),W=h=>{!r.value||!g.value||tt(h)&<()},l.on("error",W)}catch(l){console.warn("绑定 TUICallEngine error 监听失败:",l)}}function Ke(){var e,t;try{const o=(t=(e=U).getTUICallEngineInstance)==null?void 0:t.call(e);o!=null&&o.off&&W&&o.off("error",W)}catch{}W=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 Gt=e=>{!r.value||!g.value||tt(e.reason)&<()};Hn(()=>{Ve(),window.addEventListener("unhandledrejection",Gt)}),On(()=>{J(),N.reset(),K==null||K(),xe(),Mt(),He(),Ke(),window.removeEventListener("unhandledrejection",Gt)});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 C=await Z.create({SDKAppID:t}).updateMyProfile({avatar:e});console.log("IM 头像更新成功:",C),l(C)}catch(v){console.error("更新头像异常:",v),l(null)}},500)})}catch(o){console.error("IM 头像更新失败:",o.message||o)}};Kn(()=>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 Pt({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 Pt({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 U.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&&(U.setCallback({beforeCalling:()=>{zt(),J(),N.reset(),ot.value=!1,It++,kt=c.value,Qt(),w.value=!0,pt=Ne()},afterCalling:()=>{N.beginStopNow(),(async()=>(await yt(),w.value=!1,await gt()))()}}),Ue(),Re(),Me(),zt(),De(),Pe(),Oe()),console.log("Chat UIKit 登录成功,患者用户ID:",_.value),m.value="加载聊天界面...",setTimeout(async()=>{var h;u.value=!0,await Ht(),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);x.value=v.conversationID,console.log("已创建/获取会话:",x.value),T(x.value),console.log("已激活会话"),await $e(o,_.value)}catch(v){console.error("创建/激活会话失败:",v)}},800)}catch(t){console.error("初始化聊天失败:",t),f.value=t.message||"初始化聊天失败",I.msgError(f.value)}},We=async()=>{if(!g.value){I.msgWarning("通话服务初始化中,请稍后再试");return}if(!_.value){I.msgWarning("未找到患者通话ID,无法发起群视频");return}try{if(!a.value){console.warn("assistant_id 为空,尝试重新获取");const t=await Pt({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){I.msgWarning("助理ID获取失败,无法发起群视频"),console.error("userIDList 不完整:",e,"assistant_ids:",a.value);return}console.log("发起群视频通话,参与者:",e),await U.calls({userIDList:e,type:jn.VIDEO_CALL})}catch(e){console.error("发起群视频失败:",e),tt(e)?lt():I.msgError(so(e,"发起群视频失败"))}},je=y(),wt=y(100),St=y(80),Dt=y(!1),Ft=y(0),qt=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-xo)/2))}const Ut=y(!1),Zt=y(0),te=y(0),ee=y(0),ne=y(0),Ge=F(()=>({left:`${Ct.value}px`,top:`${Tt.value}px`})),Fe=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)},qe=async()=>{if(!ut.value){ut.value=!0;try{if(p.value==null){I.msgWarning("缺少患者信息,无法同步舌苔照片");return}const e=Jt.value,t=xt.value,o=e||t;if(!o)return;const l=await ao(o,{extraRoots:[t].filter(Boolean)});if(!l){I.msgWarning("截屏失败,请确认视频画面已加载");return}const h=await mn(l,`callshot-${Date.now()}.jpg`),v=h.url||h.uri;if(!v){I.msgError("上传未返回图片路径");return}if(c.value==null){I.msgWarning("请先保存诊单后再从视频同步舌苔照片");return}const C=await pn({id:c.value});if(Number(C.patient_id)!==Number(p.value)){I.msgError("患者与当前诊单不匹配,无法同步");return}const E=[...C.tongue_images||[]];if(E.length>=9){I.msgWarning("舌苔照片已达上限 9 张");return}const A=[...E,v],L=JSON.parse(JSON.stringify(C));L.tongue_images=A,await gn(L),I.msgSuccess("舌苔照片已同步到诊单"),window.dispatchEvent(new CustomEvent(Sn,{detail:{diagnosisId:c.value,tongue_images:A}}))}catch(e){const t=e;console.error(t),I.msgError((t==null?void 0:t.message)||"上传失败")}finally{ut.value=!1}}},Xe=async()=>{if(g.value)try{N.beginStopNow(),await gt(),await U.hangup()}catch(e){console.warn("关闭视频窗口时挂断失败:",e)}w.value=!1},Ye=F(()=>({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,Ft.value=e.clientX,qt.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-Ft.value),St.value=Math.max(0,Yt.value+e.clientY-qt.value))},se=()=>{Dt.value=!1,document.removeEventListener("mousemove",ie),document.removeEventListener("mouseup",se)},Qe=async()=>{if(Mt(),g.value){const e=$.getData(z.CALL,H.CALL_STATUS);if(e===ht||e===j)try{N.beginStopNow(),await gt(),await U.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 M(),G(zn,{to:"body"},[Vt(b("div",{ref_key:"chatWindowRef",ref:je,class:Bn(["chat-floating-window",{"chat-floating-window--minimized":s.value}]),style:de(Ye.value)},[b("div",{class:"chat-window-header",onMousedown:Je},[b("span",{class:"chat-window-title",title:d.value},"与 "+q(d.value)+" 通讯",9,wo),b("div",{class:"chat-header-actions",onMousedown:t[2]||(t[2]=dt(()=>{},["stop"]))},[S(l,{type:"danger",link:"",class:"chat-close-btn",onClick:Qe},{default:R(()=>[S(o,null,{default:R(()=>[S(k(ue))]),_:1})]),_:1}),s.value?(M(),G(h,{key:1,content:"展开聊天窗口",placement:"top"},{default:R(()=>[S(l,{type:"primary",link:"",class:"chat-expand-btn",onClick:t[1]||(t[1]=C=>s.value=!1)},{default:R(()=>[S(o,null,{default:R(()=>[S(k(cn))]),_:1}),t[6]||(t[6]=b("span",{class:"chat-header-btn-text"},"展开",-1))]),_:1})]),_:1})):(M(),G(h,{key:0,content:"缩小为标题条,不关闭会话",placement:"top"},{default:R(()=>[S(l,{type:"primary",link:"",class:"chat-minimize-btn",onClick:t[0]||(t[0]=C=>s.value=!0)},{default:R(()=>[S(o,null,{default:R(()=>[S(k(ln))]),_:1}),t[5]||(t[5]=b("span",{class:"chat-header-btn-text"},"缩小",-1))]),_:1})]),_:1}))],32)],32),Vt(b("div",So,[u.value?f.value?(M(),V("div",To,[S(v,{title:f.value,type:"error",closable:!1},null,8,["title"])])):(M(),V("div",Eo,[S(k(Gn),{language:"zh-CN",theme:"light"},{default:R(()=>[b("div",Ao,[S(k(Tn),{class:"chat-area"},{default:R(()=>[S(k(kn),{conversationID:x.value,Message:vo},null,8,["conversationID"]),S(k(bn),null,{headerToolbar:R(()=>[b("div",Io,[S(k(Rn)),S(k(Mn)),S(k(Ln)),g.value?(M(),G(k(Dn),{key:0})):B("",!0),g.value?(M(),G(k(xn),{key:1})):B("",!0),g.value?(M(),G(l,{key:2,size:"small",type:"primary",onClick:We},{default:R(()=>[...t[7]||(t[7]=[$n(" 群视频 ",-1)])]),_:1})):B("",!0)])]),_:1})]),_:1})])]),_:1})])):(M(),V("div",Co,[S(o,{class:"is-loading"},{default:R(()=>[S(k(un))]),_:1}),b("span",null,q(m.value),1)]))],512),[[Nt,!s.value]]),g.value?Vt((M(),V("div",{key:0,ref_key:"callKitWrapperRef",ref:Jt,class:"chat-dialog-call-kit-wrapper",style:de(Ge.value)},[b("div",{class:"call-kit-drag-handle",onMousedown:Fe},[b("div",ko,[t[8]||(t[8]=b("span",{class:"drag-handle-text"},"视频通话",-1)),ot.value?(M(),V("span",bo,"本地录制中")):B("",!0)]),b("div",Ro,[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(qe,["stop","prevent"])},{default:R(()=>[S(o,null,{default:R(()=>[S(k(dn))]),_:1}),t[9]||(t[9]=b("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:R(()=>[S(o,null,{default:R(()=>[S(k(ue))]),_:1})]),_:1}),S(o,{class:"drag-handle-icon"},{default:R(()=>[S(k(fn))]),_:1})])],32),b("div",{ref_key:"callKitContentRef",ref:xt,class:"call-kit-content"},[S(k(Wn),{allowedMinimized:!0,allowedFullScreen:!0,class:"chat-dialog-call-kit"})],512)],4)),[[Nt,w.value]]):B("",!0)],6),[[Nt,r.value]])])}}}),Ka=we(Uo,[["__scopeId","data-v-aac2c1ad"]]);export{Ka as default};
|