"use strict";const e=require("../../common/vendor.js"),o=require("../../config/api.js"),i=require("../../utils/payment.js"),t={components:{PaymentModal:()=>"../../components/PaymentModal.js"},data:()=>({API_BASE:o.API_BASE,loadOptions:null,lastUserId:null,loading:!1,videos:[],selectedVideoId:"",selectedVideoName:"",selectedVideoUrl:"",selectedPhotoUrl:"",selectedVoiceId:"",selectedDialect:"",selectedLanguageHint:"",selectedLanguageHintLabel:"",languageHintOptions:["中文(zh)","英文(en)","法语(fr)","德语(de)","日语(ja)","韩语(ko)","俄语(ru)"],dialectOptions:["广东话","东北话","甘肃话","贵州话","河南话","湖北话","江西话","闽南话","宁夏话","山西话","陕西话","山东话","上海话","四川话","天津话","云南话"],isConnecting:!1,connectingText:"正在接通...",videoCache:{},downloadingVideos:{},localVideoUrl:"",cacheProgress:{},preCachingInProgress:!1,videoPreloadStatus:{},callStarted:!1,callStatus:"视频通话中",callDuration:"00:00",callStartTime:null,durationTimer:null,messages:[],recognizingText:"",scrollTop:0,isRecording:!1,isProcessing:!1,isSpeaking:!1,processingText:"正在聆听...",recorderManager:null,audioFilePath:"",recordingStartTime:null,autoListen:!1,autoLoopTimer:null,longPressTimer:null,isTouching:!1,stopFallbackTimer:null,stopFallbackRetries:0,stopFallbackActive:!1,vadEnabled:!0,vadVoiceThreshold:.004,vadSilenceMs:600,vadMaxDurationMs:15e3,vadSpeaking:!1,vadSilenceStart:null,vadMaxTimer:null,vadLastSoundTime:null,vadLastFrameTime:null,vadWatchTimer:null,audioContext:null,audioCacheKey:"",currentAudioSrc:"",pendingAudioUrl:"",audioTriedFallback:!1,audioSessionId:0,audioPlayedInSession:!1,audioPlayStartAt:0,audioTriedRedownload:!1,audioTriedRecreateContext:!1,audioPlayInvokedInSession:!1,audioPlayTargetSessionId:0,audioDiagnosedInSession:!1,videoContext:null,audioContextActivated:!1,videoInitialPlayed:!1,processingTimeout:null,showSettingsDialog:!1,dialogMemoryIdentity:"",dialogMemoryInfo:"",dialogMemoryCatchphrase:"",systemPrompt:"",paymentModalData:{show:!1,serviceType:"",serviceName:"",serviceDesc:"",price:0,orderNo:"",paymentTips:"点击确认支付后将开始视频通话"},_paymentResolve:null,_paymentReject:null,_paymentOnSuccess:null,_paymentOnFailed:null}),async onLoad(o){console.log("[VideoCallNew] 页面加载",o),this.loadOptions=o;const i=e.index.getStorageSync("userId");this.lastUserId=i,await this.loadVideoCache(),o&&o.videoId?(this.selectedVideoId=o.videoId,this.selectedVideoName=decodeURIComponent(o.videoName||"复活视频"),this.selectedVideoUrl=decodeURIComponent(o.videoUrl||""),this.selectedVoiceId=o.voiceId||"",this.selectedDialect="",console.log("[VideoCallNew] 从URL参数加载视频信息"),console.log("[VideoCallNew] 视频ID:",this.selectedVideoId),console.log("[VideoCallNew] 视频名称:",this.selectedVideoName),console.log("[VideoCallNew] 视频URL:",this.selectedVideoUrl),console.log("[VideoCallNew] 音色ID:",this.selectedVoiceId),await this.checkAndLoadLocalVideo(this.selectedVideoId,this.selectedVideoUrl),this.initRecorder(),this.initAudioContext(),this.initVideoContext(),this.startAutoLoop(),setTimeout((()=>{this.startVideoCallDirect()}),300)):(this.loadVideos(),this.initRecorder(),this.initAudioContext(),this.initVideoContext(),this.startAutoLoop())},onShow(){console.log("[VideoCallNew] 页面显示");const o=e.index.getStorageSync("userId");o!==this.lastUserId&&(console.log("[VideoCallNew] 检测到用户切换"),console.log("[VideoCallNew] 上次用户ID:",this.lastUserId,"当前用户ID:",o),this.lastUserId=o),this.callStarted||this.loadOptions&&this.loadOptions.videoId||(console.log("[VideoCallNew] 页面重新显示,刷新视频列表"),this.loadVideos())},onUnload(){this.cleanup()},methods:{isVideoUsableForCall(e){if(!e)return!1;const o=e.edited_video_url||e.videoUrl||e.local_video_path||e.video_url||e.localVideoPath,i=e.voice_id||e.voiceId;return!!o&&!!i},async loadVideos(){this.loading=!0;const o=e.index.getStorageSync("userId")||"",i=e.index.getStorageSync("token")||"";await this.loadVideoCache(),e.index.request({url:`${this.API_BASE}/api/photo-revival/videos`,method:"GET",header:{"X-User-Id":o,Authorization:i?`Bearer ${i}`:""},success:e=>{if(console.log("[VideoCallNew] 视频列表响应:",e.data),200===e.statusCode){let o=[];Array.isArray(e.data)?o=e.data:e.data&&Array.isArray(e.data.data)?o=e.data.data:(e.data&&e.data.videos&&Array.isArray(e.data.videos)||e.data&&e.data.success&&Array.isArray(e.data.videos))&&(o=e.data.videos),this.videos=(o||[]).filter((e=>this.isVideoUsableForCall(e))),console.log("[VideoCallNew] 加载视频列表成功:",this.videos.length)}},fail:o=>{console.error("[VideoCallNew] 加载视频列表失败:",o),e.index.showToast({title:"加载失败",icon:"none"})},complete:()=>{this.loading=!1}})},selectVideo(e){this.selectedVideoId=e.id,this.selectedVideoName=e.name||"复活视频",this.selectedVideoUrl=e.edited_video_url||e.videoUrl||e.local_video_path||e.video_url||e.localVideoPath,this.selectedPhotoUrl=e.photoUrl||e.photo_url||e.photoPath||"",this.selectedVoiceId=e.voice_id||e.voiceId,this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",console.log("[VideoCallNew] 选择视频:",this.selectedVideoId),console.log("[VideoCallNew] 视频URL:",this.selectedVideoUrl),console.log("[VideoCallNew] 照片URL:",this.selectedPhotoUrl),console.log("[VideoCallNew] 音色ID:",this.selectedVoiceId)},async startVideoCall(o){this.selectVideo(o),this.selectedVideoId&&this.selectedVoiceId?this.selectedVideoUrl?(console.log("[VideoCallNew] 准备视频通话,视频ID:",this.selectedVideoId),console.log("[VideoCallNew] 视频URL:",this.selectedVideoUrl),await this.checkAndLoadLocalVideo(this.selectedVideoId,this.selectedVideoUrl),i.showPaymentModal(this,i.SERVICE_TYPES.VIDEO_CALL.type,(()=>{this.showCallSettings()}),(e=>{console.error("[Payment] 支付失败:",e)}))):e.index.showToast({title:"视频地址不存在",icon:"none"}):e.index.showToast({title:"该视频无法进行通话",icon:"none"})},async startVideoCallDirect(){return this.selectedVideoId&&this.selectedVoiceId?this.selectedVideoUrl?(console.log("[VideoCallNew] 直接开始视频通话"),console.log("[VideoCallNew] 视频ID:",this.selectedVideoId),console.log("[VideoCallNew] 当前使用URL:",this.localVideoUrl||this.selectedVideoUrl),void i.showPaymentModal(this,i.SERVICE_TYPES.VIDEO_CALL.type,(()=>{this.showCallSettings()}),(o=>{console.error("[Payment] 支付失败:",o),setTimeout((()=>{e.index.navigateBack()}),1e3)}))):(e.index.showToast({title:"视频地址不存在",icon:"none"}),void setTimeout((()=>{e.index.navigateBack()}),1500)):(e.index.showToast({title:"视频信息不完整",icon:"none"}),void setTimeout((()=>{e.index.navigateBack()}),1500))},showCallSettings(){this.dialogMemoryIdentity="",this.dialogMemoryInfo="",this.dialogMemoryCatchphrase="",this.showSettingsDialog=!0},closeSettingsDialog(){this.showSettingsDialog=!1},confirmSettings(){if(console.log("[VideoCallNew] 开始视频通话"),console.log("[VideoCallNew] 使用视频的音色ID:",this.selectedVoiceId),this.showSettingsDialog=!1,this.videoInitialPlayed=!1,this.isConnecting=!0,this.connectingText="正在接通...",this.dialogMemoryIdentity||this.dialogMemoryInfo)if(this.dialogMemoryIdentity){let e=`你是${this.dialogMemoryIdentity},你已经去世。用户正在和你对话。`;e+="\n\n你的性格特点:\n\n亲切、真实、克制",e+="\n\n你的行事风格:\n\n直接回答,不绕弯",e+="\n\n你的语言特点:\n\n自然口语,语气温和",this.dialogMemoryInfo&&(e+=`\n\n补充设定(请严格遵循):\n\n${this.dialogMemoryInfo}`),e+="\n\n注意:不要使用括号(包括()和())来描述动作、心理、背景。",e+="\n\n规则:\n\n1. 不要虚构不存在的事,不要编造记忆或经历。\n2. 不要回忆以前(除非用户明确提到并且你能基于已有设定回答)。\n3. 不要使用任何称呼(因为用户可能是任何身份)。\n4. 不要使用emoji/颜文字/特殊符号。\n5. 顺应用户话题,亲切回答问题。\n6. 时刻记住自己是逝者。\n7. 每次回复保持在20~50字之间。",this.systemPrompt=e}else{let e="你是一位已经去世的人。用户正在和你对话。";e+="\n\n你的性格特点:\n\n亲切、真实、克制",e+="\n\n你的行事风格:\n\n直接回答,不绕弯",e+="\n\n你的语言特点:\n\n自然口语,语气温和",this.dialogMemoryInfo&&(e+=`\n\n补充设定(请严格遵循):\n\n${this.dialogMemoryInfo}`),e+="\n\n注意:不要使用括号(包括()和())来描述动作、心理、背景。",e+="\n\n规则:\n\n1. 不要虚构不存在的事,不要编造记忆或经历。\n2. 不要回忆以前(除非用户明确提到并且你能基于已有设定回答)。\n3. 不要使用任何称呼(因为用户可能是任何身份)。\n4. 不要使用emoji/颜文字/特殊符号。\n5. 顺应用户话题,亲切回答问题。\n6. 时刻记住自己是逝者。\n7. 每次回复保持在20~50字之间。",this.systemPrompt=e}else{let e="你是一位已经去世的人。用户正在和你对话。";e+="\n\n你的性格特点:\n\n亲切、真实、克制",e+="\n\n你的行事风格:\n\n直接回答,不绕弯",e+="\n\n你的语言特点:\n\n自然口语,语气温和",e+="\n\n注意:不要使用括号(包括()和())来描述动作、心理、背景。",e+="\n\n规则:\n\n1. 不要虚构不存在的事,不要编造记忆或经历。\n2. 不要回忆以前(除非用户明确提到并且你能基于已有设定回答)。\n3. 不要使用任何称呼(因为用户可能是任何身份)。\n4. 不要使用emoji/颜文字/特殊符号。\n5. 顺应用户话题,亲切回答问题。\n6. 时刻记住自己是逝者。\n7. 每次回复保持在20~50字之间。",this.systemPrompt=e}console.log("[VideoCallNew] 系统提示词:",this.systemPrompt),this.callStarted=!0,this.startCallTimer(),this.$nextTick((()=>{this.videoContext=e.index.createVideoContext("callVideo",this),console.log("[VideoCallNew] 重新初始化视频上下文"),console.log("[VideoCallNew] 当前视频URL:",this.localVideoUrl||this.selectedVideoUrl)}))},startCallTimer(){this.callStartTime=Date.now(),this.durationTimer=setInterval((()=>{const e=Math.floor((Date.now()-this.callStartTime)/1e3),o=Math.floor(e/60).toString().padStart(2,"0"),i=(e%60).toString().padStart(2,"0");this.callDuration=`${o}:${i}`,e>=600&&(console.log("[VideoCallNew] 通话时长已达10分钟,自动挂断"),this.autoEndCall())}),1e3)},initRecorder(){this.recorderManager=e.index.getRecorderManager(),console.log("[VAD] RecorderManager 对象:",this.recorderManager),console.log("[VAD] onFrameRecorded 方法存在:",typeof this.recorderManager.onFrameRecorded),this.recorderManager.onStart((()=>{console.log("[VideoCallNew] 开始录音")})),this.recorderManager.onStop((e=>{console.log("[VideoCallNew] 录音完成:",e.tempFilePath),this.isRecording=!1,this.isTouching=!1,this.longPressTimer&&(clearTimeout(this.longPressTimer),this.longPressTimer=null),this.stopFallbackTimer&&(clearTimeout(this.stopFallbackTimer),this.stopFallbackTimer=null),this.stopFallbackActive=!1,this.stopFallbackRetries=0,this.resetVADState();if((e.duration||Date.now()-(this.recordingStartTime||Date.now()))<400)return console.warn("[VideoCallNew] 录音过短,已忽略"),this.isProcessing=!1,void(this.callStatus="通话中");this.audioFilePath=e.tempFilePath,this.processConversation()})),"function"==typeof this.recorderManager.onFrameRecorded?(console.log("[VAD] ✅ onFrameRecorded 支持,已绑定帧回调"),this.recorderManager.onFrameRecorded((e=>{console.log("[VAD] 🎯 收到帧数据!大小:",e.frameBuffer?e.frameBuffer.byteLength:0,"bytes"),this.vadEnabled&&!this.isProcessing?this.handleVADFrame(e.frameBuffer):console.log("[VAD] VAD已禁用或正在处理,跳过")}))):(console.error("[VAD] ❌ onFrameRecorded 不支持,VAD功能将无法使用"),console.error("[VAD] recorderManager 类型:",typeof this.recorderManager),console.error("[VAD] 可用方法:",Object.keys(this.recorderManager)),this.vadEnabled=!1),this.recorderManager.onError((o=>{console.error("[VideoCallNew] 录音失败:",o),this.isRecording=!1,this.resetVADState();o.errMsg&&(o.errMsg.includes("permission")||o.errMsg.includes("authorize")||o.errMsg.includes("denied")||o.errMsg.includes("占用"))?e.index.showModal({title:"需要麦克风权限",content:"录音功能需要麦克风权限才能使用。\n\n请前往:\n手机设置 → 应用管理 → 时光意境 → 权限管理 → 开启麦克风权限",confirmText:"我知道了",showCancel:!1}):e.index.showToast({title:"录音失败: "+(o.errMsg||"未知错误"),icon:"none",duration:3e3})}))},initVideoContext(){this.videoContext=e.index.createVideoContext("callVideo",this)},initAudioContext(){if(!this.audioContext){this.audioContext=e.index.createInnerAudioContext(),this.audioContext.volume=1;try{this.audioContext.obeyMuteSwitch=!1}catch(o){console.warn("[VideoCallNew] 设置obeyMuteSwitch失败:",o)}console.log("[VideoCallNew] 🔊 音频上下文初始化完成,音量设置为最大"),this.audioContext.onCanplay((()=>{console.log("[VideoCallNew] ✅ 音频已准备好,可以播放"),this.tryPlayAudioForSession("canplay")})),this.audioContext.onEnded((()=>{console.log("[VideoCallNew] AI回复播放完成"),this.isSpeaking=!1,this.callStatus="通话中",this.videoContext&&this.videoContext.pause()})),this.audioContext.onError((i=>{this.isSpeaking&&!this.audioDiagnosedInSession&&this.pendingAudioUrl&&(this.audioDiagnosedInSession=!0,this.diagnoseAudioUrl(this.pendingAudioUrl));const t=!(!i||!(67===i.errCode||i.errMsg&&String(i.errMsg).includes("decode"))),s=!(!this.pendingAudioUrl||this.currentAudioSrc!==this.pendingAudioUrl&&this.audioContext.src!==this.pendingAudioUrl);if(this.isSpeaking&&!this.audioTriedFallback&&t&&s&&this.pendingAudioUrl&&this.audioContext){this.audioTriedFallback=!0,console.warn("[VideoCallNew] 音频播放失败,尝试回退本地重试一次。errCode=",i.errCode,"errMsg=",i.errMsg);const e=this.audioSessionId;return void this.downloadAudioTemp(this.pendingAudioUrl).then((i=>{if(e===this.audioSessionId&&i&&this.audioContext&&this.isSpeaking&&i!==this.pendingAudioUrl&&i!==this.currentAudioSrc&&i!==this.audioContext.src){try{this.audioContext.stop()}catch(o){}this.currentAudioSrc=i,this.audioContext.src=i,setTimeout((()=>{if(e===this.audioSessionId&&this.audioContext&&this.isSpeaking)try{this.audioContext.play(),console.log("[VideoCallNew] ✅ 已使用本地音频回退重试播放")}catch(o){}}),150)}}))}if(this.isSpeaking&&t&&!this.audioTriedRecreateContext&&this.audioContext){this.audioTriedRecreateContext=!0;const e=this.audioSessionId,i=this.currentAudioSrc||this.audioContext&&this.audioContext.src||this.pendingAudioUrl;return console.warn("[VideoCallNew] decode fail,尝试重建音频上下文并重试一次"),void this.recreateAudioContext().then((()=>{e===this.audioSessionId&&this.audioContext&&this.isSpeaking&&i&&(this.audioContext.src=i,this.currentAudioSrc=i,setTimeout((()=>{if(e===this.audioSessionId&&this.audioContext&&this.isSpeaking)try{this.audioContext.play(),console.log("[VideoCallNew] ✅ 已重建音频上下文并重试播放")}catch(o){}}),200))}))}const a=!!(this.audioContext&&this.audioContext.src&&String(this.audioContext.src).startsWith("wxfile://store_"));if(this.isSpeaking&&t&&!this.audioTriedRedownload&&a&&this.pendingAudioUrl&&this.audioContext){this.audioTriedRedownload=!0;const e=this.audioSessionId;return console.warn("[VideoCallNew] 本地缓存音频解码失败,清缓存并重新下载临时文件重试一次"),void this.clearAudioCacheForUrl(this.pendingAudioUrl).finally((()=>{this.downloadAudioTemp(this.pendingAudioUrl).then((i=>{if(e===this.audioSessionId&&i&&this.audioContext&&this.isSpeaking){try{this.audioContext.stop()}catch(o){}this.currentAudioSrc=i,this.audioContext.src=i,setTimeout((()=>{if(e===this.audioSessionId&&this.audioContext&&this.isSpeaking)try{this.audioContext.play(),console.log("[VideoCallNew] ✅ 已使用重新下载的临时音频重试播放")}catch(o){}}),200)}}))}))}console.error("[VideoCallNew] ❌ 音频播放失败:",JSON.stringify(i)),console.error("[VideoCallNew] 错误详情 - errMsg:",i.errMsg,"errCode:",i.errCode),this.isSpeaking=!1,this.callStatus="通话中",this.isProcessing=!1,e.index.showToast({title:"音频播放失败",icon:"none",duration:2e3}),this.videoContext&&this.videoContext.pause()})),this.audioContext.onPlay((()=>{console.log("[VideoCallNew] ▶️ 音频播放事件触发"),this.audioPlayedInSession=!0,this.audioPlayStartAt=Date.now(),this.videoContext&&this.videoContext.play()})),this.audioContext.onPause((()=>{console.log("[VideoCallNew] ⏸️ 音频暂停事件触发"),this.isSpeaking&&(console.warn("[VideoCallNew] ⚠️ AI说话时音频被暂停,尝试恢复播放..."),setTimeout((()=>{if(this.isSpeaking&&this.audioContext)try{this.audioContext.play(),console.log("[VideoCallNew] ✅ 音频已恢复播放")}catch(o){console.error("[VideoCallNew] ❌ 恢复音频播放失败:",o)}}),100))})),this.audioContext.onWaiting((()=>{console.log("[VideoCallNew] ⏳ 音频加载中...")})),this.audioContext.onStop((()=>{console.log("[VideoCallNew] 音频停止事件触发")})),this.audioContext.onWaiting((()=>{console.log("[VideoCallNew] 音频等待加载")})),this.audioContext.onCanplay((()=>{console.log("[VideoCallNew] 音频可以播放"),this.tryPlayAudioForSession("canplay2")}))}},tryPlayAudioForSession(e){const o=this.audioPlayTargetSessionId;if(o&&o===this.audioSessionId&&this.audioContext&&this.isSpeaking&&!this.audioPlayInvokedInSession){this.audioPlayInvokedInSession=!0;try{this.audioContext.play(),console.log("[VideoCallNew] ✅ 已触发音频播放(",e,")")}catch(i){console.error("[VideoCallNew] ❌ 触发音频播放失败(",e,"):",i)}}},recreateAudioContext(){return new Promise((e=>{try{if(this.audioContext){try{this.audioContext.stop()}catch(o){}try{this.audioContext.destroy()}catch(o){}}}catch(o){}this.audioContext=null,this.initAudioContext(),setTimeout((()=>e()),50)}))},diagnoseAudioUrl(o){if(o){console.log("[VideoCallNew] 🔍 音频诊断:开始下载以检测是否为有效mp3",o);try{e.index.request({url:o,method:"HEAD",timeout:2e4,success:e=>{console.log("[VideoCallNew] 🔍 音频诊断:HEAD statusCode=",e.statusCode),console.log("[VideoCallNew] 🔍 音频诊断:HEAD headers=",e.header||{})},fail:e=>{console.log("[VideoCallNew] 🔍 音频诊断:HEAD失败",e)}})}catch(i){}e.index.downloadFile({url:o,timeout:2e4,success:o=>{if(console.log("[VideoCallNew] 🔍 音频诊断:downloadFile statusCode=",o.statusCode),200===o.statusCode&&o.tempFilePath)try{const t=e.index.getFileSystemManager();try{t.readFile({filePath:o.tempFilePath,position:0,length:16,success:e=>{let o="";try{const i=new Uint8Array(e.data);o=Array.from(i).map((e=>e.toString(16).padStart(2,"0"))).join(" ")}catch(i){o=""}console.log("[VideoCallNew] 🔍 音频诊断:file header(16 bytes)=",o)},fail:e=>{console.log("[VideoCallNew] 🔍 音频诊断:readFile失败",e)}})}catch(i){}t.getFileInfo({filePath:o.tempFilePath,success:e=>{console.log("[VideoCallNew] 🔍 音频诊断:tempFile size=",e.size,"path=",o.tempFilePath)},fail:e=>{console.log("[VideoCallNew] 🔍 音频诊断:getFileInfo失败",e)}})}catch(i){console.log("[VideoCallNew] 🔍 音频诊断异常:",i)}},fail:e=>{console.log("[VideoCallNew] 🔍 音频诊断:downloadFile失败",e)}})}},generateAudioCacheKey(e){if(!e)return"";let o=0;for(let i=0;i{if(!o)return void i("");const t=this.generateAudioCacheKey(o);this.audioCacheKey=t;const s=e.index.getStorageSync(t);s?e.index.getSavedFileInfo({filePath:s,success:()=>{i(s)},fail:()=>{try{e.index.removeStorageSync(t)}catch(o){}i("")}}):e.index.downloadFile({url:o,timeout:6e4,success:o=>{200===o.statusCode?e.index.saveFile({tempFilePath:o.tempFilePath,success:o=>{try{e.index.setStorageSync(t,o.savedFilePath)}catch(s){}i(o.savedFilePath)},fail:()=>{i(o.tempFilePath)}}):i("")},fail:()=>{i("")}})}))},clearAudioCacheForUrl(o){return new Promise((i=>{try{const s=this.generateAudioCacheKey(o),a=e.index.getStorageSync(s);try{e.index.removeStorageSync(s)}catch(t){}if(a)return void e.index.removeSavedFile({filePath:a,complete:()=>{i()}})}catch(t){}i()}))},downloadAudioTemp:o=>new Promise((i=>{o?e.index.downloadFile({url:o,timeout:2e4,success:e=>{200===e.statusCode&&e.tempFilePath?i(e.tempFilePath):i("")},fail:()=>{i("")}}):i("")})),handleTouchStart(e){console.log("[VideoCallNew] ========== 触摸开始 =========="),console.log("[VideoCallNew] 事件对象:",e),console.log("[VideoCallNew] isProcessing:",this.isProcessing,"isRecording:",this.isRecording),this.isProcessing||this.isRecording?console.log("[VideoCallNew] 跳过:正在处理或录音中"):(this.isTouching=!0,this.longPressTimer=setTimeout((()=>{this.isTouching&&(console.log("[VideoCallNew] 长按触发,开始录音"),this.startRecording(!0))}),300))},handleTouchEnd(e){console.log("[VideoCallNew] ========== 触摸结束 =========="),console.log("[VideoCallNew] 事件对象:",e),this.isTouching=!1,this.longPressTimer&&(clearTimeout(this.longPressTimer),this.longPressTimer=null),this.isRecording&&(console.log("[VideoCallNew] 松开手指,发送录音"),this.stopRecordingInternal("manual"))},onDialectChange(e){this.selectedDialect=this.dialectOptions[e.detail.value]||""},onLanguageHintChange(e){const o=this.languageHintOptions[e.detail.value]||"";this.selectedLanguageHintLabel=o;const i=o.match(/\(([^)]+)\)/);this.selectedLanguageHint=i&&i[1]?i[1]:""},handleTouchCancel(o){console.log("[VideoCallNew] ========== 触摸取消 =========="),console.log("[VideoCallNew] 事件对象:",o),this.isTouching=!1,this.longPressTimer&&(clearTimeout(this.longPressTimer),this.longPressTimer=null),this.isRecording&&(console.log("[VideoCallNew] 触摸取消,停止录音"),this.isRecording=!1,this.recorderManager.stop(),this.resetVADState(),e.index.showToast({title:"已取消录音",icon:"none",duration:1500}))},handleGlobalTouchEnd(e){console.log("[VideoCallNew] ========== 全局触摸结束兜底 ==========",e),this.isTouching=!1,this.longPressTimer&&(clearTimeout(this.longPressTimer),this.longPressTimer=null),this.isRecording&&this.stopRecordingInternal("manual")},handleGlobalTouchCancel(o){console.log("[VideoCallNew] ========== 全局触摸取消兜底 ==========",o),this.isTouching=!1,this.longPressTimer&&(clearTimeout(this.longPressTimer),this.longPressTimer=null),this.isRecording&&(this.isRecording=!1,this.recorderManager.stop(),this.resetVADState(),e.index.showToast({title:"已取消录音",icon:"none",duration:1500}))},startRecording(e=!1){if(this.isProcessing)return;if(this.isSpeaking&&!e)return;this.resetVADState(),this.recordingStartTime=Date.now(),this.vadLastSoundTime=this.recordingStartTime,this.vadLastFrameTime=this.recordingStartTime,this.isRecording=!0,console.log("[VAD] 开始录音,时间:",(new Date).toLocaleTimeString());this.vadEnabled&&!e&&(this.vadMaxTimer=setTimeout((()=>{console.log("[VAD] 达到最大录音时长15秒,强制停止"),this.stopRecordingInternal("max_duration")}),this.vadMaxDurationMs),this.vadWatchTimer=setInterval((()=>{if(!this.isRecording)return;const e=Date.now(),o=e-(this.recordingStartTime||e),i=e-(this.vadLastSoundTime||e);return e-(this.vadLastFrameTime||e)>8e3?(console.log("[VAD] 无帧回调超时,停止录音"),void this.stopRecordingInternal("no_frame")):!this.vadSpeaking&&o>2500?(console.log("[VAD] 未检测到语音,自动停止录音"),void this.stopRecordingInternal("no_speech")):o>500&&this.vadSpeaking&&i>this.vadSilenceMs?(console.log("[VAD] 检测到静音超时"),console.log("[VAD] 录音总时长:",o,"ms, 静音时长:",i,"ms"),void this.stopRecordingInternal("silence")):void 0}),150));const o={format:"mp3",sampleRate:16e3,numberOfChannels:1,encodeBitRate:32e3};e&&(o.duration=6e5),this.vadEnabled&&this.recorderManager.onFrameRecorded&&(o.frameSize=200,console.log("[VAD] 启用帧回调,frameSize: 200ms")),console.log("[VAD] 录音参数:",JSON.stringify(o)),this.recorderManager.start(o),this.callStatus="正在录音(自动识别说话)"},stopRecording(){this.isRecording&&this.stopRecordingInternal("manual")},stopRecordingInternal(o="manual"){if(this.isRecording){if(this.isRecording=!1,this.recorderManager.stop(),this.stopFallbackActive=!0,this.stopFallbackRetries=0,this.stopFallbackTimer&&(clearTimeout(this.stopFallbackTimer),this.stopFallbackTimer=null),this.stopFallbackTimer=setTimeout((()=>{this.retryStopRecording()}),1200),this.isProcessing=!0,this.processingText="正在聆听...",this.callStatus="处理中...",this.recognizingText="",this.resetVADState(),console.log("[VideoCallNew] 停止录音,原因:",o),!this.audioContextActivated)try{const o=e.index.createInnerAudioContext();o.src="data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQAAAAA=",o.volume=0,setTimeout((()=>{o.destroy()}),100),this.audioContextActivated=!0,console.log("[VideoCallNew] 音频上下文已激活")}catch(i){console.warn("[VideoCallNew] 激活音频上下文失败:",i)}this.processingTimeout=setTimeout((()=>{this.isProcessing&&(console.warn("[VideoCallNew] 处理超时,重置状态"),this.isProcessing=!1,this.callStatus="通话中",e.index.showToast({title:"处理超时,请重试",icon:"none"}))}),3e4)}},retryStopRecording(){if(this.stopFallbackActive&&this.recorderManager){if(this.stopFallbackRetries+=1,this.stopFallbackRetries>2)return this.stopFallbackActive=!1,this.stopFallbackTimer=null,this.isProcessing=!1,void(this.callStatus="通话中");try{this.recorderManager.stop()}catch(e){}this.stopFallbackTimer=setTimeout((()=>{this.retryStopRecording()}),1200)}},resetVADState(){this.vadSpeaking=!1,this.vadSilenceStart=null,this.vadLastSoundTime=null,this.vadLastFrameTime=null,this.vadMaxTimer&&(clearTimeout(this.vadMaxTimer),this.vadMaxTimer=null),this.vadWatchTimer&&(clearInterval(this.vadWatchTimer),this.vadWatchTimer=null)},handleVADFrame(e){if(!e||0===e.byteLength)return;this.vadLastFrameTime=Date.now();const o=this.calculateRms(e);if(o>this.vadVoiceThreshold)return this.vadSpeaking||console.log("[VAD] 检测到语音开始,音量:",o.toFixed(4)),this.vadSpeaking=!0,this.vadSilenceStart=null,void(this.vadLastSoundTime=Date.now());this.vadSpeaking?this.vadSilenceStart||(this.vadSilenceStart=Date.now(),console.log("[VAD] 检测到静音开始,音量:",o.toFixed(4))):Math.random()<.1&&console.log("[VAD] 等待语音中,当前音量:",o.toFixed(4),"阈值:",this.vadVoiceThreshold)},calculateRms(e){const o=new DataView(e),i=o.byteLength/2;if(0===i)return 0;let t=0;for(let s=0;s{this.callStarted&&this.autoListen&&(this.isSpeaking||this.isRecording||this.isProcessing||this.startRecording(!1))}),2e3))},async processConversation(){try{this.processingText="正在识别...";const o=e.index.getStorageSync("userId")||"",i=e.index.getStorageSync("token")||"";setTimeout((()=>{this.isProcessing&&(this.processingText="正在思考...")}),800),setTimeout((()=>{this.isProcessing&&(this.processingText="正在回复...")}),2e3),e.index.uploadFile({url:`${this.API_BASE}/api/conversation/talk`,filePath:this.audioFilePath,name:"audio",header:{"X-User-Id":o,Authorization:i?`Bearer ${i}`:""},formData:(()=>{const e=this.selectedVoiceId,o=(()=>{const o=(e||"").trim();if(!o)return"CLONE";return["Cherry","Kai","Mochi","Bunny","Jada","Dylan","Li","Marcus","Roy","Peter","Sunny","Eric","Rocky","Kiki"].includes(o)||o.startsWith("BV")||o.endsWith("_streaming")||o.endsWith("_offline")||o.endsWith("_bigtts")?"OFFICIAL":"CLONE"})(),i={voiceId:e,voiceType:o,serviceType:"VIDEO_CALL",systemPrompt:this.systemPrompt||"",saveHistory:"false"};return this.selectedDialect&&(i.dialect=this.selectedDialect),this.selectedLanguageHint&&(i.languageHints=this.selectedLanguageHint),i})(),success:o=>{if(this.processingTimeout&&(clearTimeout(this.processingTimeout),this.processingTimeout=null),console.log("[VideoCallNew] 对话响应:",o),200===o.statusCode){const i=JSON.parse(o.data);if(i.success)this.addMessage("user",i.recognizedText),this.addMessage("ai",i.aiResponse),this.playAIResponse(i.audioFile);else{const o=i.message||"未识别到语音内容";console.error("[VideoCallNew] 识别失败:",o),e.index.showModal({title:"对话失败",content:o+"\n\n请重试。若已支付但多次失败,请联系客服补发(提供订单号/支付时间截图)。",showCancel:!1,confirmText:"我知道了"}),this.isProcessing=!1,this.callStatus="通话中"}}else{console.error("[VideoCallNew] 请求失败,状态码:",o.statusCode);let t=null;try{t=JSON.parse(o.data)}catch(i){t=null}const s=t&&t.message?t.message:"对话请求失败: HTTP "+o.statusCode;e.index.showModal({title:"对话失败",content:s+"\n\n请重试。若已支付但多次失败,请联系客服补发(提供订单号/支付时间截图)。",showCancel:!1,confirmText:"我知道了"}),this.isProcessing=!1,this.callStatus="通话中"}},fail:o=>{this.processingTimeout&&(clearTimeout(this.processingTimeout),this.processingTimeout=null),console.error("[VideoCallNew] 对话失败:",o),e.index.showModal({title:"对话失败",content:"网络请求失败:"+(o.errMsg||"未知错误")+"\n\n请重试。若已支付但多次失败,请联系客服补发(提供订单号/支付时间截图)。",showCancel:!1,confirmText:"我知道了"}),this.isProcessing=!1,this.callStatus="通话中"}})}catch(o){this.processingTimeout&&(clearTimeout(this.processingTimeout),this.processingTimeout=null),console.error("[VideoCallNew] 对话失败:",o),e.index.showModal({title:"对话失败",content:(o.message||"未知错误")+"\n\n请重试。若已支付但多次失败,请联系客服补发(提供订单号/支付时间截图)。",showCancel:!1,confirmText:"我知道了"}),this.isProcessing=!1,this.callStatus="通话中"}},async playAIResponse(o){if(!o)return console.error("[VideoCallNew] ❌ 音频文件为空"),e.index.showToast({title:"音频文件缺失",icon:"none"}),this.isProcessing=!1,void(this.callStatus="通话中");this.processingText="正在回复...";const i=`${this.API_BASE}/api/conversation/audio/${o}`;if(console.log("[VideoCallNew] 🎵 准备播放音频:",i),console.log("[VideoCallNew] 📁 音频文件名:",o),this.audioContext)try{console.log("[VideoCallNew] 停止之前的音频..."),this.audioContext.stop()}catch(a){console.warn("[VideoCallNew] 停止音频实例失败:",a)}else console.log("[VideoCallNew] 初始化音频上下文..."),this.initAudioContext();this.audioSessionId+=1;const t=this.audioSessionId;this.audioPlayedInSession=!1,this.audioPlayStartAt=0,this.audioTriedRedownload=!1,this.audioTriedRecreateContext=!1,this.audioPlayInvokedInSession=!1,this.audioPlayTargetSessionId=t,this.audioDiagnosedInSession=!1,this.pendingAudioUrl=i,this.audioTriedFallback=!1;let s=i;try{const e=await this.downloadAudioTemp(i);t===this.audioSessionId&&e&&(s=e)}catch(a){}if(t===this.audioSessionId&&this.audioContext){this.currentAudioSrc=s,this.audioContext.src=s,this.audioContext.volume=1;try{this.audioContext.obeyMuteSwitch=!1}catch(a){console.warn("[VideoCallNew] 设置obeyMuteSwitch失败:",a)}console.log("[VideoCallNew] 🔊 音频源已设置:",this.audioContext.src),console.log("[VideoCallNew] 🔊 音频音量:",this.audioContext.volume),console.log("[VideoCallNew] 📢 如果声音过小,请检查:1.手机系统音量 2.媒体音量 3.静音开关"),console.log("[VideoCallNew] 🎬 AI开始回复,从第1秒开始循环播放视频"),this.isSpeaking=!0,this.callStatus="对方正在说话...",this.videoContext&&(this.videoContext.seek(1),setTimeout((()=>{this.videoContext&&this.videoContext.play()}),100)),console.log("[VideoCallNew] ▶️ 开始播放音频..."),setTimeout((()=>{t===this.audioSessionId&&this.tryPlayAudioForSession("timer")}),500),this.isProcessing=!1}},addMessage(e,o){const i=new Date,t=`${i.getHours()}:${i.getMinutes().toString().padStart(2,"0")}`;this.messages.push({role:e,content:o,time:t}),this.$nextTick((()=>{this.scrollTop=999999}))},handleClearHistory(o){console.log("[VideoCallNew] ========== 清空按钮被点击 =========="),console.log("[VideoCallNew] 事件对象:",o),e.index.showToast({title:"清空按钮已点击",icon:"none",duration:1e3}),e.index.showModal({title:"确认清空",content:"确定要清空对话历史吗?",confirmColor:"#8B7355",success:e=>{e.confirm&&this.clearHistory()}})},clearHistory(){const o=e.index.getStorageSync("userId")||"",i=e.index.getStorageSync("token")||"";e.index.request({url:`${this.API_BASE}/api/conversation/clear-history`,method:"POST",header:{"X-User-Id":o,Authorization:i?`Bearer ${i}`:""},success:o=>{var i;o.data&&o.data.success?(this.messages=[],e.index.showToast({title:"已清空",icon:"success"})):e.index.showToast({title:(null==(i=o.data)?void 0:i.message)||"清空失败",icon:"none"})},fail:o=>{console.error("[VideoCallNew] 清空历史失败:",o),e.index.showToast({title:"清空失败,请稍后重试",icon:"none"})}})},autoEndCall(){this.durationTimer&&(clearInterval(this.durationTimer),this.durationTimer=null),this.cleanup(),e.index.showModal({title:"通话已结束",content:"您本次通话已达10分钟时长上限,通话已自动结束。",showCancel:!1,confirmText:"好的",confirmColor:"#8B7355",success:o=>{o.confirm&&e.index.reLaunch({url:"/pages/index/index"})}})},endCall(o){console.log("[VideoCallNew] ========== 挂断按钮被点击 =========="),console.log("[VideoCallNew] 事件对象:",o),e.index.showToast({title:"挂断按钮已点击",icon:"none",duration:1e3}),e.index.showModal({title:"结束通话",content:`通话时长:${this.callDuration}\n确定要结束通话吗?`,confirmColor:"#eb3349",success:o=>{o.confirm&&(e.index.showLoading({title:"正在挂断...",mask:!0}),setTimeout((()=>{e.index.hideLoading(),this.cleanup(),e.index.showToast({title:"通话已结束",icon:"success",duration:1500}),setTimeout((()=>{e.index.reLaunch({url:"/pages/index/index"})}),1500)}),800))}})},goBack(){this.callStarted?this.endCall():e.index.navigateBack()},goToRevival(){console.log("[VideoCallNew] 跳转到复活照片页面"),e.index.navigateTo({url:"/pages/revival/revival-original",fail:e=>{console.error("[VideoCallNew] 跳转失败:",e)}})},onVideoMetadataLoaded(){console.log("[VideoCallNew] 视频元数据加载完成,可以开始播放"),this.isConnecting&&(this.connectingText="已接通",setTimeout((()=>{this.isConnecting=!1,e.index.showToast({title:"通话已接通",icon:"success",duration:1500})}),300))},onVideoLoaded(){console.log("[VideoCallNew] 视频数据加载成功"),console.log("[VideoCallNew] 当前视频URL:",this.selectedVideoUrl)},onVideoPreloaded(e){console.log("[VideoCallNew] 视频预加载完成:",e),this.videoPreloadStatus[e]=!0,this.$forceUpdate()},onVideoPlay(){console.log("[VideoCallNew] 视频开始播放")},onVideoPause(){console.log("[VideoCallNew] 视频已暂停")},onVideoTimeUpdate(e){},onVideoError(o){console.error("[VideoCallNew] 视频加载失败:",o),console.error("[VideoCallNew] 视频URL:",this.selectedVideoUrl),console.error("[VideoCallNew] 错误详情:",JSON.stringify(o)),e.index.showToast({title:"视频加载失败",icon:"none",duration:3e3})},async loadVideoCache(){try{const o=e.index.getStorageSync("videoCache");console.log("[VideoCallNew] 💾 读取缓存数据:",o),o?(this.videoCache=JSON.parse(o),console.log("[VideoCallNew] ✅ 加载视频缓存信息:",Object.keys(this.videoCache).length,"个视频"),console.log("[VideoCallNew] 缓存详情:",this.videoCache)):(console.log("[VideoCallNew] ⚠️ 未找到缓存数据"),this.videoCache={})}catch(o){console.error("[VideoCallNew] ❌ 加载视频缓存失败:",o),this.videoCache={}}},async saveVideoCache(){try{const o=JSON.stringify(this.videoCache);e.index.setStorageSync("videoCache",o),console.log("[VideoCallNew] 💾 保存视频缓存信息成功"),console.log("[VideoCallNew] 保存内容:",o);e.index.getStorageSync("videoCache")?console.log("[VideoCallNew] ✅ 验证保存成功"):console.error("[VideoCallNew] ❌ 验证保存失败,数据未持久化")}catch(o){console.error("[VideoCallNew] ❌ 保存视频缓存失败:",o)}},async checkAndLoadLocalVideo(e,o){if(e&&o){if(console.log("[VideoCallNew] 🔍 开始检查视频缓存"),console.log("[VideoCallNew] 视频ID:",e),console.log("[VideoCallNew] 当前缓存对象:",this.videoCache),console.log("[VideoCallNew] 缓存中是否有该ID:",e in this.videoCache),this.videoCache[e]){const o=this.videoCache[e];console.log("[VideoCallNew] 📝 发现缓存记录,验证文件:",o);const i=await this.checkFileExists(o);if(console.log("[VideoCallNew] 文件存在性检查结果:",i),i)return this.localVideoUrl=o,console.log("[VideoCallNew] ✅ 本地视频文件存在,使用缓存"),void console.log("[VideoCallNew] 已设置 localVideoUrl:",this.localVideoUrl);console.warn("[VideoCallNew] ⚠️ 缓存记录存在但文件丢失,清除缓存"),delete this.videoCache[e],await this.saveVideoCache()}else console.log("[VideoCallNew] ❌ 缓存中未找到视频ID:",e);console.log("[VideoCallNew] � 未找到缓存,先使用原始URL播放,同时后台下载"),this.localVideoUrl="",this.startBackgroundDownload(o,e)}else console.warn("[VideoCallNew] ⚠️ 视频ID或URL为空")},async preloadAllVideos(){if(this.preCachingInProgress)return void console.log("[VideoCallNew] 预缓存已在进行中,跳过");this.preCachingInProgress=!0,console.log("[VideoCallNew] 🚀 开始预缓存所有视频");const e=[...this.videos].sort(((e,o)=>{const i=e.created_at||e.createdAt||0;return(o.created_at||o.createdAt||0)-i}));let o=0,i=0;for(const t of e){const s=t.id,a=t.edited_video_url||t.videoUrl||t.local_video_path||t.video_url||t.localVideoPath;if(s&&a){if(this.videoCache[s]){const e=this.videoCache[s];if(await this.checkFileExists(e)){o++,this.cacheProgress[s]={progress:100,status:"completed"},console.log(`[VideoCallNew] ✅ 视频已缓存: ${t.name||s}`);continue}delete this.videoCache[s],await this.saveVideoCache()}i++,console.log(`[VideoCallNew] 📥 开始预缓存 [${i}/${e.length-o}]: ${t.name||s}`),this.cacheProgress[s]={progress:0,status:"downloading"},this.startBackgroundDownload(a,s,t.name).catch((e=>{console.error(`[VideoCallNew] 预缓存失败: ${t.name}`,e),this.cacheProgress[s]={progress:0,status:"failed"}})),await new Promise((e=>setTimeout(e,200)))}else console.warn("[VideoCallNew] 视频缺少ID或URL,跳过:",t.name)}console.log(`[VideoCallNew] 🎉 预缓存启动完成: 已缓存 ${o} 个,正在下载 ${i} 个`),this.preCachingInProgress=!1},async startBackgroundDownload(o,i,t=""){if(!o||!i)return;if(this.downloadingVideos[i])return void console.log("[VideoCallNew] 视频已在下载队列中");console.log(`[VideoCallNew] 📥 开始后台下载视频: ${t||i}`,o);const s=new Promise(((s,a)=>{e.index.downloadFile({url:o,success:o=>{200===o.statusCode?(console.log("[VideoCallNew] 视频下载成功,临时路径:",o.tempFilePath),e.index.saveFile({tempFilePath:o.tempFilePath,success:o=>{console.log(`[VideoCallNew] ✅ 视频保存成功 ${t||i}:`,o.savedFilePath),this.videoCache[i]=o.savedFilePath,this.selectedVideoId===i&&(this.localVideoUrl=o.savedFilePath,console.log("[VideoCallNew] 🎯 当前视频缓存完成,已更新播放源"),this.callStarted&&e.index.showToast({title:"已切换到本地播放",icon:"success",duration:1500})),this.saveVideoCache(),this.cacheProgress[i]&&(this.cacheProgress[i]={progress:100,status:"completed"}),console.log("[VideoCallNew] 💾 缓存已更新,下次启动将直接使用"),delete this.downloadingVideos[i],s(o.savedFilePath)},fail:e=>{console.error(`[VideoCallNew] 视频保存失败 ${t||i}:`,e),this.selectedVideoId===i&&(this.localVideoUrl=o.tempFilePath),this.cacheProgress[i]&&(this.cacheProgress[i]={progress:100,status:"failed"}),delete this.downloadingVideos[i],s(o.tempFilePath)}})):(console.error(`[VideoCallNew] 视频下载失败 ${t||i},状态码:`,o.statusCode),this.cacheProgress[i]&&(this.cacheProgress[i]={progress:0,status:"failed"}),delete this.downloadingVideos[i],a(new Error("下载失败")))},fail:e=>{console.error(`[VideoCallNew] 视频下载失败 ${t||i}:`,e),this.cacheProgress[i]&&(this.cacheProgress[i]={progress:0,status:"failed"}),delete this.downloadingVideos[i],a(e)}}).onProgressUpdate((e=>{const o=e.progress||0;this.cacheProgress[i]&&(this.cacheProgress[i].progress=o),o%20==0&&console.log(`[VideoCallNew] 下载进度 ${t||i}: ${o}%`)}))}));this.downloadingVideos[i]=s;try{await s}catch(a){console.error("[VideoCallNew] 下载视频异常:",a)}},checkFileExists:async o=>new Promise((i=>{try{if("function"!=typeof e.index.getFileSystemManager)return console.log("[VideoCallNew] 💡 当前平台不支持FileSystemManager,信任缓存记录"),void i(!0);e.index.getFileSystemManager().access({path:o,success:()=>{console.log("[VideoCallNew] ✅ 文件存在验证通过"),i(!0)},fail:()=>{console.warn("[VideoCallNew] ❌ 文件不存在"),i(!1)}})}catch(t){console.warn("[VideoCallNew] ⚠️ 检查文件存在性异常:",t),console.log("[VideoCallNew] 💡 异常情况下信任缓存记录"),i(!0)}})),cleanup(){if(console.log("[VideoCallNew] 开始清理资源"),this.durationTimer&&(clearInterval(this.durationTimer),this.durationTimer=null),this.processingTimeout&&(clearTimeout(this.processingTimeout),this.processingTimeout=null),this.stopFallbackTimer&&(clearTimeout(this.stopFallbackTimer),this.stopFallbackTimer=null),this.stopFallbackActive=!1,this.stopFallbackRetries=0,this.longPressTimer&&(clearTimeout(this.longPressTimer),this.longPressTimer=null),this.audioContext){try{this.audioContext.stop(),this.audioContext.destroy()}catch(e){console.warn("[VideoCallNew] 清理音频上下文失败:",e)}this.audioContext=null}if(this.recorderManager){try{this.isRecording&&this.recorderManager.stop()}catch(e){console.warn("[VideoCallNew] 清理录音管理器失败:",e)}this.recorderManager=null}this.vadMaxTimer&&(clearTimeout(this.vadMaxTimer),this.vadMaxTimer=null),this.vadWatchTimer&&(clearInterval(this.vadWatchTimer),this.vadWatchTimer=null),this.autoLoopTimer&&(clearInterval(this.autoLoopTimer),this.autoLoopTimer=null),console.log("[VideoCallNew] 资源清理完成")},formatTime(e){if(!e)return"";const o=new Date(e);return`${o.getFullYear()}-${String(o.getMonth()+1).padStart(2,"0")}-${String(o.getDate()).padStart(2,"0")} ${String(o.getHours()).padStart(2,"0")}:${String(o.getMinutes()).padStart(2,"0")}`},handlePaymentClose(){this.paymentModalData.show=!1,this._paymentReject&&this._paymentReject(new Error("用户取消支付"))},async handlePaymentConfirm(e){await i.handlePaymentConfirm(this,e)}}};if(!Array){e.resolveComponent("PaymentModal")()}const s=e._export_sfc(t,[["render",function(o,i,t,s,a,l){return e.e({a:!a.callStarted},a.callStarted?e.e({f:a.isConnecting},a.isConnecting?e.e({g:a.selectedPhotoUrl},a.selectedPhotoUrl?{h:a.selectedPhotoUrl}:{},{i:a.selectedPhotoUrl},a.selectedPhotoUrl?{j:a.selectedPhotoUrl}:{},{k:e.t(a.selectedVideoName),l:e.t(a.connectingText)}):{},{m:a.selectedVideoUrl},a.selectedVideoUrl?{n:a.localVideoUrl||a.selectedVideoUrl,o:e.o(((...e)=>l.onVideoError&&l.onVideoError(...e))),p:e.o(((...e)=>l.onVideoLoaded&&l.onVideoLoaded(...e))),q:e.o(((...e)=>l.onVideoMetadataLoaded&&l.onVideoMetadataLoaded(...e))),r:e.o(((...e)=>l.onVideoPlay&&l.onVideoPlay(...e))),s:e.o(((...e)=>l.onVideoPause&&l.onVideoPause(...e)))}:{},{t:a.isConnecting?1:"",v:e.t(a.selectedVideoName),w:e.t(a.callDuration),x:a.isRecording||a.isProcessing},(a.isRecording||a.isProcessing,{}),{y:a.selectedVoiceId&&a.selectedVoiceId.startsWith("cosyvoice-v3-plus-")},a.selectedVoiceId&&a.selectedVoiceId.startsWith("cosyvoice-v3-plus-")?{z:e.t(a.selectedDialect||"请选择方言(可选)"),A:a.dialectOptions,B:e.o(((...e)=>l.onDialectChange&&l.onDialectChange(...e)))}:{},{C:a.selectedVoiceId&&a.selectedVoiceId.startsWith("cosyvoice-v3-plus-")},a.selectedVoiceId&&a.selectedVoiceId.startsWith("cosyvoice-v3-plus-")?{D:e.t(a.selectedLanguageHintLabel||"请选择语言(可选)"),E:a.languageHintOptions,F:e.o(((...e)=>l.onLanguageHintChange&&l.onLanguageHintChange(...e)))}:{},{G:e.o(((...e)=>l.handleClearHistory&&l.handleClearHistory(...e))),H:a.isRecording},(a.isRecording,{}),{I:a.isRecording},(a.isRecording,{}),{J:!a.isRecording&&!a.isProcessing},(a.isRecording||a.isProcessing,{}),{K:a.isRecording},(a.isRecording,{}),{L:a.isProcessing},(a.isProcessing,{}),{M:a.isRecording?1:"",N:a.isProcessing?1:"",O:e.t(a.isRecording?"松开发送":a.isProcessing?"聆听中...":"长按说话"),P:a.isRecording?1:"",Q:e.o(((...e)=>l.handleTouchStart&&l.handleTouchStart(...e))),R:e.o(((...e)=>l.handleTouchEnd&&l.handleTouchEnd(...e))),S:e.o(((...e)=>l.handleTouchCancel&&l.handleTouchCancel(...e))),T:e.o(((...e)=>l.endCall&&l.endCall(...e)))}):e.e({b:a.loading},a.loading?{}:a.videos.length>0?{d:e.t(a.videos.length),e:e.f(a.videos,((o,i,t)=>e.e({a:o.photo_url},o.photo_url?{b:o.photo_url}:{},{c:o.edited_video_url||o.videoUrl||o.local_video_path||o.video_url||o.localVideoPath},o.edited_video_url||o.videoUrl||o.local_video_path||o.video_url||o.localVideoPath?{d:"preload-video-"+o.id,e:o.edited_video_url||o.videoUrl||o.local_video_path||o.video_url||o.localVideoPath,f:e.o((e=>l.onVideoPreloaded(o.id)),o.id)}:{},{g:e.t(o.name||"复活视频"),h:a.videoPreloadStatus[o.id]},a.videoPreloadStatus[o.id]?{}:a.cacheProgress[o.id]?e.e({j:"completed"===a.cacheProgress[o.id].status},"completed"===a.cacheProgress[o.id].status?{}:"downloading"===a.cacheProgress[o.id].status?{l:e.t(a.cacheProgress[o.id].progress)}:{},{k:"downloading"===a.cacheProgress[o.id].status}):{},{i:a.cacheProgress[o.id],m:e.t(o.text||"暂无描述"),n:o.id,o:e.o((e=>l.startVideoCall(o)),o.id)})))}:{},{c:a.videos.length>0}),{U:a.showSettingsDialog},a.showSettingsDialog?{V:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e))),W:a.dialogMemoryIdentity,X:e.o((e=>a.dialogMemoryIdentity=e.detail.value)),Y:a.dialogMemoryInfo,Z:e.o((e=>a.dialogMemoryInfo=e.detail.value)),aa:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e))),ab:e.o(((...e)=>l.confirmSettings&&l.confirmSettings(...e))),ac:e.o((()=>{})),ad:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e)))}:{},{ae:e.sr("paymentModal","125ef3e1-0"),af:e.o(l.handlePaymentClose),ag:e.o(l.handlePaymentConfirm),ah:e.p({show:a.paymentModalData.show,serviceType:a.paymentModalData.serviceType,serviceName:a.paymentModalData.serviceName,serviceDesc:a.paymentModalData.serviceDesc,price:a.paymentModalData.price,orderNo:a.paymentModalData.orderNo,paymentTips:a.paymentModalData.paymentTips}),ai:e.o(((...e)=>l.handleGlobalTouchEnd&&l.handleGlobalTouchEnd(...e))),aj:e.o(((...e)=>l.handleGlobalTouchCancel&&l.handleGlobalTouchCancel(...e)))})}],["__scopeId","data-v-125ef3e1"]]);wx.createPage(s);