diff --git a/frontend-ai/pages/index/index.vue b/frontend-ai/pages/index/index.vue
index 41783c9..95d48e7 100644
--- a/frontend-ai/pages/index/index.vue
+++ b/frontend-ai/pages/index/index.vue
@@ -23,6 +23,10 @@
+
+
+ AI生成
+
@@ -54,6 +58,7 @@
📹
开始视频通话
+ 本服务为AI生成内容,结果仅供参考
@@ -304,6 +309,20 @@ export default {
display: block;
}
+/* AI生成提示标签 */
+::v-deep .ai-tag {
+ position: absolute;
+ top: 16upx;
+ left: 16upx;
+ padding: 6upx 16upx;
+ background: rgba(255, 165, 0, 0.85);
+ color: white;
+ font-size: 22upx;
+ border-radius: 20upx;
+ font-weight: 500;
+ z-index: 10;
+}
+
/* 功能网格 */
.feature-grid {
display: grid;
@@ -387,11 +406,20 @@ export default {
padding: 0 20upx;
}
+.ai-disclaimer {
+ display: block;
+ text-align: center;
+ font-size: 22upx;
+ color: rgba(100, 100, 100, 0.7);
+ margin-top: 16upx;
+ letter-spacing: 0.5upx;
+}
+
.video-call-btn {
width: 100%;
padding: 36upx;
background: linear-gradient(135deg, #8B7355 0%, #6D8B8B 100%);
- color: white;
+ color: #ffffff !important;
border: none;
border-radius: 40upx;
font-size: 32upx;
diff --git a/frontend-ai/pages/phone-call/phone-call.vue b/frontend-ai/pages/phone-call/phone-call.vue
index 42b8789..369efd8 100644
--- a/frontend-ai/pages/phone-call/phone-call.vue
+++ b/frontend-ai/pages/phone-call/phone-call.vue
@@ -55,6 +55,7 @@
📞 开始视频通话
请先选择视频
+ 本服务为AI生成内容,结果仅供参考
@@ -64,9 +65,9 @@
-
-
+
+
+
+ AI生成
+
+
🎬
视频加载中...
@@ -1047,7 +1053,7 @@ export default {
width: 100%;
padding: 32upx;
background: linear-gradient(135deg, #8B7355 0%, #6D8B8B 100%);
- color: white;
+ color: #ffffff !important;
border: none;
border-radius: 28upx;
font-size: 30upx;
@@ -1068,7 +1074,16 @@ export default {
box-shadow: 0 2upx 8upx rgba(0, 0, 0, 0.08);
opacity: 0.65;
transform: none !important;
- color: #999;
+ color: #ffffff !important;
+}
+
+.ai-disclaimer {
+ display: block;
+ text-align: center;
+ font-size: 22upx;
+ color: rgba(100, 100, 100, 0.6);
+ margin-top: 16upx;
+ letter-spacing: 0.5upx;
}
/* 通话中阶段 */
@@ -1120,6 +1135,24 @@ export default {
background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
}
+/* AI生成提示标签 */
+.ai-tag {
+ position: absolute;
+ top: 20rpx;
+ right: 20rpx;
+ z-index: 100;
+ background: rgba(0, 0, 0, 0.6);
+ padding: 8rpx 20rpx;
+ border-radius: 30rpx;
+ backdrop-filter: blur(10rpx);
+}
+
+.ai-tag-text {
+ font-size: 22rpx;
+ color: #fff;
+ font-weight: 500;
+}
+
.placeholder-icon {
font-size: 100rpx;
margin-bottom: 20rpx;
diff --git a/frontend-ai/pages/plaza/plaza.vue b/frontend-ai/pages/plaza/plaza.vue
index 182b9ce..e90aef8 100644
--- a/frontend-ai/pages/plaza/plaza.vue
+++ b/frontend-ai/pages/plaza/plaza.vue
@@ -36,6 +36,10 @@
🎬
{{ work.workTypeLabel }}
+
+
+ AI生成
+
{{ work.title }}
@@ -495,6 +499,19 @@ export default {
font-size: 20upx;
border-radius: 20upx;
}
+
+ /* AI生成提示标签 */
+ .ai-tag {
+ position: absolute;
+ top: 12upx;
+ left: 12upx;
+ padding: 6upx 16upx;
+ background: rgba(255, 165, 0, 0.85);
+ color: white;
+ font-size: 20upx;
+ border-radius: 20upx;
+ font-weight: 500;
+ }
}
.work-info {
diff --git a/frontend-ai/pages/revival/revival-history.vue b/frontend-ai/pages/revival/revival-history.vue
index 72645cd..c7852c2 100644
--- a/frontend-ai/pages/revival/revival-history.vue
+++ b/frontend-ai/pages/revival/revival-history.vue
@@ -43,6 +43,10 @@
已缓存
+
+
+ AI生成
+
@@ -964,6 +968,25 @@ export default {
font-weight: 500;
}
+/* AI生成提示标签 */
+.ai-tag {
+ position: absolute;
+ top: 12upx;
+ left: 12upx;
+ padding: 6upx 16upx;
+ background: rgba(255, 165, 0, 0.85);
+ color: white;
+ font-size: 20upx;
+ border-radius: 20upx;
+ font-weight: 500;
+ z-index: 10;
+}
+
+.ai-tag-text {
+ font-size: 20upx;
+ font-weight: 500;
+}
+
.video-info {
padding: 20upx 16upx 16upx;
background: linear-gradient(180deg, #FFFFFF 0%, #FDFBF9 100%);
diff --git a/frontend-ai/pages/revival/revival-original.vue b/frontend-ai/pages/revival/revival-original.vue
index 0af0cf7..adaace6 100644
--- a/frontend-ai/pages/revival/revival-original.vue
+++ b/frontend-ai/pages/revival/revival-original.vue
@@ -162,6 +162,7 @@
{{ loadingText }}
🎬 开始生成视频
+ 本服务为AI生成内容,结果仅供参考
@@ -174,33 +175,40 @@
-
+
🎉 生成成功!
-
+
+
+
+
+
+ AI生成
+
+
-
+
+ 本服务为AI生成内容,结果仅供参考
✅ 合成成功!
@@ -2252,7 +2253,7 @@ export default {
max-width: 100%;
padding: 26upx;
background: linear-gradient(135deg, #6D8B8B 0%, #8B7355 100%);
- color: white;
+ color: #ffffff !important;
border: none;
border-radius: 24upx;
font-size: 30upx;
@@ -2276,6 +2277,16 @@ export default {
opacity: 0.5;
transform: none !important;
box-shadow: 0 4upx 12upx rgba(139, 115, 85, 0.15) !important;
+ color: #ffffff !important;
+}
+
+.ai-disclaimer {
+ display: block;
+ text-align: center;
+ font-size: 22upx;
+ color: rgba(100, 100, 100, 0.6);
+ margin-top: 16upx;
+ letter-spacing: 0.5upx;
}
.small-btn {
diff --git a/frontend-ai/pages/upload-audio/upload-audio.vue b/frontend-ai/pages/upload-audio/upload-audio.vue
index 5b98697..7da69ca 100644
--- a/frontend-ai/pages/upload-audio/upload-audio.vue
+++ b/frontend-ai/pages/upload-audio/upload-audio.vue
@@ -75,17 +75,18 @@
-
-
-
-
+
+
+
+ 本服务为AI生成内容,结果仅供参考
+
@@ -866,12 +867,21 @@ export default {
margin-bottom: 30upx;
}
+.ai-disclaimer {
+ display: block;
+ text-align: center;
+ font-size: 22upx;
+ color: rgba(100, 100, 100, 0.6);
+ margin-top: 16upx;
+ letter-spacing: 0.5upx;
+}
+
.submit-btn {
width: 100%;
height: 90upx;
background: linear-gradient(135deg, #8B7355 0%, #6D8B8B 100%);
border-radius: 45upx;
- color: white;
+ color: #ffffff !important;
font-size: 32upx;
font-weight: 600;
border: none;
@@ -880,6 +890,7 @@ export default {
&[disabled] {
opacity: 0.5;
box-shadow: none;
+ color: #ffffff !important;
}
}
diff --git a/frontend-ai/pages/video-call-new/video-call-new.vue b/frontend-ai/pages/video-call-new/video-call-new.vue
index b81d73a..4ece576 100644
--- a/frontend-ai/pages/video-call-new/video-call-new.vue
+++ b/frontend-ai/pages/video-call-new/video-call-new.vue
@@ -156,6 +156,11 @@
📹
视频加载中...
+
+
+
+ AI生成
+
@@ -3762,6 +3767,24 @@ export default {
}
}
+/* AI生成提示标签 */
+.ai-tag {
+ position: absolute;
+ top: 100rpx;
+ right: 24rpx;
+ z-index: 100;
+ background: rgba(0, 0, 0, 0.6);
+ padding: 8rpx 20rpx;
+ border-radius: 30rpx;
+ backdrop-filter: blur(10rpx);
+}
+
+.ai-tag-text {
+ font-size: 22rpx;
+ color: #fff;
+ font-weight: 500;
+}
+
/* 点跳动动画 */
@keyframes dotBounce {
0%, 80%, 100% {
diff --git a/frontend-ai/pages/video-call/video-call.vue b/frontend-ai/pages/video-call/video-call.vue
index ac5cfbf..2cd550c 100644
--- a/frontend-ai/pages/video-call/video-call.vue
+++ b/frontend-ai/pages/video-call/video-call.vue
@@ -34,6 +34,11 @@
@timeupdate="onVideoTimeUpdate"
>
+
+
+ AI生成
+
+
📹 视频加载中...
@@ -843,6 +848,24 @@ export default {
z-index: 1;
}
+/* AI生成提示标签 */
+.ai-tag {
+ position: absolute;
+ top: 100rpx;
+ right: 24rpx;
+ z-index: 100;
+ background: rgba(0, 0, 0, 0.6);
+ padding: 8rpx 20rpx;
+ border-radius: 30rpx;
+ backdrop-filter: blur(10rpx);
+}
+
+.ai-tag-text {
+ font-size: 22rpx;
+ color: #fff;
+ font-weight: 500;
+}
+
.video-player {
width: 100%;
height: 100%;
diff --git a/frontend-ai/pages/video-gen/video-gen.vue b/frontend-ai/pages/video-gen/video-gen.vue
index 38dcc12..063ab52 100644
--- a/frontend-ai/pages/video-gen/video-gen.vue
+++ b/frontend-ai/pages/video-gen/video-gen.vue
@@ -67,6 +67,7 @@
⏳ 生成中...
🎬 生成视频
+ 本服务为AI生成内容,结果仅供参考
@@ -80,12 +81,19 @@
✅ 生成成功
-
+
+
+
+
+
+ AI生成
+
+
@@ -481,7 +489,7 @@ export default {
width: 100%;
padding: 30rpx;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- color: white;
+ color: #ffffff !important;
border: none;
border-radius: 15rpx;
font-size: 32rpx;
@@ -490,6 +498,16 @@ export default {
.generate-btn[disabled] {
opacity: 0.6;
+ color: #ffffff !important;
+}
+
+.ai-disclaimer {
+ display: block;
+ text-align: center;
+ font-size: 22rpx;
+ color: rgba(100, 100, 100, 0.6);
+ margin-top: 16rpx;
+ letter-spacing: 0.5rpx;
}
.progress-section {
@@ -526,13 +544,43 @@ export default {
margin: 0 20rpx 20rpx;
}
-.result-video {
+.result-section {
+ position: relative;
+}
+
+.video-container {
+ position: relative;
width: 100%;
height: 500rpx;
border-radius: 15rpx;
+ overflow: hidden;
margin: 20rpx 0;
}
+.result-video {
+ width: 100%;
+ height: 100%;
+ border-radius: 15rpx;
+}
+
+/* AI生成提示标签 */
+.ai-tag {
+ position: absolute;
+ top: 16rpx;
+ right: 16rpx;
+ z-index: 100;
+ background: rgba(0, 0, 0, 0.6);
+ padding: 8rpx 20rpx;
+ border-radius: 30rpx;
+ backdrop-filter: blur(10rpx);
+}
+
+.ai-tag-text {
+ font-size: 22rpx;
+ color: #fff;
+ font-weight: 500;
+}
+
.result-actions {
display: flex;
gap: 20rpx;
diff --git a/frontend-ai/pages/video-player/video-player.vue b/frontend-ai/pages/video-player/video-player.vue
index 8998204..9678989 100644
--- a/frontend-ai/pages/video-player/video-player.vue
+++ b/frontend-ai/pages/video-player/video-player.vue
@@ -62,6 +62,11 @@
+
+
+
+ AI生成
+
@@ -1700,4 +1705,22 @@ export default {
transform: scale(0.95);
background: rgba(255, 255, 255, 0.15);
}
+
+/* AI生成提示标签 */
+.ai-tag {
+ position: absolute;
+ top: 140rpx;
+ right: 24rpx;
+ z-index: 100;
+ background: rgba(0, 0, 0, 0.6);
+ padding: 8rpx 20rpx;
+ border-radius: 30rpx;
+ backdrop-filter: blur(10rpx);
+}
+
+.ai-tag-text {
+ font-size: 22rpx;
+ color: #fff;
+ font-weight: 500;
+}
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.js
index ee807e5..fdc4354 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.js
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.js
@@ -1 +1 @@
-"use strict";const e=require("../../common/vendor.js"),a=require("../../config/api.js"),o={components:{VideoSelectModal:()=>"../../components/VideoSelectModal.js"},data:()=>({apiBase:a.API_BASE,title:"时光意境 · AI亲人重逢",showVideoSelect:!1,banners:[]}),onLoad(){this.loadHomeBanners()},methods:{resolveUrl(e){return e?e.startsWith("http://")||e.startsWith("https://")?e:`${this.apiBase}${e}`:""},async loadHomeBanners(){try{const e=await a.request({url:"/api/system/home-banners",method:"GET"}),o=e&&e.success?e.data:[];Array.isArray(o)?this.banners=o.filter((e=>e&&e.url&&!1!==e.enabled)).sort(((e,a)=>(Number(e.sort)||0)-(Number(a.sort)||0))):this.banners=[]}catch(e){this.banners=[]}},handleBannerClick(a){if(a&&a.link){if(String(a.link).startsWith("/pages/"))return void e.index.navigateTo({url:a.link});e.index.setClipboardData({data:String(a.link)}),e.index.showToast({title:"已复制链接",icon:"none"})}},checkLogin(){const a=e.index.getStorageSync("token"),o=e.index.getStorageSync("userId");return!(!a||!o)},goVoiceClone(){e.index.switchTab({url:"/pages/revival/revival",fail:()=>{e.index.navigateTo({url:"/pages/revival/revival"})}})},goPhotoRevival(){e.index.navigateTo({url:"/pages/revival/revival-original"})},goPlaza(){e.index.navigateTo({url:"/pages/plaza/plaza"})},startVideoCall(){this.checkLogin()?this.showVideoSelect=!0:e.index.showModal({title:"提示",content:"请先登录后再使用此功能",confirmText:"去登录",cancelText:"取消",success:a=>{a.confirm&&e.index.navigateTo({url:"/pages/login/login"})}})},goAICall(){e.index.switchTab({url:"/pages/phone-call/phone-call",fail:()=>{e.index.navigateTo({url:"/pages/phone-call/phone-call"})}})},handleVideoSelect(a){console.log("[Index] 选择视频:",a),e.index.navigateTo({url:`/pages/video-call-new/video-call-new?videoId=${a.id}&videoName=${encodeURIComponent(a.name||"复活视频")}&videoUrl=${encodeURIComponent(a.videoUrl||a.local_video_path||a.video_url)}&voiceId=${a.voice_id||a.voiceId}`})},goShortDrama(){e.index.navigateTo({url:"/pages/short-drama/short-drama"})}}};if(!Array){e.resolveComponent("VideoSelectModal")()}const i=e._export_sfc(o,[["render",function(a,o,i,n,t,l){return{a:`${t.apiBase}/static/bg.png`,b:e.f(t.banners,((a,o,i)=>({a:l.resolveUrl(a.url),b:e.o((e=>l.handleBannerClick(a)),o),c:o}))),c:e.o(((...e)=>l.goPlaza&&l.goPlaza(...e))),d:e.o(((...e)=>l.goPhotoRevival&&l.goPhotoRevival(...e))),e:e.o(((...e)=>l.goShortDrama&&l.goShortDrama(...e))),f:e.o(((...e)=>l.goAICall&&l.goAICall(...e))),g:e.o(((...e)=>l.startVideoCall&&l.startVideoCall(...e))),h:e.o((e=>t.showVideoSelect=!1)),i:e.o(l.handleVideoSelect),j:e.p({show:t.showVideoSelect})}}],["__scopeId","data-v-e85e9fe9"]]);wx.createPage(i);
+"use strict";const e=require("../../common/vendor.js"),a=require("../../config/api.js"),o={components:{VideoSelectModal:()=>"../../components/VideoSelectModal.js"},data:()=>({apiBase:a.API_BASE,title:"时光意境 · AI亲人重逢",showVideoSelect:!1,banners:[]}),onLoad(){this.loadHomeBanners()},methods:{resolveUrl(e){return e?e.startsWith("http://")||e.startsWith("https://")?e:`${this.apiBase}${e}`:""},async loadHomeBanners(){try{const e=await a.request({url:"/api/system/home-banners",method:"GET"}),o=e&&e.success?e.data:[];Array.isArray(o)?this.banners=o.filter((e=>e&&e.url&&!1!==e.enabled)).sort(((e,a)=>(Number(e.sort)||0)-(Number(a.sort)||0))):this.banners=[]}catch(e){this.banners=[]}},handleBannerClick(a){if(a&&a.link){if(String(a.link).startsWith("/pages/"))return void e.index.navigateTo({url:a.link});e.index.setClipboardData({data:String(a.link)}),e.index.showToast({title:"已复制链接",icon:"none"})}},checkLogin(){const a=e.index.getStorageSync("token"),o=e.index.getStorageSync("userId");return!(!a||!o)},goVoiceClone(){e.index.switchTab({url:"/pages/revival/revival",fail:()=>{e.index.navigateTo({url:"/pages/revival/revival"})}})},goPhotoRevival(){e.index.navigateTo({url:"/pages/revival/revival-original"})},goPlaza(){e.index.navigateTo({url:"/pages/plaza/plaza"})},startVideoCall(){this.checkLogin()?this.showVideoSelect=!0:e.index.showModal({title:"提示",content:"请先登录后再使用此功能",confirmText:"去登录",cancelText:"取消",success:a=>{a.confirm&&e.index.navigateTo({url:"/pages/login/login"})}})},goAICall(){e.index.switchTab({url:"/pages/phone-call/phone-call",fail:()=>{e.index.navigateTo({url:"/pages/phone-call/phone-call"})}})},handleVideoSelect(a){console.log("[Index] 选择视频:",a),e.index.navigateTo({url:`/pages/video-call-new/video-call-new?videoId=${a.id}&videoName=${encodeURIComponent(a.name||"复活视频")}&videoUrl=${encodeURIComponent(a.videoUrl||a.local_video_path||a.video_url)}&voiceId=${a.voice_id||a.voiceId}`})},goShortDrama(){e.index.navigateTo({url:"/pages/short-drama/short-drama"})}}};if(!Array){e.resolveComponent("VideoSelectModal")()}const i=e._export_sfc(o,[["render",function(a,o,i,n,t,l){return{a:`${t.apiBase}/static/bg.png`,b:e.f(t.banners,((a,o,i)=>({a:l.resolveUrl(a.url),b:e.o((e=>l.handleBannerClick(a)),o),c:o}))),c:e.o(((...e)=>l.goPlaza&&l.goPlaza(...e))),d:e.o(((...e)=>l.goPhotoRevival&&l.goPhotoRevival(...e))),e:e.o(((...e)=>l.goShortDrama&&l.goShortDrama(...e))),f:e.o(((...e)=>l.goAICall&&l.goAICall(...e))),g:e.o(((...e)=>l.startVideoCall&&l.startVideoCall(...e))),h:e.o((e=>t.showVideoSelect=!1)),i:e.o(l.handleVideoSelect),j:e.p({show:t.showVideoSelect})}}],["__scopeId","data-v-d7e89d74"]]);wx.createPage(i);
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxml
index a203606..15f3679 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxml
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxml
@@ -1 +1 @@
-🖼️作品广场📸照片复活🎬看短剧📹视频通话只需简单三步,即可与记忆中的亲人温暖"重逢"
\ No newline at end of file
+AI生成🖼️作品广场📸照片复活🎬看短剧📹视频通话本服务为AI生成内容,结果仅供参考只需简单三步,即可与记忆中的亲人温暖"重逢"
\ No newline at end of file
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxss
index 9d25b68..ce0f4dc 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxss
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/index/index.wxss
@@ -1 +1 @@
-.memorial-bg.data-v-e85e9fe9{position:relative;min-height:100vh;overflow:hidden}.bg-image.data-v-e85e9fe9{position:fixed;top:0;left:0;width:100%;height:100%;z-index:0}.memorial-content.data-v-e85e9fe9{position:relative;z-index:2;padding:60rpx 30rpx 100rpx;max-width:1200rpx;margin:0 auto}.header.data-v-e85e9fe9{background:transparent;color:#2c2c2c;padding:40rpx 0 50rpx;text-align:center;position:relative;margin-bottom:20rpx}.header.data-v-e85e9fe9:after{content:"";position:absolute;bottom:0;left:50%;transform:translate(-50%);width:200rpx;height:3rpx;background:linear-gradient(90deg,transparent,#8B7355,transparent)}.header .logo.data-v-e85e9fe9{font-size:64rpx;font-weight:700;margin-bottom:24rpx;color:#8b7355;letter-spacing:2rpx;display:block;line-height:1.2}.header .tagline.data-v-e85e9fe9{font-size:32rpx;color:#666;font-weight:300;margin:0 auto;display:block;line-height:1.5}.memorial-quote.data-v-e85e9fe9{text-align:center;margin:30rpx 0 70rpx;padding:22rpx;background:rgba(255,255,255,.6);border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);box-shadow:0 8rpx 30rpx rgba(0,0,0,.06)}.data-v-e85e9fe9 .banner-swiper{width:100%;height:900rpx;border-radius:22rpx;overflow:hidden}.data-v-e85e9fe9 .banner-item{width:100%;height:100%}.data-v-e85e9fe9 .banner-image{width:100%;height:100%;display:block}.feature-grid.data-v-e85e9fe9{display:grid;grid-template-columns:repeat(4,1fr);gap:12rpx;margin:30rpx 0;align-items:stretch}.data-v-e85e9fe9 .feature-item{background:rgba(255,255,255,.9);border-radius:18rpx;padding:10rpx 8rpx;text-align:center;transition:all .3s cubic-bezier(.175,.885,.32,1.275);box-shadow:0 8rpx 24rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(20rpx);backdrop-filter:blur(20rpx);border:2rpx solid rgba(255,255,255,.8);position:relative;overflow:hidden;display:flex;flex-direction:column;align-items:center;justify-content:center;aspect-ratio:1;min-height:0}.data-v-e85e9fe9 .feature-item:before{content:"";position:absolute;top:0;left:0;right:0;height:4rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);transform:scaleX(0);transition:transform .3s}.data-v-e85e9fe9 .feature-item:active{transform:translateY(-8rpx) scale(.98);box-shadow:0 16rpx 40rpx rgba(0,0,0,.12)}.data-v-e85e9fe9 .feature-item:active:before{transform:scaleX(1)}.data-v-e85e9fe9 .feature-item .feature-icon{font-size:32rpx;margin-bottom:8rpx;color:#8b7355;height:56rpx;width:56rpx;line-height:56rpx;border-radius:50%;background:rgba(139,115,85,.1);display:inline-block;transition:all .3s;flex-shrink:0}.data-v-e85e9fe9 .feature-item:active .feature-icon{background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;transform:scale(1.1)}.data-v-e85e9fe9 .feature-item .feature-name{font-size:18rpx;font-weight:600;color:#2c2c2c;display:block;line-height:1.3}.video-call-section.data-v-e85e9fe9{margin:50rpx 0 40rpx;padding:0 20rpx}.video-call-btn.data-v-e85e9fe9{width:100%;padding:36rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:40rpx;font-size:32rpx;font-weight:700;box-shadow:0 16rpx 40rpx rgba(139,115,85,.3);transition:all .3s;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;gap:16rpx}.video-call-btn.data-v-e85e9fe9:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(135deg,rgba(255,255,255,.2) 0%,transparent 100%)}.video-call-btn.data-v-e85e9fe9:active{transform:translateY(-4rpx);box-shadow:0 20rpx 50rpx rgba(139,115,85,.4)}.video-call-btn .btn-icon.data-v-e85e9fe9{font-size:40rpx}.video-call-btn .btn-text.data-v-e85e9fe9{font-size:32rpx;font-weight:700}.cta-section.data-v-e85e9fe9{text-align:center;margin:70rpx 0 40rpx;padding:40rpx 30rpx;background:rgba(255,255,255,.5);border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.cta-section .cta-text.data-v-e85e9fe9{font-size:30rpx;color:#666;margin:0 auto;line-height:1.8;display:block;font-style:italic;opacity:.9}@media (max-width: 750px){.memorial-content.data-v-e85e9fe9{padding:50rpx 24rpx 80rpx}.header.data-v-e85e9fe9{padding:30rpx 0 40rpx}.header .logo.data-v-e85e9fe9{font-size:56rpx;margin-bottom:20rpx}.header .tagline.data-v-e85e9fe9{font-size:28rpx}.memorial-quote.data-v-e85e9fe9{margin:50rpx 0 60rpx;padding:18rpx}.banner-swiper.data-v-e85e9fe9{height:360rpx}.feature-grid.data-v-e85e9fe9{grid-template-columns:repeat(2,1fr);gap:12rpx;margin:50rpx 0}.feature-item.data-v-e85e9fe9{padding:12rpx 10rpx;aspect-ratio:1.25;border-radius:16rpx}.feature-item .feature-icon.data-v-e85e9fe9{font-size:40rpx;height:64rpx;width:64rpx;line-height:64rpx;margin-bottom:8rpx}.feature-item .feature-name.data-v-e85e9fe9{font-size:22rpx}.video-call-section.data-v-e85e9fe9{margin:40rpx 0 30rpx;padding:0 16rpx}.video-call-btn.data-v-e85e9fe9{padding:32rpx}.video-call-btn .btn-icon.data-v-e85e9fe9{font-size:36rpx}.video-call-btn .btn-text.data-v-e85e9fe9{font-size:28rpx}.cta-section.data-v-e85e9fe9{margin:60rpx 0 30rpx;padding:32rpx 24rpx}.cta-section .cta-text.data-v-e85e9fe9{font-size:28rpx}}
+.memorial-bg.data-v-d7e89d74{position:relative;min-height:100vh;overflow:hidden}.bg-image.data-v-d7e89d74{position:fixed;top:0;left:0;width:100%;height:100%;z-index:0}.memorial-content.data-v-d7e89d74{position:relative;z-index:2;padding:60rpx 30rpx 100rpx;max-width:1200rpx;margin:0 auto}.header.data-v-d7e89d74{background:transparent;color:#2c2c2c;padding:40rpx 0 50rpx;text-align:center;position:relative;margin-bottom:20rpx}.header.data-v-d7e89d74:after{content:"";position:absolute;bottom:0;left:50%;transform:translate(-50%);width:200rpx;height:3rpx;background:linear-gradient(90deg,transparent,#8B7355,transparent)}.header .logo.data-v-d7e89d74{font-size:64rpx;font-weight:700;margin-bottom:24rpx;color:#8b7355;letter-spacing:2rpx;display:block;line-height:1.2}.header .tagline.data-v-d7e89d74{font-size:32rpx;color:#666;font-weight:300;margin:0 auto;display:block;line-height:1.5}.memorial-quote.data-v-d7e89d74{text-align:center;margin:30rpx 0 70rpx;padding:22rpx;background:rgba(255,255,255,.6);border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);box-shadow:0 8rpx 30rpx rgba(0,0,0,.06)}.data-v-d7e89d74 .banner-swiper{width:100%;height:900rpx;border-radius:22rpx;overflow:hidden}.data-v-d7e89d74 .banner-item{width:100%;height:100%}.data-v-d7e89d74 .banner-image{width:100%;height:100%;display:block}.data-v-d7e89d74 .ai-tag{position:absolute;top:16rpx;left:16rpx;padding:6rpx 16rpx;background:rgba(255,165,0,.85);color:#fff;font-size:22rpx;border-radius:20rpx;font-weight:500;z-index:10}.feature-grid.data-v-d7e89d74{display:grid;grid-template-columns:repeat(4,1fr);gap:12rpx;margin:30rpx 0;align-items:stretch}.data-v-d7e89d74 .feature-item{background:rgba(255,255,255,.9);border-radius:18rpx;padding:10rpx 8rpx;text-align:center;transition:all .3s cubic-bezier(.175,.885,.32,1.275);box-shadow:0 8rpx 24rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(20rpx);backdrop-filter:blur(20rpx);border:2rpx solid rgba(255,255,255,.8);position:relative;overflow:hidden;display:flex;flex-direction:column;align-items:center;justify-content:center;aspect-ratio:1;min-height:0}.data-v-d7e89d74 .feature-item:before{content:"";position:absolute;top:0;left:0;right:0;height:4rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);transform:scaleX(0);transition:transform .3s}.data-v-d7e89d74 .feature-item:active{transform:translateY(-8rpx) scale(.98);box-shadow:0 16rpx 40rpx rgba(0,0,0,.12)}.data-v-d7e89d74 .feature-item:active:before{transform:scaleX(1)}.data-v-d7e89d74 .feature-item .feature-icon{font-size:32rpx;margin-bottom:8rpx;color:#8b7355;height:56rpx;width:56rpx;line-height:56rpx;border-radius:50%;background:rgba(139,115,85,.1);display:inline-block;transition:all .3s;flex-shrink:0}.data-v-d7e89d74 .feature-item:active .feature-icon{background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;transform:scale(1.1)}.data-v-d7e89d74 .feature-item .feature-name{font-size:18rpx;font-weight:600;color:#2c2c2c;display:block;line-height:1.3}.video-call-section.data-v-d7e89d74{margin:50rpx 0 40rpx;padding:0 20rpx}.ai-disclaimer.data-v-d7e89d74{display:block;text-align:center;font-size:22rpx;color:rgba(100,100,100,.7);margin-top:16rpx;letter-spacing:.5rpx}.video-call-btn.data-v-d7e89d74{width:100%;padding:36rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff!important;border:none;border-radius:40rpx;font-size:32rpx;font-weight:700;box-shadow:0 16rpx 40rpx rgba(139,115,85,.3);transition:all .3s;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;gap:16rpx}.video-call-btn.data-v-d7e89d74:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(135deg,rgba(255,255,255,.2) 0%,transparent 100%)}.video-call-btn.data-v-d7e89d74:active{transform:translateY(-4rpx);box-shadow:0 20rpx 50rpx rgba(139,115,85,.4)}.video-call-btn .btn-icon.data-v-d7e89d74{font-size:40rpx}.video-call-btn .btn-text.data-v-d7e89d74{font-size:32rpx;font-weight:700}.cta-section.data-v-d7e89d74{text-align:center;margin:70rpx 0 40rpx;padding:40rpx 30rpx;background:rgba(255,255,255,.5);border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.cta-section .cta-text.data-v-d7e89d74{font-size:30rpx;color:#666;margin:0 auto;line-height:1.8;display:block;font-style:italic;opacity:.9}@media (max-width: 750px){.memorial-content.data-v-d7e89d74{padding:50rpx 24rpx 80rpx}.header.data-v-d7e89d74{padding:30rpx 0 40rpx}.header .logo.data-v-d7e89d74{font-size:56rpx;margin-bottom:20rpx}.header .tagline.data-v-d7e89d74{font-size:28rpx}.memorial-quote.data-v-d7e89d74{margin:50rpx 0 60rpx;padding:18rpx}.banner-swiper.data-v-d7e89d74{height:360rpx}.feature-grid.data-v-d7e89d74{grid-template-columns:repeat(2,1fr);gap:12rpx;margin:50rpx 0}.feature-item.data-v-d7e89d74{padding:12rpx 10rpx;aspect-ratio:1.25;border-radius:16rpx}.feature-item .feature-icon.data-v-d7e89d74{font-size:40rpx;height:64rpx;width:64rpx;line-height:64rpx;margin-bottom:8rpx}.feature-item .feature-name.data-v-d7e89d74{font-size:22rpx}.video-call-section.data-v-d7e89d74{margin:40rpx 0 30rpx;padding:0 16rpx}.video-call-btn.data-v-d7e89d74{padding:32rpx}.video-call-btn .btn-icon.data-v-d7e89d74{font-size:36rpx}.video-call-btn .btn-text.data-v-d7e89d74{font-size:28rpx}.cta-section.data-v-d7e89d74{margin:60rpx 0 30rpx;padding:32rpx 24rpx}.cta-section .cta-text.data-v-d7e89d74{font-size:28rpx}}
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.js
index 3a7740a..37b6f1e 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.js
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.js
@@ -1 +1 @@
-"use strict";const e=require("../../common/vendor.js"),t=require("../../config/api.js"),o=require("../../common/assets.js"),i={data:()=>({API_BASE:t.API_BASE,lastUserId:null,loading:!1,videos:[],selectedVideoId:"",selectedVideoName:"",selectedVideoUrl:"",selectedVoiceId:"",selectedDialect:"",selectedLanguageHint:"",selectedLanguageHintLabel:"",languageHintOptions:["中文(zh)","英文(en)","法语(fr)","德语(de)","日语(ja)","韩语(ko)","俄语(ru)"],dialectOptions:["广东话","东北话","甘肃话","贵州话","河南话","湖北话","江西话","闽南话","宁夏话","山西话","陕西话","山东话","上海话","四川话","天津话","云南话"],callStarted:!1,callStatus:"视频通话中",callDuration:"00:00",callStartTime:null,durationTimer:null,messages:[],scrollTop:0,isRecording:!1,isProcessing:!1,isSpeaking:!1,processingText:"处理中...",recorderManager:null,audioFilePath:"",audioContext:null,showSettingsDialog:!1,dialogMemoryIdentity:"",dialogMemoryInfo:"",dialogMemoryCatchphrase:""}),onLoad(){console.log("[PhoneCall] 页面加载");const t=e.index.getStorageSync("userId");this.lastUserId=t,this.loadVideos(),this.initRecorder(),this.initAudioContext()},onShow(){console.log("[PhoneCall] 页面显示");const t=e.index.getStorageSync("userId");this.lastUserId=t,this.callStarted||this.$nextTick((()=>{setTimeout((()=>{this.loadVideos()}),100)}))},onUnload(){this.cleanup()},methods:{async loadVideos(){this.loading=!0;const t=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.request({url:`${this.API_BASE}/api/photo-revival/videos`,method:"GET",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},success:e=>{if(console.log("[PhoneCall] 视频列表响应状态码:",e.statusCode),console.log("[PhoneCall] 视频列表响应数据:",e.data),console.log("[PhoneCall] 数据类型:",typeof e.data),200===e.statusCode){let t=[];Array.isArray(e.data)?t=e.data:e.data&&Array.isArray(e.data.data)?t=e.data.data:e.data&&e.data.videos&&Array.isArray(e.data.videos)&&(t=e.data.videos),t=t.filter((e=>{const t=e.name&&(e.name.startsWith("生成失败")||e.name.startsWith("生成失败:")),o=e.edited_video_url||e.video_url||e.local_video_path||e.videoUrl||e.localVideoPath,i=o&&""!==o.trim();return!t&&i})),this.videos=t,console.log("[PhoneCall] 加载视频列表成功:",this.videos.length),console.log("[PhoneCall] 视频列表:",this.videos)}else console.error("[PhoneCall] 响应状态码异常:",e.statusCode)},fail:t=>{console.error("[PhoneCall] 加载视频列表失败:",t),e.index.showToast({title:"加载失败",icon:"none"})},complete:()=>{this.loading=!1}})},selectVideo(e){console.log("[PhoneCall] 选择视频:",e),this.selectedVideoId=e.id,this.selectedVideoName=e.name||"复活视频",this.selectedVideoUrl=e.edited_video_url||e.local_video_path||e.video_url,this.selectedVoiceId=e.voice_id,this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",console.log("[PhoneCall] 选择视频:",this.selectedVideoId,"名称:",this.selectedVideoName),console.log("[PhoneCall] 视频URL:",this.selectedVideoUrl)},onDialectChange(e){this.selectedDialect=this.dialectOptions[e.detail.value]||""},onLanguageHintChange(e){const t=this.languageHintOptions[e.detail.value]||"";this.selectedLanguageHintLabel=t;const o=t.match(/\(([^)]+)\)/);this.selectedLanguageHint=o&&o[1]?o[1]:""},startCall(){if(!this.selectedVideoId)return void e.index.showToast({title:"请先选择视频",icon:"none"});console.log("[PhoneCall] 准备视频通话,视频ID:",this.selectedVideoId);const t=this.videos.find((e=>e.id===this.selectedVideoId));if(!t)return void e.index.showToast({title:"视频信息丢失",icon:"none"});const o=t.edited_video_url||t.videoUrl||t.local_video_path||t.video_url||t.localVideoPath||"",i=t.name||"复活视频",s=this.selectedVoiceId||"";console.log("[PhoneCall] 跳转参数:",{videoId:this.selectedVideoId,videoName:i,videoUrl:o,voiceId:s}),e.index.navigateTo({url:`/pages/video-call-new/video-call-new?videoId=${this.selectedVideoId}&videoName=${encodeURIComponent(i)}&videoUrl=${encodeURIComponent(o)}&voiceId=${s}`,success:()=>{console.log("[PhoneCall] 跳转到视频通话页面成功")},fail:t=>{console.error("[PhoneCall] 跳转失败:",t),e.index.showToast({title:"跳转失败",icon:"none"})}})},closeSettingsDialog(){this.showSettingsDialog=!1},confirmSettings(){this.showSettingsDialog=!1},startCallTimer(){this.callStartTime=Date.now(),this.durationTimer=setInterval((()=>{const e=Math.floor((Date.now()-this.callStartTime)/1e3),t=Math.floor(e/60).toString().padStart(2,"0"),o=(e%60).toString().padStart(2,"0");this.callDuration=`${t}:${o}`}),1e3)},initRecorder(){this.recorderManager=e.index.getRecorderManager(),this.recorderManager.onStart((()=>{console.log("[PhoneCall] 开始录音")})),this.recorderManager.onStop((e=>{console.log("[PhoneCall] 录音完成:",e.tempFilePath),this.audioFilePath=e.tempFilePath,this.processConversation()})),this.recorderManager.onError((t=>{console.error("[PhoneCall] 录音失败:",t),this.isRecording=!1,e.index.showToast({title:"录音失败",icon:"none"})}))},initAudioContext(){this.audioContext=e.index.createInnerAudioContext(),this.audioContext.onPlay((()=>{console.log("[PhoneCall] 开始播放AI回复"),this.isSpeaking=!0,this.callStatus="对方正在说话...",e.index.vibrateShort({type:"light"})})),this.audioContext.onEnded((()=>{console.log("[PhoneCall] AI回复播放完成"),this.isSpeaking=!1,this.callStatus="通话中"})),this.audioContext.onError((e=>{console.error("[PhoneCall] 音频播放失败:",e),this.isSpeaking=!1,this.callStatus="通话中"}))},startRecording(){this.isProcessing||(this.isRecording=!0,this.recorderManager.start({format:"mp3",sampleRate:16e3}),this.callStatus="正在录音...",e.index.vibrateShort({type:"medium"}))},stopRecording(){this.isRecording&&(this.isRecording=!1,this.recorderManager.stop(),this.isProcessing=!0,this.processingText="识别中...",this.callStatus="处理中...")},async processConversation(){try{this.processingText="正在识别...";const t=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.uploadFile({url:`${this.API_BASE}/api/conversation/talk`,filePath:this.audioFilePath,name:"audio",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},formData:(()=>{const e=this.selectedVoiceId,t=(()=>{const t=(e||"").trim();if(!t)return"CLONE";return["Cherry","Kai","Mochi","Bunny","Jada","Dylan","Li","Marcus","Roy","Peter","Sunny","Eric","Rocky","Kiki"].includes(t)||t.startsWith("BV")||t.endsWith("_streaming")||t.endsWith("_offline")||t.endsWith("_bigtts")?"OFFICIAL":"CLONE"})(),o={voiceId:e,voiceType:t};return this.selectedDialect&&(o.dialect=this.selectedDialect),this.selectedLanguageHint&&(o.languageHints=this.selectedLanguageHint),o})(),success:e=>{if(console.log("[PhoneCall] 对话响应:",e),200!==e.statusCode)throw new Error("对话请求失败");{const t=JSON.parse(e.data);if(!t.success)throw new Error(t.message||"对话失败");this.addMessage("user",t.recognizedText),this.addMessage("ai",t.aiResponse),this.playAIResponse(t.audioFile)}},fail:t=>{console.error("[PhoneCall] 对话失败:",t),e.index.showToast({title:"对话失败",icon:"none"}),this.isProcessing=!1,this.callStatus="通话中"}})}catch(t){console.error("[PhoneCall] 对话失败:",t),e.index.showToast({title:"对话失败: "+t.message,icon:"none"}),this.isProcessing=!1,this.callStatus="通话中"}},playAIResponse(e){this.processingText="正在回复...",this.audioContext.src=`${this.API_BASE}/api/conversation/audio/${e}`,this.audioContext.play(),this.isProcessing=!1},addMessage(e,t){const o=new Date,i=`${o.getHours()}:${o.getMinutes().toString().padStart(2,"0")}`;this.messages.push({role:e,content:t,time:i}),this.$nextTick((()=>{this.scrollTop=999999}))},handleClearHistory(){e.index.showModal({title:"确认清空",content:"确定要清空对话历史吗?",success:t=>{if(t.confirm){const t=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.request({url:`${this.API_BASE}/api/conversation/clear-history`,method:"POST",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},success:t=>{t.data.success&&(this.messages=[],e.index.showToast({title:"已清空",icon:"success"}))}})}}})},endCall(){e.index.showModal({title:"结束通话",content:`通话时长:${this.callDuration}\n确定要结束通话吗?`,confirmColor:"#eb3349",success:t=>{t.confirm&&(e.index.vibrateShort({type:"heavy"}),e.index.showLoading({title:"正在挂断...",mask:!0}),setTimeout((()=>{e.index.hideLoading(),this.cleanup(),e.index.showToast({title:"通话已结束",icon:"success",duration:1500,success:()=>{setTimeout((()=>{e.index.navigateBack()}),1500)}})}),800))}})},goToRevival(){console.log("[PhoneCall] 跳转到复活照片页面"),e.index.navigateTo({url:"/pages/revival/revival-original",success:()=>{console.log("[PhoneCall] 跳转成功")},fail:e=>{console.error("[PhoneCall] 跳转失败:",e)}})},cleanup(){this.durationTimer&&clearInterval(this.durationTimer),this.audioContext&&this.audioContext.destroy(),this.recorderManager&&this.recorderManager.stop()},formatTime(e){if(!e)return"";let t=e;String(e).length<=10&&(t=1e3*e);const o=new Date(t);if(isNaN(o.getTime()))return"时间格式错误";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")}`}}};const s=e._export_sfc(i,[["render",function(t,i,s,a,n,l){return e.e({a:e.o(((...e)=>l.goToRevival&&l.goToRevival(...e))),b:!n.callStarted},n.callStarted?e.e({j:n.selectedVideoUrl},n.selectedVideoUrl?{k:n.selectedVideoUrl}:{},{l:e.t(n.selectedVideoName),m:e.t(n.callStatus),n:n.isSpeaking||n.isRecording?1:"",o:e.t(n.callDuration),p:e.f(n.messages,((t,o,i)=>({a:e.t("user"===t.role?"👤":"🤖"),b:e.t(t.content),c:e.t(t.time),d:o,e:e.n(t.role)}))),q:0===n.messages.length},(n.messages.length,{}),{r:n.scrollTop,s:n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")},n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")?{t:e.t(n.selectedDialect||"请选择方言(可选)"),v:n.dialectOptions,w:e.o(((...e)=>l.onDialectChange&&l.onDialectChange(...e)))}:{},{x:n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")},n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")?{y:e.t(n.selectedLanguageHintLabel||"请选择语言(可选)"),z:n.languageHintOptions,A:e.o(((...e)=>l.onLanguageHintChange&&l.onLanguageHintChange(...e)))}:{},{B:!n.isRecording&&!n.isProcessing},n.isRecording||n.isProcessing?{}:{C:e.o(((...e)=>l.startRecording&&l.startRecording(...e))),D:e.o(((...e)=>l.stopRecording&&l.stopRecording(...e)))},{E:n.isRecording},n.isRecording?{F:e.o(((...e)=>l.stopRecording&&l.stopRecording(...e)))}:{},{G:n.isProcessing},n.isProcessing?{H:e.t(n.processingText)}:{},{I:o._imports_0,J:e.o(((...e)=>l.handleClearHistory&&l.handleClearHistory(...e))),K:e.o(((...e)=>l.endCall&&l.endCall(...e)))}):e.e({c:n.loading},n.loading?{}:n.videos.length>0?{e:e.f(n.videos,((t,o,i)=>e.e({a:e.t(t.name||"复活视频"),b:e.t(t.text||"暂无描述"),c:e.t(l.formatTime(t.create_time)),d:n.selectedVideoId===t.id},(n.selectedVideoId,t.id,{}),{e:t.id,f:e.n(n.selectedVideoId===t.id?"selected":""),g:e.o((e=>l.selectVideo(t)),t.id)})))}:{},{d:n.videos.length>0,f:n.videos.length>0},n.videos.length>0?e.e({g:n.selectedVideoId},(n.selectedVideoId,{}),{h:!n.selectedVideoId,i:e.o(((...e)=>l.startCall&&l.startCall(...e)))}):{}),{L:n.showSettingsDialog},n.showSettingsDialog?{M:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e))),N:n.dialogMemoryIdentity,O:e.o((e=>n.dialogMemoryIdentity=e.detail.value)),P:n.dialogMemoryInfo,Q:e.o((e=>n.dialogMemoryInfo=e.detail.value)),R:n.dialogMemoryCatchphrase,S:e.o((e=>n.dialogMemoryCatchphrase=e.detail.value)),T:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e))),U:e.o(((...e)=>l.confirmSettings&&l.confirmSettings(...e))),V:e.o((()=>{})),W:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e)))}:{})}],["__scopeId","data-v-70ab4376"]]);wx.createPage(s);
+"use strict";const e=require("../../common/vendor.js"),t=require("../../config/api.js"),o=require("../../common/assets.js"),i={data:()=>({API_BASE:t.API_BASE,lastUserId:null,loading:!1,videos:[],selectedVideoId:"",selectedVideoName:"",selectedVideoUrl:"",selectedVoiceId:"",selectedDialect:"",selectedLanguageHint:"",selectedLanguageHintLabel:"",languageHintOptions:["中文(zh)","英文(en)","法语(fr)","德语(de)","日语(ja)","韩语(ko)","俄语(ru)"],dialectOptions:["广东话","东北话","甘肃话","贵州话","河南话","湖北话","江西话","闽南话","宁夏话","山西话","陕西话","山东话","上海话","四川话","天津话","云南话"],callStarted:!1,callStatus:"视频通话中",callDuration:"00:00",callStartTime:null,durationTimer:null,messages:[],scrollTop:0,isRecording:!1,isProcessing:!1,isSpeaking:!1,processingText:"处理中...",recorderManager:null,audioFilePath:"",audioContext:null,showSettingsDialog:!1,dialogMemoryIdentity:"",dialogMemoryInfo:"",dialogMemoryCatchphrase:""}),onLoad(){console.log("[PhoneCall] 页面加载");const t=e.index.getStorageSync("userId");this.lastUserId=t,this.loadVideos(),this.initRecorder(),this.initAudioContext()},onShow(){console.log("[PhoneCall] 页面显示");const t=e.index.getStorageSync("userId");this.lastUserId=t,this.callStarted||this.$nextTick((()=>{setTimeout((()=>{this.loadVideos()}),100)}))},onUnload(){this.cleanup()},methods:{async loadVideos(){this.loading=!0;const t=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.request({url:`${this.API_BASE}/api/photo-revival/videos`,method:"GET",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},success:e=>{if(console.log("[PhoneCall] 视频列表响应状态码:",e.statusCode),console.log("[PhoneCall] 视频列表响应数据:",e.data),console.log("[PhoneCall] 数据类型:",typeof e.data),200===e.statusCode){let t=[];Array.isArray(e.data)?t=e.data:e.data&&Array.isArray(e.data.data)?t=e.data.data:e.data&&e.data.videos&&Array.isArray(e.data.videos)&&(t=e.data.videos),t=t.filter((e=>{const t=e.name&&(e.name.startsWith("生成失败")||e.name.startsWith("生成失败:")),o=e.edited_video_url||e.video_url||e.local_video_path||e.videoUrl||e.localVideoPath,i=o&&""!==o.trim();return!t&&i})),this.videos=t,console.log("[PhoneCall] 加载视频列表成功:",this.videos.length),console.log("[PhoneCall] 视频列表:",this.videos)}else console.error("[PhoneCall] 响应状态码异常:",e.statusCode)},fail:t=>{console.error("[PhoneCall] 加载视频列表失败:",t),e.index.showToast({title:"加载失败",icon:"none"})},complete:()=>{this.loading=!1}})},selectVideo(e){console.log("[PhoneCall] 选择视频:",e),this.selectedVideoId=e.id,this.selectedVideoName=e.name||"复活视频",this.selectedVideoUrl=e.edited_video_url||e.local_video_path||e.video_url,this.selectedVoiceId=e.voice_id,this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",console.log("[PhoneCall] 选择视频:",this.selectedVideoId,"名称:",this.selectedVideoName),console.log("[PhoneCall] 视频URL:",this.selectedVideoUrl)},onDialectChange(e){this.selectedDialect=this.dialectOptions[e.detail.value]||""},onLanguageHintChange(e){const t=this.languageHintOptions[e.detail.value]||"";this.selectedLanguageHintLabel=t;const o=t.match(/\(([^)]+)\)/);this.selectedLanguageHint=o&&o[1]?o[1]:""},startCall(){if(!this.selectedVideoId)return void e.index.showToast({title:"请先选择视频",icon:"none"});console.log("[PhoneCall] 准备视频通话,视频ID:",this.selectedVideoId);const t=this.videos.find((e=>e.id===this.selectedVideoId));if(!t)return void e.index.showToast({title:"视频信息丢失",icon:"none"});const o=t.edited_video_url||t.videoUrl||t.local_video_path||t.video_url||t.localVideoPath||"",i=t.name||"复活视频",s=this.selectedVoiceId||"";console.log("[PhoneCall] 跳转参数:",{videoId:this.selectedVideoId,videoName:i,videoUrl:o,voiceId:s}),e.index.navigateTo({url:`/pages/video-call-new/video-call-new?videoId=${this.selectedVideoId}&videoName=${encodeURIComponent(i)}&videoUrl=${encodeURIComponent(o)}&voiceId=${s}`,success:()=>{console.log("[PhoneCall] 跳转到视频通话页面成功")},fail:t=>{console.error("[PhoneCall] 跳转失败:",t),e.index.showToast({title:"跳转失败",icon:"none"})}})},closeSettingsDialog(){this.showSettingsDialog=!1},confirmSettings(){this.showSettingsDialog=!1},startCallTimer(){this.callStartTime=Date.now(),this.durationTimer=setInterval((()=>{const e=Math.floor((Date.now()-this.callStartTime)/1e3),t=Math.floor(e/60).toString().padStart(2,"0"),o=(e%60).toString().padStart(2,"0");this.callDuration=`${t}:${o}`}),1e3)},initRecorder(){this.recorderManager=e.index.getRecorderManager(),this.recorderManager.onStart((()=>{console.log("[PhoneCall] 开始录音")})),this.recorderManager.onStop((e=>{console.log("[PhoneCall] 录音完成:",e.tempFilePath),this.audioFilePath=e.tempFilePath,this.processConversation()})),this.recorderManager.onError((t=>{console.error("[PhoneCall] 录音失败:",t),this.isRecording=!1,e.index.showToast({title:"录音失败",icon:"none"})}))},initAudioContext(){this.audioContext=e.index.createInnerAudioContext(),this.audioContext.onPlay((()=>{console.log("[PhoneCall] 开始播放AI回复"),this.isSpeaking=!0,this.callStatus="对方正在说话...",e.index.vibrateShort({type:"light"})})),this.audioContext.onEnded((()=>{console.log("[PhoneCall] AI回复播放完成"),this.isSpeaking=!1,this.callStatus="通话中"})),this.audioContext.onError((e=>{console.error("[PhoneCall] 音频播放失败:",e),this.isSpeaking=!1,this.callStatus="通话中"}))},startRecording(){this.isProcessing||(this.isRecording=!0,this.recorderManager.start({format:"mp3",sampleRate:16e3}),this.callStatus="正在录音...",e.index.vibrateShort({type:"medium"}))},stopRecording(){this.isRecording&&(this.isRecording=!1,this.recorderManager.stop(),this.isProcessing=!0,this.processingText="识别中...",this.callStatus="处理中...")},async processConversation(){try{this.processingText="正在识别...";const t=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.uploadFile({url:`${this.API_BASE}/api/conversation/talk`,filePath:this.audioFilePath,name:"audio",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},formData:(()=>{const e=this.selectedVoiceId,t=(()=>{const t=(e||"").trim();if(!t)return"CLONE";return["Cherry","Kai","Mochi","Bunny","Jada","Dylan","Li","Marcus","Roy","Peter","Sunny","Eric","Rocky","Kiki"].includes(t)||t.startsWith("BV")||t.endsWith("_streaming")||t.endsWith("_offline")||t.endsWith("_bigtts")?"OFFICIAL":"CLONE"})(),o={voiceId:e,voiceType:t};return this.selectedDialect&&(o.dialect=this.selectedDialect),this.selectedLanguageHint&&(o.languageHints=this.selectedLanguageHint),o})(),success:e=>{if(console.log("[PhoneCall] 对话响应:",e),200!==e.statusCode)throw new Error("对话请求失败");{const t=JSON.parse(e.data);if(!t.success)throw new Error(t.message||"对话失败");this.addMessage("user",t.recognizedText),this.addMessage("ai",t.aiResponse),this.playAIResponse(t.audioFile)}},fail:t=>{console.error("[PhoneCall] 对话失败:",t),e.index.showToast({title:"对话失败",icon:"none"}),this.isProcessing=!1,this.callStatus="通话中"}})}catch(t){console.error("[PhoneCall] 对话失败:",t),e.index.showToast({title:"对话失败: "+t.message,icon:"none"}),this.isProcessing=!1,this.callStatus="通话中"}},playAIResponse(e){this.processingText="正在回复...",this.audioContext.src=`${this.API_BASE}/api/conversation/audio/${e}`,this.audioContext.play(),this.isProcessing=!1},addMessage(e,t){const o=new Date,i=`${o.getHours()}:${o.getMinutes().toString().padStart(2,"0")}`;this.messages.push({role:e,content:t,time:i}),this.$nextTick((()=>{this.scrollTop=999999}))},handleClearHistory(){e.index.showModal({title:"确认清空",content:"确定要清空对话历史吗?",success:t=>{if(t.confirm){const t=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.request({url:`${this.API_BASE}/api/conversation/clear-history`,method:"POST",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},success:t=>{t.data.success&&(this.messages=[],e.index.showToast({title:"已清空",icon:"success"}))}})}}})},endCall(){e.index.showModal({title:"结束通话",content:`通话时长:${this.callDuration}\n确定要结束通话吗?`,confirmColor:"#eb3349",success:t=>{t.confirm&&(e.index.vibrateShort({type:"heavy"}),e.index.showLoading({title:"正在挂断...",mask:!0}),setTimeout((()=>{e.index.hideLoading(),this.cleanup(),e.index.showToast({title:"通话已结束",icon:"success",duration:1500,success:()=>{setTimeout((()=>{e.index.navigateBack()}),1500)}})}),800))}})},goToRevival(){console.log("[PhoneCall] 跳转到复活照片页面"),e.index.navigateTo({url:"/pages/revival/revival-original",success:()=>{console.log("[PhoneCall] 跳转成功")},fail:e=>{console.error("[PhoneCall] 跳转失败:",e)}})},cleanup(){this.durationTimer&&clearInterval(this.durationTimer),this.audioContext&&this.audioContext.destroy(),this.recorderManager&&this.recorderManager.stop()},formatTime(e){if(!e)return"";let t=e;String(e).length<=10&&(t=1e3*e);const o=new Date(t);if(isNaN(o.getTime()))return"时间格式错误";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")}`}}};const s=e._export_sfc(i,[["render",function(t,i,s,a,n,l){return e.e({a:e.o(((...e)=>l.goToRevival&&l.goToRevival(...e))),b:!n.callStarted},n.callStarted?e.e({k:n.selectedVideoUrl},n.selectedVideoUrl?{l:n.selectedVideoUrl}:{},{m:!n.selectedVideoUrl},(n.selectedVideoUrl,{}),{n:e.t(n.selectedVideoName),o:e.t(n.callStatus),p:n.isSpeaking||n.isRecording?1:"",q:e.t(n.callDuration),r:e.f(n.messages,((t,o,i)=>({a:e.t("user"===t.role?"👤":"🤖"),b:e.t(t.content),c:e.t(t.time),d:o,e:e.n(t.role)}))),s:0===n.messages.length},(n.messages.length,{}),{t:n.scrollTop,v:n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")},n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")?{w:e.t(n.selectedDialect||"请选择方言(可选)"),x:n.dialectOptions,y:e.o(((...e)=>l.onDialectChange&&l.onDialectChange(...e)))}:{},{z:n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")},n.selectedVoiceId&&n.selectedVoiceId.startsWith("cosyvoice-v3-plus-")?{A:e.t(n.selectedLanguageHintLabel||"请选择语言(可选)"),B:n.languageHintOptions,C:e.o(((...e)=>l.onLanguageHintChange&&l.onLanguageHintChange(...e)))}:{},{D:!n.isRecording&&!n.isProcessing},n.isRecording||n.isProcessing?{}:{E:e.o(((...e)=>l.startRecording&&l.startRecording(...e))),F:e.o(((...e)=>l.stopRecording&&l.stopRecording(...e)))},{G:n.isRecording},n.isRecording?{H:e.o(((...e)=>l.stopRecording&&l.stopRecording(...e)))}:{},{I:n.isProcessing},n.isProcessing?{J:e.t(n.processingText)}:{},{K:o._imports_0,L:e.o(((...e)=>l.handleClearHistory&&l.handleClearHistory(...e))),M:e.o(((...e)=>l.endCall&&l.endCall(...e)))}):e.e({c:n.loading},n.loading?{}:n.videos.length>0?{e:e.f(n.videos,((t,o,i)=>e.e({a:e.t(t.name||"复活视频"),b:e.t(t.text||"暂无描述"),c:e.t(l.formatTime(t.create_time)),d:n.selectedVideoId===t.id},(n.selectedVideoId,t.id,{}),{e:t.id,f:e.n(n.selectedVideoId===t.id?"selected":""),g:e.o((e=>l.selectVideo(t)),t.id)})))}:{},{d:n.videos.length>0,f:n.videos.length>0},n.videos.length>0?e.e({g:n.selectedVideoId},(n.selectedVideoId,{}),{h:!n.selectedVideoId,i:e.o(((...e)=>l.startCall&&l.startCall(...e)))}):{},{j:n.videos.length>0},(n.videos.length,{})),{N:n.showSettingsDialog},n.showSettingsDialog?{O:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e))),P:n.dialogMemoryIdentity,Q:e.o((e=>n.dialogMemoryIdentity=e.detail.value)),R:n.dialogMemoryInfo,S:e.o((e=>n.dialogMemoryInfo=e.detail.value)),T:n.dialogMemoryCatchphrase,U:e.o((e=>n.dialogMemoryCatchphrase=e.detail.value)),V:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e))),W:e.o(((...e)=>l.confirmSettings&&l.confirmSettings(...e))),X:e.o((()=>{})),Y:e.o(((...e)=>l.closeSettingsDialog&&l.closeSettingsDialog(...e)))}:{})}],["__scopeId","data-v-a48cd222"]]);wx.createPage(s);
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.wxml
index bdffbe1..267c0c1 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.wxml
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.wxml
@@ -1 +1 @@
-🎬 选择复活视频选择一个已生成的复活视频开始视频通话⏳ 加载视频列表...🎬{{video.a}}{{video.b}}{{video.c}}✓🎬暂无复活视频请先点击上方"复活照片"生成视频🎬视频加载中...{{l}}{{m}}{{o}}{{msg.a}}{{msg.b}}{{msg.c}}💬按住下方按钮开始说话方言{{t}}语言提示(可选){{y}}💡 仅处理第一个值;不设置不生效💭 记忆设定(可选)设置对话记忆,让AI更真实地模拟对方身份性格特点口头禅
\ No newline at end of file
+🎬 选择复活视频选择一个已生成的复活视频开始视频通话⏳ 加载视频列表...🎬{{video.a}}{{video.b}}{{video.c}}✓🎬暂无复活视频请先点击上方"复活照片"生成视频本服务为AI生成内容,结果仅供参考AI生成🎬视频加载中...{{n}}{{o}}{{q}}{{msg.a}}{{msg.b}}{{msg.c}}💬按住下方按钮开始说话方言{{w}}语言提示(可选){{A}}💡 仅处理第一个值;不设置不生效💭 记忆设定(可选)设置对话记忆,让AI更真实地模拟对方身份性格特点口头禅
\ No newline at end of file
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.wxss
index b72e2d4..6256f8d 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.wxss
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/phone-call/phone-call.wxss
@@ -1 +1 @@
-.phone-call-container.data-v-70ab4376{min-height:100vh;background:linear-gradient(180deg,#f8f5f0,#fdf8f2);background-image:radial-gradient(circle at 10% 20%,rgba(212,185,150,.08) 0%,transparent 25%),radial-gradient(circle at 90% 80%,rgba(109,139,139,.08) 0%,transparent 25%);position:relative}.memorial-content.data-v-70ab4376{position:relative;z-index:2;padding:40rpx 24rpx 30rpx;max-width:1000rpx;margin:0 auto;width:100%;box-sizing:border-box}.revival-btn-section.data-v-70ab4376{margin:0 0 32rpx;padding:0}.revival-btn.data-v-70ab4376{width:100%;padding:32rpx 40rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:32rpx;font-size:32rpx;font-weight:600;box-shadow:0 8rpx 24rpx rgba(139,115,85,.25);transition:all .3s ease;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;gap:16rpx}.revival-btn.data-v-70ab4376:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(135deg,rgba(255,255,255,.15) 0%,transparent 100%)}.revival-btn.data-v-70ab4376:active{transform:translateY(-2rpx);box-shadow:0 12rpx 32rpx rgba(139,115,85,.35)}.revival-btn .btn-icon.data-v-70ab4376{font-size:40rpx;line-height:1}.revival-btn .btn-text.data-v-70ab4376{font-size:32rpx;font-weight:600;letter-spacing:.5rpx}.select-voice-section.data-v-70ab4376{flex:1;padding:40rpx;display:flex;flex-direction:column}.select-video-section.data-v-70ab4376{padding:0;flex:1;display:flex;flex-direction:column;opacity:1;transition:opacity .2s ease}.section-card.data-v-70ab4376{background:rgba(255,255,255,.98);border-radius:28rpx;padding:36rpx 28rpx;box-shadow:0 4rpx 20rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);border:1rpx solid rgba(212,185,150,.2);flex:1;display:flex;flex-direction:column}.card-title.data-v-70ab4376{font-size:34rpx;font-weight:700;color:#2c2c2c;margin-bottom:12rpx;line-height:1.4;letter-spacing:.3rpx}.card-desc.data-v-70ab4376{font-size:26rpx;color:#666;margin-bottom:28rpx;line-height:1.6;opacity:.9}.loading-box.data-v-70ab4376{padding:100rpx 40rpx;text-align:center;flex:1;display:flex;align-items:center;justify-content:center;opacity:1;transition:opacity .3s ease}.loading-text.data-v-70ab4376{font-size:28rpx;color:#999;opacity:.8}.video-list.data-v-70ab4376{display:flex;flex-direction:column;gap:16rpx;margin-bottom:28rpx;flex:1;overflow-y:auto;opacity:1;transition:opacity .3s ease}.video-card.data-v-70ab4376{background:rgba(255,255,255,.95);border:1.5rpx solid rgba(212,185,150,.25);border-radius:20rpx;padding:28rpx 24rpx;display:flex;align-items:center;transition:all .25s ease;box-shadow:0 2rpx 8rpx rgba(0,0,0,.06);position:relative}.video-card.data-v-70ab4376:active{transform:translateY(-1rpx);box-shadow:0 4rpx 12rpx rgba(0,0,0,.1)}.video-card.selected.data-v-70ab4376{background:linear-gradient(135deg,rgba(139,115,85,.1),rgba(109,139,139,.08));border-color:#8b7355;box-shadow:0 4rpx 16rpx rgba(139,115,85,.18)}.video-card-icon.data-v-70ab4376{font-size:44rpx;margin-right:20rpx;flex-shrink:0;line-height:1}.video-card-content.data-v-70ab4376{flex:1;display:flex;flex-direction:column;min-width:0}.video-card-name.data-v-70ab4376{font-size:30rpx;font-weight:600;color:#2c2c2c;margin-bottom:8rpx;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.video-card-desc.data-v-70ab4376{font-size:24rpx;color:#666;margin-bottom:6rpx;line-height:1.5;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;opacity:.9}.video-card-time.data-v-70ab4376{font-size:22rpx;color:#999;opacity:.85}.video-card-check.data-v-70ab4376{font-size:36rpx;color:#8b7355;font-weight:700;margin-left:12rpx;flex-shrink:0;line-height:1}.empty-box.data-v-70ab4376{padding:100rpx 40rpx;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center;flex:1}.empty-icon.data-v-70ab4376{font-size:100rpx;margin-bottom:24rpx;opacity:.6}.empty-text.data-v-70ab4376{font-size:28rpx;color:#666;margin-bottom:16rpx;font-weight:500}.empty-hint.data-v-70ab4376{font-size:24rpx;color:#999;opacity:.8;line-height:1.5}.start-call-btn.data-v-70ab4376{width:100%;padding:32rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:28rpx;font-size:30rpx;font-weight:600;box-shadow:0 6rpx 20rpx rgba(139,115,85,.25);transition:all .3s ease;margin-top:auto;letter-spacing:.5rpx}.start-call-btn.data-v-70ab4376:active{transform:translateY(-1rpx);box-shadow:0 8rpx 24rpx rgba(139,115,85,.3)}.start-call-btn[disabled].data-v-70ab4376{background:#e5e5e5;box-shadow:0 2rpx 8rpx rgba(0,0,0,.08);opacity:.65;transform:none!important;color:#999}.call-active-section.data-v-70ab4376{opacity:1;transition:opacity .2s ease;flex:1;display:flex;flex-direction:column;padding:24rpx;overflow:hidden}.video-call-card.data-v-70ab4376{background:rgba(255,255,255,.98);border-radius:28rpx;padding:32rpx 28rpx;text-align:center;margin-bottom:20rpx;box-shadow:0 4rpx 20rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);border:1rpx solid rgba(212,185,150,.2)}.video-container.data-v-70ab4376{width:100%;height:480rpx;background:#000;border-radius:20rpx;overflow:hidden;margin-bottom:20rpx;position:relative;box-shadow:0 4rpx 16rpx rgba(0,0,0,.15)}.video-player.data-v-70ab4376{width:100%;height:100%}.video-placeholder.data-v-70ab4376{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;background:linear-gradient(135deg,#2c3e50,#34495e)}.placeholder-icon.data-v-70ab4376{font-size:100rpx;margin-bottom:20rpx}.placeholder-text.data-v-70ab4376{font-size:28rpx;color:#fff;opacity:.8}.call-video-name.data-v-70ab4376{display:block;font-size:30rpx;font-weight:700;color:#2c2c2c;margin-bottom:12rpx;line-height:1.4;letter-spacing:.3rpx}.call-status.data-v-70ab4376{display:block;font-size:26rpx;color:#666;margin-bottom:10rpx;transition:all .3s ease;opacity:.9}.call-status.status-active.data-v-70ab4376{color:#11998e;font-weight:600;opacity:1;animation:statusBlink-70ab4376 1.5s ease-in-out infinite}.call-duration.data-v-70ab4376{display:block;font-size:24rpx;color:#999;opacity:.85}.chat-history.data-v-70ab4376{flex:1;background:rgba(255,255,255,.98);border-radius:28rpx;padding:28rpx 24rpx;margin-bottom:20rpx;box-shadow:0 4rpx 20rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);border:1rpx solid rgba(212,185,150,.2);overflow:hidden}.message-item.data-v-70ab4376{display:flex;margin-bottom:24rpx;animation:fadeIn-70ab4376 .3s ease}.message-item.user.data-v-70ab4376{flex-direction:row-reverse}.message-avatar.data-v-70ab4376{font-size:44rpx;margin:0 16rpx;flex-shrink:0;line-height:1}.message-bubble.data-v-70ab4376{max-width:72%;padding:20rpx 24rpx;border-radius:20rpx;display:flex;flex-direction:column;box-shadow:0 2rpx 8rpx rgba(0,0,0,.06)}.message-item.user .message-bubble.data-v-70ab4376{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff}.message-item.ai .message-bubble.data-v-70ab4376{background:rgba(248,248,248,.95);color:#2c2c2c;border:1rpx solid rgba(0,0,0,.04)}.message-text.data-v-70ab4376{font-size:28rpx;line-height:1.6;margin-bottom:8rpx;word-break:break-word}.message-time.data-v-70ab4376{font-size:20rpx;opacity:.75;text-align:right}.empty-chat.data-v-70ab4376{padding:100rpx 40rpx;text-align:center;display:flex;flex-direction:column;align-items:center}.empty-chat-icon.data-v-70ab4376{font-size:80rpx;margin-bottom:20rpx;opacity:.5}.empty-chat-text.data-v-70ab4376{font-size:26rpx;color:#999}.controls.data-v-70ab4376{background:rgba(255,255,255,.98);border-radius:28rpx;padding:28rpx 24rpx;box-shadow:0 -2rpx 16rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);border:1rpx solid rgba(212,185,150,.2)}.record-control.data-v-70ab4376{margin-bottom:20rpx}.record-btn.data-v-70ab4376{width:100%;padding:36rpx;border:none;border-radius:28rpx;display:flex;flex-direction:column;align-items:center;justify-content:center;font-weight:600;transition:all .3s ease}.record-btn.idle.data-v-70ab4376{background:linear-gradient(135deg,#11998e,#38ef7d);color:#fff;box-shadow:0 6rpx 16rpx rgba(17,153,142,.25)}.record-btn.recording.data-v-70ab4376{background:linear-gradient(135deg,#eb3349,#f45c43);color:#fff;box-shadow:0 6rpx 16rpx rgba(235,51,73,.25);animation:recordingPulse-70ab4376 1s ease-in-out infinite}.record-btn.processing.data-v-70ab4376{background:#e5e5e5;color:#666}.record-btn-icon.data-v-70ab4376{font-size:56rpx;margin-bottom:10rpx;line-height:1}.record-btn-icon.pulse.data-v-70ab4376{animation:pulse-70ab4376 1s infinite}.record-btn-text.data-v-70ab4376{font-size:26rpx;letter-spacing:.5rpx}.action-buttons.data-v-70ab4376{display:flex;gap:16rpx}.action-btn.data-v-70ab4376{flex:1;padding:24rpx 20rpx;background:rgba(248,248,248,.95);border:none;border-radius:20rpx;display:flex;flex-direction:column;align-items:center;color:#666;transition:all .25s ease;box-shadow:0 2rpx 6rpx rgba(0,0,0,.04)}.action-btn.data-v-70ab4376:active{transform:scale(.97)}.action-btn.end-call.data-v-70ab4376{background:linear-gradient(135deg,#d9534f,#c9302c);color:#fff;box-shadow:0 4rpx 16rpx rgba(217,83,79,.25)}.action-btn-icon.data-v-70ab4376{font-size:32rpx;margin-bottom:8rpx;line-height:1}.action-btn-text.data-v-70ab4376{font-size:24rpx;font-weight:500;letter-spacing:.3rpx}@keyframes fadeIn-70ab4376{0%{opacity:0;transform:translateY(20rpx)}to{opacity:1;transform:translateY(0)}}@keyframes pulse-70ab4376{0%,to{transform:scale(1)}50%{transform:scale(1.1)}}@keyframes avatarPulse-70ab4376{0%,to{transform:scale(1)}50%{transform:scale(1.05)}}@keyframes waveExpand-70ab4376{0%{transform:scale(1);opacity:.8}to{transform:scale(2);opacity:0}}@keyframes statusBlink-70ab4376{0%,to{opacity:1}50%{opacity:.6}}@keyframes recordingPulse-70ab4376{0%,to{transform:scale(1);box-shadow:0 8rpx 16rpx rgba(235,51,73,.3)}50%{transform:scale(1.02);box-shadow:0 12rpx 24rpx rgba(235,51,73,.5),0 0 0 8rpx rgba(235,51,73,.2)}}.settings-dialog-mask.data-v-70ab4376{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;z-index:9999}.settings-dialog.data-v-70ab4376{width:90%;max-width:600rpx;background:#fff;border-radius:24rpx;overflow:hidden}.dialog-header.data-v-70ab4376{padding:30rpx;background:linear-gradient(135deg,#667eea,#764ba2);display:flex;justify-content:space-between;align-items:center}.dialog-title.data-v-70ab4376{font-size:32rpx;font-weight:700;color:#fff}.dialog-close.data-v-70ab4376{font-size:40rpx;color:#fff;opacity:.8;padding:0 10rpx}.dialog-content.data-v-70ab4376{max-height:60vh;overflow-y:auto;padding:30rpx}.dialog-section.data-v-70ab4376{margin-bottom:30rpx}.section-label.data-v-70ab4376{font-size:28rpx;font-weight:700;color:#333;margin-bottom:10rpx}.section-hint.data-v-70ab4376{font-size:24rpx;color:#999;margin-bottom:20rpx;display:block}.voice-selector.data-v-70ab4376{background:#f5f5f5;padding:24rpx;border-radius:12rpx;display:flex;justify-content:space-between;align-items:center}.voice-selected.data-v-70ab4376{font-size:28rpx;color:#333}.voice-arrow.data-v-70ab4376{font-size:32rpx;color:#999}.memory-item.data-v-70ab4376{margin-bottom:20rpx}.memory-label.data-v-70ab4376{font-size:26rpx;color:#666;margin-bottom:10rpx;display:block}.memory-input.data-v-70ab4376{width:100%;padding:28rpx 20rpx;min-height:88rpx;background:#f5f5f5;border-radius:12rpx;font-size:28rpx;border:none}.memory-textarea.data-v-70ab4376{width:100%;min-height:120rpx;padding:20rpx;background:#f5f5f5;border-radius:12rpx;font-size:28rpx;border:none}.dialog-footer.data-v-70ab4376{padding:20rpx 30rpx 30rpx;display:flex;gap:20rpx}.dialog-btn.data-v-70ab4376{flex:1;padding:24rpx;border-radius:12rpx;font-size:28rpx;font-weight:700;border:none}.dialog-btn.cancel.data-v-70ab4376{background:#f5f5f5;color:#666}.dialog-btn.confirm.data-v-70ab4376{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff}
+.phone-call-container.data-v-a48cd222{min-height:100vh;background:linear-gradient(180deg,#f8f5f0,#fdf8f2);background-image:radial-gradient(circle at 10% 20%,rgba(212,185,150,.08) 0%,transparent 25%),radial-gradient(circle at 90% 80%,rgba(109,139,139,.08) 0%,transparent 25%);position:relative}.memorial-content.data-v-a48cd222{position:relative;z-index:2;padding:40rpx 24rpx 30rpx;max-width:1000rpx;margin:0 auto;width:100%;box-sizing:border-box}.revival-btn-section.data-v-a48cd222{margin:0 0 32rpx;padding:0}.revival-btn.data-v-a48cd222{width:100%;padding:32rpx 40rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:32rpx;font-size:32rpx;font-weight:600;box-shadow:0 8rpx 24rpx rgba(139,115,85,.25);transition:all .3s ease;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;gap:16rpx}.revival-btn.data-v-a48cd222:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(135deg,rgba(255,255,255,.15) 0%,transparent 100%)}.revival-btn.data-v-a48cd222:active{transform:translateY(-2rpx);box-shadow:0 12rpx 32rpx rgba(139,115,85,.35)}.revival-btn .btn-icon.data-v-a48cd222{font-size:40rpx;line-height:1}.revival-btn .btn-text.data-v-a48cd222{font-size:32rpx;font-weight:600;letter-spacing:.5rpx}.select-voice-section.data-v-a48cd222{flex:1;padding:40rpx;display:flex;flex-direction:column}.select-video-section.data-v-a48cd222{padding:0;flex:1;display:flex;flex-direction:column;opacity:1;transition:opacity .2s ease}.section-card.data-v-a48cd222{background:rgba(255,255,255,.98);border-radius:28rpx;padding:36rpx 28rpx;box-shadow:0 4rpx 20rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);border:1rpx solid rgba(212,185,150,.2);flex:1;display:flex;flex-direction:column}.card-title.data-v-a48cd222{font-size:34rpx;font-weight:700;color:#2c2c2c;margin-bottom:12rpx;line-height:1.4;letter-spacing:.3rpx}.card-desc.data-v-a48cd222{font-size:26rpx;color:#666;margin-bottom:28rpx;line-height:1.6;opacity:.9}.loading-box.data-v-a48cd222{padding:100rpx 40rpx;text-align:center;flex:1;display:flex;align-items:center;justify-content:center;opacity:1;transition:opacity .3s ease}.loading-text.data-v-a48cd222{font-size:28rpx;color:#999;opacity:.8}.video-list.data-v-a48cd222{display:flex;flex-direction:column;gap:16rpx;margin-bottom:28rpx;flex:1;overflow-y:auto;opacity:1;transition:opacity .3s ease}.video-card.data-v-a48cd222{background:rgba(255,255,255,.95);border:1.5rpx solid rgba(212,185,150,.25);border-radius:20rpx;padding:28rpx 24rpx;display:flex;align-items:center;transition:all .25s ease;box-shadow:0 2rpx 8rpx rgba(0,0,0,.06);position:relative}.video-card.data-v-a48cd222:active{transform:translateY(-1rpx);box-shadow:0 4rpx 12rpx rgba(0,0,0,.1)}.video-card.selected.data-v-a48cd222{background:linear-gradient(135deg,rgba(139,115,85,.1),rgba(109,139,139,.08));border-color:#8b7355;box-shadow:0 4rpx 16rpx rgba(139,115,85,.18)}.video-card-icon.data-v-a48cd222{font-size:44rpx;margin-right:20rpx;flex-shrink:0;line-height:1}.video-card-content.data-v-a48cd222{flex:1;display:flex;flex-direction:column;min-width:0}.video-card-name.data-v-a48cd222{font-size:30rpx;font-weight:600;color:#2c2c2c;margin-bottom:8rpx;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.video-card-desc.data-v-a48cd222{font-size:24rpx;color:#666;margin-bottom:6rpx;line-height:1.5;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;opacity:.9}.video-card-time.data-v-a48cd222{font-size:22rpx;color:#999;opacity:.85}.video-card-check.data-v-a48cd222{font-size:36rpx;color:#8b7355;font-weight:700;margin-left:12rpx;flex-shrink:0;line-height:1}.empty-box.data-v-a48cd222{padding:100rpx 40rpx;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center;flex:1}.empty-icon.data-v-a48cd222{font-size:100rpx;margin-bottom:24rpx;opacity:.6}.empty-text.data-v-a48cd222{font-size:28rpx;color:#666;margin-bottom:16rpx;font-weight:500}.empty-hint.data-v-a48cd222{font-size:24rpx;color:#999;opacity:.8;line-height:1.5}.start-call-btn.data-v-a48cd222{width:100%;padding:32rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff!important;border:none;border-radius:28rpx;font-size:30rpx;font-weight:600;box-shadow:0 6rpx 20rpx rgba(139,115,85,.25);transition:all .3s ease;margin-top:auto;letter-spacing:.5rpx}.start-call-btn.data-v-a48cd222:active{transform:translateY(-1rpx);box-shadow:0 8rpx 24rpx rgba(139,115,85,.3)}.start-call-btn[disabled].data-v-a48cd222{background:#e5e5e5;box-shadow:0 2rpx 8rpx rgba(0,0,0,.08);opacity:.65;transform:none!important;color:#fff!important}.ai-disclaimer.data-v-a48cd222{display:block;text-align:center;font-size:22rpx;color:rgba(100,100,100,.6);margin-top:16rpx;letter-spacing:.5rpx}.call-active-section.data-v-a48cd222{opacity:1;transition:opacity .2s ease;flex:1;display:flex;flex-direction:column;padding:24rpx;overflow:hidden}.video-call-card.data-v-a48cd222{background:rgba(255,255,255,.98);border-radius:28rpx;padding:32rpx 28rpx;text-align:center;margin-bottom:20rpx;box-shadow:0 4rpx 20rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);border:1rpx solid rgba(212,185,150,.2)}.video-container.data-v-a48cd222{width:100%;height:480rpx;background:#000;border-radius:20rpx;overflow:hidden;margin-bottom:20rpx;position:relative;box-shadow:0 4rpx 16rpx rgba(0,0,0,.15)}.video-player.data-v-a48cd222{width:100%;height:100%}.video-placeholder.data-v-a48cd222{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;background:linear-gradient(135deg,#2c3e50,#34495e)}.ai-tag.data-v-a48cd222{position:absolute;top:20rpx;right:20rpx;z-index:100;background:rgba(0,0,0,.6);padding:8rpx 20rpx;border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.ai-tag-text.data-v-a48cd222{font-size:22rpx;color:#fff;font-weight:500}.placeholder-icon.data-v-a48cd222{font-size:100rpx;margin-bottom:20rpx}.placeholder-text.data-v-a48cd222{font-size:28rpx;color:#fff;opacity:.8}.call-video-name.data-v-a48cd222{display:block;font-size:30rpx;font-weight:700;color:#2c2c2c;margin-bottom:12rpx;line-height:1.4;letter-spacing:.3rpx}.call-status.data-v-a48cd222{display:block;font-size:26rpx;color:#666;margin-bottom:10rpx;transition:all .3s ease;opacity:.9}.call-status.status-active.data-v-a48cd222{color:#11998e;font-weight:600;opacity:1;animation:statusBlink-a48cd222 1.5s ease-in-out infinite}.call-duration.data-v-a48cd222{display:block;font-size:24rpx;color:#999;opacity:.85}.chat-history.data-v-a48cd222{flex:1;background:rgba(255,255,255,.98);border-radius:28rpx;padding:28rpx 24rpx;margin-bottom:20rpx;box-shadow:0 4rpx 20rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);border:1rpx solid rgba(212,185,150,.2);overflow:hidden}.message-item.data-v-a48cd222{display:flex;margin-bottom:24rpx;animation:fadeIn-a48cd222 .3s ease}.message-item.user.data-v-a48cd222{flex-direction:row-reverse}.message-avatar.data-v-a48cd222{font-size:44rpx;margin:0 16rpx;flex-shrink:0;line-height:1}.message-bubble.data-v-a48cd222{max-width:72%;padding:20rpx 24rpx;border-radius:20rpx;display:flex;flex-direction:column;box-shadow:0 2rpx 8rpx rgba(0,0,0,.06)}.message-item.user .message-bubble.data-v-a48cd222{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff}.message-item.ai .message-bubble.data-v-a48cd222{background:rgba(248,248,248,.95);color:#2c2c2c;border:1rpx solid rgba(0,0,0,.04)}.message-text.data-v-a48cd222{font-size:28rpx;line-height:1.6;margin-bottom:8rpx;word-break:break-word}.message-time.data-v-a48cd222{font-size:20rpx;opacity:.75;text-align:right}.empty-chat.data-v-a48cd222{padding:100rpx 40rpx;text-align:center;display:flex;flex-direction:column;align-items:center}.empty-chat-icon.data-v-a48cd222{font-size:80rpx;margin-bottom:20rpx;opacity:.5}.empty-chat-text.data-v-a48cd222{font-size:26rpx;color:#999}.controls.data-v-a48cd222{background:rgba(255,255,255,.98);border-radius:28rpx;padding:28rpx 24rpx;box-shadow:0 -2rpx 16rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);border:1rpx solid rgba(212,185,150,.2)}.record-control.data-v-a48cd222{margin-bottom:20rpx}.record-btn.data-v-a48cd222{width:100%;padding:36rpx;border:none;border-radius:28rpx;display:flex;flex-direction:column;align-items:center;justify-content:center;font-weight:600;transition:all .3s ease}.record-btn.idle.data-v-a48cd222{background:linear-gradient(135deg,#11998e,#38ef7d);color:#fff;box-shadow:0 6rpx 16rpx rgba(17,153,142,.25)}.record-btn.recording.data-v-a48cd222{background:linear-gradient(135deg,#eb3349,#f45c43);color:#fff;box-shadow:0 6rpx 16rpx rgba(235,51,73,.25);animation:recordingPulse-a48cd222 1s ease-in-out infinite}.record-btn.processing.data-v-a48cd222{background:#e5e5e5;color:#666}.record-btn-icon.data-v-a48cd222{font-size:56rpx;margin-bottom:10rpx;line-height:1}.record-btn-icon.pulse.data-v-a48cd222{animation:pulse-a48cd222 1s infinite}.record-btn-text.data-v-a48cd222{font-size:26rpx;letter-spacing:.5rpx}.action-buttons.data-v-a48cd222{display:flex;gap:16rpx}.action-btn.data-v-a48cd222{flex:1;padding:24rpx 20rpx;background:rgba(248,248,248,.95);border:none;border-radius:20rpx;display:flex;flex-direction:column;align-items:center;color:#666;transition:all .25s ease;box-shadow:0 2rpx 6rpx rgba(0,0,0,.04)}.action-btn.data-v-a48cd222:active{transform:scale(.97)}.action-btn.end-call.data-v-a48cd222{background:linear-gradient(135deg,#d9534f,#c9302c);color:#fff;box-shadow:0 4rpx 16rpx rgba(217,83,79,.25)}.action-btn-icon.data-v-a48cd222{font-size:32rpx;margin-bottom:8rpx;line-height:1}.action-btn-text.data-v-a48cd222{font-size:24rpx;font-weight:500;letter-spacing:.3rpx}@keyframes fadeIn-a48cd222{0%{opacity:0;transform:translateY(20rpx)}to{opacity:1;transform:translateY(0)}}@keyframes pulse-a48cd222{0%,to{transform:scale(1)}50%{transform:scale(1.1)}}@keyframes avatarPulse-a48cd222{0%,to{transform:scale(1)}50%{transform:scale(1.05)}}@keyframes waveExpand-a48cd222{0%{transform:scale(1);opacity:.8}to{transform:scale(2);opacity:0}}@keyframes statusBlink-a48cd222{0%,to{opacity:1}50%{opacity:.6}}@keyframes recordingPulse-a48cd222{0%,to{transform:scale(1);box-shadow:0 8rpx 16rpx rgba(235,51,73,.3)}50%{transform:scale(1.02);box-shadow:0 12rpx 24rpx rgba(235,51,73,.5),0 0 0 8rpx rgba(235,51,73,.2)}}.settings-dialog-mask.data-v-a48cd222{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;z-index:9999}.settings-dialog.data-v-a48cd222{width:90%;max-width:600rpx;background:#fff;border-radius:24rpx;overflow:hidden}.dialog-header.data-v-a48cd222{padding:30rpx;background:linear-gradient(135deg,#667eea,#764ba2);display:flex;justify-content:space-between;align-items:center}.dialog-title.data-v-a48cd222{font-size:32rpx;font-weight:700;color:#fff}.dialog-close.data-v-a48cd222{font-size:40rpx;color:#fff;opacity:.8;padding:0 10rpx}.dialog-content.data-v-a48cd222{max-height:60vh;overflow-y:auto;padding:30rpx}.dialog-section.data-v-a48cd222{margin-bottom:30rpx}.section-label.data-v-a48cd222{font-size:28rpx;font-weight:700;color:#333;margin-bottom:10rpx}.section-hint.data-v-a48cd222{font-size:24rpx;color:#999;margin-bottom:20rpx;display:block}.voice-selector.data-v-a48cd222{background:#f5f5f5;padding:24rpx;border-radius:12rpx;display:flex;justify-content:space-between;align-items:center}.voice-selected.data-v-a48cd222{font-size:28rpx;color:#333}.voice-arrow.data-v-a48cd222{font-size:32rpx;color:#999}.memory-item.data-v-a48cd222{margin-bottom:20rpx}.memory-label.data-v-a48cd222{font-size:26rpx;color:#666;margin-bottom:10rpx;display:block}.memory-input.data-v-a48cd222{width:100%;padding:28rpx 20rpx;min-height:88rpx;background:#f5f5f5;border-radius:12rpx;font-size:28rpx;border:none}.memory-textarea.data-v-a48cd222{width:100%;min-height:120rpx;padding:20rpx;background:#f5f5f5;border-radius:12rpx;font-size:28rpx;border:none}.dialog-footer.data-v-a48cd222{padding:20rpx 30rpx 30rpx;display:flex;gap:20rpx}.dialog-btn.data-v-a48cd222{flex:1;padding:24rpx;border-radius:12rpx;font-size:28rpx;font-weight:700;border:none}.dialog-btn.cancel.data-v-a48cd222{background:#f5f5f5;color:#666}.dialog-btn.confirm.data-v-a48cd222{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff}
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/plaza/plaza.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/plaza/plaza.js
index 6947386..e15d5a4 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/plaza/plaza.js
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/plaza/plaza.js
@@ -1 +1 @@
-"use strict";const e=require("../../common/vendor.js"),t=require("../../config/api.js"),o={data:()=>({API_BASE:t.API_BASE,works:[],page:0,size:10,loading:!1,hasMore:!0,loadedOnce:!1,hasCachedWorks:!1,enableVideoPreload:!1,preloadQueue:[],activePreloads:0,maxConcurrentPreloads:2,preloadingKeys:{}}),onLoad(){try{const t=e.index.getStorageSync("plaza_works_cache_v1");Array.isArray(t)&&t.length>0&&(this.works=t,this.hasCachedWorks=!0,this.loadedOnce=!0)}catch(t){this.hasCachedWorks=!1}this.loadWorks(!0)},onShow(){this.loadedOnce&&0!==this.works.length||this.loadWorks(!0)},methods:{normalizeMediaUrl(e){return e?e.startsWith("/")?`${this.API_BASE}${e}`:e.startsWith("http://115.190.167.176:20002")?e.replace("http://115.190.167.176:20002",this.API_BASE):e:e},generateCacheKey(e){let t=0;for(let o=0;o0;){const e=this.preloadQueue.shift();this.activePreloads+=1,this.preloadVideoToCache(e.url,e.cacheKey).finally((()=>{this.activePreloads=Math.max(0,this.activePreloads-1),this.processPreloadQueue()}))}},preloadVideoToCache(t,o){return new Promise((i=>{e.index.downloadFile({url:t,timeout:6e4,success:a=>{200===a.statusCode?e.index.saveFile({tempFilePath:a.tempFilePath,success:a=>{const r=a.savedFilePath;e.index.setStorageSync(o,r);const s=e.index.getStorageSync("video_cache_info")||{};s[o]={path:r,url:t,time:Date.now()},e.index.setStorageSync("video_cache_info",s),i()},fail:()=>{i()}}):i()},fail:()=>{i()},complete:()=>{this.preloadingKeys&&o&&(this.preloadingKeys[o]=!1)}})}))},preloadWorks(t){Array.isArray(t)&&0!==t.length&&e.index.getNetworkType({success:e=>{e&&"wifi"===e.networkType&&t.forEach((e=>{e&&e.contentUrl&&this.enqueuePreload(e.contentUrl)}))},fail:()=>{}})},getWorkTypeLabel:e=>({VOICE_CLONE:"声音克隆",PHOTO_REVIVAL:"照片复活",VIDEO_CALL:"视频对话"}[e]||"作品"),toggleLike(t){const o=e.index.getStorageSync("token")||"",i=e.index.getStorageSync("userId")||"";i?e.index.request({url:`${this.API_BASE}/api/works/${t.id}/like`,method:"POST",header:{"X-User-Id":i,Authorization:o?`Bearer ${o}`:""},success:o=>{var i;if(200===o.statusCode&&o.data&&o.data.success&&o.data.data)return t.liked=!!o.data.data.liked,void(t.likeCount=o.data.data.likeCount||0);e.index.showToast({title:(null==(i=o.data)?void 0:i.message)||"操作失败",icon:"none"})},fail:()=>{e.index.showToast({title:"操作失败",icon:"none"})}}):e.index.showToast({title:"请先登录",icon:"none"})},formatTime(e){if(!e)return"";const t=new Date(e);if(Number.isNaN(t.getTime()))return String(e);const o=e=>e<10?`0${e}`:`${e}`;return`${t.getFullYear()}-${o(t.getMonth()+1)}-${o(t.getDate())} ${o(t.getHours())}:${o(t.getMinutes())}:${o(t.getSeconds())}`},loadMore(){!this.loading&&this.hasMore&&this.loadWorks(!1)},loadWorks(o){if(this.loading)return;this.loading=!0;const i=e.index.getStorageSync("token")||"",a=e.index.getStorageSync("userId")||"";o&&(this.page=0,this.hasMore=!0,this.hasCachedWorks||(this.works=[])),e.index.request({url:`${this.API_BASE}${t.API_ENDPOINTS.works.plaza}?page=${this.page}&size=${this.size}`,method:"GET",header:{"X-User-Id":a,Authorization:i?`Bearer ${i}`:""},success:t=>{if(200===t.statusCode&&t.data){const a=(t.data.content||[]).map((e=>({...e,coverUrl:this.normalizeMediaUrl(e.coverUrl),contentUrl:this.normalizeMediaUrl(e.contentUrl),audioUrl:this.normalizeMediaUrl(e.audioUrl),workTypeLabel:this.getWorkTypeLabel(e.workType),likeCount:e.likeCount||0,liked:!!e.liked})));if(o){this.works=a,this.hasCachedWorks=!1;try{e.index.setStorageSync("plaza_works_cache_v1",a)}catch(i){}}else this.works=this.works.concat(a);return this.page+=1,this.hasMore=!t.data.last,void(this.loadedOnce=!0)}e.index.showToast({title:`加载失败(${t.statusCode})`,icon:"none"})},fail:()=>{e.index.showToast({title:"加载失败",icon:"none"})},complete:()=>{this.loading=!1}})},viewWork(t){if(!t||!t.contentUrl&&!t.editedVideoUrl&&!t.edited_video_url)return void e.index.showToast({title:"作品不可用",icon:"none"});const o=t.editedVideoUrl||t.edited_video_url||t.contentUrl;let i=`/pages/video-player/video-player?audioInVideo=1&url=${encodeURIComponent(o)}&title=${encodeURIComponent(t.title||"作品")}`;e.index.navigateTo({url:i})}}};const i=e._export_sfc(o,[["render",function(t,o,i,a,r,s){return e.e({a:r.loading&&0===r.works.length},r.loading&&0===r.works.length?{b:e.f(6,((e,t,o)=>({a:e})))}:r.loading||0!==r.works.length?{d:e.f(r.works,((t,o,i)=>e.e({a:t.coverUrl},t.coverUrl?{b:t.coverUrl}:{},{c:e.t(t.workTypeLabel),d:e.t(t.title),e:e.t(t.userNickname||"匿名"),f:e.t(s.formatTime(t.publishedAt||t.createdAt)),g:e.t(t.liked?"❤️":"🤍"),h:e.t(t.likeCount||0),i:t.liked?1:"",j:e.o((e=>s.toggleLike(t)),t.id),k:e.o((()=>{}),t.id),l:t.id,m:e.o((e=>s.viewWork(t)),t.id)})))}:{},{c:!r.loading&&0===r.works.length,e:r.loading&&r.works.length>0},(r.loading&&r.works.length,{}),{f:!r.hasMore&&r.works.length>0},(!r.hasMore&&r.works.length,{}),{g:e.o(((...e)=>s.loadMore&&s.loadMore(...e)))})}],["__scopeId","data-v-c0fcbd71"]]);wx.createPage(i);
+"use strict";const e=require("../../common/vendor.js"),t=require("../../config/api.js"),o={data:()=>({API_BASE:t.API_BASE,works:[],page:0,size:10,loading:!1,hasMore:!0,loadedOnce:!1,hasCachedWorks:!1,enableVideoPreload:!1,preloadQueue:[],activePreloads:0,maxConcurrentPreloads:2,preloadingKeys:{}}),onLoad(){try{const t=e.index.getStorageSync("plaza_works_cache_v1");Array.isArray(t)&&t.length>0&&(this.works=t,this.hasCachedWorks=!0,this.loadedOnce=!0)}catch(t){this.hasCachedWorks=!1}this.loadWorks(!0)},onShow(){this.loadedOnce&&0!==this.works.length||this.loadWorks(!0)},methods:{normalizeMediaUrl(e){return e?e.startsWith("/")?`${this.API_BASE}${e}`:e.startsWith("http://115.190.167.176:20002")?e.replace("http://115.190.167.176:20002",this.API_BASE):e:e},generateCacheKey(e){let t=0;for(let o=0;o0;){const e=this.preloadQueue.shift();this.activePreloads+=1,this.preloadVideoToCache(e.url,e.cacheKey).finally((()=>{this.activePreloads=Math.max(0,this.activePreloads-1),this.processPreloadQueue()}))}},preloadVideoToCache(t,o){return new Promise((i=>{e.index.downloadFile({url:t,timeout:6e4,success:a=>{200===a.statusCode?e.index.saveFile({tempFilePath:a.tempFilePath,success:a=>{const r=a.savedFilePath;e.index.setStorageSync(o,r);const s=e.index.getStorageSync("video_cache_info")||{};s[o]={path:r,url:t,time:Date.now()},e.index.setStorageSync("video_cache_info",s),i()},fail:()=>{i()}}):i()},fail:()=>{i()},complete:()=>{this.preloadingKeys&&o&&(this.preloadingKeys[o]=!1)}})}))},preloadWorks(t){Array.isArray(t)&&0!==t.length&&e.index.getNetworkType({success:e=>{e&&"wifi"===e.networkType&&t.forEach((e=>{e&&e.contentUrl&&this.enqueuePreload(e.contentUrl)}))},fail:()=>{}})},getWorkTypeLabel:e=>({VOICE_CLONE:"声音克隆",PHOTO_REVIVAL:"照片复活",VIDEO_CALL:"视频对话"}[e]||"作品"),toggleLike(t){const o=e.index.getStorageSync("token")||"",i=e.index.getStorageSync("userId")||"";i?e.index.request({url:`${this.API_BASE}/api/works/${t.id}/like`,method:"POST",header:{"X-User-Id":i,Authorization:o?`Bearer ${o}`:""},success:o=>{var i;if(200===o.statusCode&&o.data&&o.data.success&&o.data.data)return t.liked=!!o.data.data.liked,void(t.likeCount=o.data.data.likeCount||0);e.index.showToast({title:(null==(i=o.data)?void 0:i.message)||"操作失败",icon:"none"})},fail:()=>{e.index.showToast({title:"操作失败",icon:"none"})}}):e.index.showToast({title:"请先登录",icon:"none"})},formatTime(e){if(!e)return"";const t=new Date(e);if(Number.isNaN(t.getTime()))return String(e);const o=e=>e<10?`0${e}`:`${e}`;return`${t.getFullYear()}-${o(t.getMonth()+1)}-${o(t.getDate())} ${o(t.getHours())}:${o(t.getMinutes())}:${o(t.getSeconds())}`},loadMore(){!this.loading&&this.hasMore&&this.loadWorks(!1)},loadWorks(o){if(this.loading)return;this.loading=!0;const i=e.index.getStorageSync("token")||"",a=e.index.getStorageSync("userId")||"";o&&(this.page=0,this.hasMore=!0,this.hasCachedWorks||(this.works=[])),e.index.request({url:`${this.API_BASE}${t.API_ENDPOINTS.works.plaza}?page=${this.page}&size=${this.size}`,method:"GET",header:{"X-User-Id":a,Authorization:i?`Bearer ${i}`:""},success:t=>{if(200===t.statusCode&&t.data){const a=(t.data.content||[]).map((e=>({...e,coverUrl:this.normalizeMediaUrl(e.coverUrl),contentUrl:this.normalizeMediaUrl(e.contentUrl),audioUrl:this.normalizeMediaUrl(e.audioUrl),workTypeLabel:this.getWorkTypeLabel(e.workType),likeCount:e.likeCount||0,liked:!!e.liked})));if(o){this.works=a,this.hasCachedWorks=!1;try{e.index.setStorageSync("plaza_works_cache_v1",a)}catch(i){}}else this.works=this.works.concat(a);return this.page+=1,this.hasMore=!t.data.last,void(this.loadedOnce=!0)}e.index.showToast({title:`加载失败(${t.statusCode})`,icon:"none"})},fail:()=>{e.index.showToast({title:"加载失败",icon:"none"})},complete:()=>{this.loading=!1}})},viewWork(t){if(!t||!t.contentUrl&&!t.editedVideoUrl&&!t.edited_video_url)return void e.index.showToast({title:"作品不可用",icon:"none"});const o=t.editedVideoUrl||t.edited_video_url||t.contentUrl;let i=`/pages/video-player/video-player?audioInVideo=1&url=${encodeURIComponent(o)}&title=${encodeURIComponent(t.title||"作品")}`;e.index.navigateTo({url:i})}}};const i=e._export_sfc(o,[["render",function(t,o,i,a,r,s){return e.e({a:r.loading&&0===r.works.length},r.loading&&0===r.works.length?{b:e.f(6,((e,t,o)=>({a:e})))}:r.loading||0!==r.works.length?{d:e.f(r.works,((t,o,i)=>e.e({a:t.coverUrl},t.coverUrl?{b:t.coverUrl}:{},{c:e.t(t.workTypeLabel),d:e.t(t.title),e:e.t(t.userNickname||"匿名"),f:e.t(s.formatTime(t.publishedAt||t.createdAt)),g:e.t(t.liked?"❤️":"🤍"),h:e.t(t.likeCount||0),i:t.liked?1:"",j:e.o((e=>s.toggleLike(t)),t.id),k:e.o((()=>{}),t.id),l:t.id,m:e.o((e=>s.viewWork(t)),t.id)})))}:{},{c:!r.loading&&0===r.works.length,e:r.loading&&r.works.length>0},(r.loading&&r.works.length,{}),{f:!r.hasMore&&r.works.length>0},(!r.hasMore&&r.works.length,{}),{g:e.o(((...e)=>s.loadMore&&s.loadMore(...e)))})}],["__scopeId","data-v-2b48ee52"]]);wx.createPage(i);
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/plaza/plaza.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/plaza/plaza.wxml
index de33a87..945d269 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/plaza/plaza.wxml
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/plaza/plaza.wxml
@@ -1 +1 @@
-🖼️暂无作品快去发布你的第一个作品吧🎬{{work.c}}{{work.d}}{{work.e}}{{work.f}}{{work.g}}{{work.h}}⏳ 加载更多...没有更多了
\ No newline at end of file
+🖼️暂无作品快去发布你的第一个作品吧🎬{{work.c}}AI生成{{work.d}}{{work.e}}{{work.f}}{{work.g}}{{work.h}}⏳ 加载更多...没有更多了
\ No newline at end of file
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/plaza/plaza.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/plaza/plaza.wxss
index 46afb71..8dfa0d8 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/plaza/plaza.wxss
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/plaza/plaza.wxss
@@ -1 +1 @@
-.plaza-container.data-v-c0fcbd71{min-height:100vh;background:#fdf8f2;display:flex;flex-direction:column}.header.data-v-c0fcbd71{padding:32rpx 32rpx 20rpx 40rpx}.header .title.data-v-c0fcbd71{font-size:44rpx;font-weight:700;color:#8b7355;display:block;margin-bottom:8rpx}.header .subtitle.data-v-c0fcbd71{font-size:24rpx;color:#999;display:block}.works-list.data-v-c0fcbd71{flex:1;padding:0 24rpx 40rpx;box-sizing:border-box}.loading-box.data-v-c0fcbd71,.empty-box.data-v-c0fcbd71{padding:200rpx 40rpx;text-align:center;display:flex;flex-direction:column;align-items:center}.loading-text.data-v-c0fcbd71{font-size:28rpx;color:#999}.empty-icon.data-v-c0fcbd71{font-size:120rpx;margin-bottom:30rpx;opacity:.5}.empty-text.data-v-c0fcbd71{font-size:32rpx;color:#666;margin-bottom:16rpx}.empty-hint.data-v-c0fcbd71{font-size:26rpx;color:#999}.works-grid.data-v-c0fcbd71{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16rpx}.skeleton-grid.data-v-c0fcbd71{padding-top:16rpx}.skeleton-card.data-v-c0fcbd71{background:#fff}.skeleton-cover.data-v-c0fcbd71{position:relative;width:100%;padding-top:150%;background:#f1f1f1}.skeleton-line.data-v-c0fcbd71{height:22rpx;background:#f1f1f1;border-radius:10rpx;margin-top:12rpx}.skeleton-title.data-v-c0fcbd71{height:26rpx;margin-top:0}.skeleton-sub.data-v-c0fcbd71{height:20rpx}.skeleton-sub.short.data-v-c0fcbd71{width:60%}.work-card.data-v-c0fcbd71{background:#fff;border-radius:16rpx;overflow:hidden;box-shadow:0 4rpx 12rpx rgba(0,0,0,.06);transition:all .3s}.work-card.data-v-c0fcbd71:active{transform:translateY(-4rpx);box-shadow:0 8rpx 20rpx rgba(0,0,0,.12)}.work-cover.data-v-c0fcbd71{position:relative;width:100%;padding-top:150%;overflow:hidden;background:#f5f5f5}.work-cover .cover-img.data-v-c0fcbd71{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:cover}.work-cover .cover-placeholder.data-v-c0fcbd71{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center}.work-cover .placeholder-icon.data-v-c0fcbd71{font-size:60rpx;color:#ccc}.work-cover .work-type.data-v-c0fcbd71{position:absolute;top:12rpx;right:12rpx;padding:6rpx 16rpx;background:rgba(0,0,0,.6);color:#fff;font-size:20rpx;border-radius:20rpx}.work-info.data-v-c0fcbd71{padding:20rpx}.work-info .work-title.data-v-c0fcbd71{display:block;font-size:28rpx;font-weight:700;color:#333;margin-bottom:12rpx;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.work-info .work-author.data-v-c0fcbd71{display:block;font-size:22rpx;color:#666;margin-bottom:10rpx;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.work-info .work-time.data-v-c0fcbd71{display:block;font-size:22rpx;color:#999}.work-actions.data-v-c0fcbd71{margin-top:14rpx;display:flex;justify-content:flex-end}.like-btn.data-v-c0fcbd71{display:flex;align-items:center;gap:10rpx;padding:10rpx 16rpx;border-radius:999rpx;background:rgba(139,115,85,.08)}.like-btn.liked.data-v-c0fcbd71{background:rgba(220,60,90,.1)}.like-icon.data-v-c0fcbd71{font-size:26rpx}.like-count.data-v-c0fcbd71{font-size:22rpx;color:#666}.loading-more-text.data-v-c0fcbd71,.no-more-text.data-v-c0fcbd71{font-size:24rpx;color:#999}
+.plaza-container.data-v-2b48ee52{min-height:100vh;background:#fdf8f2;display:flex;flex-direction:column}.header.data-v-2b48ee52{padding:32rpx 32rpx 20rpx 40rpx}.header .title.data-v-2b48ee52{font-size:44rpx;font-weight:700;color:#8b7355;display:block;margin-bottom:8rpx}.header .subtitle.data-v-2b48ee52{font-size:24rpx;color:#999;display:block}.works-list.data-v-2b48ee52{flex:1;padding:0 24rpx 40rpx;box-sizing:border-box}.loading-box.data-v-2b48ee52,.empty-box.data-v-2b48ee52{padding:200rpx 40rpx;text-align:center;display:flex;flex-direction:column;align-items:center}.loading-text.data-v-2b48ee52{font-size:28rpx;color:#999}.empty-icon.data-v-2b48ee52{font-size:120rpx;margin-bottom:30rpx;opacity:.5}.empty-text.data-v-2b48ee52{font-size:32rpx;color:#666;margin-bottom:16rpx}.empty-hint.data-v-2b48ee52{font-size:26rpx;color:#999}.works-grid.data-v-2b48ee52{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16rpx}.skeleton-grid.data-v-2b48ee52{padding-top:16rpx}.skeleton-card.data-v-2b48ee52{background:#fff}.skeleton-cover.data-v-2b48ee52{position:relative;width:100%;padding-top:150%;background:#f1f1f1}.skeleton-line.data-v-2b48ee52{height:22rpx;background:#f1f1f1;border-radius:10rpx;margin-top:12rpx}.skeleton-title.data-v-2b48ee52{height:26rpx;margin-top:0}.skeleton-sub.data-v-2b48ee52{height:20rpx}.skeleton-sub.short.data-v-2b48ee52{width:60%}.work-card.data-v-2b48ee52{background:#fff;border-radius:16rpx;overflow:hidden;box-shadow:0 4rpx 12rpx rgba(0,0,0,.06);transition:all .3s}.work-card.data-v-2b48ee52:active{transform:translateY(-4rpx);box-shadow:0 8rpx 20rpx rgba(0,0,0,.12)}.work-cover.data-v-2b48ee52{position:relative;width:100%;padding-top:150%;overflow:hidden;background:#f5f5f5}.work-cover .cover-img.data-v-2b48ee52{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:cover}.work-cover .cover-placeholder.data-v-2b48ee52{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center}.work-cover .placeholder-icon.data-v-2b48ee52{font-size:60rpx;color:#ccc}.work-cover .work-type.data-v-2b48ee52{position:absolute;top:12rpx;right:12rpx;padding:6rpx 16rpx;background:rgba(0,0,0,.6);color:#fff;font-size:20rpx;border-radius:20rpx}.work-cover .ai-tag.data-v-2b48ee52{position:absolute;top:12rpx;left:12rpx;padding:6rpx 16rpx;background:rgba(255,165,0,.85);color:#fff;font-size:20rpx;border-radius:20rpx;font-weight:500}.work-info.data-v-2b48ee52{padding:20rpx}.work-info .work-title.data-v-2b48ee52{display:block;font-size:28rpx;font-weight:700;color:#333;margin-bottom:12rpx;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.work-info .work-author.data-v-2b48ee52{display:block;font-size:22rpx;color:#666;margin-bottom:10rpx;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.work-info .work-time.data-v-2b48ee52{display:block;font-size:22rpx;color:#999}.work-actions.data-v-2b48ee52{margin-top:14rpx;display:flex;justify-content:flex-end}.like-btn.data-v-2b48ee52{display:flex;align-items:center;gap:10rpx;padding:10rpx 16rpx;border-radius:999rpx;background:rgba(139,115,85,.08)}.like-btn.liked.data-v-2b48ee52{background:rgba(220,60,90,.1)}.like-icon.data-v-2b48ee52{font-size:26rpx}.like-count.data-v-2b48ee52{font-size:22rpx;color:#666}.loading-more-text.data-v-2b48ee52,.no-more-text.data-v-2b48ee52{font-size:24rpx;color:#999}
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-history.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-history.js
index ab25067..64600d2 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-history.js
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-history.js
@@ -1 +1 @@
-"use strict";const e=require("../../common/vendor.js"),i=require("../../config/api.js"),o={data:()=>({API_BASE:i.API_BASE,videos:[],loading:!1,enablePrecache:!1,precacheQueue:[],precaching:!1,precacheInFlight:{},publishDialogVisible:!1,publishTitle:"",publishTargetVideo:null,shareTargetVideo:null}),onLoad(){this.loadVideos()},onShareAppMessage(){const e=this.shareTargetVideo||{},i=e&&(e.name||"").trim()?e.name:"我的视频",o=e&&e.photo_url?e.photo_url:void 0,t=e&&(e.edited_video_url||e.local_video_path||e.video_url)?String(e.edited_video_url||e.local_video_path||e.video_url):"";return{title:i,path:"/pages/video-player/video-player?audioInVideo=1&url="+encodeURIComponent(t)+"&title="+encodeURIComponent(i),imageUrl:o}},onShareTimeline(){const e=this.shareTargetVideo||{},i=e&&(e.name||"").trim()?e.name:"我的视频",o=e&&e.photo_url?e.photo_url:void 0,t=e&&(e.edited_video_url||e.local_video_path||e.video_url)?String(e.edited_video_url||e.local_video_path||e.video_url):"";return{title:i,query:"url="+encodeURIComponent(t)+"&title="+encodeURIComponent(i),imageUrl:o}},methods:{normalizeMediaUrl(e){return e?e.startsWith("/")?`${this.API_BASE}${e}`:e.startsWith("http://115.190.167.176:20002")?e.replace("http://115.190.167.176:20002",this.API_BASE):e:e},ensureLoginOrRedirect(){const i=e.index.getStorageSync("token")||"",o=e.index.getStorageSync("userId")||"";return!(!i||!o)||(e.index.showToast({title:"请先登录",icon:"none"}),setTimeout((()=>{e.index.navigateTo({url:"/pages/login/login"})}),800),!1)},isVideoPublishable(e){if(!e)return!1;return!!(e.edited_video_url||e.local_video_path||e.video_url||e.videoUrl||e.localVideoPath)},openPublishDialog(e){this.publishTargetVideo=e,this.publishTitle=e&&e.name?e.name:"复活视频",this.publishDialogVisible=!0},closePublishDialog(){this.publishDialogVisible=!1,this.publishTitle="",this.publishTargetVideo=null},confirmPublish(){const i=this.publishTargetVideo;if(!i)return void this.closePublishDialog();const o=(this.publishTitle||"").trim();o?o.length>20?e.index.showToast({title:"标题不能超过20字",icon:"none"}):(this.closePublishDialog(),this.publishVideo(i,o)):e.index.showToast({title:"请输入标题",icon:"none"})},publishVideo(i,o){const t=e.index.getStorageSync("token")||"",s=e.index.getStorageSync("userId")||"";t&&s?(e.index.showLoading({title:"发布中..."}),e.index.request({url:`${this.API_BASE}/api/works/publish/revival-video`,method:"POST",header:{"Content-Type":"application/json","X-User-Id":s,Authorization:t?`Bearer ${t}`:""},data:{userId:Number(s),revivalVideoId:i.id,title:o},success:o=>{var t;200===o.statusCode&&o.data&&o.data.success?(i.published=!0,i.workId=o.data.data&&o.data.data.id,e.index.showToast({title:"发布成功",icon:"success"})):e.index.showToast({title:(null==(t=o.data)?void 0:t.message)||"发布失败",icon:"none"})},fail:()=>{e.index.showToast({title:"发布失败",icon:"none"})},complete:()=>{e.index.hideLoading()}})):e.index.showToast({title:"请先登录",icon:"none"})},loadVideos(){if(!this.ensureLoginOrRedirect())return this.loading=!1,void(this.videos=[]);this.loading=!0;const i=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.request({url:`${this.API_BASE}/api/photo-revival/videos`,method:"GET",header:{"X-User-Id":i,Authorization:o?`Bearer ${o}`:""},success:e=>{console.log("[RevivalHistory] API响应:",e.data),console.log("[RevivalHistory] 用户ID:",i),e.data.success&&(this.videos=(e.data.videos||[]).map((e=>({...e,photo_url:this.normalizeMediaUrl(e&&e.photo_url?String(e.photo_url):""),video_url:this.normalizeMediaUrl(e&&e.video_url?String(e.video_url):""),edited_video_url:this.normalizeMediaUrl(e&&e.edited_video_url?String(e.edited_video_url):""),local_video_path:this.normalizeMediaUrl(e&&e.local_video_path?String(e.local_video_path):""),audio_url:this.normalizeMediaUrl(e&&e.audio_url?String(e.audio_url):""),published:!1,workId:null}))),console.log("[RevivalHistory] 加载视频数量:",this.videos.length),this.checkVideosCache(),this.loadPublishStatus())},fail:i=>{console.error("[RevivalHistory] 加载失败:",i),e.index.showToast({title:"加载失败",icon:"none"})},complete:()=>{this.loading=!1}})},loadPublishStatus(){const i=e.index.getStorageSync("token")||"",o=e.index.getStorageSync("userId")||"";this.videos.forEach((t=>{e.index.request({url:`${this.API_BASE}/api/works/source?sourceType=REVIVAL_VIDEO&sourceId=${t.id}`,method:"GET",header:{"X-User-Id":o,Authorization:i?`Bearer ${i}`:""},success:e=>{200===e.statusCode&&e.data&&(t.published=1===e.data.published,t.workId=e.data.id)}})}))},togglePublish(i){const o=e.index.getStorageSync("token")||"",t=e.index.getStorageSync("userId")||"";o&&t?i.published?e.index.showModal({title:"取消发布",content:"确定要从作品广场下架该作品吗?",success:s=>{s.confirm&&(e.index.showLoading({title:"处理中..."}),e.index.request({url:`${this.API_BASE}/api/works/unpublish?workId=${i.workId}&userId=${t}`,method:"POST",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},success:o=>{var t;200===o.statusCode&&o.data&&o.data.success?(i.published=!1,e.index.showToast({title:"已取消发布",icon:"success"})):e.index.showToast({title:(null==(t=o.data)?void 0:t.message)||"操作失败",icon:"none"})},fail:()=>{e.index.showToast({title:"操作失败",icon:"none"})},complete:()=>{e.index.hideLoading()}}))}}):this.openPublishDialog(i):e.index.showToast({title:"请先登录",icon:"none"})},checkVideosCache(){let i=0;this.videos.forEach((o=>{const t=o.edited_video_url||o.local_video_path||o.video_url;if(t){const s=this.normalizeMediaUrl(t),a=this.generateCacheKey(s),n=e.index.getStorageSync(a);o.isCached=!!n,this.enablePrecache&&!o.isCached&&"undefined"!=typeof plus&&i<3&&(i++,this.enqueuePrecache(s))}}))},enqueuePrecache(e){e&&(this.precacheInFlight[e]||-1===this.precacheQueue.indexOf(e)&&(this.precacheQueue.push(e),this.processPrecacheQueue()))},async processPrecacheQueue(){if(!this.precaching&&this.precacheQueue.length){this.precaching=!0;try{for(;this.precacheQueue.length;){const i=this.precacheQueue.shift();if(i&&!this.precacheInFlight[i]){this.precacheInFlight[i]=!0;try{await this.precacheVideoApp(i)}catch(e){}finally{delete this.precacheInFlight[i]}}}}finally{this.precaching=!1}}},precacheVideoApp(i){return new Promise(((o,t)=>{if("undefined"==typeof plus)return void o();const s=this.generateCacheKey(i);e.index.getStorageSync(s)?o():e.index.downloadFile({url:i,success:a=>{200===a.statusCode?e.index.saveFile({tempFilePath:a.tempFilePath,success:t=>{const a=t.savedFilePath;e.index.setStorageSync(s,a);const n=e.index.getStorageSync("video_cache_info")||{};n[s]={path:a,url:i,time:Date.now()},e.index.setStorageSync("video_cache_info",n),o(a)},fail:e=>{t(e)}}):t(new Error("download failed"))},fail:e=>{t(e)}})}))},generateCacheKey(e){let i=0;for(let o=0;o{console.log("[RevivalHistory] 跳转成功")},fail:i=>{console.error("[RevivalHistory] 跳转失败:",i),e.index.showToast({title:"跳转失败: "+i.errMsg,icon:"none"})}})},playVideo(i){const o=i&&i.local_video_path?String(i.local_video_path):"",t=i.edited_video_url||i.local_video_path||i.video_url,s=t?String(t):"";if(i.edited_video_url||-1!==o.indexOf("/static/videos/revival_")||s.indexOf("/static/videos/revival_"),!t)return void e.index.showToast({title:"视频地址不存在",icon:"none"});let a=`/pages/video-player/video-player?audioInVideo=1&url=${encodeURIComponent(t)}&title=${encodeURIComponent(i.name||"复活视频")}`;e.index.navigateTo({url:a,fail:i=>{console.error("[RevivalHistory] 跳转失败:",i),e.index.showToast({title:"播放失败,请稍后重试",icon:"none"})}})},prepareShare(e){this.shareTargetVideo=e||null},shareVideo(i){console.log("[RevivalHistory] 分享视频:",i);i.edited_video_url||i.local_video_path||i.video_url?e.index.showActionSheet({itemList:["保存到相册","复制链接"],success:e=>{0===e.tapIndex?this.saveVideoToAlbum(i):1===e.tapIndex&&this.copyVideoLink(i)}}):e.index.showToast({title:"视频地址不存在",icon:"none"})},async copyVideoLink(i){const o=i.edited_video_url||i.local_video_path||i.video_url;o?e.index.setClipboardData({data:o,success:()=>{e.index.showToast({title:"链接已复制",icon:"success"})}}):e.index.showToast({title:"视频地址不存在",icon:"none"})},async saveVideoToAlbum(e){const i=e.edited_video_url||e.local_video_path||e.video_url;console.log("[RevivalHistory] 保存视频:",i),this.saveVideoOnly(i)},saveVideoOnly(i){e.index.showLoading({title:"保存中..."}),i.startsWith("file://")||i.startsWith("wxfile://")?e.index.saveVideoToPhotosAlbum({filePath:i,success:()=>{e.index.hideLoading(),e.index.showToast({title:"保存成功",icon:"success"})},fail:i=>{e.index.hideLoading(),console.error("[RevivalHistory] 保存失败:",i),i.errMsg.includes("auth")?e.index.showModal({title:"需要授权",content:"请授权保存到相册",success:i=>{i.confirm&&e.index.openSetting()}}):e.index.showToast({title:"保存失败",icon:"none"})}}):e.index.downloadFile({url:i,success:i=>{200===i.statusCode?e.index.saveVideoToPhotosAlbum({filePath:i.tempFilePath,success:()=>{e.index.hideLoading(),e.index.showToast({title:"保存成功",icon:"success"})},fail:i=>{e.index.hideLoading(),console.error("[RevivalHistory] 保存失败:",i),i.errMsg.includes("auth")?e.index.showModal({title:"需要授权",content:"请授权保存到相册",success:i=>{i.confirm&&e.index.openSetting()}}):e.index.showToast({title:"保存失败",icon:"none"})}}):(e.index.hideLoading(),e.index.showToast({title:"下载失败",icon:"none"}))},fail:i=>{e.index.hideLoading(),console.error("[RevivalHistory] 下载失败:",i),e.index.showToast({title:"下载失败",icon:"none"})}})},async deleteVideo(o){e.index.showModal({title:"确认删除",content:`确定要删除视频"${o.name||"复活视频"}"吗?`,success:t=>{if(t.confirm){const t=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";e.index.request({url:`${i.API_BASE}/api/photo-revival/videos/${o.id}`,method:"DELETE",header:{"X-User-Id":t,Authorization:s?`Bearer ${s}`:""},success:i=>{var o;200===i.statusCode&&i.data&&i.data.success?(e.index.showToast({title:"删除成功",icon:"success"}),this.loadVideos()):e.index.showToast({title:(null==(o=i.data)?void 0:o.message)||"删除失败",icon:"none"})},fail:i=>{e.index.showToast({title:"删除失败,请重试",icon:"none"})}})}}})},formatTime(e){if(!e)return"";const i=new Date(e);return`${i.getFullYear()}-${String(i.getMonth()+1).padStart(2,"0")}-${String(i.getDate()).padStart(2,"0")} ${String(i.getHours()).padStart(2,"0")}:${String(i.getMinutes()).padStart(2,"0")}`},formatDuration(e){if(!e)return"";return`${Math.floor(e/60)}:${String(e%60).padStart(2,"0")}`}}};const t=e._export_sfc(o,[["render",function(i,o,t,s,a,n){return e.e({a:e.t(a.videos.length),b:a.loading},a.loading||0===a.videos.length?{}:{d:e.f(a.videos,((i,o,t)=>e.e({a:i.photo_url},i.photo_url?{b:i.photo_url}:{},{c:i.isCached},(i.isCached,{}),{d:e.t(i.name||"复活视频"),e:i.text},i.text?{f:e.t(i.text)}:{},{g:e.t(n.formatTime(i.create_time)),h:e.o((e=>n.viewVideo(i)),i.id),i:e.o((e=>n.saveVideoToAlbum(i)),i.id),j:e.o((e=>n.prepareShare(i)),i.id),k:n.isVideoPublishable(i)},n.isVideoPublishable(i)?{l:e.t(i.published?"↩️":"📢"),m:e.t(i.published?"下架":"发布"),n:e.o((e=>n.togglePublish(i)),i.id)}:{},{o:e.o((e=>n.deleteVideo(i)),i.id),p:i.id,q:e.o((e=>n.viewVideo(i)),i.id)})))},{c:0===a.videos.length,e:a.publishDialogVisible},a.publishDialogVisible?{f:a.publishTitle,g:e.o((e=>a.publishTitle=e.detail.value)),h:e.o(((...e)=>n.closePublishDialog&&n.closePublishDialog(...e))),i:e.o(((...e)=>n.confirmPublish&&n.confirmPublish(...e))),j:e.o((()=>{})),k:e.o(((...e)=>n.closePublishDialog&&n.closePublishDialog(...e)))}:{})}],["__scopeId","data-v-a9bdd541"]]);o.__runtimeHooks=6,wx.createPage(t);
+"use strict";const e=require("../../common/vendor.js"),i=require("../../config/api.js"),o={data:()=>({API_BASE:i.API_BASE,videos:[],loading:!1,enablePrecache:!1,precacheQueue:[],precaching:!1,precacheInFlight:{},publishDialogVisible:!1,publishTitle:"",publishTargetVideo:null,shareTargetVideo:null}),onLoad(){this.loadVideos()},onShareAppMessage(){const e=this.shareTargetVideo||{},i=e&&(e.name||"").trim()?e.name:"我的视频",o=e&&e.photo_url?e.photo_url:void 0,t=e&&(e.edited_video_url||e.local_video_path||e.video_url)?String(e.edited_video_url||e.local_video_path||e.video_url):"";return{title:i,path:"/pages/video-player/video-player?audioInVideo=1&url="+encodeURIComponent(t)+"&title="+encodeURIComponent(i),imageUrl:o}},onShareTimeline(){const e=this.shareTargetVideo||{},i=e&&(e.name||"").trim()?e.name:"我的视频",o=e&&e.photo_url?e.photo_url:void 0,t=e&&(e.edited_video_url||e.local_video_path||e.video_url)?String(e.edited_video_url||e.local_video_path||e.video_url):"";return{title:i,query:"url="+encodeURIComponent(t)+"&title="+encodeURIComponent(i),imageUrl:o}},methods:{normalizeMediaUrl(e){return e?e.startsWith("/")?`${this.API_BASE}${e}`:e.startsWith("http://115.190.167.176:20002")?e.replace("http://115.190.167.176:20002",this.API_BASE):e:e},ensureLoginOrRedirect(){const i=e.index.getStorageSync("token")||"",o=e.index.getStorageSync("userId")||"";return!(!i||!o)||(e.index.showToast({title:"请先登录",icon:"none"}),setTimeout((()=>{e.index.navigateTo({url:"/pages/login/login"})}),800),!1)},isVideoPublishable(e){if(!e)return!1;return!!(e.edited_video_url||e.local_video_path||e.video_url||e.videoUrl||e.localVideoPath)},openPublishDialog(e){this.publishTargetVideo=e,this.publishTitle=e&&e.name?e.name:"复活视频",this.publishDialogVisible=!0},closePublishDialog(){this.publishDialogVisible=!1,this.publishTitle="",this.publishTargetVideo=null},confirmPublish(){const i=this.publishTargetVideo;if(!i)return void this.closePublishDialog();const o=(this.publishTitle||"").trim();o?o.length>20?e.index.showToast({title:"标题不能超过20字",icon:"none"}):(this.closePublishDialog(),this.publishVideo(i,o)):e.index.showToast({title:"请输入标题",icon:"none"})},publishVideo(i,o){const t=e.index.getStorageSync("token")||"",s=e.index.getStorageSync("userId")||"";t&&s?(e.index.showLoading({title:"发布中..."}),e.index.request({url:`${this.API_BASE}/api/works/publish/revival-video`,method:"POST",header:{"Content-Type":"application/json","X-User-Id":s,Authorization:t?`Bearer ${t}`:""},data:{userId:Number(s),revivalVideoId:i.id,title:o},success:o=>{var t;200===o.statusCode&&o.data&&o.data.success?(i.published=!0,i.workId=o.data.data&&o.data.data.id,e.index.showToast({title:"发布成功",icon:"success"})):e.index.showToast({title:(null==(t=o.data)?void 0:t.message)||"发布失败",icon:"none"})},fail:()=>{e.index.showToast({title:"发布失败",icon:"none"})},complete:()=>{e.index.hideLoading()}})):e.index.showToast({title:"请先登录",icon:"none"})},loadVideos(){if(!this.ensureLoginOrRedirect())return this.loading=!1,void(this.videos=[]);this.loading=!0;const i=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.request({url:`${this.API_BASE}/api/photo-revival/videos`,method:"GET",header:{"X-User-Id":i,Authorization:o?`Bearer ${o}`:""},success:e=>{console.log("[RevivalHistory] API响应:",e.data),console.log("[RevivalHistory] 用户ID:",i),e.data.success&&(this.videos=(e.data.videos||[]).map((e=>({...e,photo_url:this.normalizeMediaUrl(e&&e.photo_url?String(e.photo_url):""),video_url:this.normalizeMediaUrl(e&&e.video_url?String(e.video_url):""),edited_video_url:this.normalizeMediaUrl(e&&e.edited_video_url?String(e.edited_video_url):""),local_video_path:this.normalizeMediaUrl(e&&e.local_video_path?String(e.local_video_path):""),audio_url:this.normalizeMediaUrl(e&&e.audio_url?String(e.audio_url):""),published:!1,workId:null}))),console.log("[RevivalHistory] 加载视频数量:",this.videos.length),this.checkVideosCache(),this.loadPublishStatus())},fail:i=>{console.error("[RevivalHistory] 加载失败:",i),e.index.showToast({title:"加载失败",icon:"none"})},complete:()=>{this.loading=!1}})},loadPublishStatus(){const i=e.index.getStorageSync("token")||"",o=e.index.getStorageSync("userId")||"";this.videos.forEach((t=>{e.index.request({url:`${this.API_BASE}/api/works/source?sourceType=REVIVAL_VIDEO&sourceId=${t.id}`,method:"GET",header:{"X-User-Id":o,Authorization:i?`Bearer ${i}`:""},success:e=>{200===e.statusCode&&e.data&&(t.published=1===e.data.published,t.workId=e.data.id)}})}))},togglePublish(i){const o=e.index.getStorageSync("token")||"",t=e.index.getStorageSync("userId")||"";o&&t?i.published?e.index.showModal({title:"取消发布",content:"确定要从作品广场下架该作品吗?",success:s=>{s.confirm&&(e.index.showLoading({title:"处理中..."}),e.index.request({url:`${this.API_BASE}/api/works/unpublish?workId=${i.workId}&userId=${t}`,method:"POST",header:{"X-User-Id":t,Authorization:o?`Bearer ${o}`:""},success:o=>{var t;200===o.statusCode&&o.data&&o.data.success?(i.published=!1,e.index.showToast({title:"已取消发布",icon:"success"})):e.index.showToast({title:(null==(t=o.data)?void 0:t.message)||"操作失败",icon:"none"})},fail:()=>{e.index.showToast({title:"操作失败",icon:"none"})},complete:()=>{e.index.hideLoading()}}))}}):this.openPublishDialog(i):e.index.showToast({title:"请先登录",icon:"none"})},checkVideosCache(){let i=0;this.videos.forEach((o=>{const t=o.edited_video_url||o.local_video_path||o.video_url;if(t){const s=this.normalizeMediaUrl(t),a=this.generateCacheKey(s),n=e.index.getStorageSync(a);o.isCached=!!n,this.enablePrecache&&!o.isCached&&"undefined"!=typeof plus&&i<3&&(i++,this.enqueuePrecache(s))}}))},enqueuePrecache(e){e&&(this.precacheInFlight[e]||-1===this.precacheQueue.indexOf(e)&&(this.precacheQueue.push(e),this.processPrecacheQueue()))},async processPrecacheQueue(){if(!this.precaching&&this.precacheQueue.length){this.precaching=!0;try{for(;this.precacheQueue.length;){const i=this.precacheQueue.shift();if(i&&!this.precacheInFlight[i]){this.precacheInFlight[i]=!0;try{await this.precacheVideoApp(i)}catch(e){}finally{delete this.precacheInFlight[i]}}}}finally{this.precaching=!1}}},precacheVideoApp(i){return new Promise(((o,t)=>{if("undefined"==typeof plus)return void o();const s=this.generateCacheKey(i);e.index.getStorageSync(s)?o():e.index.downloadFile({url:i,success:a=>{200===a.statusCode?e.index.saveFile({tempFilePath:a.tempFilePath,success:t=>{const a=t.savedFilePath;e.index.setStorageSync(s,a);const n=e.index.getStorageSync("video_cache_info")||{};n[s]={path:a,url:i,time:Date.now()},e.index.setStorageSync("video_cache_info",n),o(a)},fail:e=>{t(e)}}):t(new Error("download failed"))},fail:e=>{t(e)}})}))},generateCacheKey(e){let i=0;for(let o=0;o{console.log("[RevivalHistory] 跳转成功")},fail:i=>{console.error("[RevivalHistory] 跳转失败:",i),e.index.showToast({title:"跳转失败: "+i.errMsg,icon:"none"})}})},playVideo(i){const o=i&&i.local_video_path?String(i.local_video_path):"",t=i.edited_video_url||i.local_video_path||i.video_url,s=t?String(t):"";if(i.edited_video_url||-1!==o.indexOf("/static/videos/revival_")||s.indexOf("/static/videos/revival_"),!t)return void e.index.showToast({title:"视频地址不存在",icon:"none"});let a=`/pages/video-player/video-player?audioInVideo=1&url=${encodeURIComponent(t)}&title=${encodeURIComponent(i.name||"复活视频")}`;e.index.navigateTo({url:a,fail:i=>{console.error("[RevivalHistory] 跳转失败:",i),e.index.showToast({title:"播放失败,请稍后重试",icon:"none"})}})},prepareShare(e){this.shareTargetVideo=e||null},shareVideo(i){console.log("[RevivalHistory] 分享视频:",i);i.edited_video_url||i.local_video_path||i.video_url?e.index.showActionSheet({itemList:["保存到相册","复制链接"],success:e=>{0===e.tapIndex?this.saveVideoToAlbum(i):1===e.tapIndex&&this.copyVideoLink(i)}}):e.index.showToast({title:"视频地址不存在",icon:"none"})},async copyVideoLink(i){const o=i.edited_video_url||i.local_video_path||i.video_url;o?e.index.setClipboardData({data:o,success:()=>{e.index.showToast({title:"链接已复制",icon:"success"})}}):e.index.showToast({title:"视频地址不存在",icon:"none"})},async saveVideoToAlbum(e){const i=e.edited_video_url||e.local_video_path||e.video_url;console.log("[RevivalHistory] 保存视频:",i),this.saveVideoOnly(i)},saveVideoOnly(i){e.index.showLoading({title:"保存中..."}),i.startsWith("file://")||i.startsWith("wxfile://")?e.index.saveVideoToPhotosAlbum({filePath:i,success:()=>{e.index.hideLoading(),e.index.showToast({title:"保存成功",icon:"success"})},fail:i=>{e.index.hideLoading(),console.error("[RevivalHistory] 保存失败:",i),i.errMsg.includes("auth")?e.index.showModal({title:"需要授权",content:"请授权保存到相册",success:i=>{i.confirm&&e.index.openSetting()}}):e.index.showToast({title:"保存失败",icon:"none"})}}):e.index.downloadFile({url:i,success:i=>{200===i.statusCode?e.index.saveVideoToPhotosAlbum({filePath:i.tempFilePath,success:()=>{e.index.hideLoading(),e.index.showToast({title:"保存成功",icon:"success"})},fail:i=>{e.index.hideLoading(),console.error("[RevivalHistory] 保存失败:",i),i.errMsg.includes("auth")?e.index.showModal({title:"需要授权",content:"请授权保存到相册",success:i=>{i.confirm&&e.index.openSetting()}}):e.index.showToast({title:"保存失败",icon:"none"})}}):(e.index.hideLoading(),e.index.showToast({title:"下载失败",icon:"none"}))},fail:i=>{e.index.hideLoading(),console.error("[RevivalHistory] 下载失败:",i),e.index.showToast({title:"下载失败",icon:"none"})}})},async deleteVideo(o){e.index.showModal({title:"确认删除",content:`确定要删除视频"${o.name||"复活视频"}"吗?`,success:t=>{if(t.confirm){const t=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";e.index.request({url:`${i.API_BASE}/api/photo-revival/videos/${o.id}`,method:"DELETE",header:{"X-User-Id":t,Authorization:s?`Bearer ${s}`:""},success:i=>{var o;200===i.statusCode&&i.data&&i.data.success?(e.index.showToast({title:"删除成功",icon:"success"}),this.loadVideos()):e.index.showToast({title:(null==(o=i.data)?void 0:o.message)||"删除失败",icon:"none"})},fail:i=>{e.index.showToast({title:"删除失败,请重试",icon:"none"})}})}}})},formatTime(e){if(!e)return"";const i=new Date(e);return`${i.getFullYear()}-${String(i.getMonth()+1).padStart(2,"0")}-${String(i.getDate()).padStart(2,"0")} ${String(i.getHours()).padStart(2,"0")}:${String(i.getMinutes()).padStart(2,"0")}`},formatDuration(e){if(!e)return"";return`${Math.floor(e/60)}:${String(e%60).padStart(2,"0")}`}}};const t=e._export_sfc(o,[["render",function(i,o,t,s,a,n){return e.e({a:e.t(a.videos.length),b:a.loading},a.loading||0===a.videos.length?{}:{d:e.f(a.videos,((i,o,t)=>e.e({a:i.photo_url},i.photo_url?{b:i.photo_url}:{},{c:i.isCached},(i.isCached,{}),{d:e.t(i.name||"复活视频"),e:i.text},i.text?{f:e.t(i.text)}:{},{g:e.t(n.formatTime(i.create_time)),h:e.o((e=>n.viewVideo(i)),i.id),i:e.o((e=>n.saveVideoToAlbum(i)),i.id),j:e.o((e=>n.prepareShare(i)),i.id),k:n.isVideoPublishable(i)},n.isVideoPublishable(i)?{l:e.t(i.published?"↩️":"📢"),m:e.t(i.published?"下架":"发布"),n:e.o((e=>n.togglePublish(i)),i.id)}:{},{o:e.o((e=>n.deleteVideo(i)),i.id),p:i.id,q:e.o((e=>n.viewVideo(i)),i.id)})))},{c:0===a.videos.length,e:a.publishDialogVisible},a.publishDialogVisible?{f:a.publishTitle,g:e.o((e=>a.publishTitle=e.detail.value)),h:e.o(((...e)=>n.closePublishDialog&&n.closePublishDialog(...e))),i:e.o(((...e)=>n.confirmPublish&&n.confirmPublish(...e))),j:e.o((()=>{})),k:e.o(((...e)=>n.closePublishDialog&&n.closePublishDialog(...e)))}:{})}],["__scopeId","data-v-29c0c228"]]);o.__runtimeHooks=6,wx.createPage(t);
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-history.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-history.wxml
index 0a14ffd..a5e8316 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-history.wxml
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-history.wxml
@@ -1 +1 @@
-⏳ 加载中...📹暂无复活视频快去复活你的第一张照片吧📹▶已缓存{{video.d}}{{video.f}}{{video.g}}▶️播放💾保存{{video.l}}{{video.m}}🗑️删除发布作品取消发布
\ No newline at end of file
+⏳ 加载中...📹暂无复活视频快去复活你的第一张照片吧📹▶已缓存AI生成{{video.d}}{{video.f}}{{video.g}}▶️播放💾保存{{video.l}}{{video.m}}🗑️删除发布作品取消发布
\ No newline at end of file
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-history.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-history.wxss
index 5a6c85e..b3cc4f7 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-history.wxss
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-history.wxss
@@ -1 +1 @@
-.history-container.data-v-a9bdd541{min-height:100vh;background:linear-gradient(180deg,#fdf8f2,#f5ede3);display:flex;flex-direction:column}.header.data-v-a9bdd541{padding:48rpx 32rpx 32rpx 40rpx;background:transparent}.header .title.data-v-a9bdd541{font-size:52rpx;font-weight:700;color:#8b7355;display:block;margin-bottom:12rpx;letter-spacing:3rpx;text-shadow:0 2rpx 4rpx rgba(139,115,85,.1)}.header .subtitle.data-v-a9bdd541{font-size:26rpx;color:#b8a898;display:inline-block;background:rgba(139,115,85,.08);padding:6rpx 16rpx;border-radius:20rpx}.video-list.data-v-a9bdd541{flex:1;padding:0 24rpx;box-sizing:border-box}.loading-box.data-v-a9bdd541{display:flex;flex-direction:column;justify-content:center;align-items:center;padding:160rpx 0}.loading-text.data-v-a9bdd541{font-size:28rpx;color:#8b7355;margin-top:16rpx}.empty-box.data-v-a9bdd541{display:flex;flex-direction:column;align-items:center;padding:180rpx 40rpx}.empty-icon.data-v-a9bdd541{font-size:140rpx;margin-bottom:40rpx;filter:grayscale(20%)}.empty-text.data-v-a9bdd541{font-size:34rpx;color:#8b7355;margin-bottom:16rpx;font-weight:600}.empty-hint.data-v-a9bdd541{font-size:26rpx;color:#b8a898;text-align:center;line-height:1.6;background:rgba(139,115,85,.06);padding:16rpx 32rpx;border-radius:24rpx}.video-grid.data-v-a9bdd541{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20rpx;padding:0 0 40rpx;box-sizing:border-box}.video-card.data-v-a9bdd541{background:#fff;border-radius:28rpx;overflow:hidden;box-shadow:0 8rpx 32rpx rgba(139,115,85,.12);transition:all .3s cubic-bezier(.4,0,.2,1);width:100%;box-sizing:border-box;border:1rpx solid rgba(139,115,85,.08)}.video-card.data-v-a9bdd541:active{transform:translateY(-6rpx) scale(1.01);box-shadow:0 16rpx 40rpx rgba(139,115,85,.2)}.video-cover.data-v-a9bdd541{position:relative;width:100%;padding-top:150%;overflow:hidden;background:linear-gradient(135deg,#f8f4f0,#ede6dd)}.cover-image.data-v-a9bdd541{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:cover;transition:transform .3s ease}.video-card:active .cover-image.data-v-a9bdd541{transform:scale(1.02)}.play-overlay.data-v-a9bdd541{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:88rpx;height:88rpx;background:rgba(255,255,255,.95);border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 8rpx 24rpx rgba(0,0,0,.2)}.play-icon.data-v-a9bdd541{font-size:36rpx;color:#8b7355;padding-left:6rpx}.cover-placeholder.data-v-a9bdd541{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center}.placeholder-icon.data-v-a9bdd541{font-size:60rpx;color:#ccc}.video-duration.data-v-a9bdd541{position:absolute;bottom:8rpx;right:8rpx;background:rgba(0,0,0,.7);color:#fff;padding:4rpx 10rpx;border-radius:6rpx;font-size:20rpx}.cache-badge.data-v-a9bdd541{position:absolute;top:12rpx;right:12rpx;background:linear-gradient(135deg,#8b7355,#a68b5b);padding:6rpx 12rpx;border-radius:20rpx;box-shadow:0 2rpx 8rpx rgba(139,115,85,.4)}.cache-text.data-v-a9bdd541{color:#fff;font-size:18rpx;font-weight:500}.video-info.data-v-a9bdd541{padding:20rpx 16rpx 16rpx;background:linear-gradient(180deg,#fff,#fdfbf9)}.video-title.data-v-a9bdd541{font-size:28rpx;font-weight:600;color:#5a4a3a;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;text-overflow:ellipsis;margin-bottom:8rpx;line-height:1.4}.video-text.data-v-a9bdd541{font-size:22rpx;color:#999;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;overflow:hidden;text-overflow:ellipsis;margin-bottom:8rpx}.video-meta.data-v-a9bdd541{display:flex;justify-content:space-between;align-items:center;gap:8rpx}.video-time.data-v-a9bdd541{font-size:20rpx;color:#b8a898;background:rgba(139,115,85,.06);padding:4rpx 10rpx;border-radius:8rpx}.video-status.data-v-a9bdd541{font-size:20rpx;color:#8b7355;background:rgba(139,115,85,.1);padding:2rpx 8rpx;border-radius:6rpx}.video-actions.data-v-a9bdd541{display:flex;border-top:1rpx solid rgba(139,115,85,.1);background:#fdfbf9}.action-btn.data-v-a9bdd541{flex:1;padding:14rpx 4rpx;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6rpx;border-right:1rpx solid rgba(139,115,85,.1);transition:all .2s ease;background:transparent;border:none;border-radius:0;line-height:normal}.action-btn.data-v-a9bdd541:after{border:none}.action-btn.data-v-a9bdd541:last-child{border-right:none}.action-btn.data-v-a9bdd541:active{background:rgba(139,115,85,.08);transform:scale(.96)}.action-btn.delete.data-v-a9bdd541:active{background:rgba(220,80,80,.08)}.action-btn.share.data-v-a9bdd541:active{background:rgba(139,115,85,.1)}.action-btn.publish.data-v-a9bdd541:active{background:rgba(100,180,100,.1)}.action-icon.data-v-a9bdd541{font-size:26rpx}.action-text.data-v-a9bdd541{font-size:18rpx;color:#8b7355;font-weight:500}.publish-mask.data-v-a9bdd541{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:60rpx;z-index:9999}.publish-dialog.data-v-a9bdd541{width:100%;max-width:650rpx;background:#fff;border-radius:28rpx;padding:36rpx;box-shadow:0 20rpx 60rpx rgba(0,0,0,.2)}.publish-title.data-v-a9bdd541{font-size:32rpx;font-weight:700;color:#333;margin-bottom:24rpx}.publish-input.data-v-a9bdd541{width:100%;background:#f7f2ea;border-radius:20rpx;min-height:96rpx;padding:28rpx;font-size:30rpx;color:#333;box-sizing:border-box}.publish-actions.data-v-a9bdd541{display:flex;gap:20rpx;margin-top:28rpx}.publish-btn.data-v-a9bdd541{flex:1;text-align:center;padding:22rpx 0;border-radius:22rpx;font-size:28rpx;font-weight:600}.publish-btn.cancel.data-v-a9bdd541{background:#f0f0f0;color:#333}.publish-btn.confirm.data-v-a9bdd541{background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff}
+.history-container.data-v-29c0c228{min-height:100vh;background:linear-gradient(180deg,#fdf8f2,#f5ede3);display:flex;flex-direction:column}.header.data-v-29c0c228{padding:48rpx 32rpx 32rpx 40rpx;background:transparent}.header .title.data-v-29c0c228{font-size:52rpx;font-weight:700;color:#8b7355;display:block;margin-bottom:12rpx;letter-spacing:3rpx;text-shadow:0 2rpx 4rpx rgba(139,115,85,.1)}.header .subtitle.data-v-29c0c228{font-size:26rpx;color:#b8a898;display:inline-block;background:rgba(139,115,85,.08);padding:6rpx 16rpx;border-radius:20rpx}.video-list.data-v-29c0c228{flex:1;padding:0 24rpx;box-sizing:border-box}.loading-box.data-v-29c0c228{display:flex;flex-direction:column;justify-content:center;align-items:center;padding:160rpx 0}.loading-text.data-v-29c0c228{font-size:28rpx;color:#8b7355;margin-top:16rpx}.empty-box.data-v-29c0c228{display:flex;flex-direction:column;align-items:center;padding:180rpx 40rpx}.empty-icon.data-v-29c0c228{font-size:140rpx;margin-bottom:40rpx;filter:grayscale(20%)}.empty-text.data-v-29c0c228{font-size:34rpx;color:#8b7355;margin-bottom:16rpx;font-weight:600}.empty-hint.data-v-29c0c228{font-size:26rpx;color:#b8a898;text-align:center;line-height:1.6;background:rgba(139,115,85,.06);padding:16rpx 32rpx;border-radius:24rpx}.video-grid.data-v-29c0c228{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20rpx;padding:0 0 40rpx;box-sizing:border-box}.video-card.data-v-29c0c228{background:#fff;border-radius:28rpx;overflow:hidden;box-shadow:0 8rpx 32rpx rgba(139,115,85,.12);transition:all .3s cubic-bezier(.4,0,.2,1);width:100%;box-sizing:border-box;border:1rpx solid rgba(139,115,85,.08)}.video-card.data-v-29c0c228:active{transform:translateY(-6rpx) scale(1.01);box-shadow:0 16rpx 40rpx rgba(139,115,85,.2)}.video-cover.data-v-29c0c228{position:relative;width:100%;padding-top:150%;overflow:hidden;background:linear-gradient(135deg,#f8f4f0,#ede6dd)}.cover-image.data-v-29c0c228{position:absolute;top:0;left:0;width:100%;height:100%;object-fit:cover;transition:transform .3s ease}.video-card:active .cover-image.data-v-29c0c228{transform:scale(1.02)}.play-overlay.data-v-29c0c228{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:88rpx;height:88rpx;background:rgba(255,255,255,.95);border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 8rpx 24rpx rgba(0,0,0,.2)}.play-icon.data-v-29c0c228{font-size:36rpx;color:#8b7355;padding-left:6rpx}.cover-placeholder.data-v-29c0c228{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center}.placeholder-icon.data-v-29c0c228{font-size:60rpx;color:#ccc}.video-duration.data-v-29c0c228{position:absolute;bottom:8rpx;right:8rpx;background:rgba(0,0,0,.7);color:#fff;padding:4rpx 10rpx;border-radius:6rpx;font-size:20rpx}.cache-badge.data-v-29c0c228{position:absolute;top:12rpx;right:12rpx;background:linear-gradient(135deg,#8b7355,#a68b5b);padding:6rpx 12rpx;border-radius:20rpx;box-shadow:0 2rpx 8rpx rgba(139,115,85,.4)}.cache-text.data-v-29c0c228{color:#fff;font-size:18rpx;font-weight:500}.ai-tag.data-v-29c0c228{position:absolute;top:12rpx;left:12rpx;padding:6rpx 16rpx;background:rgba(255,165,0,.85);color:#fff;font-size:20rpx;border-radius:20rpx;font-weight:500;z-index:10}.ai-tag-text.data-v-29c0c228{font-size:20rpx;font-weight:500}.video-info.data-v-29c0c228{padding:20rpx 16rpx 16rpx;background:linear-gradient(180deg,#fff,#fdfbf9)}.video-title.data-v-29c0c228{font-size:28rpx;font-weight:600;color:#5a4a3a;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;text-overflow:ellipsis;margin-bottom:8rpx;line-height:1.4}.video-text.data-v-29c0c228{font-size:22rpx;color:#999;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;overflow:hidden;text-overflow:ellipsis;margin-bottom:8rpx}.video-meta.data-v-29c0c228{display:flex;justify-content:space-between;align-items:center;gap:8rpx}.video-time.data-v-29c0c228{font-size:20rpx;color:#b8a898;background:rgba(139,115,85,.06);padding:4rpx 10rpx;border-radius:8rpx}.video-status.data-v-29c0c228{font-size:20rpx;color:#8b7355;background:rgba(139,115,85,.1);padding:2rpx 8rpx;border-radius:6rpx}.video-actions.data-v-29c0c228{display:flex;border-top:1rpx solid rgba(139,115,85,.1);background:#fdfbf9}.action-btn.data-v-29c0c228{flex:1;padding:14rpx 4rpx;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6rpx;border-right:1rpx solid rgba(139,115,85,.1);transition:all .2s ease;background:transparent;border:none;border-radius:0;line-height:normal}.action-btn.data-v-29c0c228:after{border:none}.action-btn.data-v-29c0c228:last-child{border-right:none}.action-btn.data-v-29c0c228:active{background:rgba(139,115,85,.08);transform:scale(.96)}.action-btn.delete.data-v-29c0c228:active{background:rgba(220,80,80,.08)}.action-btn.share.data-v-29c0c228:active{background:rgba(139,115,85,.1)}.action-btn.publish.data-v-29c0c228:active{background:rgba(100,180,100,.1)}.action-icon.data-v-29c0c228{font-size:26rpx}.action-text.data-v-29c0c228{font-size:18rpx;color:#8b7355;font-weight:500}.publish-mask.data-v-29c0c228{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:60rpx;z-index:9999}.publish-dialog.data-v-29c0c228{width:100%;max-width:650rpx;background:#fff;border-radius:28rpx;padding:36rpx;box-shadow:0 20rpx 60rpx rgba(0,0,0,.2)}.publish-title.data-v-29c0c228{font-size:32rpx;font-weight:700;color:#333;margin-bottom:24rpx}.publish-input.data-v-29c0c228{width:100%;background:#f7f2ea;border-radius:20rpx;min-height:96rpx;padding:28rpx;font-size:30rpx;color:#333;box-sizing:border-box}.publish-actions.data-v-29c0c228{display:flex;gap:20rpx;margin-top:28rpx}.publish-btn.data-v-29c0c228{flex:1;text-align:center;padding:22rpx 0;border-radius:22rpx;font-size:28rpx;font-weight:600}.publish-btn.cancel.data-v-29c0c228{background:#f0f0f0;color:#333}.publish-btn.confirm.data-v-29c0c228{background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff}
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-original.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-original.js
index bd114f8..4f2c874 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-original.js
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-original.js
@@ -1 +1 @@
-"use strict";const e=require("../../common/vendor.js"),o=require("../../config/api.js"),t=require("../../utils/payment.js"),i={components:{PaymentModal:()=>"../../components/PaymentModal.js"},data:()=>({API_BASE:o.API_BASE,photoFile:null,photoPreview:"",modelOptions:[{value:"veo",label:"Veo",hint:"需要音色,生成说话人视频",disabled:!1,maintenanceMsg:""},{value:"volcengine",label:"火山引擎",hint:"需要音色,生成说话人视频",disabled:!1,maintenanceMsg:""}],selectedModel:"veo",selectedModelName:"Veo",modelHint:"需要音色,生成说话人视频",voices:[],voiceTypeOptions:[{value:"CLONE",label:"克隆音色"},{value:"OFFICIAL",label:"官方音色(Flash)"}],selectedVoiceType:"CLONE",selectedVoiceTypeLabel:"克隆音色",selectedVoiceId:"",selectedVoiceName:"",selectedDialect:"",selectedLanguageHint:"",selectedLanguageHintLabel:"",selectedSupportsDialect:!1,selectedSupportsLanguageHints:!1,languageHintOptions:["中文(zh)","英文(en)","法语(fr)","德语(de)","日语(ja)","韩语(ko)","俄语(ru)"],dialectOptions:["广东话","东北话","甘肃话","贵州话","河南话","湖北话","江西话","闽南话","宁夏话","山西话","陕西话","山东话","上海话","四川话","天津话","云南话"],videoTitle:"",text:"",showHelpModal:!1,loading:!1,loadingText:"",progress:[],videoUrl:"",audioUrl:"",localVideoPath:"",localAudioPath:"",isPlaying:!1,videoRetried:!1,paymentModalData:{show:!1,serviceType:"",serviceName:"",serviceDesc:"",price:0,orderNo:"",paymentTips:"点击确认支付后将开始生成视频"},_paymentResolve:null,_paymentReject:null,_paymentOnSuccess:null,_paymentOnFailed:null}),computed:{displayVoices(){const e=(this.voices||[]).filter((e=>e&&(e.voice_type||"CLONE")===this.selectedVoiceType));if("OFFICIAL"!==(this.selectedVoiceType||"CLONE"))return e;const o={"湾区大叔":"台湾","台湾小何":"台湾","双节棍小哥":"台湾","广州德哥":"广州","浩宇小哥":"大陆"};return e.map((e=>{const t=e&&e.voice_name?String(e.voice_name):"",i=t&&o[t]?o[t]:"";return i?{...e,voice_name:`${i}-${t}`}:e}))},canGenerate(){const e=this.modelOptions.find((e=>e.value===this.selectedModel));return(!e||!e.disabled)&&(this.photoFile&&this.videoTitle&&this.text&&this.selectedVoiceId)}},onLoad(){this.loadVoices(),this.loadModelStatus()},methods:{onVoiceTypeChange(e){const o=this.voiceTypeOptions[e.detail.value];this.selectedVoiceType=o?o.value:"CLONE",this.selectedVoiceTypeLabel=o?o.label:"克隆音色",this.selectedVoiceId="",this.selectedVoiceName="",this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",this.selectedSupportsDialect=!1,this.selectedSupportsLanguageHints=!1},showVoiceHelp(){this.showHelpModal=!0},goToUpload(){this.showHelpModal=!1,e.index.navigateTo({url:"/pages/upload-audio/upload-audio"})},getCurrentModelMaintenanceMsg(){const e=this.modelOptions.find((e=>e.value===this.selectedModel));return e&&e.disabled?e.maintenanceMsg:""},onModelChange(e){const o=e.detail.value,t=this.modelOptions[o];this.selectedModel=t.value,this.selectedModelName=t.label,this.modelHint=t.hint,console.log("[Revival] 选择模型:",this.selectedModel)},choosePhoto(){e.index.chooseImage({count:1,sizeType:["compressed"],sourceType:["album","camera"],success:e=>{this.photoFile={path:e.tempFilePaths[0],name:"photo.jpg"},this.photoPreview=e.tempFilePaths[0]},fail:o=>{e.index.showToast({title:"选择照片失败",icon:"none"})}})},chooseAudio(){},chooseAudioFileFromSystem(){},copyContentUriToLocalForAudio(e,o){},async startRecordAudio(){},loadModelStatus(){console.log("[Revival] 开始加载模型状态..."),e.index.request({url:`${this.API_BASE}/api/system/model-status`,method:"GET",success:e=>{if(console.log("[Revival] 模型状态响应:",e),200===e.statusCode&&e.data&&e.data.success){const o=e.data.data;if("true"===o.veo_disabled){const e=this.modelOptions.find((e=>"veo"===e.value));e&&(e.disabled=!0,e.maintenanceMsg=o.veo_message||"官方接口参数更新,正在处理中,暂不可用")}if("true"===o.volcengine_disabled){const e=this.modelOptions.find((e=>"volcengine"===e.value));e&&(e.disabled=!0,e.maintenanceMsg=o.volcengine_message||"官方接口参数更新,正在处理中,暂不可用")}console.log("[Revival] 模型状态已更新:",this.modelOptions)}},fail:e=>{console.error("[Revival] 加载模型状态失败:",e)}})},loadVoices(){console.log("[Revival] 开始加载音色列表..."),console.log("[Revival] API地址:",`${this.API_BASE}/api/voice/list`);const o=e.index.getStorageSync("userId")||"",t=e.index.getStorageSync("token")||"";console.log("[Revival] 用户ID:",o),e.index.request({url:`${this.API_BASE}/api/voice/list`,method:"GET",header:{"X-User-Id":o,Authorization:t?`Bearer ${t}`:""},success:o=>{if(console.log("[Revival] API响应状态码:",o.statusCode),console.log("[Revival] API响应数据:",o.data),200===o.statusCode)if(o.data&&o.data.voices){const t=["Cherry","Kai","Mochi","Bunny"];this.voices=(o.data.voices||[]).filter((e=>!(e&&e.voice&&t.includes(e.voice)))),console.log("[Revival] 音色列表:",this.voices),console.log("[Revival] 音色数量:",this.voices.length),this.voices.length>0?(this.selectedVoiceId=this.voices[0].voice,this.selectedVoiceName=this.voices[0].voice_name||this.voices[0].voice,this.selectedDialect="",console.log("[Revival] 默认选中音色:",this.selectedVoiceId)):(console.log("[Revival] 音色列表为空"),e.index.showToast({title:"暂无可用音色,请先创建",icon:"none"}))}else console.error("[Revival] 响应数据格式错误:",o.data),this.voices=[];else console.error("[Revival] 请求失败,状态码:",o.statusCode)},fail:o=>{console.error("[Revival] 加载音色列表失败:",o),e.index.showToast({title:"加载音色列表失败",icon:"none"})}})},onVoiceChange(e){const o=this.displayVoices[e.detail.value];this.selectedVoiceId=o.voice,this.selectedVoiceName=o.voice_name||o.voice,this.selectedVoiceType=o.voice_type||this.selectedVoiceType||"CLONE",this.selectedVoiceTypeLabel="OFFICIAL"===this.selectedVoiceType?"官方音色(Flash)":"克隆音色",this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",this.selectedSupportsDialect=!!o.supportsDialect,this.selectedSupportsLanguageHints=!!o.supportsLanguageHints,"OFFICIAL"===(this.selectedVoiceType||"CLONE")&&(this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",this.selectedSupportsDialect=!1,this.selectedSupportsLanguageHints=!1)},onDialectChange(e){this.selectedDialect=this.dialectOptions[e.detail.value]||""},onLanguageHintChange(e){const o=this.languageHintOptions[e.detail.value]||"";this.selectedLanguageHintLabel=o;const t=o.match(/\(([^)]+)\)/);this.selectedLanguageHint=t&&t[1]?t[1]:""},async handleGenerate(){const i=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";if(!i)return void e.index.showModal({title:"提示",content:"请先登录后再继续",confirmText:"去登录",cancelText:"取消",success:o=>{o.confirm&&e.index.navigateTo({url:"/pages/login/login"})}});const a="volcengine"===this.selectedModel?"VOLCENGINE_VIDEO":"PHOTO_REVIVAL",n="volcengine"===this.selectedModel?t.SERVICE_TYPES.VOLCENGINE_VIDEO.type:t.SERVICE_TYPES.PHOTO_REVIVAL.type;let l=null;try{l=await new Promise(((t,n)=>{e.index.request({url:`${o.API_BASE}/api/pay/usage-preview?serviceType=${a}`,method:"GET",header:{"X-User-Id":i,Authorization:s?`Bearer ${s}`:""},success:e=>{200===e.statusCode&&e.data&&e.data.success?t(e.data):n(new Error(e.data&&e.data.message?e.data.message:"预检失败: HTTP "+e.statusCode))},fail:e=>n(new Error(e&&e.errMsg?e.errMsg:"预检失败"))})}))}catch(d){return void e.index.showModal({title:"检查次数失败",content:d&&d.message?d.message:"检查剩余次数失败,请稍后重试",showCancel:!1,confirmText:"我知道了"})}(l&&"number"==typeof l.remainingTotalCount?l.remainingTotalCount:0)<=0?t.showPaymentModal(this,n,(()=>{this.executeGenerate()}),(e=>{console.error("[Payment] 支付失败:",e)})):this.executeGenerate()},async executeGenerate(){this.loading=!0,this.progress=[],this.videoUrl="",this.audioUrl="";try{"volcengine"===this.selectedModel?await this.generateWithVolcengine():await this.generateWithExistingVoice()}catch(o){o.message.includes("响应超时")||o.message.includes("历史记录")?(this.addProgress("⚠️ "+o.message,"warning"),e.index.showModal({title:"提示",content:o.message,showCancel:!0,cancelText:"知道了",confirmText:"查看历史",success:o=>{o.confirm&&e.index.navigateTo({url:"/pages/revival/revival-history"})}})):(this.addProgress("生成失败: "+o.message,"error"),e.index.showModal({title:"生成失败",content:(o.message||"生成失败")+"\n\n你可以点击“重试”再次生成。\n若已支付但多次生成失败,请联系客服补发(提供订单号/支付时间截图)。",confirmText:"重试",cancelText:"我知道了",success:e=>{e.confirm&&this.executeGenerate()}}))}finally{this.loading=!1}},async generateWithVolcengine(){return new Promise(((o,i)=>{this.addProgress("📤 正在上传照片...","loading"),e.index.showModal({title:"🎬 视频生成中",content:"火山引擎视频生成通常需要1-3分钟。\n\n您可以最小化APP做其他事情,生成完成后会弹出提示。\n\n请保持网络连接稳定。",showCancel:!1,confirmText:"我知道了"}),setTimeout((()=>{this.addProgress("🎬 正在生成视频(通常1-3分钟)...","loading")}),2e3);const s=e.index.getStorageSync("userId")||"",a=e.index.getStorageSync("token")||"";console.log("[Revival-Volcengine] 准备上传照片:",this.photoFile),console.log("[Revival-Volcengine] 用户ID:",s),console.log("[Revival-Volcengine] API地址:",`${this.API_BASE}/api/photo-revival/volcengine-video`),e.index.uploadFile({url:`${this.API_BASE}/api/photo-revival/volcengine-video`,filePath:this.photoFile.path,name:"photo",timeout:36e5,header:{"X-User-Id":s,Authorization:a?`Bearer ${a}`:""},formData:(()=>{const e={voiceId:this.selectedVoiceId,voiceType:this.selectedVoiceType,text:this.text,duration:8,name:this.videoTitle};return this.selectedSupportsDialect&&this.selectedDialect&&(e.dialect=this.selectedDialect),this.selectedSupportsLanguageHints&&this.selectedLanguageHint&&(e.languageHints=this.selectedLanguageHint),e})(),success:s=>{console.log("[Revival-Volcengine] 上传响应:",s);let a=null;try{a=JSON.parse(s.data)}catch(l){a=null}if(402===s.statusCode)return console.warn("[Revival-Volcengine] HTTP 402:次数不足,需要付费"),this.addProgress("⚠️ 次数不足,请先付费","warning"),e.index.showModal({title:"需要付费",content:a&&a.message?a.message:"次数不足,请先完成支付后再生成",confirmText:"去支付",cancelText:"取消",success:o=>{o.confirm&&t.showPaymentModal(this,t.SERVICE_TYPES.PHOTO_REVIVAL.type,(()=>{e.index.showToast({title:"支付成功,请重新点击生成",icon:"none"})}),(()=>{}))}}),void i(new Error(a&&a.message?a.message:"次数不足,请先付费"));if(504===s.statusCode)return console.warn("[Revival-Volcengine] HTTP 504:请求超时,但后端可能仍在生成中"),setTimeout((()=>{e.index.showModal({title:"⏰ 响应超时",content:"网络响应超时(HTTP 504),但视频可能仍在后台生成中。\n\n是否立即查看历史记录?",confirmText:"查看历史",cancelText:"稍后查看",success:o=>{o.confirm&&e.index.navigateTo({url:"/pages/revival/revival-history"})}})}),800),this.addProgress("⏳ 网络响应超时(HTTP 504),视频可能仍在后台生成中,请稍后到历史记录查看","loading"),void o();if(200===s.statusCode){if(a&&"success"===a.status)return this.addProgress("✅ 视频生成完成","done"),this.videoRetried=!1,e.index.showToast({title:"生成成功!",icon:"success"}),void o();const t=a&&a.message?a.message:"生成失败";return console.error("[Revival-Volcengine] 后端返回错误:",t),void i(new Error(t))}const n=a&&a.message?a.message:"上传失败: HTTP "+s.statusCode;i(new Error(n))},fail:o=>{console.error("[Revival-Volcengine] 上传响应超时:",o),setTimeout((()=>{e.index.showModal({title:"⏰ 响应超时",content:"网络响应超时,但视频可能已经生成成功。\n\n是否立即查看历史记录?",confirmText:"查看历史",cancelText:"稍后查看",success:o=>{o.confirm&&e.index.navigateTo({url:"/pages/revival/revival-history"})}})}),3e3),i(new Error("网络响应超时,视频可能正在生成中,请稍后在历史记录中查看"))}})}))},async generateWithNewVoice(){this.addProgress("正在创建音色...","loading")},generateWithExistingVoice(){return new Promise(((o,t)=>{this.addProgress("⏳ 正在上传照片...","loading"),e.index.showModal({title:"⏳ 视频生成中",content:"视频生成通常需要2-5分钟,高峰期可能需要10-30分钟。\n\n您可以最小化APP做其他事情,生成完成后会弹出提示。\n\n请保持网络连接稳定。",showCancel:!1,confirmText:"我知道了"}),setTimeout((()=>{this.addProgress("🎵 正在合成语音...","loading")}),2e3),setTimeout((()=>{this.addProgress("🎬 正在生成视频(通常2-5分钟,高峰期可能更久)...","loading")}),5e3);const i=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";console.log("[Revival] 准备上传照片:",this.photoFile),console.log("[Revival] 照片路径:",this.photoFile.path),console.log("[Revival] 用户ID:",i),console.log("[Revival] Token:",s?"已设置":"未设置"),console.log("[Revival] API地址:",`${this.API_BASE}/api/photo-revival/revive-quick`),i||(console.warn("[Revival] ⚠️ 警告:用户ID为空,视频可能无法正确保存到数据库"),e.index.showModal({title:"提示",content:"检测到您未登录,视频将无法保存到历史记录。是否继续?",success:e=>{e.confirm||t(new Error("用户取消操作"))}})),e.index.uploadFile({url:`${this.API_BASE}/api/photo-revival/revive-quick`,filePath:this.photoFile.path,name:"photo",timeout:36e5,header:{"X-User-Id":i,Authorization:s?`Bearer ${s}`:""},formData:(()=>{const e={voiceId:this.selectedVoiceId,voiceType:this.selectedVoiceType,text:this.text,name:this.videoTitle,serverUrl:this.API_BASE};return this.selectedSupportsDialect&&this.selectedDialect&&(e.dialect=this.selectedDialect),this.selectedSupportsLanguageHints&&this.selectedLanguageHint&&(e.languageHints=this.selectedLanguageHint),e})(),success:i=>{console.log("[Revival] 上传响应:",i);let s=null;try{s=JSON.parse(i.data)}catch(n){s=null}if(504===i.statusCode)return console.warn("[Revival] HTTP 504:请求超时,但后端可能仍在生成中"),setTimeout((()=>{e.index.showModal({title:"⏰ 响应超时",content:"网络响应超时(HTTP 504),但视频可能仍在后台生成中。\n\n是否立即查看历史记录?",confirmText:"查看历史",cancelText:"稍后查看",success:o=>{o.confirm&&e.index.navigateTo({url:"/pages/revival/revival-history"})}})}),800),this.addProgress("⏳ 网络响应超时(HTTP 504),视频可能仍在后台生成中,请稍后到历史记录查看","loading"),void o();if(200===i.statusCode){if(s&&"success"===s.status)return this.handleResult(s),void o();const e=s&&s.message?s.message:"生成失败";return console.error("[Revival] 后端返回错误:",e),void t(new Error(e))}const a=s&&s.message?s.message:"上传失败: HTTP "+i.statusCode;t(new Error(a))},fail:o=>{console.error("[Revival] 上传响应超时:",o),setTimeout((()=>{e.index.showModal({title:"⏰ 响应超时",content:"网络响应超时,但视频可能已经生成成功。\n\n是否立即查看历史记录?",confirmText:"查看历史",cancelText:"稍后查看",success:o=>{o.confirm&&e.index.navigateTo({url:"/pages/revival/revival-history"})}})}),3e3),t(new Error("网络响应超时,视频可能正在生成中,请稍后在历史记录中查看"))}})}))},async handleResult(o){if("success"!==o.status)throw new Error(o.message||"生成失败");"new"===this.mode&&this.addProgress("✅ 音色创建完成","done"),this.addProgress("✅ 语音合成完成","done"),this.addProgress("✅ 视频生成完成","done"),this.videoUrl=o.videoUrl,this.audioUrl=o.audioUrl,this.videoRetried=!1,this.saveToHistory(o),e.index.showModal({title:"🎉 生成成功!",content:'视频已生成完成!\n\n点击"查看视频"可以立即查看和播放视频。',cancelText:"稍后查看",confirmText:"查看视频",success:e=>{e.confirm&&this.scrollToResult()}}),"new"===this.mode&&this.loadVoices()},togglePlay(){this.isPlaying?this.pausePlayback():this.startPlayback()},startPlayback(){const o=e.index.createVideoContext("resultVideo",this),t=e.index.createInnerAudioContext();t.src=this.audioUrl,o.play(),t.play(),this.isPlaying=!0,this.audioContext=t},pausePlayback(){e.index.createVideoContext("resultVideo",this).pause(),this.audioContext&&this.audioContext.pause(),this.isPlaying=!1},onVideoPlay(){this.isPlaying=!0},onVideoPause(){this.isPlaying=!1,this.audioContext&&this.audioContext.pause()},onVideoEnded(){this.isPlaying=!1,this.audioContext&&this.audioContext.stop()},onVideoLoaded(e){console.log("[Revival] 视频加载成功:",e)},onVideoError(o){if(console.error("[Revival] 视频加载失败:",o),console.error("[Revival] 视频URL:",this.videoUrl),console.error("[Revival] 错误详情:",o.detail),!this.videoRetried)return console.log("[Revival] 尝试重新加载视频..."),this.videoRetried=!0,void setTimeout((()=>{e.index.createVideoContext("resultVideo",this).stop();const o=this.videoUrl;this.videoUrl="",this.$nextTick((()=>{this.videoUrl=o+"?t="+Date.now()}))}),500);e.index.showModal({title:"视频加载失败",content:"无法播放视频,可能是网络或格式问题。\n\n您可以尝试:\n1. 检查网络连接\n2. 返回后重新进入播放\n3. 重新生成视频或稍后再试",showCancel:!1})},onVideoWaiting(e){console.log("[Revival] 视频缓冲中...",e)},onVideoTimeUpdate(e){},scrollToResult(){this.$nextTick((()=>{e.index.createSelectorQuery().in(this).select(".result-section").boundingClientRect((o=>{o&&e.index.pageScrollTo({scrollTop:o.top-100,duration:300})})).exec()}))},addProgress(e,o){this.progress.push({text:e,status:o}),this.loadingText=e},goToHistory(){e.index.navigateTo({url:"/pages/revival/revival-history"})},viewVideo(){if(console.log("[Revival] 准备播放视频"),console.log("[Revival] videoUrl:",this.videoUrl),console.log("[Revival] audioUrl:",this.audioUrl),!this.videoUrl)return void e.index.showToast({title:"视频地址不存在",icon:"none"});let o=`/pages/video-player/video-player?url=${encodeURIComponent(this.videoUrl)}&title=${encodeURIComponent("复活视频")}`;o+="&audioInVideo=1",console.log("[Revival] 跳转播放页:",o),e.index.navigateTo({url:o,success:()=>{console.log("[Revival] 跳转播放页面成功")},fail:o=>{console.error("[Revival] 跳转播放页面失败:",o),e.index.showToast({title:"跳转失败",icon:"none"})}})},handlePaymentClose(){this.paymentModalData.show=!1,this._paymentReject&&this._paymentReject(new Error("用户取消支付"))},async handlePaymentConfirm(e){await t.handlePaymentConfirm(this,e)},manualSaveToHistory(){if(!this.videoUrl)return void e.index.showToast({title:"没有可保存的记录",icon:"none"});const o={photoUrl:this.photoPreview,videoUrl:this.videoUrl,audioUrl:this.audioUrl,voiceId:this.selectedVoiceId};this.saveToHistory(o),e.index.showToast({title:"已保存到历史",icon:"success"})},async downloadVideoToLocal(o){try{console.log("[Revival] 开始下载视频到本地:",o);const t=await new Promise(((t,i)=>{e.index.downloadFile({url:o,success:e=>{200===e.statusCode?(console.log("[Revival] 视频下载成功:",e.tempFilePath),t(e.tempFilePath)):i(new Error("下载失败,状态码: "+e.statusCode))},fail:e=>{console.error("[Revival] 视频下载失败:",e),i(e)}})})),i=await this.saveFilePermanently(t,"video");this.localVideoPath=i,console.log("[Revival] 视频已保存到:",i)}catch(t){console.error("[Revival] 下载视频失败:",t),e.index.showToast({title:"视频下载失败,将使用在线播放",icon:"none"})}},saveFilePermanently:async(o,t)=>new Promise(((i,s)=>{const a=e.index.getFileSystemManager(),n=`${e.index.env.USER_DATA_PATH}/revival_${t}s/`,l=n+`${t}_${Date.now()}.${"video"===t?"mp4":"mp3"}`;a.mkdir({dirPath:n,recursive:!0,success:()=>{a.copyFile({srcPath:o,destPath:l,success:()=>{console.log(`[Revival] ${t}已保存到永久存储:`,l),i(l)},fail:e=>{console.error(`[Revival] 保存${t}失败:`,e),i(o)}})},fail:e=>{console.error("[Revival] 创建目录失败:",e),i(o)}})})),saveToHistory(o){try{console.log("[Revival] 开始保存历史记录"),console.log("[Revival] 结果数据:",o);let t=[];const i=e.index.getStorageSync("generation_history");i&&(t=JSON.parse(i));const s={type:"revival",timestamp:Date.now(),text:this.text,voiceId:"existing"===this.mode?this.selectedVoiceId:o.voiceId||this.selectedVoiceId,photoUrl:this.photoPreview,videoUrl:o.videoUrl,audioUrl:o.audioUrl};console.log("[Revival] 保存记录:",s),t.unshift(s),t.length>100&&(t=t.slice(0,100)),e.index.setStorageSync("generation_history",JSON.stringify(t)),console.log("[Revival] 已保存到历史记录,当前共",t.length,"条")}catch(t){console.error("[Revival] 保存历史记录失败:",t)}},downloadVideo(){e.index.showLoading({title:"正在保存..."}),e.index.downloadFile({url:this.videoUrl,success:o=>{200===o.statusCode?e.index.saveVideoToPhotosAlbum({filePath:o.tempFilePath,success:()=>{e.index.hideLoading(),e.index.showToast({title:"保存成功",icon:"success"})},fail:o=>{e.index.hideLoading(),e.index.showToast({title:"保存失败: "+o.errMsg,icon:"none"})}}):(e.index.hideLoading(),e.index.showToast({title:"下载失败",icon:"none"}))},fail:o=>{e.index.hideLoading(),e.index.showToast({title:"下载失败: "+o.errMsg,icon:"none"})}})},startVideoCall(){if(!this.videoUrl||!this.selectedVoiceId)return void e.index.showToast({title:"缺少必要信息",icon:"none"});const o="new"===this.mode?this.voiceName:"对方";e.index.navigateTo({url:`/pages/video-call/video-call?idleVideo=${encodeURIComponent(this.videoUrl)}&talkingVideo=${encodeURIComponent(this.videoUrl)}&voiceId=${this.selectedVoiceId}&callerName=${encodeURIComponent(o)}`})}}};if(!Array){e.resolveComponent("PaymentModal")()}const s=e._export_sfc(i,[["render",function(o,t,i,s,a,n){return e.e({a:e.o(((...e)=>n.goToHistory&&n.goToHistory(...e))),b:a.showHelpModal},a.showHelpModal?{c:e.o((e=>a.showHelpModal=!1)),d:`${a.API_BASE}/static/1.jpg`,e:`${a.API_BASE}/static/2.jpg`,f:e.o((e=>a.showHelpModal=!1)),g:e.o(((...e)=>n.goToUpload&&n.goToUpload(...e))),h:e.o((()=>{})),i:e.o((e=>a.showHelpModal=!1))}:{},{j:a.photoPreview,k:a.photoPreview,l:!a.photoPreview,m:e.o(((...e)=>n.choosePhoto&&n.choosePhoto(...e))),n:a.videoTitle,o:e.o((e=>a.videoTitle=e.detail.value)),p:e.t(a.videoTitle.length),q:e.t(a.selectedModelName||"请选择模型"),r:a.modelOptions,s:e.o(((...e)=>n.onModelChange&&n.onModelChange(...e))),t:n.getCurrentModelMaintenanceMsg()},n.getCurrentModelMaintenanceMsg()?{v:e.t(n.getCurrentModelMaintenanceMsg())}:{w:e.t(a.modelHint)},{x:e.o(((...e)=>n.showVoiceHelp&&n.showVoiceHelp(...e))),y:e.t(a.selectedVoiceTypeLabel),z:a.voiceTypeOptions,A:e.o(((...e)=>n.onVoiceTypeChange&&n.onVoiceTypeChange(...e))),B:e.t(a.selectedVoiceName||"请选择音色"),C:n.displayVoices,D:e.o(((...e)=>n.onVoiceChange&&n.onVoiceChange(...e))),E:a.selectedSupportsDialect&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")},a.selectedSupportsDialect&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")?{F:e.t(a.selectedDialect||"请选择方言(可选)"),G:a.dialectOptions,H:e.o(((...e)=>n.onDialectChange&&n.onDialectChange(...e)))}:{},{I:a.selectedSupportsLanguageHints&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")},a.selectedSupportsLanguageHints&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")?{J:e.t(a.selectedLanguageHintLabel||"请选择语言(可选)"),K:a.languageHintOptions,L:e.o(((...e)=>n.onLanguageHintChange&&n.onLanguageHintChange(...e)))}:{},{M:a.text,N:e.o((e=>a.text=e.detail.value)),O:e.t(a.text.length),P:a.loading},a.loading?{Q:e.t(a.loadingText)}:{},{R:a.loading||!n.canGenerate,S:e.o(((...e)=>n.handleGenerate&&n.handleGenerate(...e))),T:a.progress.length>0},a.progress.length>0?{U:e.f(a.progress,((o,t,i)=>({a:e.t("done"===o.status?"✅":"error"===o.status?"❌":"⏳"),b:e.n(o.status),c:e.t(o.text),d:t})))}:{},{V:a.videoUrl},a.videoUrl?{W:a.videoUrl,X:a.photoPreview,Y:e.o(((...e)=>n.onVideoPlay&&n.onVideoPlay(...e))),Z:e.o(((...e)=>n.onVideoPause&&n.onVideoPause(...e))),aa:e.o(((...e)=>n.onVideoEnded&&n.onVideoEnded(...e))),ab:e.o(((...e)=>n.onVideoError&&n.onVideoError(...e))),ac:e.o(((...e)=>n.onVideoLoaded&&n.onVideoLoaded(...e))),ad:e.o(((...e)=>n.onVideoWaiting&&n.onVideoWaiting(...e))),ae:e.o(((...e)=>n.onVideoTimeUpdate&&n.onVideoTimeUpdate(...e))),af:a.audioUrl,ag:e.o(((...e)=>n.viewVideo&&n.viewVideo(...e))),ah:e.o(((...e)=>n.downloadVideo&&n.downloadVideo(...e)))}:{},{ai:e.sr("paymentModal","3b9db2aa-0"),aj:e.o(n.handlePaymentClose),ak:e.o(n.handlePaymentConfirm),al: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})})}],["__scopeId","data-v-3b9db2aa"]]);wx.createPage(s);
+"use strict";const e=require("../../common/vendor.js"),o=require("../../config/api.js"),t=require("../../utils/payment.js"),i={components:{PaymentModal:()=>"../../components/PaymentModal.js"},data:()=>({API_BASE:o.API_BASE,photoFile:null,photoPreview:"",modelOptions:[{value:"veo",label:"Veo",hint:"需要音色,生成说话人视频",disabled:!1,maintenanceMsg:""},{value:"volcengine",label:"火山引擎",hint:"需要音色,生成说话人视频",disabled:!1,maintenanceMsg:""}],selectedModel:"veo",selectedModelName:"Veo",modelHint:"需要音色,生成说话人视频",voices:[],voiceTypeOptions:[{value:"CLONE",label:"克隆音色"},{value:"OFFICIAL",label:"官方音色(Flash)"}],selectedVoiceType:"CLONE",selectedVoiceTypeLabel:"克隆音色",selectedVoiceId:"",selectedVoiceName:"",selectedDialect:"",selectedLanguageHint:"",selectedLanguageHintLabel:"",selectedSupportsDialect:!1,selectedSupportsLanguageHints:!1,languageHintOptions:["中文(zh)","英文(en)","法语(fr)","德语(de)","日语(ja)","韩语(ko)","俄语(ru)"],dialectOptions:["广东话","东北话","甘肃话","贵州话","河南话","湖北话","江西话","闽南话","宁夏话","山西话","陕西话","山东话","上海话","四川话","天津话","云南话"],videoTitle:"",text:"",showHelpModal:!1,loading:!1,loadingText:"",progress:[],videoUrl:"",audioUrl:"",localVideoPath:"",localAudioPath:"",isPlaying:!1,videoRetried:!1,paymentModalData:{show:!1,serviceType:"",serviceName:"",serviceDesc:"",price:0,orderNo:"",paymentTips:"点击确认支付后将开始生成视频"},_paymentResolve:null,_paymentReject:null,_paymentOnSuccess:null,_paymentOnFailed:null}),computed:{displayVoices(){const e=(this.voices||[]).filter((e=>e&&(e.voice_type||"CLONE")===this.selectedVoiceType));if("OFFICIAL"!==(this.selectedVoiceType||"CLONE"))return e;const o={"湾区大叔":"台湾","台湾小何":"台湾","双节棍小哥":"台湾","广州德哥":"广州","浩宇小哥":"大陆"};return e.map((e=>{const t=e&&e.voice_name?String(e.voice_name):"",i=t&&o[t]?o[t]:"";return i?{...e,voice_name:`${i}-${t}`}:e}))},canGenerate(){const e=this.modelOptions.find((e=>e.value===this.selectedModel));return(!e||!e.disabled)&&(this.photoFile&&this.videoTitle&&this.text&&this.selectedVoiceId)}},onLoad(){this.loadVoices(),this.loadModelStatus()},methods:{onVoiceTypeChange(e){const o=this.voiceTypeOptions[e.detail.value];this.selectedVoiceType=o?o.value:"CLONE",this.selectedVoiceTypeLabel=o?o.label:"克隆音色",this.selectedVoiceId="",this.selectedVoiceName="",this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",this.selectedSupportsDialect=!1,this.selectedSupportsLanguageHints=!1},showVoiceHelp(){this.showHelpModal=!0},goToUpload(){this.showHelpModal=!1,e.index.navigateTo({url:"/pages/upload-audio/upload-audio"})},getCurrentModelMaintenanceMsg(){const e=this.modelOptions.find((e=>e.value===this.selectedModel));return e&&e.disabled?e.maintenanceMsg:""},onModelChange(e){const o=e.detail.value,t=this.modelOptions[o];this.selectedModel=t.value,this.selectedModelName=t.label,this.modelHint=t.hint,console.log("[Revival] 选择模型:",this.selectedModel)},choosePhoto(){e.index.chooseImage({count:1,sizeType:["compressed"],sourceType:["album","camera"],success:e=>{this.photoFile={path:e.tempFilePaths[0],name:"photo.jpg"},this.photoPreview=e.tempFilePaths[0]},fail:o=>{e.index.showToast({title:"选择照片失败",icon:"none"})}})},chooseAudio(){},chooseAudioFileFromSystem(){},copyContentUriToLocalForAudio(e,o){},async startRecordAudio(){},loadModelStatus(){console.log("[Revival] 开始加载模型状态..."),e.index.request({url:`${this.API_BASE}/api/system/model-status`,method:"GET",success:e=>{if(console.log("[Revival] 模型状态响应:",e),200===e.statusCode&&e.data&&e.data.success){const o=e.data.data;if("true"===o.veo_disabled){const e=this.modelOptions.find((e=>"veo"===e.value));e&&(e.disabled=!0,e.maintenanceMsg=o.veo_message||"官方接口参数更新,正在处理中,暂不可用")}if("true"===o.volcengine_disabled){const e=this.modelOptions.find((e=>"volcengine"===e.value));e&&(e.disabled=!0,e.maintenanceMsg=o.volcengine_message||"官方接口参数更新,正在处理中,暂不可用")}console.log("[Revival] 模型状态已更新:",this.modelOptions)}},fail:e=>{console.error("[Revival] 加载模型状态失败:",e)}})},loadVoices(){console.log("[Revival] 开始加载音色列表..."),console.log("[Revival] API地址:",`${this.API_BASE}/api/voice/list`);const o=e.index.getStorageSync("userId")||"",t=e.index.getStorageSync("token")||"";console.log("[Revival] 用户ID:",o),e.index.request({url:`${this.API_BASE}/api/voice/list`,method:"GET",header:{"X-User-Id":o,Authorization:t?`Bearer ${t}`:""},success:o=>{if(console.log("[Revival] API响应状态码:",o.statusCode),console.log("[Revival] API响应数据:",o.data),200===o.statusCode)if(o.data&&o.data.voices){const t=["Cherry","Kai","Mochi","Bunny"];this.voices=(o.data.voices||[]).filter((e=>!(e&&e.voice&&t.includes(e.voice)))),console.log("[Revival] 音色列表:",this.voices),console.log("[Revival] 音色数量:",this.voices.length),this.voices.length>0?(this.selectedVoiceId=this.voices[0].voice,this.selectedVoiceName=this.voices[0].voice_name||this.voices[0].voice,this.selectedDialect="",console.log("[Revival] 默认选中音色:",this.selectedVoiceId)):(console.log("[Revival] 音色列表为空"),e.index.showToast({title:"暂无可用音色,请先创建",icon:"none"}))}else console.error("[Revival] 响应数据格式错误:",o.data),this.voices=[];else console.error("[Revival] 请求失败,状态码:",o.statusCode)},fail:o=>{console.error("[Revival] 加载音色列表失败:",o),e.index.showToast({title:"加载音色列表失败",icon:"none"})}})},onVoiceChange(e){const o=this.displayVoices[e.detail.value];this.selectedVoiceId=o.voice,this.selectedVoiceName=o.voice_name||o.voice,this.selectedVoiceType=o.voice_type||this.selectedVoiceType||"CLONE",this.selectedVoiceTypeLabel="OFFICIAL"===this.selectedVoiceType?"官方音色(Flash)":"克隆音色",this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",this.selectedSupportsDialect=!!o.supportsDialect,this.selectedSupportsLanguageHints=!!o.supportsLanguageHints,"OFFICIAL"===(this.selectedVoiceType||"CLONE")&&(this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",this.selectedSupportsDialect=!1,this.selectedSupportsLanguageHints=!1)},onDialectChange(e){this.selectedDialect=this.dialectOptions[e.detail.value]||""},onLanguageHintChange(e){const o=this.languageHintOptions[e.detail.value]||"";this.selectedLanguageHintLabel=o;const t=o.match(/\(([^)]+)\)/);this.selectedLanguageHint=t&&t[1]?t[1]:""},async handleGenerate(){const i=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";if(!i)return void e.index.showModal({title:"提示",content:"请先登录后再继续",confirmText:"去登录",cancelText:"取消",success:o=>{o.confirm&&e.index.navigateTo({url:"/pages/login/login"})}});const a="volcengine"===this.selectedModel?"VOLCENGINE_VIDEO":"PHOTO_REVIVAL",n="volcengine"===this.selectedModel?t.SERVICE_TYPES.VOLCENGINE_VIDEO.type:t.SERVICE_TYPES.PHOTO_REVIVAL.type;let l=null;try{l=await new Promise(((t,n)=>{e.index.request({url:`${o.API_BASE}/api/pay/usage-preview?serviceType=${a}`,method:"GET",header:{"X-User-Id":i,Authorization:s?`Bearer ${s}`:""},success:e=>{200===e.statusCode&&e.data&&e.data.success?t(e.data):n(new Error(e.data&&e.data.message?e.data.message:"预检失败: HTTP "+e.statusCode))},fail:e=>n(new Error(e&&e.errMsg?e.errMsg:"预检失败"))})}))}catch(d){return void e.index.showModal({title:"检查次数失败",content:d&&d.message?d.message:"检查剩余次数失败,请稍后重试",showCancel:!1,confirmText:"我知道了"})}(l&&"number"==typeof l.remainingTotalCount?l.remainingTotalCount:0)<=0?t.showPaymentModal(this,n,(()=>{this.executeGenerate()}),(e=>{console.error("[Payment] 支付失败:",e)})):this.executeGenerate()},async executeGenerate(){this.loading=!0,this.progress=[],this.videoUrl="",this.audioUrl="";try{"volcengine"===this.selectedModel?await this.generateWithVolcengine():await this.generateWithExistingVoice()}catch(o){o.message.includes("响应超时")||o.message.includes("历史记录")?(this.addProgress("⚠️ "+o.message,"warning"),e.index.showModal({title:"提示",content:o.message,showCancel:!0,cancelText:"知道了",confirmText:"查看历史",success:o=>{o.confirm&&e.index.navigateTo({url:"/pages/revival/revival-history"})}})):(this.addProgress("生成失败: "+o.message,"error"),e.index.showModal({title:"生成失败",content:(o.message||"生成失败")+"\n\n你可以点击“重试”再次生成。\n若已支付但多次生成失败,请联系客服补发(提供订单号/支付时间截图)。",confirmText:"重试",cancelText:"我知道了",success:e=>{e.confirm&&this.executeGenerate()}}))}finally{this.loading=!1}},async generateWithVolcengine(){return new Promise(((o,i)=>{this.addProgress("📤 正在上传照片...","loading"),e.index.showModal({title:"🎬 视频生成中",content:"火山引擎视频生成通常需要1-3分钟。\n\n您可以最小化APP做其他事情,生成完成后会弹出提示。\n\n请保持网络连接稳定。",showCancel:!1,confirmText:"我知道了"}),setTimeout((()=>{this.addProgress("🎬 正在生成视频(通常1-3分钟)...","loading")}),2e3);const s=e.index.getStorageSync("userId")||"",a=e.index.getStorageSync("token")||"";console.log("[Revival-Volcengine] 准备上传照片:",this.photoFile),console.log("[Revival-Volcengine] 用户ID:",s),console.log("[Revival-Volcengine] API地址:",`${this.API_BASE}/api/photo-revival/volcengine-video`),e.index.uploadFile({url:`${this.API_BASE}/api/photo-revival/volcengine-video`,filePath:this.photoFile.path,name:"photo",timeout:36e5,header:{"X-User-Id":s,Authorization:a?`Bearer ${a}`:""},formData:(()=>{const e={voiceId:this.selectedVoiceId,voiceType:this.selectedVoiceType,text:this.text,duration:8,name:this.videoTitle};return this.selectedSupportsDialect&&this.selectedDialect&&(e.dialect=this.selectedDialect),this.selectedSupportsLanguageHints&&this.selectedLanguageHint&&(e.languageHints=this.selectedLanguageHint),e})(),success:s=>{console.log("[Revival-Volcengine] 上传响应:",s);let a=null;try{a=JSON.parse(s.data)}catch(l){a=null}if(402===s.statusCode)return console.warn("[Revival-Volcengine] HTTP 402:次数不足,需要付费"),this.addProgress("⚠️ 次数不足,请先付费","warning"),e.index.showModal({title:"需要付费",content:a&&a.message?a.message:"次数不足,请先完成支付后再生成",confirmText:"去支付",cancelText:"取消",success:o=>{o.confirm&&t.showPaymentModal(this,t.SERVICE_TYPES.PHOTO_REVIVAL.type,(()=>{e.index.showToast({title:"支付成功,请重新点击生成",icon:"none"})}),(()=>{}))}}),void i(new Error(a&&a.message?a.message:"次数不足,请先付费"));if(504===s.statusCode)return console.warn("[Revival-Volcengine] HTTP 504:请求超时,但后端可能仍在生成中"),setTimeout((()=>{e.index.showModal({title:"⏰ 响应超时",content:"网络响应超时(HTTP 504),但视频可能仍在后台生成中。\n\n是否立即查看历史记录?",confirmText:"查看历史",cancelText:"稍后查看",success:o=>{o.confirm&&e.index.navigateTo({url:"/pages/revival/revival-history"})}})}),800),this.addProgress("⏳ 网络响应超时(HTTP 504),视频可能仍在后台生成中,请稍后到历史记录查看","loading"),void o();if(200===s.statusCode){if(a&&"success"===a.status)return this.addProgress("✅ 视频生成完成","done"),this.videoRetried=!1,e.index.showToast({title:"生成成功!",icon:"success"}),void o();const t=a&&a.message?a.message:"生成失败";return console.error("[Revival-Volcengine] 后端返回错误:",t),void i(new Error(t))}const n=a&&a.message?a.message:"上传失败: HTTP "+s.statusCode;i(new Error(n))},fail:o=>{console.error("[Revival-Volcengine] 上传响应超时:",o),setTimeout((()=>{e.index.showModal({title:"⏰ 响应超时",content:"网络响应超时,但视频可能已经生成成功。\n\n是否立即查看历史记录?",confirmText:"查看历史",cancelText:"稍后查看",success:o=>{o.confirm&&e.index.navigateTo({url:"/pages/revival/revival-history"})}})}),3e3),i(new Error("网络响应超时,视频可能正在生成中,请稍后在历史记录中查看"))}})}))},async generateWithNewVoice(){this.addProgress("正在创建音色...","loading")},generateWithExistingVoice(){return new Promise(((o,t)=>{this.addProgress("⏳ 正在上传照片...","loading"),e.index.showModal({title:"⏳ 视频生成中",content:"视频生成通常需要2-5分钟,高峰期可能需要10-30分钟。\n\n您可以最小化APP做其他事情,生成完成后会弹出提示。\n\n请保持网络连接稳定。",showCancel:!1,confirmText:"我知道了"}),setTimeout((()=>{this.addProgress("🎵 正在合成语音...","loading")}),2e3),setTimeout((()=>{this.addProgress("🎬 正在生成视频(通常2-5分钟,高峰期可能更久)...","loading")}),5e3);const i=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";console.log("[Revival] 准备上传照片:",this.photoFile),console.log("[Revival] 照片路径:",this.photoFile.path),console.log("[Revival] 用户ID:",i),console.log("[Revival] Token:",s?"已设置":"未设置"),console.log("[Revival] API地址:",`${this.API_BASE}/api/photo-revival/revive-quick`),i||(console.warn("[Revival] ⚠️ 警告:用户ID为空,视频可能无法正确保存到数据库"),e.index.showModal({title:"提示",content:"检测到您未登录,视频将无法保存到历史记录。是否继续?",success:e=>{e.confirm||t(new Error("用户取消操作"))}})),e.index.uploadFile({url:`${this.API_BASE}/api/photo-revival/revive-quick`,filePath:this.photoFile.path,name:"photo",timeout:36e5,header:{"X-User-Id":i,Authorization:s?`Bearer ${s}`:""},formData:(()=>{const e={voiceId:this.selectedVoiceId,voiceType:this.selectedVoiceType,text:this.text,name:this.videoTitle,serverUrl:this.API_BASE};return this.selectedSupportsDialect&&this.selectedDialect&&(e.dialect=this.selectedDialect),this.selectedSupportsLanguageHints&&this.selectedLanguageHint&&(e.languageHints=this.selectedLanguageHint),e})(),success:i=>{console.log("[Revival] 上传响应:",i);let s=null;try{s=JSON.parse(i.data)}catch(n){s=null}if(504===i.statusCode)return console.warn("[Revival] HTTP 504:请求超时,但后端可能仍在生成中"),setTimeout((()=>{e.index.showModal({title:"⏰ 响应超时",content:"网络响应超时(HTTP 504),但视频可能仍在后台生成中。\n\n是否立即查看历史记录?",confirmText:"查看历史",cancelText:"稍后查看",success:o=>{o.confirm&&e.index.navigateTo({url:"/pages/revival/revival-history"})}})}),800),this.addProgress("⏳ 网络响应超时(HTTP 504),视频可能仍在后台生成中,请稍后到历史记录查看","loading"),void o();if(200===i.statusCode){if(s&&"success"===s.status)return this.handleResult(s),void o();const e=s&&s.message?s.message:"生成失败";return console.error("[Revival] 后端返回错误:",e),void t(new Error(e))}const a=s&&s.message?s.message:"上传失败: HTTP "+i.statusCode;t(new Error(a))},fail:o=>{console.error("[Revival] 上传响应超时:",o),setTimeout((()=>{e.index.showModal({title:"⏰ 响应超时",content:"网络响应超时,但视频可能已经生成成功。\n\n是否立即查看历史记录?",confirmText:"查看历史",cancelText:"稍后查看",success:o=>{o.confirm&&e.index.navigateTo({url:"/pages/revival/revival-history"})}})}),3e3),t(new Error("网络响应超时,视频可能正在生成中,请稍后在历史记录中查看"))}})}))},async handleResult(o){if("success"!==o.status)throw new Error(o.message||"生成失败");"new"===this.mode&&this.addProgress("✅ 音色创建完成","done"),this.addProgress("✅ 语音合成完成","done"),this.addProgress("✅ 视频生成完成","done"),this.videoUrl=o.videoUrl,this.audioUrl=o.audioUrl,this.videoRetried=!1,this.saveToHistory(o),e.index.showModal({title:"🎉 生成成功!",content:'视频已生成完成!\n\n点击"查看视频"可以立即查看和播放视频。',cancelText:"稍后查看",confirmText:"查看视频",success:e=>{e.confirm&&this.scrollToResult()}}),"new"===this.mode&&this.loadVoices()},togglePlay(){this.isPlaying?this.pausePlayback():this.startPlayback()},startPlayback(){const o=e.index.createVideoContext("resultVideo",this),t=e.index.createInnerAudioContext();t.src=this.audioUrl,o.play(),t.play(),this.isPlaying=!0,this.audioContext=t},pausePlayback(){e.index.createVideoContext("resultVideo",this).pause(),this.audioContext&&this.audioContext.pause(),this.isPlaying=!1},onVideoPlay(){this.isPlaying=!0},onVideoPause(){this.isPlaying=!1,this.audioContext&&this.audioContext.pause()},onVideoEnded(){this.isPlaying=!1,this.audioContext&&this.audioContext.stop()},onVideoLoaded(e){console.log("[Revival] 视频加载成功:",e)},onVideoError(o){if(console.error("[Revival] 视频加载失败:",o),console.error("[Revival] 视频URL:",this.videoUrl),console.error("[Revival] 错误详情:",o.detail),!this.videoRetried)return console.log("[Revival] 尝试重新加载视频..."),this.videoRetried=!0,void setTimeout((()=>{e.index.createVideoContext("resultVideo",this).stop();const o=this.videoUrl;this.videoUrl="",this.$nextTick((()=>{this.videoUrl=o+"?t="+Date.now()}))}),500);e.index.showModal({title:"视频加载失败",content:"无法播放视频,可能是网络或格式问题。\n\n您可以尝试:\n1. 检查网络连接\n2. 返回后重新进入播放\n3. 重新生成视频或稍后再试",showCancel:!1})},onVideoWaiting(e){console.log("[Revival] 视频缓冲中...",e)},onVideoTimeUpdate(e){},scrollToResult(){this.$nextTick((()=>{e.index.createSelectorQuery().in(this).select(".result-section").boundingClientRect((o=>{o&&e.index.pageScrollTo({scrollTop:o.top-100,duration:300})})).exec()}))},addProgress(e,o){this.progress.push({text:e,status:o}),this.loadingText=e},goToHistory(){e.index.navigateTo({url:"/pages/revival/revival-history"})},viewVideo(){if(console.log("[Revival] 准备播放视频"),console.log("[Revival] videoUrl:",this.videoUrl),console.log("[Revival] audioUrl:",this.audioUrl),!this.videoUrl)return void e.index.showToast({title:"视频地址不存在",icon:"none"});let o=`/pages/video-player/video-player?url=${encodeURIComponent(this.videoUrl)}&title=${encodeURIComponent("复活视频")}`;o+="&audioInVideo=1",console.log("[Revival] 跳转播放页:",o),e.index.navigateTo({url:o,success:()=>{console.log("[Revival] 跳转播放页面成功")},fail:o=>{console.error("[Revival] 跳转播放页面失败:",o),e.index.showToast({title:"跳转失败",icon:"none"})}})},handlePaymentClose(){this.paymentModalData.show=!1,this._paymentReject&&this._paymentReject(new Error("用户取消支付"))},async handlePaymentConfirm(e){await t.handlePaymentConfirm(this,e)},manualSaveToHistory(){if(!this.videoUrl)return void e.index.showToast({title:"没有可保存的记录",icon:"none"});const o={photoUrl:this.photoPreview,videoUrl:this.videoUrl,audioUrl:this.audioUrl,voiceId:this.selectedVoiceId};this.saveToHistory(o),e.index.showToast({title:"已保存到历史",icon:"success"})},async downloadVideoToLocal(o){try{console.log("[Revival] 开始下载视频到本地:",o);const t=await new Promise(((t,i)=>{e.index.downloadFile({url:o,success:e=>{200===e.statusCode?(console.log("[Revival] 视频下载成功:",e.tempFilePath),t(e.tempFilePath)):i(new Error("下载失败,状态码: "+e.statusCode))},fail:e=>{console.error("[Revival] 视频下载失败:",e),i(e)}})})),i=await this.saveFilePermanently(t,"video");this.localVideoPath=i,console.log("[Revival] 视频已保存到:",i)}catch(t){console.error("[Revival] 下载视频失败:",t),e.index.showToast({title:"视频下载失败,将使用在线播放",icon:"none"})}},saveFilePermanently:async(o,t)=>new Promise(((i,s)=>{const a=e.index.getFileSystemManager(),n=`${e.index.env.USER_DATA_PATH}/revival_${t}s/`,l=n+`${t}_${Date.now()}.${"video"===t?"mp4":"mp3"}`;a.mkdir({dirPath:n,recursive:!0,success:()=>{a.copyFile({srcPath:o,destPath:l,success:()=>{console.log(`[Revival] ${t}已保存到永久存储:`,l),i(l)},fail:e=>{console.error(`[Revival] 保存${t}失败:`,e),i(o)}})},fail:e=>{console.error("[Revival] 创建目录失败:",e),i(o)}})})),saveToHistory(o){try{console.log("[Revival] 开始保存历史记录"),console.log("[Revival] 结果数据:",o);let t=[];const i=e.index.getStorageSync("generation_history");i&&(t=JSON.parse(i));const s={type:"revival",timestamp:Date.now(),text:this.text,voiceId:"existing"===this.mode?this.selectedVoiceId:o.voiceId||this.selectedVoiceId,photoUrl:this.photoPreview,videoUrl:o.videoUrl,audioUrl:o.audioUrl};console.log("[Revival] 保存记录:",s),t.unshift(s),t.length>100&&(t=t.slice(0,100)),e.index.setStorageSync("generation_history",JSON.stringify(t)),console.log("[Revival] 已保存到历史记录,当前共",t.length,"条")}catch(t){console.error("[Revival] 保存历史记录失败:",t)}},downloadVideo(){e.index.showLoading({title:"正在保存..."}),e.index.downloadFile({url:this.videoUrl,success:o=>{200===o.statusCode?e.index.saveVideoToPhotosAlbum({filePath:o.tempFilePath,success:()=>{e.index.hideLoading(),e.index.showToast({title:"保存成功",icon:"success"})},fail:o=>{e.index.hideLoading(),e.index.showToast({title:"保存失败: "+o.errMsg,icon:"none"})}}):(e.index.hideLoading(),e.index.showToast({title:"下载失败",icon:"none"}))},fail:o=>{e.index.hideLoading(),e.index.showToast({title:"下载失败: "+o.errMsg,icon:"none"})}})},startVideoCall(){if(!this.videoUrl||!this.selectedVoiceId)return void e.index.showToast({title:"缺少必要信息",icon:"none"});const o="new"===this.mode?this.voiceName:"对方";e.index.navigateTo({url:`/pages/video-call/video-call?idleVideo=${encodeURIComponent(this.videoUrl)}&talkingVideo=${encodeURIComponent(this.videoUrl)}&voiceId=${this.selectedVoiceId}&callerName=${encodeURIComponent(o)}`})}}};if(!Array){e.resolveComponent("PaymentModal")()}const s=e._export_sfc(i,[["render",function(o,t,i,s,a,n){return e.e({a:e.o(((...e)=>n.goToHistory&&n.goToHistory(...e))),b:a.showHelpModal},a.showHelpModal?{c:e.o((e=>a.showHelpModal=!1)),d:`${a.API_BASE}/static/1.jpg`,e:`${a.API_BASE}/static/2.jpg`,f:e.o((e=>a.showHelpModal=!1)),g:e.o(((...e)=>n.goToUpload&&n.goToUpload(...e))),h:e.o((()=>{})),i:e.o((e=>a.showHelpModal=!1))}:{},{j:a.photoPreview,k:a.photoPreview,l:!a.photoPreview,m:e.o(((...e)=>n.choosePhoto&&n.choosePhoto(...e))),n:a.videoTitle,o:e.o((e=>a.videoTitle=e.detail.value)),p:e.t(a.videoTitle.length),q:e.t(a.selectedModelName||"请选择模型"),r:a.modelOptions,s:e.o(((...e)=>n.onModelChange&&n.onModelChange(...e))),t:n.getCurrentModelMaintenanceMsg()},n.getCurrentModelMaintenanceMsg()?{v:e.t(n.getCurrentModelMaintenanceMsg())}:{w:e.t(a.modelHint)},{x:e.o(((...e)=>n.showVoiceHelp&&n.showVoiceHelp(...e))),y:e.t(a.selectedVoiceTypeLabel),z:a.voiceTypeOptions,A:e.o(((...e)=>n.onVoiceTypeChange&&n.onVoiceTypeChange(...e))),B:e.t(a.selectedVoiceName||"请选择音色"),C:n.displayVoices,D:e.o(((...e)=>n.onVoiceChange&&n.onVoiceChange(...e))),E:a.selectedSupportsDialect&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")},a.selectedSupportsDialect&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")?{F:e.t(a.selectedDialect||"请选择方言(可选)"),G:a.dialectOptions,H:e.o(((...e)=>n.onDialectChange&&n.onDialectChange(...e)))}:{},{I:a.selectedSupportsLanguageHints&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")},a.selectedSupportsLanguageHints&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")?{J:e.t(a.selectedLanguageHintLabel||"请选择语言(可选)"),K:a.languageHintOptions,L:e.o(((...e)=>n.onLanguageHintChange&&n.onLanguageHintChange(...e)))}:{},{M:a.text,N:e.o((e=>a.text=e.detail.value)),O:e.t(a.text.length),P:a.loading},a.loading?{Q:e.t(a.loadingText)}:{},{R:a.loading||!n.canGenerate,S:e.o(((...e)=>n.handleGenerate&&n.handleGenerate(...e))),T:a.progress.length>0},a.progress.length>0?{U:e.f(a.progress,((o,t,i)=>({a:e.t("done"===o.status?"✅":"error"===o.status?"❌":"⏳"),b:e.n(o.status),c:e.t(o.text),d:t})))}:{},{V:a.videoUrl},a.videoUrl?{W:a.videoUrl,X:a.photoPreview,Y:e.o(((...e)=>n.onVideoPlay&&n.onVideoPlay(...e))),Z:e.o(((...e)=>n.onVideoPause&&n.onVideoPause(...e))),aa:e.o(((...e)=>n.onVideoEnded&&n.onVideoEnded(...e))),ab:e.o(((...e)=>n.onVideoError&&n.onVideoError(...e))),ac:e.o(((...e)=>n.onVideoLoaded&&n.onVideoLoaded(...e))),ad:e.o(((...e)=>n.onVideoWaiting&&n.onVideoWaiting(...e))),ae:e.o(((...e)=>n.onVideoTimeUpdate&&n.onVideoTimeUpdate(...e))),af:a.audioUrl,ag:e.o(((...e)=>n.viewVideo&&n.viewVideo(...e))),ah:e.o(((...e)=>n.downloadVideo&&n.downloadVideo(...e)))}:{},{ai:e.sr("paymentModal","829992d9-0"),aj:e.o(n.handlePaymentClose),ak:e.o(n.handlePaymentConfirm),al: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})})}],["__scopeId","data-v-829992d9"]]);wx.createPage(s);
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-original.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-original.wxml
index 5b3bfa9..a90197b 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-original.wxml
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-original.wxml
@@ -1 +1 @@
-照片复活让记忆中的人再次开口说话1️⃣ 点击底部导航"声音克隆"2️⃣ 点击"上传音频"按钮3️⃣ 录制或上传10-20秒清晰人声建议录制清晰的普通话朗读,避免背景噪音4️⃣ 创建成功后即可在此选择使用💡 提示:音色质量越好,合成效果越自然合规提示照片中避免:未成年人、明显真人正脸/疑似公众人物、裸露低俗、血腥暴力、涉政涉恐等内容避免:平台截图/水印/二维码/账号昵称/大量文字(图片中的文字也会被审核)建议:使用清晰、无水印、无UI、背景干净的照片;台词避免敏感词📷点击选择照片{{p}} / 20💡 标题将显示在历史记录和AI通话页面{{q}} ⚠️ {{v}}💡 {{w}}{{y}}{{B}}💡 请先在"声音克隆"页面创建音色方言{{F}}语言提示(可选){{J}}{{O}} / 500生成进度{{item.a}}{{item.c}}🎉 生成成功!
\ No newline at end of file
+照片复活让记忆中的人再次开口说话1️⃣ 点击底部导航"声音克隆"2️⃣ 点击"上传音频"按钮3️⃣ 录制或上传10-20秒清晰人声建议录制清晰的普通话朗读,避免背景噪音4️⃣ 创建成功后即可在此选择使用💡 提示:音色质量越好,合成效果越自然合规提示照片中避免:未成年人、明显真人正脸/疑似公众人物、裸露低俗、血腥暴力、涉政涉恐等内容避免:平台截图/水印/二维码/账号昵称/大量文字(图片中的文字也会被审核)建议:使用清晰、无水印、无UI、背景干净的照片;台词避免敏感词📷点击选择照片{{p}} / 20💡 标题将显示在历史记录和AI通话页面{{q}} ⚠️ {{v}}💡 {{w}}{{y}}{{B}}💡 请先在"声音克隆"页面创建音色方言{{F}}语言提示(可选){{J}}{{O}} / 500本服务为AI生成内容,结果仅供参考生成进度{{item.a}}{{item.c}}🎉 生成成功!AI生成
\ No newline at end of file
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-original.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-original.wxss
index ab9ea58..ac9fc15 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-original.wxss
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival-original.wxss
@@ -1 +1 @@
-.revival-container.data-v-3b9db2aa{min-height:100vh;background:#fdf8f2;background-image:radial-gradient(circle at 10% 20%,rgba(212,185,150,.1) 0%,transparent 20%),radial-gradient(circle at 90% 80%,rgba(109,139,139,.1) 0%,transparent 20%);display:flex;flex-direction:column}.hero.data-v-3b9db2aa{display:flex;align-items:center;justify-content:space-between;padding:32rpx 32rpx 12rpx;gap:20rpx;max-width:1000rpx;margin:0 auto}.hero-text.data-v-3b9db2aa{display:flex;flex-direction:column;gap:8rpx}.hero-title.data-v-3b9db2aa{font-size:44rpx;font-weight:700;color:#8b7355;letter-spacing:2rpx}.hero-subtitle.data-v-3b9db2aa{font-size:28rpx;color:#666}.history-btn.data-v-3b9db2aa{padding:16rpx 32rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:36rpx;font-size:26rpx;box-shadow:0 4rpx 12rpx rgba(139,115,85,.3);transition:all .3s}.history-btn.data-v-3b9db2aa:active{transform:translateY(-2rpx);box-shadow:0 6rpx 16rpx rgba(139,115,85,.4)}.content.data-v-3b9db2aa{flex:1;background:transparent;padding:32rpx;max-width:650rpx;margin:0 auto 40rpx;display:flex;flex-direction:column;gap:28rpx;align-items:center}.tips-card.data-v-3b9db2aa{width:100%;max-width:580rpx;background:rgba(255,255,255,.95);border-radius:20rpx;padding:22rpx 24rpx;box-shadow:0 6rpx 20rpx rgba(0,0,0,.06);border:2rpx solid rgba(139,115,85,.12)}.tips-title.data-v-3b9db2aa{font-size:28rpx;font-weight:700;color:#8b7355;margin-bottom:12rpx}.tips-item.data-v-3b9db2aa{font-size:24rpx;color:#666;line-height:1.6;margin-top:8rpx}.step-card.data-v-3b9db2aa{width:100%;max-width:580rpx;background:rgba(255,255,255,.95);border-radius:20rpx;padding:28rpx 24rpx;margin:0;box-shadow:0 6rpx 20rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(12rpx);backdrop-filter:blur(12rpx);border:2rpx solid rgba(139,115,85,.12)}.step-header.data-v-3b9db2aa{display:flex;align-items:center;justify-content:space-between;margin-bottom:24rpx}.step-number.data-v-3b9db2aa{width:44rpx;height:44rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;margin-right:14rpx;font-size:26rpx;box-shadow:0 3rpx 10rpx rgba(139,115,85,.25)}.step-title.data-v-3b9db2aa{font-size:30rpx;font-weight:700;color:#2c2c2c;flex:1}.help-icon.data-v-3b9db2aa{font-size:32rpx;color:#8b7355;padding:10rpx;margin-left:10rpx;transition:all .3s}.help-icon.data-v-3b9db2aa:active{transform:scale(1.2);color:#6d8b8b}.upload-btn.data-v-3b9db2aa{width:100%;min-height:700rpx;border:3rpx dashed #D4B996;border-radius:16rpx;background:rgba(212,185,150,.05);display:flex;align-items:center;justify-content:center;padding:0;overflow:hidden;position:relative;transition:all .3s}.upload-btn.data-v-3b9db2aa:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:radial-gradient(circle at 30% 30%,rgba(139,115,85,.08) 0%,transparent 50%),radial-gradient(circle at 70% 70%,rgba(109,139,139,.08) 0%,transparent 50%);z-index:0}.upload-btn.data-v-3b9db2aa:active{border-color:#8b7355;background:rgba(212,185,150,.1)}.preview-img.data-v-3b9db2aa{width:100%;height:700rpx;border-radius:14rpx;position:absolute;top:0;left:0;right:0;bottom:0;z-index:1}.upload-placeholder.data-v-3b9db2aa{display:flex;flex-direction:column;align-items:center;color:#8b7355;gap:12rpx}.icon.data-v-3b9db2aa{font-size:72rpx}.mode-selector.data-v-3b9db2aa{display:flex;gap:20rpx;margin-bottom:24rpx}.mode-btn.data-v-3b9db2aa{flex:1;padding:24rpx;border:2rpx solid rgba(212,185,150,.3);border-radius:30rpx;background:rgba(255,255,255,.7);font-size:28rpx;color:#666;transition:all .3s;box-shadow:0 2rpx 8rpx rgba(0,0,0,.05)}.mode-btn.active.data-v-3b9db2aa{background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border-color:transparent;box-shadow:0 8rpx 24rpx rgba(139,115,85,.3)}.voice-section.data-v-3b9db2aa{display:flex;flex-direction:column;gap:20rpx}.upload-btn-small.data-v-3b9db2aa{padding:24rpx;border:2rpx solid #e0e0e0;border-radius:12rpx;background:#f8f9ff;font-size:28rpx;color:#666}.input.data-v-3b9db2aa,.picker.data-v-3b9db2aa{padding:24rpx;border:2rpx solid #e0e0e0;border-radius:12rpx;font-size:28rpx;background:#fff}.picker-large.data-v-3b9db2aa{width:100%}.picker-large .picker.data-v-3b9db2aa{padding:32rpx 24rpx;font-size:32rpx;font-weight:500}.input-hint.data-v-3b9db2aa{font-size:24rpx;color:#999;margin-top:16rpx;line-height:1.6}.maintenance-warning.data-v-3b9db2aa{font-size:24rpx;color:#ff6b6b;background:rgba(255,107,107,.1);padding:16rpx;border-radius:8rpx;margin-top:16rpx;line-height:1.6;border:1rpx solid rgba(255,107,107,.3)}.input-field.data-v-3b9db2aa{width:100%;height:90rpx;padding:24rpx;border:2rpx solid rgba(139,115,85,.2);border-radius:12rpx;font-size:32rpx;box-sizing:border-box;background:#fff;transition:border-color .3s}.input-field.data-v-3b9db2aa:focus{border-color:#8b7355}.textarea.data-v-3b9db2aa{width:100%;min-height:150rpx;padding:20rpx;border:2rpx solid rgba(139,115,85,.2);border-radius:12rpx;font-size:28rpx;line-height:1.6;box-sizing:border-box;background:#fff;transition:border-color .3s}.textarea.data-v-3b9db2aa:focus{border-color:#8b7355}.char-count.data-v-3b9db2aa{text-align:right;font-size:24rpx;color:#999;margin-top:16rpx}.generate-btn.data-v-3b9db2aa{width:520rpx;max-width:580rpx;padding:28rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:20rpx;font-size:30rpx;font-weight:700;margin:12rpx auto 0;display:block;box-shadow:0 10rpx 28rpx rgba(139,115,85,.3);transition:all .3s}.generate-btn.data-v-3b9db2aa:active{transform:translateY(-2rpx);box-shadow:0 14rpx 36rpx rgba(139,115,85,.4)}.generate-btn[disabled].data-v-3b9db2aa{opacity:.5;box-shadow:0 8rpx 20rpx rgba(0,0,0,.1);transform:none!important}.progress-section.data-v-3b9db2aa{width:100%;max-width:580rpx;background:rgba(255,255,255,.96);border-radius:16rpx;padding:24rpx;box-shadow:0 6rpx 20rpx rgba(0,0,0,.08);border:2rpx solid rgba(139,115,85,.12)}.progress-title.data-v-3b9db2aa{font-size:32rpx;font-weight:700;margin-bottom:24rpx;color:#333}.progress-item.data-v-3b9db2aa{display:flex;align-items:center;padding:18rpx 0;border-bottom:1rpx solid #f0f0f0}.progress-item.data-v-3b9db2aa:last-child{border-bottom:none}.progress-icon.data-v-3b9db2aa{font-size:32rpx;margin-right:16rpx}.progress-text.data-v-3b9db2aa{font-size:28rpx;color:#666}.result-section.data-v-3b9db2aa{width:100%;max-width:580rpx;background:rgba(255,255,255,.96);border-radius:16rpx;padding:24rpx;margin-top:24rpx;box-shadow:0 8rpx 24rpx rgba(0,0,0,.1);border:2rpx solid rgba(139,115,85,.12)}.result-title.data-v-3b9db2aa{font-size:36rpx;font-weight:700;color:#333;text-align:center;margin-bottom:24rpx}.result-video.data-v-3b9db2aa{width:100%;height:400rpx;border-radius:16rpx;margin-bottom:16rpx;background:#000}.play-controls.data-v-3b9db2aa{display:flex;justify-content:center;margin-bottom:24rpx}.play-btn.data-v-3b9db2aa{padding:20rpx 72rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:48rpx;font-size:30rpx;font-weight:700;box-shadow:0 6rpx 16rpx rgba(139,115,85,.3);display:flex;align-items:center;justify-content:center;transition:all .3s}.play-btn.data-v-3b9db2aa:active{transform:scale(.96);box-shadow:0 3rpx 10rpx rgba(139,115,85,.25)}.result-info.data-v-3b9db2aa{background:#f5f5f5;padding:20rpx;border-radius:12rpx;margin-bottom:24rpx}.info-label.data-v-3b9db2aa{font-size:24rpx;color:#999;display:block;margin-bottom:8rpx}.info-value.data-v-3b9db2aa{font-size:22rpx;color:#666;word-break:break-all}.video-call-btn.data-v-3b9db2aa{width:100%;padding:24rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:16rpx;font-size:28rpx;font-weight:700;margin-bottom:12rpx;box-shadow:0 4rpx 12rpx rgba(139,115,85,.3);transition:all .3s}.video-call-btn.data-v-3b9db2aa:active{transform:translateY(-1rpx);box-shadow:0 6rpx 16rpx rgba(139,115,85,.4)}.download-btn.data-v-3b9db2aa{width:100%;padding:24rpx;background:linear-gradient(135deg,#6d8b8b,#5a7a7a);color:#fff;border:none;border-radius:16rpx;font-size:28rpx;margin-bottom:12rpx;box-shadow:0 4rpx 12rpx rgba(109,139,139,.3);transition:all .3s}.download-btn.data-v-3b9db2aa:active{transform:translateY(-1rpx);box-shadow:0 6rpx 16rpx rgba(109,139,139,.4)}.save-history-btn.data-v-3b9db2aa{width:100%;padding:24rpx;background:linear-gradient(135deg,#d4b996,#c4a986);color:#fff;border:none;border-radius:16rpx;font-size:28rpx;box-shadow:0 4rpx 12rpx rgba(212,185,150,.3);transition:all .3s}.save-history-btn.data-v-3b9db2aa:active{transform:translateY(-1rpx);box-shadow:0 6rpx 16rpx rgba(212,185,150,.4)}.help-modal.data-v-3b9db2aa{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;z-index:9999;padding:40rpx}.help-content.data-v-3b9db2aa{width:100%;max-width:640rpx;max-height:85vh;background:#fff;border-radius:24rpx;overflow:hidden;display:flex;flex-direction:column;box-shadow:0 8rpx 32rpx rgba(0,0,0,.3)}.help-header.data-v-3b9db2aa{display:flex;align-items:center;justify-content:space-between;padding:32rpx;border-bottom:2rpx solid #f0f0f0}.help-title.data-v-3b9db2aa{font-size:32rpx;font-weight:700;color:#333}.close-btn.data-v-3b9db2aa{font-size:40rpx;color:#999;padding:10rpx;line-height:1}.help-body.data-v-3b9db2aa{flex:1;padding:24rpx 32rpx;overflow-y:auto;-webkit-overflow-scrolling:touch}.help-step.data-v-3b9db2aa{margin-bottom:40rpx}.help-step.data-v-3b9db2aa:last-child{margin-bottom:0}.help-step-title.data-v-3b9db2aa{display:block;font-size:28rpx;font-weight:600;color:#333;margin-bottom:16rpx}.help-step-desc.data-v-3b9db2aa{display:block;font-size:24rpx;color:#666;line-height:1.6;padding-left:32rpx}.help-image.data-v-3b9db2aa{width:calc(100% + 48rpx);margin-left:-24rpx;height:auto;border-radius:12rpx;margin-top:16rpx;box-shadow:0 4rpx 12rpx rgba(0,0,0,.1);display:block}.help-footer.data-v-3b9db2aa{display:flex;gap:20rpx;padding:24rpx 32rpx;border-top:2rpx solid #f0f0f0}.help-btn.data-v-3b9db2aa{flex:1;padding:24rpx;border-radius:12rpx;font-size:28rpx;border:none;transition:all .3s}.help-btn.secondary.data-v-3b9db2aa{background:#f5f5f5;color:#666}.help-btn.primary.data-v-3b9db2aa{background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff}.help-btn.data-v-3b9db2aa:active{transform:scale(.98)}
+.revival-container.data-v-829992d9{min-height:100vh;background:#fdf8f2;background-image:radial-gradient(circle at 10% 20%,rgba(212,185,150,.1) 0%,transparent 20%),radial-gradient(circle at 90% 80%,rgba(109,139,139,.1) 0%,transparent 20%);display:flex;flex-direction:column}.hero.data-v-829992d9{display:flex;align-items:center;justify-content:space-between;padding:32rpx 32rpx 12rpx;gap:20rpx;max-width:1000rpx;margin:0 auto}.hero-text.data-v-829992d9{display:flex;flex-direction:column;gap:8rpx}.hero-title.data-v-829992d9{font-size:44rpx;font-weight:700;color:#8b7355;letter-spacing:2rpx}.hero-subtitle.data-v-829992d9{font-size:28rpx;color:#666}.history-btn.data-v-829992d9{padding:16rpx 32rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:36rpx;font-size:26rpx;box-shadow:0 4rpx 12rpx rgba(139,115,85,.3);transition:all .3s}.history-btn.data-v-829992d9:active{transform:translateY(-2rpx);box-shadow:0 6rpx 16rpx rgba(139,115,85,.4)}.content.data-v-829992d9{flex:1;background:transparent;padding:32rpx;max-width:650rpx;margin:0 auto 40rpx;display:flex;flex-direction:column;gap:28rpx;align-items:center}.tips-card.data-v-829992d9{width:100%;max-width:580rpx;background:rgba(255,255,255,.95);border-radius:20rpx;padding:22rpx 24rpx;box-shadow:0 6rpx 20rpx rgba(0,0,0,.06);border:2rpx solid rgba(139,115,85,.12)}.tips-title.data-v-829992d9{font-size:28rpx;font-weight:700;color:#8b7355;margin-bottom:12rpx}.tips-item.data-v-829992d9{font-size:24rpx;color:#666;line-height:1.6;margin-top:8rpx}.step-card.data-v-829992d9{width:100%;max-width:580rpx;background:rgba(255,255,255,.95);border-radius:20rpx;padding:28rpx 24rpx;margin:0;box-shadow:0 6rpx 20rpx rgba(0,0,0,.08);-webkit-backdrop-filter:blur(12rpx);backdrop-filter:blur(12rpx);border:2rpx solid rgba(139,115,85,.12)}.step-header.data-v-829992d9{display:flex;align-items:center;justify-content:space-between;margin-bottom:24rpx}.step-number.data-v-829992d9{width:44rpx;height:44rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;margin-right:14rpx;font-size:26rpx;box-shadow:0 3rpx 10rpx rgba(139,115,85,.25)}.step-title.data-v-829992d9{font-size:30rpx;font-weight:700;color:#2c2c2c;flex:1}.help-icon.data-v-829992d9{font-size:32rpx;color:#8b7355;padding:10rpx;margin-left:10rpx;transition:all .3s}.help-icon.data-v-829992d9:active{transform:scale(1.2);color:#6d8b8b}.upload-btn.data-v-829992d9{width:100%;min-height:700rpx;border:3rpx dashed #D4B996;border-radius:16rpx;background:rgba(212,185,150,.05);display:flex;align-items:center;justify-content:center;padding:0;overflow:hidden;position:relative;transition:all .3s}.upload-btn.data-v-829992d9:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:radial-gradient(circle at 30% 30%,rgba(139,115,85,.08) 0%,transparent 50%),radial-gradient(circle at 70% 70%,rgba(109,139,139,.08) 0%,transparent 50%);z-index:0}.upload-btn.data-v-829992d9:active{border-color:#8b7355;background:rgba(212,185,150,.1)}.preview-img.data-v-829992d9{width:100%;height:700rpx;border-radius:14rpx;position:absolute;top:0;left:0;right:0;bottom:0;z-index:1}.upload-placeholder.data-v-829992d9{display:flex;flex-direction:column;align-items:center;color:#8b7355;gap:12rpx}.icon.data-v-829992d9{font-size:72rpx}.mode-selector.data-v-829992d9{display:flex;gap:20rpx;margin-bottom:24rpx}.mode-btn.data-v-829992d9{flex:1;padding:24rpx;border:2rpx solid rgba(212,185,150,.3);border-radius:30rpx;background:rgba(255,255,255,.7);font-size:28rpx;color:#666;transition:all .3s;box-shadow:0 2rpx 8rpx rgba(0,0,0,.05)}.mode-btn.active.data-v-829992d9{background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border-color:transparent;box-shadow:0 8rpx 24rpx rgba(139,115,85,.3)}.voice-section.data-v-829992d9{display:flex;flex-direction:column;gap:20rpx}.upload-btn-small.data-v-829992d9{padding:24rpx;border:2rpx solid #e0e0e0;border-radius:12rpx;background:#f8f9ff;font-size:28rpx;color:#666}.input.data-v-829992d9,.picker.data-v-829992d9{padding:24rpx;border:2rpx solid #e0e0e0;border-radius:12rpx;font-size:28rpx;background:#fff}.picker-large.data-v-829992d9{width:100%}.picker-large .picker.data-v-829992d9{padding:32rpx 24rpx;font-size:32rpx;font-weight:500}.input-hint.data-v-829992d9{font-size:24rpx;color:#999;margin-top:16rpx;line-height:1.6}.maintenance-warning.data-v-829992d9{font-size:24rpx;color:#ff6b6b;background:rgba(255,107,107,.1);padding:16rpx;border-radius:8rpx;margin-top:16rpx;line-height:1.6;border:1rpx solid rgba(255,107,107,.3)}.input-field.data-v-829992d9{width:100%;height:90rpx;padding:24rpx;border:2rpx solid rgba(139,115,85,.2);border-radius:12rpx;font-size:32rpx;box-sizing:border-box;background:#fff;transition:border-color .3s}.input-field.data-v-829992d9:focus{border-color:#8b7355}.textarea.data-v-829992d9{width:100%;min-height:150rpx;padding:20rpx;border:2rpx solid rgba(139,115,85,.2);border-radius:12rpx;font-size:28rpx;line-height:1.6;box-sizing:border-box;background:#fff;transition:border-color .3s}.textarea.data-v-829992d9:focus{border-color:#8b7355}.char-count.data-v-829992d9{text-align:right;font-size:24rpx;color:#999;margin-top:16rpx}.generate-btn.data-v-829992d9{width:520rpx;max-width:580rpx;padding:28rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff!important;border:none;border-radius:20rpx;font-size:30rpx;font-weight:700;margin:12rpx auto 0;display:block;box-shadow:0 10rpx 28rpx rgba(139,115,85,.3);transition:all .3s}.generate-btn.data-v-829992d9:active{transform:translateY(-2rpx);box-shadow:0 14rpx 36rpx rgba(139,115,85,.4)}.generate-btn[disabled].data-v-829992d9{opacity:.5;box-shadow:0 8rpx 20rpx rgba(0,0,0,.1);transform:none!important;color:#fff!important}.ai-disclaimer.data-v-829992d9{display:block;text-align:center;font-size:22rpx;color:rgba(100,100,100,.6);margin-top:16rpx;letter-spacing:.5rpx}.progress-section.data-v-829992d9{width:100%;max-width:580rpx;background:rgba(255,255,255,.96);border-radius:16rpx;padding:24rpx;box-shadow:0 6rpx 20rpx rgba(0,0,0,.08);border:2rpx solid rgba(139,115,85,.12)}.progress-title.data-v-829992d9{font-size:32rpx;font-weight:700;margin-bottom:24rpx;color:#333}.progress-item.data-v-829992d9{display:flex;align-items:center;padding:18rpx 0;border-bottom:1rpx solid #f0f0f0}.progress-item.data-v-829992d9:last-child{border-bottom:none}.progress-icon.data-v-829992d9{font-size:32rpx;margin-right:16rpx}.progress-text.data-v-829992d9{font-size:28rpx;color:#666}.result-section.data-v-829992d9{width:100%;max-width:580rpx;background:rgba(255,255,255,.96);border-radius:16rpx;padding:24rpx;margin-top:24rpx;box-shadow:0 8rpx 24rpx rgba(0,0,0,.1);border:2rpx solid rgba(139,115,85,.12)}.result-title.data-v-829992d9{font-size:36rpx;font-weight:700;color:#333;text-align:center;margin-bottom:24rpx}.result-section.data-v-829992d9{position:relative}.video-container.data-v-829992d9{position:relative;width:100%;height:400rpx;border-radius:16rpx;overflow:hidden;margin-bottom:16rpx;background:#000}.result-video.data-v-829992d9{width:100%;height:100%;border-radius:16rpx;background:#000}.ai-tag.data-v-829992d9{position:absolute;top:16rpx;right:16rpx;z-index:100;background:rgba(0,0,0,.6);padding:8rpx 20rpx;border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.ai-tag-text.data-v-829992d9{font-size:22rpx;color:#fff;font-weight:500}.play-controls.data-v-829992d9{display:flex;justify-content:center;margin-bottom:24rpx}.play-btn.data-v-829992d9{padding:20rpx 72rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:48rpx;font-size:30rpx;font-weight:700;box-shadow:0 6rpx 16rpx rgba(139,115,85,.3);display:flex;align-items:center;justify-content:center;transition:all .3s}.play-btn.data-v-829992d9:active{transform:scale(.96);box-shadow:0 3rpx 10rpx rgba(139,115,85,.25)}.result-info.data-v-829992d9{background:#f5f5f5;padding:20rpx;border-radius:12rpx;margin-bottom:24rpx}.info-label.data-v-829992d9{font-size:24rpx;color:#999;display:block;margin-bottom:8rpx}.info-value.data-v-829992d9{font-size:22rpx;color:#666;word-break:break-all}.video-call-btn.data-v-829992d9{width:100%;padding:24rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:16rpx;font-size:28rpx;font-weight:700;margin-bottom:12rpx;box-shadow:0 4rpx 12rpx rgba(139,115,85,.3);transition:all .3s}.video-call-btn.data-v-829992d9:active{transform:translateY(-1rpx);box-shadow:0 6rpx 16rpx rgba(139,115,85,.4)}.download-btn.data-v-829992d9{width:100%;padding:24rpx;background:linear-gradient(135deg,#6d8b8b,#5a7a7a);color:#fff;border:none;border-radius:16rpx;font-size:28rpx;margin-bottom:12rpx;box-shadow:0 4rpx 12rpx rgba(109,139,139,.3);transition:all .3s}.download-btn.data-v-829992d9:active{transform:translateY(-1rpx);box-shadow:0 6rpx 16rpx rgba(109,139,139,.4)}.save-history-btn.data-v-829992d9{width:100%;padding:24rpx;background:linear-gradient(135deg,#d4b996,#c4a986);color:#fff;border:none;border-radius:16rpx;font-size:28rpx;box-shadow:0 4rpx 12rpx rgba(212,185,150,.3);transition:all .3s}.save-history-btn.data-v-829992d9:active{transform:translateY(-1rpx);box-shadow:0 6rpx 16rpx rgba(212,185,150,.4)}.help-modal.data-v-829992d9{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;z-index:9999;padding:40rpx}.help-content.data-v-829992d9{width:100%;max-width:640rpx;max-height:85vh;background:#fff;border-radius:24rpx;overflow:hidden;display:flex;flex-direction:column;box-shadow:0 8rpx 32rpx rgba(0,0,0,.3)}.help-header.data-v-829992d9{display:flex;align-items:center;justify-content:space-between;padding:32rpx;border-bottom:2rpx solid #f0f0f0}.help-title.data-v-829992d9{font-size:32rpx;font-weight:700;color:#333}.close-btn.data-v-829992d9{font-size:40rpx;color:#999;padding:10rpx;line-height:1}.help-body.data-v-829992d9{flex:1;padding:24rpx 32rpx;overflow-y:auto;-webkit-overflow-scrolling:touch}.help-step.data-v-829992d9{margin-bottom:40rpx}.help-step.data-v-829992d9:last-child{margin-bottom:0}.help-step-title.data-v-829992d9{display:block;font-size:28rpx;font-weight:600;color:#333;margin-bottom:16rpx}.help-step-desc.data-v-829992d9{display:block;font-size:24rpx;color:#666;line-height:1.6;padding-left:32rpx}.help-image.data-v-829992d9{width:calc(100% + 48rpx);margin-left:-24rpx;height:auto;border-radius:12rpx;margin-top:16rpx;box-shadow:0 4rpx 12rpx rgba(0,0,0,.1);display:block}.help-footer.data-v-829992d9{display:flex;gap:20rpx;padding:24rpx 32rpx;border-top:2rpx solid #f0f0f0}.help-btn.data-v-829992d9{flex:1;padding:24rpx;border-radius:12rpx;font-size:28rpx;border:none;transition:all .3s}.help-btn.secondary.data-v-829992d9{background:#f5f5f5;color:#666}.help-btn.primary.data-v-829992d9{background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff}.help-btn.data-v-829992d9:active{transform:scale(.98)}
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival.js
index 4c0c4c5..c5d96b8 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival.js
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival.js
@@ -1 +1 @@
-"use strict";const e=require("../../common/vendor.js"),t=require("../../config/api.js"),s=require("../../utils/payment.js"),i=require("../../common/assets.js"),o={components:{PaymentModal:()=>"../../components/PaymentModal.js"},data:()=>({API_BASE:t.API_BASE,activeTab:"synthesize",loading:!1,message:{type:"",text:""},selectedFile:null,voiceDisplayName:"",voices:[],voiceTypeOptions:[{value:"CLONE",label:"克隆音色"},{value:"OFFICIAL",label:"官方音色(Flash/BigTTS)"}],selectedVoiceType:"CLONE",selectedVoiceTypeLabel:"克隆音色",selectedVoiceId:"",selectedVoiceName:"",selectedDialect:"",selectedLanguageHint:"",selectedLanguageHintLabel:"",selectedSupportsDialect:!1,selectedSupportsLanguageHints:!1,languageHintOptions:["中文(zh)","英文(en)","法语(fr)","德语(de)","日语(ja)","韩语(ko)","俄语(ru)"],dialectOptions:["广东话","东北话","甘肃话","贵州话","河南话","湖北话","江西话","闽南话","宁夏话","山西话","陕西话","山东话","上海话","四川话","天津话","云南话"],ttsText:"",ttsLoading:!1,audioUrl:null,templates:[],expandedCategory:"memorial",isRecording:!1,recorderManager:null,conversationVoiceId:"",conversationVoiceLabel:"",conversationDialect:"",conversationLanguageHint:"",conversationLanguageHintLabel:"",conversationVoiceType:"CLONE",conversationVoiceTypeLabel:"克隆音色",conversationSupportsDialect:!1,conversationSupportsLanguageHints:!1,recognizedText:"",aiResponse:"",conversationAudio:null,isProcessing:!1,memoryIdentity:"",memoryInfo:"",systemPrompt:"",audioFilePath:"",paymentModalData:{show:!1,serviceType:"",serviceName:"",serviceDesc:"",price:0,orderNo:"",paymentTips:"点击确认支付后将开始处理您的请求"},_paymentResolve:null,_paymentReject:null,_paymentOnSuccess:null,_paymentOnFailed:null}),computed:{apiBaseUrl(){return this.API_BASE},voicesOnly(){return(this.voices||[]).map((e=>({voice:e.voice,label:e.voice_name||e.voice,voice_type:e.voice_type,supportsDialect:e.supportsDialect,supportsLanguageHints:e.supportsLanguageHints})))},conversationDisplayVoices(){const e=(this.voices||[]).filter((e=>e&&(e.voice_type||"CLONE")===(this.conversationVoiceType||"CLONE")));if("OFFICIAL"!==(this.conversationVoiceType||"CLONE"))return e;const t=["Cherry","Kai","Mochi","Bunny"],i=["Cherry","Kai","Mochi","Bunny"],o=e.filter((e=>!(e&&t.includes(e.voice)))).map(((e,t)=>({v:e,idx:t}))).sort(((e,t)=>{const s=i.indexOf(e.v.voice),o=i.indexOf(t.v.voice),n=-1===s?999:s,a=-1===o?999:o;return n!==a?n-a:e.idx-t.idx})).map((e=>e.v));return s.mapOfficialVoiceDisplay(o)},displayVoices(){const e=(this.voices||[]).filter((e=>e&&(e.voice_type||"CLONE")===this.selectedVoiceType));if("OFFICIAL"!==(this.selectedVoiceType||"CLONE"))return e;const t=["Cherry","Kai","Mochi","Bunny"],i=["Cherry","Kai","Mochi","Bunny"],o=e.filter((e=>!(e&&t.includes(e.voice)))).map(((e,t)=>({v:e,idx:t}))).sort(((e,t)=>{const s=i.indexOf(e.v.voice),o=i.indexOf(t.v.voice),n=-1===s?999:s,a=-1===o?999:o;return n!==a?n-a:e.idx-t.idx})).map((e=>e.v));return s.mapOfficialVoiceDisplay(o)}},watch:{activeTab(e){this.conversationVoiceId="",this.conversationVoiceLabel="",this.conversationDialect="",this.conversationLanguageHint="",this.conversationLanguageHintLabel="",this.conversationSupportsDialect=!1,this.conversationSupportsLanguageHints=!1,"list"!==e&&"synthesize"!==e&&"conversation"!==e||this.loadVoices()}},onLoad(){this.useDefaultTemplates(),this.loadVoices(),this.loadTemplatesFromServer(),this.initRecorder()},onShow(){!this.checkLogin||!this.checkLogin()||this.voices&&0!==this.voices.length||this.loadVoices()},methods:{onVoiceTypeChange(e){const t=this.voiceTypeOptions[e.detail.value];this.selectedVoiceType=t?t.value:"CLONE",this.selectedVoiceTypeLabel=t?t.label:"克隆音色",this.selectedVoiceId="",this.selectedVoiceName="",this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",this.selectedSupportsDialect=!1,this.selectedSupportsLanguageHints=!1},onConversationVoiceTypeChange(e){const t=this.voiceTypeOptions[e.detail.value];this.conversationVoiceType=t?t.value:"CLONE",this.conversationVoiceTypeLabel=t?t.label:"克隆音色",this.conversationVoiceId="",this.conversationVoiceLabel="",this.conversationDialect="",this.conversationLanguageHint="",this.conversationLanguageHintLabel="",this.conversationSupportsDialect=!1,this.conversationSupportsLanguageHints=!1},showVoiceHelp(){e.index.showModal({title:"💡 如何获取音色?",content:'1️⃣ 点击底部导航"声音克隆"\n\n2️⃣ 点击"上传音频"按钮\n\n3️⃣ 录制或上传10-20秒清晰人声\n\n4️⃣ 创建成功后即可在此选择使用\n\n💡 提示:音色质量越好,合成效果越自然',showCancel:!0,cancelText:"知道了",confirmText:"去创建",success:t=>{t.confirm&&e.index.switchTab({url:"/pages/upload-audio/upload-audio"})}})},checkLogin(){const t=e.index.getStorageSync("token"),s=e.index.getStorageSync("userId");return!(!t||!s)},showMessage(e,t){this.message={type:e,text:t},setTimeout((()=>{this.message={type:"",text:""}}),5e3)},chooseAudioFile(){const t="undefined"!=typeof plus,s="undefined"!=typeof document&&!t,i=void 0!==e.wx$1;if(t)e.index.showModal({title:"选择方式",content:"APP 环境请使用录音功能创建音色(推荐10-20秒清晰朗读)\n\n提示:如需上传音频文件,请使用手机浏览器访问本系统",confirmText:"开始录音",cancelText:"取消",success:e=>{e.confirm&&this.startRecordAudio()}});else if(s){const e=document.createElement("input");e.type="file",e.accept="audio/*,.mp3,.wav,.m4a,.aac",e.onchange=e=>{const t=e.target.files[0];if(t){if(t.size>10485760)return void this.showMessage("error","文件大小不能超过10MB");const e=URL.createObjectURL(t);this.selectedFile={path:e,name:t.name,size:t.size,file:t},this.showMessage("success",`已选择: ${t.name} (${(t.size/1024).toFixed(2)} KB)`)}},e.click()}else i&&e.index.chooseMessageFile({count:1,type:"file",extension:[".mp3",".wav",".m4a",".aac"],success:e=>{const t=e.tempFiles[0];t.size>10485760?this.showMessage("error","文件大小不能超过10MB"):(this.selectedFile={path:t.path,name:t.name,size:t.size},this.showMessage("success",`已选择: ${t.name} (${(t.size/1024).toFixed(2)} KB)`))},fail:e=>{this.showMessage("error","选择文件失败: "+(e.errMsg||"未知错误"))}})},async startRecordAudio(){const t=e.index.getRecorderManager();t.onStart((()=>{this.showMessage("success","正在录音...")})),t.onStop((e=>{this.selectedFile={path:e.tempFilePath,name:"record_"+Date.now()+".mp3"},this.showMessage("success","录音完成")})),t.onError((e=>{console.error("录音失败:",e),this.showMessage("error","录音失败")})),e.index.showModal({title:"录音",content:"点击确定开始录音,录音时长10-20秒",success:e=>{e.confirm&&(t.start({format:"mp3",sampleRate:16e3}),setTimeout((()=>{t.stop()}),2e4))}})},async handleCreateVoice(){if(!this.checkLogin())return void e.index.showModal({title:"提示",content:"请先登录后再使用此功能",confirmText:"去登录",cancelText:"取消",success:t=>{t.confirm&&e.index.navigateTo({url:"/pages/login/login"})}});if(!this.selectedFile)return void this.showMessage("error","请先选择音频文件");if(!this.voiceDisplayName.trim())return void this.showMessage("error","请输入音色名称");const t=`voice${this.voices.length+1}`;this.loading=!0,console.log("[Index] 开始上传音频文件..."),console.log("[Index] 文件路径:",this.selectedFile.path),console.log("[Index] 音色标识:",t),console.log("[Index] 音色显示名称:",this.voiceDisplayName);const s=e.index.getStorageSync("userId")||"",i=e.index.getStorageSync("token")||"";e.index.uploadFile({url:`${this.apiBaseUrl}/api/voice/create`,filePath:this.selectedFile.path,name:"audio",header:{"X-User-Id":s,Authorization:i?`Bearer ${i}`:""},formData:{name:t,displayName:this.voiceDisplayName},success:e=>{if(console.log("[Index] 上传响应:",e),200===e.statusCode)try{const t=JSON.parse(e.data);t.success?(this.showMessage("success",`创建成功!音色: ${this.voiceDisplayName}`),this.selectedFile=null,this.voiceDisplayName="",this.loadVoices()):this.showMessage("error",t.message||"创建失败")}catch(t){console.error("[Index] 解析响应失败:",t),this.showMessage("error","服务器响应格式错误")}else this.showMessage("error",`上传失败: HTTP ${e.statusCode}`)},fail:e=>{console.error("[Index] 上传失败:",e),this.showMessage("error","上传失败: "+(e.errMsg||"未知错误"))},complete:()=>{this.loading=!1}})},async loadVoices(){this.loading=!0;const t=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";console.log("[Revival] 加载音色 - userId:",t,"token:",s?"已设置":"未设置"),e.index.request({url:`${this.apiBaseUrl}/api/voice/list`,method:"GET",header:{"X-User-Id":t,Authorization:s?`Bearer ${s}`:""},success:e=>{if(console.log("[Revival] 音色列表响应:",e.data),e.data.success){const t=["Cherry","Kai","Mochi","Bunny"];this.voices=(e.data.voices||[]).filter((e=>!(e&&e.voice&&e.voice.startsWith("cosyvoice-v3-flash-")))).filter((e=>!(e&&e.voice&&t.includes(e.voice)))),console.log("[Revival] 加载音色数量:",this.voices.length)}else console.error("[Revival] 加载音色失败:",e.data.message)},fail:e=>{console.error("[Revival] 请求失败:",e),this.showMessage("error","加载音色失败")},complete:()=>{this.loading=!1}})},handleDeleteVoice(t){e.index.showModal({title:"确认删除",content:`确定删除音色 ${t}?`,success:s=>{if(s.confirm){console.log("[Revival] 开始删除音色:",t);const s=e.index.getStorageSync("userId")||"",i=e.index.getStorageSync("token")||"";e.index.showLoading({title:"删除中...",mask:!0}),e.index.request({url:`${this.apiBaseUrl}/api/voice/delete/${t}`,method:"DELETE",header:{"X-User-Id":s,Authorization:i?`Bearer ${i}`:""},success:t=>{console.log("[Revival] 删除音色响应:",t),e.index.hideLoading(),200===t.statusCode?t.data&&t.data.success?(this.showMessage("success","删除成功"),this.loadVoices()):this.showMessage("error",t.data.message||"删除失败"):this.showMessage("error",`删除失败: HTTP ${t.statusCode}`)},fail:t=>{console.error("[Revival] 删除音色失败:",t),e.index.hideLoading(),this.showMessage("error","网络请求失败: "+(t.errMsg||"请检查网络连接"))}})}}})},onVoiceChange(e){const t=this.displayVoices[e.detail.value];this.selectedVoiceId=t.voice,this.selectedVoiceName=t.voice_name||t.voice,this.selectedVoiceType=t.voice_type||this.selectedVoiceType||"CLONE",this.selectedVoiceTypeLabel="OFFICIAL"===this.selectedVoiceType?"官方音色(Flash/BigTTS)":"克隆音色",this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",this.selectedSupportsDialect=!!t.supportsDialect,this.selectedSupportsLanguageHints=!!t.supportsLanguageHints,"OFFICIAL"===(this.selectedVoiceType||"CLONE")&&(this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",this.selectedSupportsDialect=!1,this.selectedSupportsLanguageHints=!1)},onDialectChange(e){this.selectedDialect=this.dialectOptions[e.detail.value]||""},onLanguageHintChange(e){const t=this.languageHintOptions[e.detail.value]||"";this.selectedLanguageHintLabel=t;const s=t.match(/\(([^)]+)\)/);this.selectedLanguageHint=s&&s[1]?s[1]:""},onConversationVoiceChange(e){const t=this.conversationDisplayVoices[e.detail.value];this.conversationVoiceId=t.voice,this.conversationVoiceLabel=t.voice_name||t.voice,this.conversationVoiceType=t.voice_type||this.conversationVoiceType||"CLONE",this.conversationVoiceTypeLabel="OFFICIAL"===this.conversationVoiceType?"官方音色(Flash)":"克隆音色",this.conversationDialect="",this.conversationLanguageHint="",this.conversationLanguageHintLabel="",this.conversationSupportsDialect=!!t.supportsDialect,this.conversationSupportsLanguageHints=!!t.supportsLanguageHints,"OFFICIAL"===(this.conversationVoiceType||"CLONE")&&(this.conversationDialect="",this.conversationLanguageHint="",this.conversationLanguageHintLabel="",this.conversationSupportsDialect=!1,this.conversationSupportsLanguageHints=!1)},onConversationDialectChange(e){this.conversationDialect=this.dialectOptions[e.detail.value]||""},onConversationLanguageHintChange(e){const t=this.languageHintOptions[e.detail.value]||"";this.conversationLanguageHintLabel=t;const s=t.match(/\(([^)]+)\)/);this.conversationLanguageHint=s&&s[1]?s[1]:""},toggleCategory(e){this.expandedCategory===e?this.expandedCategory="":this.expandedCategory=e},getTemplatesByCategory(e){return this.templates.filter((t=>t.category===e))},selectTemplate(e){this.ttsText=e.content,this.showMessage("success","已应用模板")},loadTemplatesFromServer(){const t=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";console.log("[Templates] 尝试从服务器加载模板..."),e.index.request({url:`${this.apiBaseUrl}/api/templates/list`,method:"GET",header:{"X-User-Id":t,Authorization:s?`Bearer ${s}`:""},success:e=>{console.log("[Templates] 服务器响应:",e),e.data&&e.data.success&&e.data.templates&&e.data.templates.length>0?(this.templates=e.data.templates,console.log("[Templates] 从服务器加载成功,数量:",this.templates.length)):e.data&&Array.isArray(e.data)&&e.data.length>0?(this.templates=e.data,console.log("[Templates] 从服务器加载成功(数组格式),数量:",this.templates.length)):console.log("[Templates] 服务器无数据,继续使用默认模板")},fail:e=>{console.log("[Templates] 服务器请求失败,继续使用默认模板:",e)}})},useDefaultTemplates(){this.templates=[{category:"memorial",title:"思念",content:"妈妈,我好想你,你在那边还好吗?"},{category:"memorial",title:"感恩",content:"谢谢您一直以来对我的照顾和关爱。"},{category:"memorial",title:"告白",content:"有些话当时没说出口,现在想对您说..."},{category:"greeting",title:"问候",content:"今天天气很好,您最喜欢这样的天气了。"},{category:"greeting",title:"日常",content:"最近过得还好,就是很想您。"},{category:"memory",title:"回忆",content:"还记得小时候您做的红烧肉,真好吃。"},{category:"memory",title:"往事",content:"那年夏天,我们一起去海边的情景还历历在目。"}],console.log("[Templates] 使用默认模板,数量:",this.templates.length)},async handleSynthesize(){this.checkLogin()?this.ttsText.trim()&&this.selectedVoiceId?s.showPaymentModal(this,s.SERVICE_TYPES.TTS_SYNTHESIS.type,(()=>{this.executeSynthesize()}),(e=>{console.error("[Payment] 支付失败:",e)})):this.showMessage("error","请输入文本并选择音色"):e.index.showModal({title:"提示",content:"请先登录后再使用此功能",confirmText:"去登录",cancelText:"取消",success:t=>{t.confirm&&e.index.navigateTo({url:"/pages/login/login"})}})},executeSynthesize(){this.ttsLoading=!0,this.audioUrl=null;const t=this.selectedVoiceId&&this.selectedVoiceId.startsWith("cosyvoice-v3-plus-")?"/api/tts/cosy-synthesize":"/api/tts/synthesize";console.log("[TTS] 发送合成请求:",{url:`${this.apiBaseUrl}${t}`,text:this.ttsText,voiceId:this.selectedVoiceId,dialect:this.selectedDialect});const i=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"",n={text:this.ttsText,voiceId:this.selectedVoiceId,voiceType:this.selectedVoiceType};"OFFICIAL"!==(this.selectedVoiceType||"CLONE")&&this.selectedSupportsDialect&&this.selectedDialect&&(n.dialect=this.selectedDialect),"OFFICIAL"!==(this.selectedVoiceType||"CLONE")&&this.selectedSupportsLanguageHints&&this.selectedLanguageHint&&(n.languageHints=this.selectedLanguageHint),e.index.request({url:`${this.apiBaseUrl}${t}`,method:"POST",header:{"X-User-Id":i,Authorization:o?`Bearer ${o}`:"","content-type":"application/x-www-form-urlencoded"},data:n,success:t=>{console.log("[TTS] 请求成功:",t),402!==t.statusCode?200===t.statusCode?t.data&&t.data.success?(this.showMessage("success","合成成功!"),this.audioUrl=`${this.apiBaseUrl}/api/tts/download/${t.data.audioFile}`,console.log("[TTS] 音频URL:",this.audioUrl)):e.index.showModal({title:"生成失败",content:"合成失败:"+(t.data&&t.data.message?t.data.message:"未知错误")+"\n\n你可以点击“重试”再次生成。\n若已支付但多次生成失败,请联系客服补发(提供订单号/支付时间截图)。",confirmText:"重试",cancelText:"我知道了",success:e=>{e.confirm&&this.executeSynthesize()}}):e.index.showModal({title:"生成失败",content:(t.data&&t.data.message?t.data.message:"生成失败")+"\n\n你可以点击“重试”再次生成。\n若已支付但多次生成失败,请联系客服补发(提供订单号/支付时间截图)。",confirmText:"重试",cancelText:"我知道了",success:e=>{e.confirm&&this.executeSynthesize()}}):e.index.showModal({title:"需要付费",content:t.data&&t.data.message?t.data.message:"免费次数已用完,请先完成支付",confirmText:"去支付",cancelText:"取消",success:e=>{e.confirm&&s.showPaymentModal(this,s.SERVICE_TYPES.TTS_SYNTHESIS.type,(()=>{this.executeSynthesize()}),(e=>{console.error("[Payment] 支付失败:",e)}))}})},fail:t=>{console.error("[TTS] 请求失败:",t),e.index.showModal({title:"生成失败",content:"网络请求失败:"+(t.errMsg||"请检查网络连接")+"\n\n你可以点击“重试”再次生成。\n若已支付但多次生成失败,请联系客服补发(提供订单号/支付时间截图)。",confirmText:"重试",cancelText:"我知道了",success:e=>{e.confirm&&this.executeSynthesize()}})},complete:()=>{this.ttsLoading=!1}})},initRecorder(){this.recorderManager=e.index.getRecorderManager(),this.recorderManager.onStop((e=>{this.audioFilePath=e.tempFilePath,this.handleConversation()})),this.recorderManager.onError((t=>{console.error("[Revival] 录音失败:",t),this.isRecording=!1;t.errMsg&&(t.errMsg.includes("permission")||t.errMsg.includes("authorize")||t.errMsg.includes("denied")||t.errMsg.includes("占用"))?e.index.showModal({title:"需要麦克风权限",content:"录音功能需要麦克风权限才能使用。\n\n请前往:\n手机设置 → 应用管理 → 时光意境 → 权限管理 → 开启麦克风权限",confirmText:"我知道了",showCancel:!1}):this.showMessage("error","录音失败: "+(t.errMsg||"未知错误"))}))},startRecording(){this.checkLogin()?s.showPaymentModal(this,s.SERVICE_TYPES.CONVERSATION.type,(()=>{this.executeRecording()}),(e=>{console.error("[Payment] 支付失败:",e)})):e.index.showModal({title:"提示",content:"请先登录后再使用此功能",confirmText:"去登录",cancelText:"取消",success:t=>{t.confirm&&e.index.navigateTo({url:"/pages/login/login"})}})},executeRecording(){this.recorderManager.start({format:"mp3",sampleRate:16e3,numberOfChannels:1}),this.isRecording=!0,this.recognizedText="",this.aiResponse="",this.conversationAudio=null,this.showMessage("success","开始录音...")},stopRecording(){this.recorderManager.stop(),this.isRecording=!1,this.showMessage("success","处理中...")},buildSystemPrompt(){if(this.memoryIdentity||this.memoryInfo){if(this.memoryIdentity){let e=`你是${this.memoryIdentity},你已经去世。用户正在和你对话。`;return e+="\n\n你的性格特点:\n\n亲切、真实、克制",e+="\n\n你的行事风格:\n\n直接回答,不绕弯",e+="\n\n你的语言特点:\n\n自然口语,语气温和",this.memoryInfo&&(e+=`\n\n补充设定(请严格遵循):\n\n${this.memoryInfo}`),e+="\n\n注意:不要使用括号(包括()和())来描述动作、心理、背景。",e+="\n\n规则:\n\n1. 不要虚构不存在的事,不要编造记忆或经历。\n2. 不要回忆以前(除非用户明确提到并且你能基于已有设定回答)。\n3. 不要使用任何称呼(因为用户可能是任何身份)。\n4. 不要使用emoji/颜文字/特殊符号。\n5. 顺应用户话题,亲切回答问题。\n6. 时刻记住自己是逝者。\n7. 每次回复保持在20~50字之间。",e}let e="你是一位已经去世的人。用户正在和你对话。";return e+="\n\n你的性格特点:\n\n亲切、真实、克制",e+="\n\n你的行事风格:\n\n直接回答,不绕弯",e+="\n\n你的语言特点:\n\n自然口语,语气温和",this.memoryInfo&&(e+=`\n\n补充设定(请严格遵循):\n\n${this.memoryInfo}`),e+="\n\n你可以将动作、神情语气、心理活动、故事背景放在()中来表示,为对话提供补充信息。",e+="\n\n规则:\n\n1. 不要虚构不存在的事,不要编造记忆或经历。\n2. 不要回忆以前(除非用户明确提到并且你能基于已有设定回答)。\n3. 不要使用任何称呼(因为用户可能是任何身份)。\n4. 不要使用emoji/颜文字/特殊符号。\n5. 顺应用户话题,亲切回答问题。\n6. 时刻记住自己是逝者。\n7. 每次回复保持在20~50字之间。",e}let e="你是一位已经去世的人。用户正在和你对话。";return 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字之间。","你是一位已经去世的人。用户正在和你对话。\n\n你的性格特点:\n\n亲切、真实、克制\n\n你的行事风格:\n\n直接回答,不绕弯\n\n你的语言特点:\n\n自然口语,语气温和\n\n注意:不要使用括号(包括()和())来描述动作、心理、背景。\n\n规则:\n\n1. 不要虚构不存在的事,不要编造记忆或经历。\n2. 不要回忆以前(除非用户明确提到并且你能基于已有设定回答)。\n3. 不要使用任何称呼(因为用户可能是任何身份)。\n4. 不要使用emoji/颜文字/特殊符号。\n5. 顺应用户话题,亲切回答问题。\n6. 时刻记住自己是逝者。\n7. 每次回复保持在20~50字之间。"},handleConversation(){this.isProcessing=!0;const t=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"",i={voiceId:this.conversationVoiceId||"",voiceType:this.conversationVoiceType||"CLONE",saveHistory:"false"},o=this.buildSystemPrompt();i.systemPrompt=o,"OFFICIAL"!==(this.conversationVoiceType||"CLONE")&&this.conversationSupportsDialect&&this.conversationDialect&&(i.dialect=this.conversationDialect),"OFFICIAL"!==(this.conversationVoiceType||"CLONE")&&this.conversationSupportsLanguageHints&&this.conversationLanguageHint&&(i.languageHints=this.conversationLanguageHint),e.index.uploadFile({url:`${this.apiBaseUrl}/api/conversation/talk`,filePath:this.audioFilePath,name:"audio",formData:i,header:{"X-User-Id":t,Authorization:s?`Bearer ${s}`:""},success:t=>{console.log("[Index] 对话响应状态码:",t.statusCode),console.log("[Index] 对话响应数据:",t.data);let s=null;try{s="string"==typeof t.data?JSON.parse(t.data):t.data}catch(o){s=null}if(200!==t.statusCode){const i=s&&s.message?s.message:"对话失败: HTTP "+t.statusCode;return void e.index.showModal({title:"对话失败",content:i+"\n\n请重试。若已支付但多次失败,请联系客服补发(提供订单号/支付时间截图)。",showCancel:!1,confirmText:"我知道了"})}if(s&&s.success)return this.recognizedText=s.recognizedText,this.aiResponse=s.aiResponse,this.conversationAudio=`${this.apiBaseUrl}/api/conversation/audio/${s.audioFile}`,void this.showMessage("success","对话成功!");const i=s&&s.message?s.message:"对话失败";e.index.showModal({title:"对话失败",content:i+"\n\n请重试。若已支付但多次失败,请联系客服补发(提供订单号/支付时间截图)。",confirmText:"重试",cancelText:"我知道了",success:e=>{e.confirm&&this.handleConversation()}})},fail:t=>{console.error("[Index] 对话请求失败:",t),e.index.showModal({title:"对话失败",content:"网络请求失败:"+(t.errMsg||"未知错误")+"\n\n请重试。若已支付但多次失败,请联系客服补发(提供订单号/支付时间截图)。",confirmText:"重试",cancelText:"我知道了",success:e=>{e.confirm&&this.handleConversation()}})},complete:()=>{this.isProcessing=!1}})},handleApplyMemory(){if(!this.memoryIdentity.trim())return void this.showMessage("error","请填写身份信息");this.systemPrompt=this.buildSystemPrompt();const t=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";e.index.request({url:`${this.apiBaseUrl}/api/conversation/set-prompt`,method:"POST",header:{"X-User-Id":t,Authorization:s?`Bearer ${s}`:"","content-type":"application/x-www-form-urlencoded"},data:{prompt:this.systemPrompt},success:e=>{e.data.success&&this.showMessage("success","✓ 记忆设定已应用")}})},goToRevival(){console.log("[Revival] 点击复活照片,准备跳转"),e.index.navigateTo({url:"/pages/revival/revival-original",success:()=>{console.log("[Revival] 跳转成功")},fail:t=>{console.error("[Revival] 跳转失败:",t),e.index.showToast({title:"页面跳转失败",icon:"none"})}})},goToPhoneCall(){e.index.switchTab({url:"/pages/phone-call/phone-call"})},goToUpload(){e.index.navigateTo({url:"/pages/upload-audio/upload-audio"})},handleClearHistory(){const t=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";e.index.request({url:`${this.apiBaseUrl}/api/conversation/clear-history`,method:"POST",header:{"X-User-Id":t,Authorization:s?`Bearer ${s}`:""},success:e=>{e.data.success&&(this.recognizedText="",this.aiResponse="",this.conversationAudio=null,this.showMessage("success","已清空"))}})},formatTime(e){if(!e)return"未知时间";const t=new Date(e<1e10?1e3*e:e);if(isNaN(t.getTime()))return"无效时间";return`${t.getFullYear()}年${String(t.getMonth()+1).padStart(2,"0")}月${String(t.getDate()).padStart(2,"0")}日 ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`},handlePaymentClose(){this.paymentModalData.show=!1,this._paymentReject&&this._paymentReject(new Error("用户取消支付"))},async handlePaymentConfirm(e){await s.handlePaymentConfirm(this,e)}}};if(!Array){e.resolveComponent("PaymentModal")()}const n=e._export_sfc(o,[["render",function(t,s,o,n,a,c){return e.e({a:a.message.text},a.message.text?{b:e.t(a.message.text),c:e.n(a.message.type)}:{},{d:e.o(((...e)=>c.goToUpload&&c.goToUpload(...e))),e:e.n("synthesize"===a.activeTab?"active":""),f:e.o((e=>a.activeTab="synthesize")),g:e.n("conversation"===a.activeTab?"active":""),h:e.o((e=>a.activeTab="conversation")),i:e.n("list"===a.activeTab?"active":""),j:e.o((e=>a.activeTab="list")),k:"synthesize"===a.activeTab},"synthesize"===a.activeTab?e.e({l:e.o(((...e)=>c.showVoiceHelp&&c.showVoiceHelp(...e))),m:e.t(a.selectedVoiceTypeLabel),n:a.voiceTypeOptions,o:e.o(((...e)=>c.onVoiceTypeChange&&c.onVoiceTypeChange(...e))),p:e.t(a.selectedVoiceName||"请选择音色"),q:c.displayVoices,r:e.o(((...e)=>c.onVoiceChange&&c.onVoiceChange(...e))),s:a.selectedSupportsDialect&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")},a.selectedSupportsDialect&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")?{t:e.t(a.selectedDialect||"请选择方言(可选)"),v:a.dialectOptions,w:e.o(((...e)=>c.onDialectChange&&c.onDialectChange(...e)))}:{},{x:a.selectedSupportsLanguageHints&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")},a.selectedSupportsLanguageHints&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")?{y:e.t(a.selectedLanguageHintLabel||"请选择语言(可选)"),z:a.languageHintOptions,A:e.o(((...e)=>c.onLanguageHintChange&&c.onLanguageHintChange(...e)))}:{},{B:0===a.templates.length},0===a.templates.length?{}:e.e({C:"memorial"===a.expandedCategory?1:"",D:e.o((e=>c.toggleCategory("memorial"))),E:"memorial"===a.expandedCategory},"memorial"===a.expandedCategory?{F:e.f(c.getTemplatesByCategory("memorial"),((t,s,i)=>({a:e.t(t.title),b:e.t(t.content),c:s,d:e.o((e=>c.selectTemplate(t)),s)})))}:{},{G:"greeting"===a.expandedCategory?1:"",H:e.o((e=>c.toggleCategory("greeting"))),I:"greeting"===a.expandedCategory},"greeting"===a.expandedCategory?{J:e.f(c.getTemplatesByCategory("greeting"),((t,s,i)=>({a:e.t(t.title),b:e.t(t.content),c:s,d:e.o((e=>c.selectTemplate(t)),s)})))}:{},{K:"memory"===a.expandedCategory?1:"",L:e.o((e=>c.toggleCategory("memory"))),M:"memory"===a.expandedCategory},"memory"===a.expandedCategory?{N:e.f(c.getTemplatesByCategory("memory"),((t,s,i)=>({a:e.t(t.title),b:e.t(t.content),c:s,d:e.o((e=>c.selectTemplate(t)),s)})))}:{}),{O:a.ttsText,P:e.o((e=>a.ttsText=e.detail.value)),Q:e.t(a.ttsText.length),R:a.ttsText.length>=90?1:"",S:e.t(a.ttsLoading?"⏳ 合成中...":"🔊 开始合成"),T:a.ttsLoading||!a.ttsText.trim()||!a.selectedVoiceId,U:e.o(((...e)=>c.handleSynthesize&&c.handleSynthesize(...e))),V:a.audioUrl},a.audioUrl?{W:a.audioUrl}:{}):{},{X:"conversation"===a.activeTab},"conversation"===a.activeTab?e.e({Y:a.memoryIdentity,Z:e.o((e=>a.memoryIdentity=e.detail.value)),aa:a.memoryInfo,ab:e.o((e=>a.memoryInfo=e.detail.value)),ac:e.t(a.memoryInfo.length),ad:e.o(((...e)=>c.handleApplyMemory&&c.handleApplyMemory(...e))),ae:e.t(a.conversationVoiceTypeLabel),af:a.voiceTypeOptions,ag:e.o(((...e)=>c.onConversationVoiceTypeChange&&c.onConversationVoiceTypeChange(...e))),ah:e.t(a.conversationVoiceLabel||"请选择音色"),ai:c.conversationDisplayVoices,aj:e.o(((...e)=>c.onConversationVoiceChange&&c.onConversationVoiceChange(...e))),ak:a.conversationSupportsDialect&&"OFFICIAL"!==(a.conversationVoiceType||"CLONE")},a.conversationSupportsDialect&&"OFFICIAL"!==(a.conversationVoiceType||"CLONE")?{al:e.t(a.conversationDialect||"请选择方言(可选)"),am:a.dialectOptions,an:e.o(((...e)=>c.onConversationDialectChange&&c.onConversationDialectChange(...e)))}:{},{ao:a.conversationSupportsLanguageHints&&"OFFICIAL"!==(a.conversationVoiceType||"CLONE")},a.conversationSupportsLanguageHints&&"OFFICIAL"!==(a.conversationVoiceType||"CLONE")?{ap:e.t(a.conversationLanguageHintLabel||"请选择语言(可选)"),aq:a.languageHintOptions,ar:e.o(((...e)=>c.onConversationLanguageHintChange&&c.onConversationLanguageHintChange(...e)))}:{},{as:!a.isRecording&&!a.isProcessing},a.isRecording||a.isProcessing?{}:{at:e.o(((...e)=>c.startRecording&&c.startRecording(...e)))},{av:a.isRecording},a.isRecording?{aw:e.o(((...e)=>c.stopRecording&&c.stopRecording(...e)))}:{},{ax:a.isProcessing},(a.isProcessing,{}),{ay:i._imports_0,az:a.isRecording||a.isProcessing?1:"",aA:e.o((e=>a.isRecording||a.isProcessing?null:c.handleClearHistory())),aB:a.recognizedText},a.recognizedText?{aC:e.t(a.recognizedText)}:{},{aD:a.aiResponse},a.aiResponse?{aE:e.t(a.aiResponse)}:{},{aF:a.conversationAudio},a.conversationAudio?{aG:a.conversationAudio}:{}):{},{aH:"list"===a.activeTab},"list"===a.activeTab?e.e({aI:e.t(a.loading?"⏳":"🔄"),aJ:a.loading,aK:e.o(((...e)=>c.loadVoices&&c.loadVoices(...e))),aL:a.loading},a.loading||0===a.voices.length?{}:{aN:e.f(a.voices,((t,s,o)=>e.e({a:e.t(t.voice_name||t.voice),b:t.is_public},(t.is_public,{}),{c:e.t(c.formatTime(t.create_time,"YYYY-MM-DD HH:mm:ss")),d:!t.is_public},t.is_public?{}:{e:i._imports_0,f:e.o((e=>c.handleDeleteVoice(t.voice)),t.voice)},{g:t.voice})))},{aM:0===a.voices.length}):{},{aO:e.sr("paymentModal","2298a053-0"),aP:e.o(c.handlePaymentClose),aQ:e.o(c.handlePaymentConfirm),aR: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})})}],["__scopeId","data-v-2298a053"]]);wx.createPage(n);
+"use strict";const e=require("../../common/vendor.js"),t=require("../../config/api.js"),s=require("../../utils/payment.js"),i=require("../../common/assets.js"),o={components:{PaymentModal:()=>"../../components/PaymentModal.js"},data:()=>({API_BASE:t.API_BASE,activeTab:"synthesize",loading:!1,message:{type:"",text:""},selectedFile:null,voiceDisplayName:"",voices:[],voiceTypeOptions:[{value:"CLONE",label:"克隆音色"},{value:"OFFICIAL",label:"官方音色(Flash/BigTTS)"}],selectedVoiceType:"CLONE",selectedVoiceTypeLabel:"克隆音色",selectedVoiceId:"",selectedVoiceName:"",selectedDialect:"",selectedLanguageHint:"",selectedLanguageHintLabel:"",selectedSupportsDialect:!1,selectedSupportsLanguageHints:!1,languageHintOptions:["中文(zh)","英文(en)","法语(fr)","德语(de)","日语(ja)","韩语(ko)","俄语(ru)"],dialectOptions:["广东话","东北话","甘肃话","贵州话","河南话","湖北话","江西话","闽南话","宁夏话","山西话","陕西话","山东话","上海话","四川话","天津话","云南话"],ttsText:"",ttsLoading:!1,audioUrl:null,templates:[],expandedCategory:"memorial",isRecording:!1,recorderManager:null,conversationVoiceId:"",conversationVoiceLabel:"",conversationDialect:"",conversationLanguageHint:"",conversationLanguageHintLabel:"",conversationVoiceType:"CLONE",conversationVoiceTypeLabel:"克隆音色",conversationSupportsDialect:!1,conversationSupportsLanguageHints:!1,recognizedText:"",aiResponse:"",conversationAudio:null,isProcessing:!1,memoryIdentity:"",memoryInfo:"",systemPrompt:"",audioFilePath:"",paymentModalData:{show:!1,serviceType:"",serviceName:"",serviceDesc:"",price:0,orderNo:"",paymentTips:"点击确认支付后将开始处理您的请求"},_paymentResolve:null,_paymentReject:null,_paymentOnSuccess:null,_paymentOnFailed:null}),computed:{apiBaseUrl(){return this.API_BASE},voicesOnly(){return(this.voices||[]).map((e=>({voice:e.voice,label:e.voice_name||e.voice,voice_type:e.voice_type,supportsDialect:e.supportsDialect,supportsLanguageHints:e.supportsLanguageHints})))},conversationDisplayVoices(){const e=(this.voices||[]).filter((e=>e&&(e.voice_type||"CLONE")===(this.conversationVoiceType||"CLONE")));if("OFFICIAL"!==(this.conversationVoiceType||"CLONE"))return e;const t=["Cherry","Kai","Mochi","Bunny"],i=["Cherry","Kai","Mochi","Bunny"],o=e.filter((e=>!(e&&t.includes(e.voice)))).map(((e,t)=>({v:e,idx:t}))).sort(((e,t)=>{const s=i.indexOf(e.v.voice),o=i.indexOf(t.v.voice),n=-1===s?999:s,a=-1===o?999:o;return n!==a?n-a:e.idx-t.idx})).map((e=>e.v));return s.mapOfficialVoiceDisplay(o)},displayVoices(){const e=(this.voices||[]).filter((e=>e&&(e.voice_type||"CLONE")===this.selectedVoiceType));if("OFFICIAL"!==(this.selectedVoiceType||"CLONE"))return e;const t=["Cherry","Kai","Mochi","Bunny"],i=["Cherry","Kai","Mochi","Bunny"],o=e.filter((e=>!(e&&t.includes(e.voice)))).map(((e,t)=>({v:e,idx:t}))).sort(((e,t)=>{const s=i.indexOf(e.v.voice),o=i.indexOf(t.v.voice),n=-1===s?999:s,a=-1===o?999:o;return n!==a?n-a:e.idx-t.idx})).map((e=>e.v));return s.mapOfficialVoiceDisplay(o)}},watch:{activeTab(e){this.conversationVoiceId="",this.conversationVoiceLabel="",this.conversationDialect="",this.conversationLanguageHint="",this.conversationLanguageHintLabel="",this.conversationSupportsDialect=!1,this.conversationSupportsLanguageHints=!1,"list"!==e&&"synthesize"!==e&&"conversation"!==e||this.loadVoices()}},onLoad(){this.useDefaultTemplates(),this.loadVoices(),this.loadTemplatesFromServer(),this.initRecorder()},onShow(){!this.checkLogin||!this.checkLogin()||this.voices&&0!==this.voices.length||this.loadVoices()},methods:{onVoiceTypeChange(e){const t=this.voiceTypeOptions[e.detail.value];this.selectedVoiceType=t?t.value:"CLONE",this.selectedVoiceTypeLabel=t?t.label:"克隆音色",this.selectedVoiceId="",this.selectedVoiceName="",this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",this.selectedSupportsDialect=!1,this.selectedSupportsLanguageHints=!1},onConversationVoiceTypeChange(e){const t=this.voiceTypeOptions[e.detail.value];this.conversationVoiceType=t?t.value:"CLONE",this.conversationVoiceTypeLabel=t?t.label:"克隆音色",this.conversationVoiceId="",this.conversationVoiceLabel="",this.conversationDialect="",this.conversationLanguageHint="",this.conversationLanguageHintLabel="",this.conversationSupportsDialect=!1,this.conversationSupportsLanguageHints=!1},showVoiceHelp(){e.index.showModal({title:"💡 如何获取音色?",content:'1️⃣ 点击底部导航"声音克隆"\n\n2️⃣ 点击"上传音频"按钮\n\n3️⃣ 录制或上传10-20秒清晰人声\n\n4️⃣ 创建成功后即可在此选择使用\n\n💡 提示:音色质量越好,合成效果越自然',showCancel:!0,cancelText:"知道了",confirmText:"去创建",success:t=>{t.confirm&&e.index.switchTab({url:"/pages/upload-audio/upload-audio"})}})},checkLogin(){const t=e.index.getStorageSync("token"),s=e.index.getStorageSync("userId");return!(!t||!s)},showMessage(e,t){this.message={type:e,text:t},setTimeout((()=>{this.message={type:"",text:""}}),5e3)},chooseAudioFile(){const t="undefined"!=typeof plus,s="undefined"!=typeof document&&!t,i=void 0!==e.wx$1;if(t)e.index.showModal({title:"选择方式",content:"APP 环境请使用录音功能创建音色(推荐10-20秒清晰朗读)\n\n提示:如需上传音频文件,请使用手机浏览器访问本系统",confirmText:"开始录音",cancelText:"取消",success:e=>{e.confirm&&this.startRecordAudio()}});else if(s){const e=document.createElement("input");e.type="file",e.accept="audio/*,.mp3,.wav,.m4a,.aac",e.onchange=e=>{const t=e.target.files[0];if(t){if(t.size>10485760)return void this.showMessage("error","文件大小不能超过10MB");const e=URL.createObjectURL(t);this.selectedFile={path:e,name:t.name,size:t.size,file:t},this.showMessage("success",`已选择: ${t.name} (${(t.size/1024).toFixed(2)} KB)`)}},e.click()}else i&&e.index.chooseMessageFile({count:1,type:"file",extension:[".mp3",".wav",".m4a",".aac"],success:e=>{const t=e.tempFiles[0];t.size>10485760?this.showMessage("error","文件大小不能超过10MB"):(this.selectedFile={path:t.path,name:t.name,size:t.size},this.showMessage("success",`已选择: ${t.name} (${(t.size/1024).toFixed(2)} KB)`))},fail:e=>{this.showMessage("error","选择文件失败: "+(e.errMsg||"未知错误"))}})},async startRecordAudio(){const t=e.index.getRecorderManager();t.onStart((()=>{this.showMessage("success","正在录音...")})),t.onStop((e=>{this.selectedFile={path:e.tempFilePath,name:"record_"+Date.now()+".mp3"},this.showMessage("success","录音完成")})),t.onError((e=>{console.error("录音失败:",e),this.showMessage("error","录音失败")})),e.index.showModal({title:"录音",content:"点击确定开始录音,录音时长10-20秒",success:e=>{e.confirm&&(t.start({format:"mp3",sampleRate:16e3}),setTimeout((()=>{t.stop()}),2e4))}})},async handleCreateVoice(){if(!this.checkLogin())return void e.index.showModal({title:"提示",content:"请先登录后再使用此功能",confirmText:"去登录",cancelText:"取消",success:t=>{t.confirm&&e.index.navigateTo({url:"/pages/login/login"})}});if(!this.selectedFile)return void this.showMessage("error","请先选择音频文件");if(!this.voiceDisplayName.trim())return void this.showMessage("error","请输入音色名称");const t=`voice${this.voices.length+1}`;this.loading=!0,console.log("[Index] 开始上传音频文件..."),console.log("[Index] 文件路径:",this.selectedFile.path),console.log("[Index] 音色标识:",t),console.log("[Index] 音色显示名称:",this.voiceDisplayName);const s=e.index.getStorageSync("userId")||"",i=e.index.getStorageSync("token")||"";e.index.uploadFile({url:`${this.apiBaseUrl}/api/voice/create`,filePath:this.selectedFile.path,name:"audio",header:{"X-User-Id":s,Authorization:i?`Bearer ${i}`:""},formData:{name:t,displayName:this.voiceDisplayName},success:e=>{if(console.log("[Index] 上传响应:",e),200===e.statusCode)try{const t=JSON.parse(e.data);t.success?(this.showMessage("success",`创建成功!音色: ${this.voiceDisplayName}`),this.selectedFile=null,this.voiceDisplayName="",this.loadVoices()):this.showMessage("error",t.message||"创建失败")}catch(t){console.error("[Index] 解析响应失败:",t),this.showMessage("error","服务器响应格式错误")}else this.showMessage("error",`上传失败: HTTP ${e.statusCode}`)},fail:e=>{console.error("[Index] 上传失败:",e),this.showMessage("error","上传失败: "+(e.errMsg||"未知错误"))},complete:()=>{this.loading=!1}})},async loadVoices(){this.loading=!0;const t=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";console.log("[Revival] 加载音色 - userId:",t,"token:",s?"已设置":"未设置"),e.index.request({url:`${this.apiBaseUrl}/api/voice/list`,method:"GET",header:{"X-User-Id":t,Authorization:s?`Bearer ${s}`:""},success:e=>{if(console.log("[Revival] 音色列表响应:",e.data),e.data.success){const t=["Cherry","Kai","Mochi","Bunny"];this.voices=(e.data.voices||[]).filter((e=>!(e&&e.voice&&e.voice.startsWith("cosyvoice-v3-flash-")))).filter((e=>!(e&&e.voice&&t.includes(e.voice)))),console.log("[Revival] 加载音色数量:",this.voices.length)}else console.error("[Revival] 加载音色失败:",e.data.message)},fail:e=>{console.error("[Revival] 请求失败:",e),this.showMessage("error","加载音色失败")},complete:()=>{this.loading=!1}})},handleDeleteVoice(t){e.index.showModal({title:"确认删除",content:`确定删除音色 ${t}?`,success:s=>{if(s.confirm){console.log("[Revival] 开始删除音色:",t);const s=e.index.getStorageSync("userId")||"",i=e.index.getStorageSync("token")||"";e.index.showLoading({title:"删除中...",mask:!0}),e.index.request({url:`${this.apiBaseUrl}/api/voice/delete/${t}`,method:"DELETE",header:{"X-User-Id":s,Authorization:i?`Bearer ${i}`:""},success:t=>{console.log("[Revival] 删除音色响应:",t),e.index.hideLoading(),200===t.statusCode?t.data&&t.data.success?(this.showMessage("success","删除成功"),this.loadVoices()):this.showMessage("error",t.data.message||"删除失败"):this.showMessage("error",`删除失败: HTTP ${t.statusCode}`)},fail:t=>{console.error("[Revival] 删除音色失败:",t),e.index.hideLoading(),this.showMessage("error","网络请求失败: "+(t.errMsg||"请检查网络连接"))}})}}})},onVoiceChange(e){const t=this.displayVoices[e.detail.value];this.selectedVoiceId=t.voice,this.selectedVoiceName=t.voice_name||t.voice,this.selectedVoiceType=t.voice_type||this.selectedVoiceType||"CLONE",this.selectedVoiceTypeLabel="OFFICIAL"===this.selectedVoiceType?"官方音色(Flash/BigTTS)":"克隆音色",this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",this.selectedSupportsDialect=!!t.supportsDialect,this.selectedSupportsLanguageHints=!!t.supportsLanguageHints,"OFFICIAL"===(this.selectedVoiceType||"CLONE")&&(this.selectedDialect="",this.selectedLanguageHint="",this.selectedLanguageHintLabel="",this.selectedSupportsDialect=!1,this.selectedSupportsLanguageHints=!1)},onDialectChange(e){this.selectedDialect=this.dialectOptions[e.detail.value]||""},onLanguageHintChange(e){const t=this.languageHintOptions[e.detail.value]||"";this.selectedLanguageHintLabel=t;const s=t.match(/\(([^)]+)\)/);this.selectedLanguageHint=s&&s[1]?s[1]:""},onConversationVoiceChange(e){const t=this.conversationDisplayVoices[e.detail.value];this.conversationVoiceId=t.voice,this.conversationVoiceLabel=t.voice_name||t.voice,this.conversationVoiceType=t.voice_type||this.conversationVoiceType||"CLONE",this.conversationVoiceTypeLabel="OFFICIAL"===this.conversationVoiceType?"官方音色(Flash)":"克隆音色",this.conversationDialect="",this.conversationLanguageHint="",this.conversationLanguageHintLabel="",this.conversationSupportsDialect=!!t.supportsDialect,this.conversationSupportsLanguageHints=!!t.supportsLanguageHints,"OFFICIAL"===(this.conversationVoiceType||"CLONE")&&(this.conversationDialect="",this.conversationLanguageHint="",this.conversationLanguageHintLabel="",this.conversationSupportsDialect=!1,this.conversationSupportsLanguageHints=!1)},onConversationDialectChange(e){this.conversationDialect=this.dialectOptions[e.detail.value]||""},onConversationLanguageHintChange(e){const t=this.languageHintOptions[e.detail.value]||"";this.conversationLanguageHintLabel=t;const s=t.match(/\(([^)]+)\)/);this.conversationLanguageHint=s&&s[1]?s[1]:""},toggleCategory(e){this.expandedCategory===e?this.expandedCategory="":this.expandedCategory=e},getTemplatesByCategory(e){return this.templates.filter((t=>t.category===e))},selectTemplate(e){this.ttsText=e.content,this.showMessage("success","已应用模板")},loadTemplatesFromServer(){const t=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";console.log("[Templates] 尝试从服务器加载模板..."),e.index.request({url:`${this.apiBaseUrl}/api/templates/list`,method:"GET",header:{"X-User-Id":t,Authorization:s?`Bearer ${s}`:""},success:e=>{console.log("[Templates] 服务器响应:",e),e.data&&e.data.success&&e.data.templates&&e.data.templates.length>0?(this.templates=e.data.templates,console.log("[Templates] 从服务器加载成功,数量:",this.templates.length)):e.data&&Array.isArray(e.data)&&e.data.length>0?(this.templates=e.data,console.log("[Templates] 从服务器加载成功(数组格式),数量:",this.templates.length)):console.log("[Templates] 服务器无数据,继续使用默认模板")},fail:e=>{console.log("[Templates] 服务器请求失败,继续使用默认模板:",e)}})},useDefaultTemplates(){this.templates=[{category:"memorial",title:"思念",content:"妈妈,我好想你,你在那边还好吗?"},{category:"memorial",title:"感恩",content:"谢谢您一直以来对我的照顾和关爱。"},{category:"memorial",title:"告白",content:"有些话当时没说出口,现在想对您说..."},{category:"greeting",title:"问候",content:"今天天气很好,您最喜欢这样的天气了。"},{category:"greeting",title:"日常",content:"最近过得还好,就是很想您。"},{category:"memory",title:"回忆",content:"还记得小时候您做的红烧肉,真好吃。"},{category:"memory",title:"往事",content:"那年夏天,我们一起去海边的情景还历历在目。"}],console.log("[Templates] 使用默认模板,数量:",this.templates.length)},async handleSynthesize(){this.checkLogin()?this.ttsText.trim()&&this.selectedVoiceId?s.showPaymentModal(this,s.SERVICE_TYPES.TTS_SYNTHESIS.type,(()=>{this.executeSynthesize()}),(e=>{console.error("[Payment] 支付失败:",e)})):this.showMessage("error","请输入文本并选择音色"):e.index.showModal({title:"提示",content:"请先登录后再使用此功能",confirmText:"去登录",cancelText:"取消",success:t=>{t.confirm&&e.index.navigateTo({url:"/pages/login/login"})}})},executeSynthesize(){this.ttsLoading=!0,this.audioUrl=null;const t=this.selectedVoiceId&&this.selectedVoiceId.startsWith("cosyvoice-v3-plus-")?"/api/tts/cosy-synthesize":"/api/tts/synthesize";console.log("[TTS] 发送合成请求:",{url:`${this.apiBaseUrl}${t}`,text:this.ttsText,voiceId:this.selectedVoiceId,dialect:this.selectedDialect});const i=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"",n={text:this.ttsText,voiceId:this.selectedVoiceId,voiceType:this.selectedVoiceType};"OFFICIAL"!==(this.selectedVoiceType||"CLONE")&&this.selectedSupportsDialect&&this.selectedDialect&&(n.dialect=this.selectedDialect),"OFFICIAL"!==(this.selectedVoiceType||"CLONE")&&this.selectedSupportsLanguageHints&&this.selectedLanguageHint&&(n.languageHints=this.selectedLanguageHint),e.index.request({url:`${this.apiBaseUrl}${t}`,method:"POST",header:{"X-User-Id":i,Authorization:o?`Bearer ${o}`:"","content-type":"application/x-www-form-urlencoded"},data:n,success:t=>{console.log("[TTS] 请求成功:",t),402!==t.statusCode?200===t.statusCode?t.data&&t.data.success?(this.showMessage("success","合成成功!"),this.audioUrl=`${this.apiBaseUrl}/api/tts/download/${t.data.audioFile}`,console.log("[TTS] 音频URL:",this.audioUrl)):e.index.showModal({title:"生成失败",content:"合成失败:"+(t.data&&t.data.message?t.data.message:"未知错误")+"\n\n你可以点击“重试”再次生成。\n若已支付但多次生成失败,请联系客服补发(提供订单号/支付时间截图)。",confirmText:"重试",cancelText:"我知道了",success:e=>{e.confirm&&this.executeSynthesize()}}):e.index.showModal({title:"生成失败",content:(t.data&&t.data.message?t.data.message:"生成失败")+"\n\n你可以点击“重试”再次生成。\n若已支付但多次生成失败,请联系客服补发(提供订单号/支付时间截图)。",confirmText:"重试",cancelText:"我知道了",success:e=>{e.confirm&&this.executeSynthesize()}}):e.index.showModal({title:"需要付费",content:t.data&&t.data.message?t.data.message:"免费次数已用完,请先完成支付",confirmText:"去支付",cancelText:"取消",success:e=>{e.confirm&&s.showPaymentModal(this,s.SERVICE_TYPES.TTS_SYNTHESIS.type,(()=>{this.executeSynthesize()}),(e=>{console.error("[Payment] 支付失败:",e)}))}})},fail:t=>{console.error("[TTS] 请求失败:",t),e.index.showModal({title:"生成失败",content:"网络请求失败:"+(t.errMsg||"请检查网络连接")+"\n\n你可以点击“重试”再次生成。\n若已支付但多次生成失败,请联系客服补发(提供订单号/支付时间截图)。",confirmText:"重试",cancelText:"我知道了",success:e=>{e.confirm&&this.executeSynthesize()}})},complete:()=>{this.ttsLoading=!1}})},initRecorder(){this.recorderManager=e.index.getRecorderManager(),this.recorderManager.onStop((e=>{this.audioFilePath=e.tempFilePath,this.handleConversation()})),this.recorderManager.onError((t=>{console.error("[Revival] 录音失败:",t),this.isRecording=!1;t.errMsg&&(t.errMsg.includes("permission")||t.errMsg.includes("authorize")||t.errMsg.includes("denied")||t.errMsg.includes("占用"))?e.index.showModal({title:"需要麦克风权限",content:"录音功能需要麦克风权限才能使用。\n\n请前往:\n手机设置 → 应用管理 → 时光意境 → 权限管理 → 开启麦克风权限",confirmText:"我知道了",showCancel:!1}):this.showMessage("error","录音失败: "+(t.errMsg||"未知错误"))}))},startRecording(){this.checkLogin()?s.showPaymentModal(this,s.SERVICE_TYPES.CONVERSATION.type,(()=>{this.executeRecording()}),(e=>{console.error("[Payment] 支付失败:",e)})):e.index.showModal({title:"提示",content:"请先登录后再使用此功能",confirmText:"去登录",cancelText:"取消",success:t=>{t.confirm&&e.index.navigateTo({url:"/pages/login/login"})}})},executeRecording(){this.recorderManager.start({format:"mp3",sampleRate:16e3,numberOfChannels:1}),this.isRecording=!0,this.recognizedText="",this.aiResponse="",this.conversationAudio=null,this.showMessage("success","开始录音...")},stopRecording(){this.recorderManager.stop(),this.isRecording=!1,this.showMessage("success","处理中...")},buildSystemPrompt(){if(this.memoryIdentity||this.memoryInfo){if(this.memoryIdentity){let e=`你是${this.memoryIdentity},你已经去世。用户正在和你对话。`;return e+="\n\n你的性格特点:\n\n亲切、真实、克制",e+="\n\n你的行事风格:\n\n直接回答,不绕弯",e+="\n\n你的语言特点:\n\n自然口语,语气温和",this.memoryInfo&&(e+=`\n\n补充设定(请严格遵循):\n\n${this.memoryInfo}`),e+="\n\n注意:不要使用括号(包括()和())来描述动作、心理、背景。",e+="\n\n规则:\n\n1. 不要虚构不存在的事,不要编造记忆或经历。\n2. 不要回忆以前(除非用户明确提到并且你能基于已有设定回答)。\n3. 不要使用任何称呼(因为用户可能是任何身份)。\n4. 不要使用emoji/颜文字/特殊符号。\n5. 顺应用户话题,亲切回答问题。\n6. 时刻记住自己是逝者。\n7. 每次回复保持在20~50字之间。",e}let e="你是一位已经去世的人。用户正在和你对话。";return e+="\n\n你的性格特点:\n\n亲切、真实、克制",e+="\n\n你的行事风格:\n\n直接回答,不绕弯",e+="\n\n你的语言特点:\n\n自然口语,语气温和",this.memoryInfo&&(e+=`\n\n补充设定(请严格遵循):\n\n${this.memoryInfo}`),e+="\n\n你可以将动作、神情语气、心理活动、故事背景放在()中来表示,为对话提供补充信息。",e+="\n\n规则:\n\n1. 不要虚构不存在的事,不要编造记忆或经历。\n2. 不要回忆以前(除非用户明确提到并且你能基于已有设定回答)。\n3. 不要使用任何称呼(因为用户可能是任何身份)。\n4. 不要使用emoji/颜文字/特殊符号。\n5. 顺应用户话题,亲切回答问题。\n6. 时刻记住自己是逝者。\n7. 每次回复保持在20~50字之间。",e}let e="你是一位已经去世的人。用户正在和你对话。";return 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字之间。","你是一位已经去世的人。用户正在和你对话。\n\n你的性格特点:\n\n亲切、真实、克制\n\n你的行事风格:\n\n直接回答,不绕弯\n\n你的语言特点:\n\n自然口语,语气温和\n\n注意:不要使用括号(包括()和())来描述动作、心理、背景。\n\n规则:\n\n1. 不要虚构不存在的事,不要编造记忆或经历。\n2. 不要回忆以前(除非用户明确提到并且你能基于已有设定回答)。\n3. 不要使用任何称呼(因为用户可能是任何身份)。\n4. 不要使用emoji/颜文字/特殊符号。\n5. 顺应用户话题,亲切回答问题。\n6. 时刻记住自己是逝者。\n7. 每次回复保持在20~50字之间。"},handleConversation(){this.isProcessing=!0;const t=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"",i={voiceId:this.conversationVoiceId||"",voiceType:this.conversationVoiceType||"CLONE",saveHistory:"false"},o=this.buildSystemPrompt();i.systemPrompt=o,"OFFICIAL"!==(this.conversationVoiceType||"CLONE")&&this.conversationSupportsDialect&&this.conversationDialect&&(i.dialect=this.conversationDialect),"OFFICIAL"!==(this.conversationVoiceType||"CLONE")&&this.conversationSupportsLanguageHints&&this.conversationLanguageHint&&(i.languageHints=this.conversationLanguageHint),e.index.uploadFile({url:`${this.apiBaseUrl}/api/conversation/talk`,filePath:this.audioFilePath,name:"audio",formData:i,header:{"X-User-Id":t,Authorization:s?`Bearer ${s}`:""},success:t=>{console.log("[Index] 对话响应状态码:",t.statusCode),console.log("[Index] 对话响应数据:",t.data);let s=null;try{s="string"==typeof t.data?JSON.parse(t.data):t.data}catch(o){s=null}if(200!==t.statusCode){const i=s&&s.message?s.message:"对话失败: HTTP "+t.statusCode;return void e.index.showModal({title:"对话失败",content:i+"\n\n请重试。若已支付但多次失败,请联系客服补发(提供订单号/支付时间截图)。",showCancel:!1,confirmText:"我知道了"})}if(s&&s.success)return this.recognizedText=s.recognizedText,this.aiResponse=s.aiResponse,this.conversationAudio=`${this.apiBaseUrl}/api/conversation/audio/${s.audioFile}`,void this.showMessage("success","对话成功!");const i=s&&s.message?s.message:"对话失败";e.index.showModal({title:"对话失败",content:i+"\n\n请重试。若已支付但多次失败,请联系客服补发(提供订单号/支付时间截图)。",confirmText:"重试",cancelText:"我知道了",success:e=>{e.confirm&&this.handleConversation()}})},fail:t=>{console.error("[Index] 对话请求失败:",t),e.index.showModal({title:"对话失败",content:"网络请求失败:"+(t.errMsg||"未知错误")+"\n\n请重试。若已支付但多次失败,请联系客服补发(提供订单号/支付时间截图)。",confirmText:"重试",cancelText:"我知道了",success:e=>{e.confirm&&this.handleConversation()}})},complete:()=>{this.isProcessing=!1}})},handleApplyMemory(){if(!this.memoryIdentity.trim())return void this.showMessage("error","请填写身份信息");this.systemPrompt=this.buildSystemPrompt();const t=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";e.index.request({url:`${this.apiBaseUrl}/api/conversation/set-prompt`,method:"POST",header:{"X-User-Id":t,Authorization:s?`Bearer ${s}`:"","content-type":"application/x-www-form-urlencoded"},data:{prompt:this.systemPrompt},success:e=>{e.data.success&&this.showMessage("success","✓ 记忆设定已应用")}})},goToRevival(){console.log("[Revival] 点击复活照片,准备跳转"),e.index.navigateTo({url:"/pages/revival/revival-original",success:()=>{console.log("[Revival] 跳转成功")},fail:t=>{console.error("[Revival] 跳转失败:",t),e.index.showToast({title:"页面跳转失败",icon:"none"})}})},goToPhoneCall(){e.index.switchTab({url:"/pages/phone-call/phone-call"})},goToUpload(){e.index.navigateTo({url:"/pages/upload-audio/upload-audio"})},handleClearHistory(){const t=e.index.getStorageSync("userId")||"",s=e.index.getStorageSync("token")||"";e.index.request({url:`${this.apiBaseUrl}/api/conversation/clear-history`,method:"POST",header:{"X-User-Id":t,Authorization:s?`Bearer ${s}`:""},success:e=>{e.data.success&&(this.recognizedText="",this.aiResponse="",this.conversationAudio=null,this.showMessage("success","已清空"))}})},formatTime(e){if(!e)return"未知时间";const t=new Date(e<1e10?1e3*e:e);if(isNaN(t.getTime()))return"无效时间";return`${t.getFullYear()}年${String(t.getMonth()+1).padStart(2,"0")}月${String(t.getDate()).padStart(2,"0")}日 ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`},handlePaymentClose(){this.paymentModalData.show=!1,this._paymentReject&&this._paymentReject(new Error("用户取消支付"))},async handlePaymentConfirm(e){await s.handlePaymentConfirm(this,e)}}};if(!Array){e.resolveComponent("PaymentModal")()}const n=e._export_sfc(o,[["render",function(t,s,o,n,a,c){return e.e({a:a.message.text},a.message.text?{b:e.t(a.message.text),c:e.n(a.message.type)}:{},{d:e.o(((...e)=>c.goToUpload&&c.goToUpload(...e))),e:e.n("synthesize"===a.activeTab?"active":""),f:e.o((e=>a.activeTab="synthesize")),g:e.n("conversation"===a.activeTab?"active":""),h:e.o((e=>a.activeTab="conversation")),i:e.n("list"===a.activeTab?"active":""),j:e.o((e=>a.activeTab="list")),k:"synthesize"===a.activeTab},"synthesize"===a.activeTab?e.e({l:e.o(((...e)=>c.showVoiceHelp&&c.showVoiceHelp(...e))),m:e.t(a.selectedVoiceTypeLabel),n:a.voiceTypeOptions,o:e.o(((...e)=>c.onVoiceTypeChange&&c.onVoiceTypeChange(...e))),p:e.t(a.selectedVoiceName||"请选择音色"),q:c.displayVoices,r:e.o(((...e)=>c.onVoiceChange&&c.onVoiceChange(...e))),s:a.selectedSupportsDialect&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")},a.selectedSupportsDialect&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")?{t:e.t(a.selectedDialect||"请选择方言(可选)"),v:a.dialectOptions,w:e.o(((...e)=>c.onDialectChange&&c.onDialectChange(...e)))}:{},{x:a.selectedSupportsLanguageHints&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")},a.selectedSupportsLanguageHints&&"OFFICIAL"!==(a.selectedVoiceType||"CLONE")?{y:e.t(a.selectedLanguageHintLabel||"请选择语言(可选)"),z:a.languageHintOptions,A:e.o(((...e)=>c.onLanguageHintChange&&c.onLanguageHintChange(...e)))}:{},{B:0===a.templates.length},0===a.templates.length?{}:e.e({C:"memorial"===a.expandedCategory?1:"",D:e.o((e=>c.toggleCategory("memorial"))),E:"memorial"===a.expandedCategory},"memorial"===a.expandedCategory?{F:e.f(c.getTemplatesByCategory("memorial"),((t,s,i)=>({a:e.t(t.title),b:e.t(t.content),c:s,d:e.o((e=>c.selectTemplate(t)),s)})))}:{},{G:"greeting"===a.expandedCategory?1:"",H:e.o((e=>c.toggleCategory("greeting"))),I:"greeting"===a.expandedCategory},"greeting"===a.expandedCategory?{J:e.f(c.getTemplatesByCategory("greeting"),((t,s,i)=>({a:e.t(t.title),b:e.t(t.content),c:s,d:e.o((e=>c.selectTemplate(t)),s)})))}:{},{K:"memory"===a.expandedCategory?1:"",L:e.o((e=>c.toggleCategory("memory"))),M:"memory"===a.expandedCategory},"memory"===a.expandedCategory?{N:e.f(c.getTemplatesByCategory("memory"),((t,s,i)=>({a:e.t(t.title),b:e.t(t.content),c:s,d:e.o((e=>c.selectTemplate(t)),s)})))}:{}),{O:a.ttsText,P:e.o((e=>a.ttsText=e.detail.value)),Q:e.t(a.ttsText.length),R:a.ttsText.length>=90?1:"",S:e.t(a.ttsLoading?"⏳ 合成中...":"🔊 开始合成"),T:a.ttsLoading||!a.ttsText.trim()||!a.selectedVoiceId,U:e.o(((...e)=>c.handleSynthesize&&c.handleSynthesize(...e))),V:a.audioUrl},a.audioUrl?{W:a.audioUrl}:{}):{},{X:"conversation"===a.activeTab},"conversation"===a.activeTab?e.e({Y:a.memoryIdentity,Z:e.o((e=>a.memoryIdentity=e.detail.value)),aa:a.memoryInfo,ab:e.o((e=>a.memoryInfo=e.detail.value)),ac:e.t(a.memoryInfo.length),ad:e.o(((...e)=>c.handleApplyMemory&&c.handleApplyMemory(...e))),ae:e.t(a.conversationVoiceTypeLabel),af:a.voiceTypeOptions,ag:e.o(((...e)=>c.onConversationVoiceTypeChange&&c.onConversationVoiceTypeChange(...e))),ah:e.t(a.conversationVoiceLabel||"请选择音色"),ai:c.conversationDisplayVoices,aj:e.o(((...e)=>c.onConversationVoiceChange&&c.onConversationVoiceChange(...e))),ak:a.conversationSupportsDialect&&"OFFICIAL"!==(a.conversationVoiceType||"CLONE")},a.conversationSupportsDialect&&"OFFICIAL"!==(a.conversationVoiceType||"CLONE")?{al:e.t(a.conversationDialect||"请选择方言(可选)"),am:a.dialectOptions,an:e.o(((...e)=>c.onConversationDialectChange&&c.onConversationDialectChange(...e)))}:{},{ao:a.conversationSupportsLanguageHints&&"OFFICIAL"!==(a.conversationVoiceType||"CLONE")},a.conversationSupportsLanguageHints&&"OFFICIAL"!==(a.conversationVoiceType||"CLONE")?{ap:e.t(a.conversationLanguageHintLabel||"请选择语言(可选)"),aq:a.languageHintOptions,ar:e.o(((...e)=>c.onConversationLanguageHintChange&&c.onConversationLanguageHintChange(...e)))}:{},{as:!a.isRecording&&!a.isProcessing},a.isRecording||a.isProcessing?{}:{at:e.o(((...e)=>c.startRecording&&c.startRecording(...e)))},{av:a.isRecording},a.isRecording?{aw:e.o(((...e)=>c.stopRecording&&c.stopRecording(...e)))}:{},{ax:a.isProcessing},(a.isProcessing,{}),{ay:i._imports_0,az:a.isRecording||a.isProcessing?1:"",aA:e.o((e=>a.isRecording||a.isProcessing?null:c.handleClearHistory())),aB:a.recognizedText},a.recognizedText?{aC:e.t(a.recognizedText)}:{},{aD:a.aiResponse},a.aiResponse?{aE:e.t(a.aiResponse)}:{},{aF:a.conversationAudio},a.conversationAudio?{aG:a.conversationAudio}:{}):{},{aH:"list"===a.activeTab},"list"===a.activeTab?e.e({aI:e.t(a.loading?"⏳":"🔄"),aJ:a.loading,aK:e.o(((...e)=>c.loadVoices&&c.loadVoices(...e))),aL:a.loading},a.loading||0===a.voices.length?{}:{aN:e.f(a.voices,((t,s,o)=>e.e({a:e.t(t.voice_name||t.voice),b:t.is_public},(t.is_public,{}),{c:e.t(c.formatTime(t.create_time,"YYYY-MM-DD HH:mm:ss")),d:!t.is_public},t.is_public?{}:{e:i._imports_0,f:e.o((e=>c.handleDeleteVoice(t.voice)),t.voice)},{g:t.voice})))},{aM:0===a.voices.length}):{},{aO:e.sr("paymentModal","41b5703e-0"),aP:e.o(c.handlePaymentClose),aQ:e.o(c.handlePaymentConfirm),aR: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})})}],["__scopeId","data-v-41b5703e"]]);wx.createPage(n);
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival.wxml
index f2ae9cd..475e9db 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival.wxml
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival.wxml
@@ -1 +1 @@
-{{b}} 🔊 合成 💬 对话 📋 列表 🎵 语音合成选择音色类型❓{{m}}{{p}}💡 请先在"声音克隆"页面创建音色方言{{t}}语言提示(可选){{y}}💡 仅处理第一个值;不设置不生效 文案模板⏳ 加载中...{{template.a}}{{template.b}}{{template.a}}{{template.b}}{{template.a}}{{template.b}}输入文本(最多100字){{Q}} / 100 ✅ 合成成功!💬 实时语音对话身份*基础信息{{ac}}/200选择回复音色{{ae}}{{ah}}方言{{al}}语言提示(可选){{ap}}💡 仅处理第一个值;不设置不生效 🎤 开始说话 ⏹️ 停止录音 ⏳ 处理中... 🎤 您说:{{aC}}💬 AI回复:{{aE}}🔊 语音回复:⏳ 加载中...🎤 暂无音色{{voice.a}} 公共{{voice.c}}
\ No newline at end of file
+{{b}} 🔊 合成 💬 对话 📋 列表 🎵 语音合成选择音色类型❓{{m}}{{p}}💡 请先在"声音克隆"页面创建音色方言{{t}}语言提示(可选){{y}}💡 仅处理第一个值;不设置不生效 文案模板⏳ 加载中...{{template.a}}{{template.b}}{{template.a}}{{template.b}}{{template.a}}{{template.b}}输入文本(最多100字){{Q}} / 100 本服务为AI生成内容,结果仅供参考✅ 合成成功!💬 实时语音对话身份*基础信息{{ac}}/200选择回复音色{{ae}}{{ah}}方言{{al}}语言提示(可选){{ap}}💡 仅处理第一个值;不设置不生效 🎤 开始说话 ⏹️ 停止录音 ⏳ 处理中... 🎤 您说:{{aC}}💬 AI回复:{{aE}}🔊 语音回复:⏳ 加载中...🎤 暂无音色{{voice.a}} 公共{{voice.c}}
\ No newline at end of file
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival.wxss
index f1908c4..2163789 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival.wxss
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/revival/revival.wxss
@@ -1 +1 @@
-.memorial-bg.data-v-2298a053{position:relative;min-height:100vh;background:linear-gradient(180deg,#f5f0e8,#e8e2d9,#d9d3ca);background-image:radial-gradient(ellipse at 20% 0%,rgba(139,115,85,.08) 0%,transparent 50%),radial-gradient(ellipse at 80% 100%,rgba(109,139,139,.08) 0%,transparent 50%);overflow:hidden}.memorial-content.data-v-2298a053{position:relative;z-index:2;padding:40rpx 32rpx 30rpx;max-width:100%;margin:0 auto}.header.data-v-2298a053{background:linear-gradient(135deg,rgba(139,115,85,.12),rgba(109,139,139,.12));color:#2c2c2c;padding:48rpx 32rpx 40rpx;text-align:center;position:relative;margin-bottom:24rpx;border-radius:32rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);box-shadow:0 4rpx 20rpx rgba(139,115,85,.1)}.header.data-v-2298a053:after{content:"";position:absolute;bottom:20rpx;left:50%;transform:translate(-50%);width:120rpx;height:3rpx;background:linear-gradient(90deg,transparent,rgba(139,115,85,.5),transparent);border-radius:2rpx}.header .logo.data-v-2298a053{font-size:52rpx;font-weight:700;margin-bottom:16rpx;color:#5d4e37;letter-spacing:4rpx;display:block;line-height:1.3;text-shadow:0 2rpx 4rpx rgba(255,255,255,.5)}.header .tagline.data-v-2298a053{font-size:26rpx;color:#7a6b5a;font-weight:400;margin:0 auto;display:block;line-height:1.6;letter-spacing:1rpx}.quick-actions.data-v-2298a053{display:flex;gap:16rpx;margin:24rpx 0 40rpx;padding:0}.action-item.data-v-2298a053{flex:1;background:rgba(255,255,255,.95);border-radius:20rpx;padding:28rpx 14rpx;text-align:center;transition:all .3s cubic-bezier(.4,0,.2,1);box-shadow:0 4rpx 16rpx rgba(139,115,85,.1);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);border:1rpx solid rgba(212,185,150,.2);position:relative;overflow:hidden}.action-item.data-v-2298a053:before{content:"";position:absolute;top:0;left:0;right:0;height:4rpx;background:linear-gradient(135deg,#6d8b8b,#8b7355);transform:scaleX(0);transition:transform .3s}.action-item.data-v-2298a053:active{transform:translateY(-4rpx);box-shadow:0 8rpx 24rpx rgba(139,115,85,.15)}.action-item.data-v-2298a053:active:before{transform:scaleX(1)}.action-item .action-icon.data-v-2298a053{font-size:48rpx;margin-bottom:14rpx;height:76rpx;width:76rpx;line-height:76rpx;border-radius:50%;background:linear-gradient(135deg,rgba(109,139,139,.1),rgba(139,115,85,.1));display:inline-block;transition:all .3s}.action-item:active .action-icon.data-v-2298a053{background:linear-gradient(135deg,#6d8b8b,#8b7355);transform:scale(1.05)}.action-item .action-name.data-v-2298a053{font-size:24rpx;font-weight:600;color:#5d4e37;display:block}.create-voice-btn-wrapper.data-v-2298a053{padding:0 4rpx;margin:20rpx 0 28rpx;display:flex;justify-content:center}.create-voice-btn.data-v-2298a053{width:100%;padding:36rpx 40rpx;background:linear-gradient(135deg,#6d8b8b,#5a7a7a,#8b7355);color:#fff;border:none;border-radius:50rpx;font-size:32rpx;font-weight:600;box-shadow:0 8rpx 24rpx rgba(109,139,139,.35),0 2rpx 8rpx rgba(139,115,85,.2),inset 0 1rpx rgba(255,255,255,.2);transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden;letter-spacing:2rpx}.create-voice-btn.data-v-2298a053:before{content:"";position:absolute;top:0;left:-100%;width:100%;height:100%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.2),transparent);transition:left .5s}.create-voice-btn.data-v-2298a053:active{transform:translateY(-2rpx) scale(.98);box-shadow:0 12rpx 32rpx rgba(109,139,139,.4),0 4rpx 12rpx rgba(139,115,85,.25)}.create-voice-btn.data-v-2298a053:active:before{left:100%}.message.data-v-2298a053{margin:0 0 20rpx;padding:18rpx 24rpx;border-radius:16rpx;font-size:24rpx;box-shadow:0 2rpx 8rpx rgba(0,0,0,.06)}.message.success.data-v-2298a053{background:linear-gradient(135deg,rgba(232,245,233,.95),rgba(200,230,201,.95));color:#2e7d32;border:1rpx solid rgba(76,175,80,.2)}.message.error.data-v-2298a053{background:linear-gradient(135deg,rgba(255,235,238,.95),rgba(255,205,210,.95));color:#c62828;border:1rpx solid rgba(239,83,80,.2)}.tabs.data-v-2298a053{display:flex;background:rgba(255,255,255,.95);margin:0 0 24rpx;width:100%;border-radius:28rpx;overflow:hidden;box-shadow:0 4rpx 16rpx rgba(139,115,85,.12),inset 0 1rpx rgba(255,255,255,.8);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);border:1rpx solid rgba(212,185,150,.2)}.tab-item.data-v-2298a053{flex:1;padding:24rpx 12rpx;text-align:center;font-size:26rpx;color:#7a6b5a;transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;font-weight:500}.tab-item.data-v-2298a053:after{content:"";position:absolute;bottom:0;left:50%;transform:translate(-50%);width:0;height:3rpx;background:linear-gradient(90deg,#6d8b8b,#8b7355);border-radius:2rpx;transition:width .3s}.tab-item.active.data-v-2298a053{background:linear-gradient(135deg,#6d8b8b,#8b7355);color:#fff;font-weight:600;box-shadow:0 2rpx 8rpx rgba(109,139,139,.3)}.tab-item.active.data-v-2298a053:after{width:0}.content.data-v-2298a053{flex:1;margin:0;padding:0 32rpx 30rpx;box-sizing:border-box;width:100%}.tab-content.data-v-2298a053{background:rgba(255,255,255,.92);border-radius:28rpx;padding:32rpx 28rpx;box-shadow:0 4rpx 20rpx rgba(139,115,85,.1),0 1rpx 4rpx rgba(0,0,0,.05);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);width:100%;box-sizing:border-box;border:1rpx solid rgba(212,185,150,.15);overflow:hidden}.section-title.data-v-2298a053{font-size:32rpx;font-weight:600;color:#5d4e37;margin-bottom:28rpx;padding-bottom:16rpx;border-bottom:2rpx solid rgba(212,185,150,.25);letter-spacing:1rpx}.form-section.data-v-2298a053{margin-bottom:28rpx;width:100%;max-width:100%;box-sizing:border-box}.form-label.data-v-2298a053{font-size:26rpx;font-weight:600;color:#5d4e37;margin-bottom:16rpx;display:block;text-align:left;letter-spacing:.5rpx}.form-label-with-help.data-v-2298a053{display:flex;align-items:center;justify-content:space-between;margin-bottom:16rpx}.help-icon.data-v-2298a053{font-size:28rpx;color:#6d8b8b;padding:8rpx 12rpx;cursor:pointer;transition:all .3s;background:rgba(109,139,139,.1);border-radius:50%}.help-icon.data-v-2298a053:active{transform:scale(1.1);color:#8b7355;background:rgba(139,115,85,.15)}.hint-text.data-v-2298a053{font-size:22rpx;color:#9a8b7a;margin-top:10rpx;padding-left:8rpx;line-height:1.5}.upload-btn.data-v-2298a053{width:100%;min-height:140rpx;background:rgba(248,244,238,.6);border:2rpx dashed rgba(109,139,139,.4);border-radius:20rpx;display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;transition:all .3s;overflow:hidden}.upload-btn.data-v-2298a053:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:radial-gradient(circle at 30% 30%,rgba(109,139,139,.08) 0%,transparent 50%),radial-gradient(circle at 70% 70%,rgba(139,115,85,.08) 0%,transparent 50%)}.upload-btn.data-v-2298a053:active{border-color:#6d8b8b;background:rgba(248,244,238,.8)}.upload-icon.data-v-2298a053{font-size:52rpx;margin-bottom:8rpx}.upload-text.data-v-2298a053{font-size:26rpx;color:#7a6b5a;text-align:center;padding:0 24rpx}.upload-success.data-v-2298a053{position:absolute;top:16rpx;right:16rpx;font-size:36rpx}.input-large.data-v-2298a053{width:100%;min-height:88rpx;padding:24rpx;border:1rpx solid rgba(212,185,150,.3);border-radius:14rpx;font-size:28rpx;background:rgba(255,255,255,.95);box-sizing:border-box;line-height:1.5;color:#5d4e37}.input-large.data-v-2298a053:focus{border-color:#6d8b8b}.input-hint.data-v-2298a053{font-size:22rpx;color:#9a8b7a;margin-top:12rpx}.input-hint-row.data-v-2298a053{display:flex;justify-content:space-between;align-items:center;margin-top:12rpx;font-size:22rpx;color:#9a8b7a}.btn-set-prompt.data-v-2298a053{padding:10rpx 20rpx;background:linear-gradient(135deg,#6d8b8b,#8b7355);color:#fff;border:none;border-radius:14rpx;font-size:22rpx;box-shadow:0 2rpx 8rpx rgba(109,139,139,.25);transition:all .3s}.btn-set-prompt.data-v-2298a053:active{transform:scale(.95);box-shadow:0 1rpx 4rpx rgba(109,139,139,.25)}.picker-large.data-v-2298a053{width:100%;padding:20rpx 24rpx;border:1rpx solid rgba(212,185,150,.3);border-radius:16rpx;font-size:26rpx;background:rgba(255,255,255,.95);box-shadow:0 1rpx 4rpx rgba(139,115,85,.06);color:#5d4e37;transition:all .3s;margin-bottom:10rpx}.picker-large.data-v-2298a053:active{border-color:#6d8b8b;box-shadow:0 2rpx 8rpx rgba(109,139,139,.12)}.memory-form .form-textarea.data-v-2298a053{width:100%}.template-categories.data-v-2298a053{margin-top:20rpx;width:100%}.category-group.data-v-2298a053{margin-bottom:16rpx;border-radius:20rpx;overflow:hidden;background:rgba(255,255,255,.7);border:1rpx solid rgba(212,185,150,.25);box-shadow:0 2rpx 8rpx rgba(139,115,85,.06)}.category-header.data-v-2298a053{display:flex;justify-content:space-between;align-items:center;padding:22rpx 24rpx;background:linear-gradient(135deg,rgba(255,255,255,.98),rgba(248,244,238,.98));cursor:pointer;transition:all .3s}.category-header.data-v-2298a053:active{background:#f8f4ee}.category-name.data-v-2298a053{font-size:28rpx;font-weight:600;color:#5d4e37}.category-arrow.data-v-2298a053{font-size:22rpx;color:#6d8b8b;transition:transform .3s}.arrow-open.data-v-2298a053{transform:rotate(180deg)}.category-content.data-v-2298a053{padding:16rpx;background:rgba(248,244,238,.4);display:grid;grid-template-columns:repeat(2,1fr);gap:14rpx;align-items:stretch}.template-item.data-v-2298a053{position:relative;padding:20rpx 18rpx;background:linear-gradient(135deg,#fff,#faf7f2);border:1rpx solid rgba(212,185,150,.3);border-radius:18rpx;box-shadow:0 2rpx 8rpx rgba(139,115,85,.06);transition:all .3s cubic-bezier(.4,0,.2,1);display:flex;flex-direction:column;justify-content:flex-start;min-height:120rpx}.template-item.data-v-2298a053:active{transform:translateY(-2rpx);box-shadow:0 4rpx 12rpx rgba(139,115,85,.12);border-color:#6d8b8b}.template-title.data-v-2298a053{display:block;font-size:26rpx;font-weight:600;color:#5d4e37;margin-bottom:10rpx;text-align:left;line-height:1.3}.template-preview.data-v-2298a053{display:block;font-size:22rpx;color:#7a6b5a;line-height:1.5;opacity:.9;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;word-break:break-all;text-align:left;flex:1}.empty-template.data-v-2298a053{padding:48rpx 0;text-align:center;color:#9a8b7a;font-size:26rpx}.char-warning.data-v-2298a053{color:#ff6b6b!important;font-weight:600}.memory-card.data-v-2298a053{background:linear-gradient(135deg,rgba(255,255,255,.98),rgba(248,244,238,.98));border-radius:24rpx;padding:28rpx;margin-bottom:28rpx;box-shadow:0 4rpx 16rpx rgba(139,115,85,.12);border:1rpx solid rgba(212,185,150,.2)}.card-header.data-v-2298a053{margin-bottom:24rpx;padding-bottom:18rpx;border-bottom:1rpx solid rgba(212,185,150,.2)}.card-title.data-v-2298a053{display:block;font-size:28rpx;font-weight:600;color:#5d4e37;margin-bottom:8rpx}.card-hint.data-v-2298a053{display:block;font-size:22rpx;color:#9a8b7a}.memory-form.data-v-2298a053{display:flex;flex-direction:column;gap:20rpx}.form-item.data-v-2298a053{display:flex;flex-direction:column}.item-label.data-v-2298a053{display:flex;align-items:center;margin-bottom:12rpx}.label-text.data-v-2298a053{font-size:26rpx;color:#5d4e37;font-weight:500}.label-required.data-v-2298a053{color:#e57373;margin-left:6rpx;font-size:28rpx}.form-input.data-v-2298a053{padding:20rpx;background:rgba(255,255,255,.95);border:1rpx solid rgba(212,185,150,.3);border-radius:16rpx;font-size:26rpx;transition:all .3s;color:#5d4e37}.form-input.data-v-2298a053:focus{border-color:#6d8b8b;background:#fff;box-shadow:0 2rpx 8rpx rgba(109,139,139,.1)}.form-textarea.data-v-2298a053{min-height:100rpx;padding:18rpx;background:rgba(255,255,255,.95);border:1rpx solid rgba(212,185,150,.3);border-radius:16rpx;font-size:24rpx;line-height:1.5;transition:all .3s;color:#5d4e37}.form-textarea.data-v-2298a053:focus{border-color:#6d8b8b;background:#fff;box-shadow:0 2rpx 8rpx rgba(109,139,139,.1)}.form-count.data-v-2298a053{font-size:20rpx;color:#9a8b7a;text-align:right;margin-top:8rpx}.apply-btn.data-v-2298a053{display:flex;align-items:center;justify-content:center;gap:10rpx;padding:22rpx;background:linear-gradient(135deg,#6d8b8b,#8b7355);color:#fff;border:none;border-radius:20rpx;font-size:28rpx;font-weight:500;box-shadow:0 4rpx 12rpx rgba(109,139,139,.25);transition:all .3s}.apply-btn.data-v-2298a053:active{transform:translateY(1rpx);box-shadow:0 2rpx 8rpx rgba(109,139,139,.25)}.btn-icon.data-v-2298a053{font-size:32rpx;font-weight:600}.textarea.data-v-2298a053{width:100%;min-height:200rpx;padding:20rpx;border:1rpx solid rgba(212,185,150,.3);border-radius:18rpx;font-size:26rpx;margin-bottom:12rpx;box-sizing:border-box;background:rgba(255,255,255,.95);box-shadow:0 2rpx 6rpx rgba(139,115,85,.06);transition:all .3s;color:#5d4e37;line-height:1.6;max-width:100%}.textarea.data-v-2298a053:focus{border-color:#6d8b8b;background:#fff;box-shadow:0 2rpx 10rpx rgba(109,139,139,.12)}.char-count.data-v-2298a053{text-align:right;font-size:20rpx;color:#9a8b7a;margin-bottom:20rpx}.char-warning.data-v-2298a053{color:#e57373!important;font-weight:600}.tips-card.data-v-2298a053{background:linear-gradient(135deg,rgba(248,244,238,.9),rgba(240,235,228,.9));padding:22rpx;border-radius:18rpx;margin-bottom:28rpx;border-left:4rpx solid #6D8B8B;box-shadow:0 2rpx 8rpx rgba(139,115,85,.08)}.tips-header.data-v-2298a053{font-size:26rpx;font-weight:600;color:#5d4e37;margin-bottom:14rpx}.tips-list.data-v-2298a053{display:flex;flex-direction:column;gap:10rpx}.tip-item.data-v-2298a053{font-size:24rpx;color:#7a6b5a;line-height:1.5}.primary-btn.data-v-2298a053{width:100%;max-width:100%;padding:26rpx;background:linear-gradient(135deg,#6d8b8b,#8b7355);color:#fff;border:none;border-radius:24rpx;font-size:30rpx;font-weight:600;box-shadow:0 6rpx 20rpx rgba(109,139,139,.3),inset 0 1rpx rgba(255,255,255,.2);transition:all .3s cubic-bezier(.4,0,.2,1);letter-spacing:1rpx;box-sizing:border-box}.primary-btn.data-v-2298a053:active{transform:translateY(-2rpx);box-shadow:0 10rpx 28rpx rgba(109,139,139,.35),inset 0 1rpx rgba(255,255,255,.2)}.primary-btn[disabled].data-v-2298a053{opacity:.5;transform:none!important;box-shadow:0 4rpx 12rpx rgba(139,115,85,.15)!important}.small-btn.data-v-2298a053{flex:0 0 auto;width:80rpx;height:80rpx;padding:0;background:rgba(180,170,160,.9);color:#fff;border:none;border-radius:18rpx;display:flex;align-items:center;justify-content:center;box-shadow:0 2rpx 8rpx rgba(139,115,85,.2);transition:all .3s;font-size:22rpx}.small-btn.data-v-2298a053:active{transform:scale(.95)}.small-btn.disabled.data-v-2298a053{opacity:.5;background:rgba(160,155,150,.6);pointer-events:none}.refresh-btn.data-v-2298a053{width:80rpx!important;height:80rpx!important;min-width:80rpx!important;min-height:80rpx!important;border-radius:18rpx!important;background:linear-gradient(135deg,#6d8b8b,#8b7355)!important;color:#fff!important;border:none!important;box-shadow:0 2rpx 8rpx rgba(109,139,139,.25)!important;font-size:36rpx!important;display:flex!important;align-items:center!important;justify-content:center!important;padding:0!important;flex-shrink:0!important;transition:all .3s!important}.refresh-btn.data-v-2298a053:active{transform:scale(.95)!important;box-shadow:0 1rpx 4rpx rgba(109,139,139,.25)!important}.danger-btn.data-v-2298a053{background:linear-gradient(135deg,#ef5350,#e53935);box-shadow:0 2rpx 8rpx rgba(239,83,80,.25)}.audio-result.data-v-2298a053{background:linear-gradient(135deg,rgba(232,245,233,.95),rgba(200,230,201,.95));padding:24rpx;border-radius:18rpx;margin-top:24rpx;box-shadow:0 2rpx 10rpx rgba(76,175,80,.1);border:1rpx solid rgba(76,175,80,.15)}.result-title.data-v-2298a053{font-size:26rpx;color:#2e7d32;font-weight:600;margin-bottom:18rpx}.prompt-section.data-v-2298a053{margin-bottom:24rpx}.label.data-v-2298a053{display:block;font-size:22rpx;color:#7a6b5a;margin-bottom:12rpx}.prompt-input-group.data-v-2298a053{display:flex;gap:16rpx}.flex-1.data-v-2298a053{flex:1;margin-bottom:0!important}.record-buttons.data-v-2298a053{display:flex;gap:16rpx;margin-bottom:24rpx;align-items:center;justify-content:space-between;flex-wrap:nowrap}.record-btn.data-v-2298a053{flex:1;padding:24rpx 32rpx;border:none;border-radius:22rpx;font-size:28rpx;font-weight:600;color:#fff;box-shadow:0 4rpx 14rpx rgba(0,0,0,.12);transition:all .25s ease;display:flex;align-items:center;justify-content:center;text-align:center;letter-spacing:.5rpx}.record-btn.data-v-2298a053:active{transform:scale(.97);box-shadow:0 2rpx 10rpx rgba(0,0,0,.15)}.record-btn.start.data-v-2298a053{background:linear-gradient(135deg,#4db6ac,#26a69a)}.record-btn.stop.data-v-2298a053{background:linear-gradient(135deg,#ef5350,#e53935)}.record-btn.processing.data-v-2298a053{background:linear-gradient(135deg,#9e9e9e,#757575)}.record-btn.disabled.data-v-2298a053{opacity:.5;pointer-events:none}.result-box.data-v-2298a053{padding:22rpx;border-radius:18rpx;margin-bottom:18rpx;box-shadow:0 2rpx 10rpx rgba(0,0,0,.06)}.result-box.user.data-v-2298a053{background:linear-gradient(135deg,rgba(227,242,253,.95),rgba(187,222,251,.95));border-left:4rpx solid #42A5F5}.result-box.ai.data-v-2298a053{background:linear-gradient(135deg,rgba(232,245,233,.95),rgba(200,230,201,.95));border-left:4rpx solid #66BB6A}.result-box.audio.data-v-2298a053{background:linear-gradient(135deg,rgba(243,229,245,.95),rgba(225,190,231,.95));border-left:4rpx solid #AB47BC}.result-label.data-v-2298a053{font-size:24rpx;font-weight:600;margin-bottom:12rpx;color:#424242}.list-header.data-v-2298a053{width:100%;display:flex;justify-content:space-between;align-items:center;margin-bottom:24rpx;padding-bottom:14rpx;border-bottom:1rpx solid rgba(212,185,150,.2)}.loading.data-v-2298a053,.empty.data-v-2298a053{text-align:center;padding:80rpx 32rpx;color:#9a8b7a;font-size:26rpx}.voice-item.data-v-2298a053{background:rgba(255,255,255,.95);border-radius:18rpx;padding:24rpx;margin-bottom:16rpx;display:flex;justify-content:space-between;align-items:center;box-shadow:0 2rpx 10rpx rgba(139,115,85,.08);border:1rpx solid rgba(212,185,150,.15);transition:all .3s}.voice-item.data-v-2298a053:active{transform:translateY(-1rpx);box-shadow:0 4rpx 14rpx rgba(139,115,85,.12)}.voice-info.data-v-2298a053{flex:1}.voice-name.data-v-2298a053{font-size:28rpx;font-weight:600;color:#5d4e37;display:block;margin-bottom:8rpx}.public-badge.data-v-2298a053{display:inline-block;margin-left:10rpx;padding:4rpx 10rpx;background:linear-gradient(135deg,#6d8b8b,#8b7355);color:#fff;font-size:18rpx;border-radius:6rpx;font-weight:400}.voice-detail.data-v-2298a053{font-size:22rpx;color:#9a8b7a;display:block}.delete-btn.data-v-2298a053{width:80rpx;height:80rpx;min-width:80rpx;min-height:80rpx;background:linear-gradient(135deg,#ef5350,#e53935);color:#fff;border:none;border-radius:18rpx;font-size:22rpx;box-shadow:0 2rpx 8rpx rgba(239,83,80,.25);transition:all .3s;display:flex;align-items:center;justify-content:center;padding:0;flex-shrink:0;margin-left:12rpx}.delete-btn.data-v-2298a053:active{transform:scale(.95);box-shadow:0 1rpx 4rpx rgba(239,83,80,.25)}.delete-icon.data-v-2298a053{width:40rpx;height:40rpx}
+.memorial-bg.data-v-41b5703e{position:relative;min-height:100vh;background:linear-gradient(180deg,#f5f0e8,#e8e2d9,#d9d3ca);background-image:radial-gradient(ellipse at 20% 0%,rgba(139,115,85,.08) 0%,transparent 50%),radial-gradient(ellipse at 80% 100%,rgba(109,139,139,.08) 0%,transparent 50%);overflow:hidden}.memorial-content.data-v-41b5703e{position:relative;z-index:2;padding:40rpx 32rpx 30rpx;max-width:100%;margin:0 auto}.header.data-v-41b5703e{background:linear-gradient(135deg,rgba(139,115,85,.12),rgba(109,139,139,.12));color:#2c2c2c;padding:48rpx 32rpx 40rpx;text-align:center;position:relative;margin-bottom:24rpx;border-radius:32rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);box-shadow:0 4rpx 20rpx rgba(139,115,85,.1)}.header.data-v-41b5703e:after{content:"";position:absolute;bottom:20rpx;left:50%;transform:translate(-50%);width:120rpx;height:3rpx;background:linear-gradient(90deg,transparent,rgba(139,115,85,.5),transparent);border-radius:2rpx}.header .logo.data-v-41b5703e{font-size:52rpx;font-weight:700;margin-bottom:16rpx;color:#5d4e37;letter-spacing:4rpx;display:block;line-height:1.3;text-shadow:0 2rpx 4rpx rgba(255,255,255,.5)}.header .tagline.data-v-41b5703e{font-size:26rpx;color:#7a6b5a;font-weight:400;margin:0 auto;display:block;line-height:1.6;letter-spacing:1rpx}.quick-actions.data-v-41b5703e{display:flex;gap:16rpx;margin:24rpx 0 40rpx;padding:0}.action-item.data-v-41b5703e{flex:1;background:rgba(255,255,255,.95);border-radius:20rpx;padding:28rpx 14rpx;text-align:center;transition:all .3s cubic-bezier(.4,0,.2,1);box-shadow:0 4rpx 16rpx rgba(139,115,85,.1);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);border:1rpx solid rgba(212,185,150,.2);position:relative;overflow:hidden}.action-item.data-v-41b5703e:before{content:"";position:absolute;top:0;left:0;right:0;height:4rpx;background:linear-gradient(135deg,#6d8b8b,#8b7355);transform:scaleX(0);transition:transform .3s}.action-item.data-v-41b5703e:active{transform:translateY(-4rpx);box-shadow:0 8rpx 24rpx rgba(139,115,85,.15)}.action-item.data-v-41b5703e:active:before{transform:scaleX(1)}.action-item .action-icon.data-v-41b5703e{font-size:48rpx;margin-bottom:14rpx;height:76rpx;width:76rpx;line-height:76rpx;border-radius:50%;background:linear-gradient(135deg,rgba(109,139,139,.1),rgba(139,115,85,.1));display:inline-block;transition:all .3s}.action-item:active .action-icon.data-v-41b5703e{background:linear-gradient(135deg,#6d8b8b,#8b7355);transform:scale(1.05)}.action-item .action-name.data-v-41b5703e{font-size:24rpx;font-weight:600;color:#5d4e37;display:block}.create-voice-btn-wrapper.data-v-41b5703e{padding:0 4rpx;margin:20rpx 0 28rpx;display:flex;justify-content:center}.create-voice-btn.data-v-41b5703e{width:100%;padding:36rpx 40rpx;background:linear-gradient(135deg,#6d8b8b,#5a7a7a,#8b7355);color:#fff;border:none;border-radius:50rpx;font-size:32rpx;font-weight:600;box-shadow:0 8rpx 24rpx rgba(109,139,139,.35),0 2rpx 8rpx rgba(139,115,85,.2),inset 0 1rpx rgba(255,255,255,.2);transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden;letter-spacing:2rpx}.create-voice-btn.data-v-41b5703e:before{content:"";position:absolute;top:0;left:-100%;width:100%;height:100%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.2),transparent);transition:left .5s}.create-voice-btn.data-v-41b5703e:active{transform:translateY(-2rpx) scale(.98);box-shadow:0 12rpx 32rpx rgba(109,139,139,.4),0 4rpx 12rpx rgba(139,115,85,.25)}.create-voice-btn.data-v-41b5703e:active:before{left:100%}.message.data-v-41b5703e{margin:0 0 20rpx;padding:18rpx 24rpx;border-radius:16rpx;font-size:24rpx;box-shadow:0 2rpx 8rpx rgba(0,0,0,.06)}.message.success.data-v-41b5703e{background:linear-gradient(135deg,rgba(232,245,233,.95),rgba(200,230,201,.95));color:#2e7d32;border:1rpx solid rgba(76,175,80,.2)}.message.error.data-v-41b5703e{background:linear-gradient(135deg,rgba(255,235,238,.95),rgba(255,205,210,.95));color:#c62828;border:1rpx solid rgba(239,83,80,.2)}.tabs.data-v-41b5703e{display:flex;background:rgba(255,255,255,.95);margin:0 0 24rpx;width:100%;border-radius:28rpx;overflow:hidden;box-shadow:0 4rpx 16rpx rgba(139,115,85,.12),inset 0 1rpx rgba(255,255,255,.8);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);border:1rpx solid rgba(212,185,150,.2)}.tab-item.data-v-41b5703e{flex:1;padding:24rpx 12rpx;text-align:center;font-size:26rpx;color:#7a6b5a;transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;font-weight:500}.tab-item.data-v-41b5703e:after{content:"";position:absolute;bottom:0;left:50%;transform:translate(-50%);width:0;height:3rpx;background:linear-gradient(90deg,#6d8b8b,#8b7355);border-radius:2rpx;transition:width .3s}.tab-item.active.data-v-41b5703e{background:linear-gradient(135deg,#6d8b8b,#8b7355);color:#fff;font-weight:600;box-shadow:0 2rpx 8rpx rgba(109,139,139,.3)}.tab-item.active.data-v-41b5703e:after{width:0}.content.data-v-41b5703e{flex:1;margin:0;padding:0 32rpx 30rpx;box-sizing:border-box;width:100%}.tab-content.data-v-41b5703e{background:rgba(255,255,255,.92);border-radius:28rpx;padding:32rpx 28rpx;box-shadow:0 4rpx 20rpx rgba(139,115,85,.1),0 1rpx 4rpx rgba(0,0,0,.05);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx);width:100%;box-sizing:border-box;border:1rpx solid rgba(212,185,150,.15);overflow:hidden}.section-title.data-v-41b5703e{font-size:32rpx;font-weight:600;color:#5d4e37;margin-bottom:28rpx;padding-bottom:16rpx;border-bottom:2rpx solid rgba(212,185,150,.25);letter-spacing:1rpx}.form-section.data-v-41b5703e{margin-bottom:28rpx;width:100%;max-width:100%;box-sizing:border-box}.form-label.data-v-41b5703e{font-size:26rpx;font-weight:600;color:#5d4e37;margin-bottom:16rpx;display:block;text-align:left;letter-spacing:.5rpx}.form-label-with-help.data-v-41b5703e{display:flex;align-items:center;justify-content:space-between;margin-bottom:16rpx}.help-icon.data-v-41b5703e{font-size:28rpx;color:#6d8b8b;padding:8rpx 12rpx;cursor:pointer;transition:all .3s;background:rgba(109,139,139,.1);border-radius:50%}.help-icon.data-v-41b5703e:active{transform:scale(1.1);color:#8b7355;background:rgba(139,115,85,.15)}.hint-text.data-v-41b5703e{font-size:22rpx;color:#9a8b7a;margin-top:10rpx;padding-left:8rpx;line-height:1.5}.upload-btn.data-v-41b5703e{width:100%;min-height:140rpx;background:rgba(248,244,238,.6);border:2rpx dashed rgba(109,139,139,.4);border-radius:20rpx;display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;transition:all .3s;overflow:hidden}.upload-btn.data-v-41b5703e:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:radial-gradient(circle at 30% 30%,rgba(109,139,139,.08) 0%,transparent 50%),radial-gradient(circle at 70% 70%,rgba(139,115,85,.08) 0%,transparent 50%)}.upload-btn.data-v-41b5703e:active{border-color:#6d8b8b;background:rgba(248,244,238,.8)}.upload-icon.data-v-41b5703e{font-size:52rpx;margin-bottom:8rpx}.upload-text.data-v-41b5703e{font-size:26rpx;color:#7a6b5a;text-align:center;padding:0 24rpx}.upload-success.data-v-41b5703e{position:absolute;top:16rpx;right:16rpx;font-size:36rpx}.input-large.data-v-41b5703e{width:100%;min-height:88rpx;padding:24rpx;border:1rpx solid rgba(212,185,150,.3);border-radius:14rpx;font-size:28rpx;background:rgba(255,255,255,.95);box-sizing:border-box;line-height:1.5;color:#5d4e37}.input-large.data-v-41b5703e:focus{border-color:#6d8b8b}.input-hint.data-v-41b5703e{font-size:22rpx;color:#9a8b7a;margin-top:12rpx}.input-hint-row.data-v-41b5703e{display:flex;justify-content:space-between;align-items:center;margin-top:12rpx;font-size:22rpx;color:#9a8b7a}.btn-set-prompt.data-v-41b5703e{padding:10rpx 20rpx;background:linear-gradient(135deg,#6d8b8b,#8b7355);color:#fff;border:none;border-radius:14rpx;font-size:22rpx;box-shadow:0 2rpx 8rpx rgba(109,139,139,.25);transition:all .3s}.btn-set-prompt.data-v-41b5703e:active{transform:scale(.95);box-shadow:0 1rpx 4rpx rgba(109,139,139,.25)}.picker-large.data-v-41b5703e{width:100%;padding:20rpx 24rpx;border:1rpx solid rgba(212,185,150,.3);border-radius:16rpx;font-size:26rpx;background:rgba(255,255,255,.95);box-shadow:0 1rpx 4rpx rgba(139,115,85,.06);color:#5d4e37;transition:all .3s;margin-bottom:10rpx}.picker-large.data-v-41b5703e:active{border-color:#6d8b8b;box-shadow:0 2rpx 8rpx rgba(109,139,139,.12)}.memory-form .form-textarea.data-v-41b5703e{width:100%}.template-categories.data-v-41b5703e{margin-top:20rpx;width:100%}.category-group.data-v-41b5703e{margin-bottom:16rpx;border-radius:20rpx;overflow:hidden;background:rgba(255,255,255,.7);border:1rpx solid rgba(212,185,150,.25);box-shadow:0 2rpx 8rpx rgba(139,115,85,.06)}.category-header.data-v-41b5703e{display:flex;justify-content:space-between;align-items:center;padding:22rpx 24rpx;background:linear-gradient(135deg,rgba(255,255,255,.98),rgba(248,244,238,.98));cursor:pointer;transition:all .3s}.category-header.data-v-41b5703e:active{background:#f8f4ee}.category-name.data-v-41b5703e{font-size:28rpx;font-weight:600;color:#5d4e37}.category-arrow.data-v-41b5703e{font-size:22rpx;color:#6d8b8b;transition:transform .3s}.arrow-open.data-v-41b5703e{transform:rotate(180deg)}.category-content.data-v-41b5703e{padding:16rpx;background:rgba(248,244,238,.4);display:grid;grid-template-columns:repeat(2,1fr);gap:14rpx;align-items:stretch}.template-item.data-v-41b5703e{position:relative;padding:20rpx 18rpx;background:linear-gradient(135deg,#fff,#faf7f2);border:1rpx solid rgba(212,185,150,.3);border-radius:18rpx;box-shadow:0 2rpx 8rpx rgba(139,115,85,.06);transition:all .3s cubic-bezier(.4,0,.2,1);display:flex;flex-direction:column;justify-content:flex-start;min-height:120rpx}.template-item.data-v-41b5703e:active{transform:translateY(-2rpx);box-shadow:0 4rpx 12rpx rgba(139,115,85,.12);border-color:#6d8b8b}.template-title.data-v-41b5703e{display:block;font-size:26rpx;font-weight:600;color:#5d4e37;margin-bottom:10rpx;text-align:left;line-height:1.3}.template-preview.data-v-41b5703e{display:block;font-size:22rpx;color:#7a6b5a;line-height:1.5;opacity:.9;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;word-break:break-all;text-align:left;flex:1}.empty-template.data-v-41b5703e{padding:48rpx 0;text-align:center;color:#9a8b7a;font-size:26rpx}.char-warning.data-v-41b5703e{color:#ff6b6b!important;font-weight:600}.memory-card.data-v-41b5703e{background:linear-gradient(135deg,rgba(255,255,255,.98),rgba(248,244,238,.98));border-radius:24rpx;padding:28rpx;margin-bottom:28rpx;box-shadow:0 4rpx 16rpx rgba(139,115,85,.12);border:1rpx solid rgba(212,185,150,.2)}.card-header.data-v-41b5703e{margin-bottom:24rpx;padding-bottom:18rpx;border-bottom:1rpx solid rgba(212,185,150,.2)}.card-title.data-v-41b5703e{display:block;font-size:28rpx;font-weight:600;color:#5d4e37;margin-bottom:8rpx}.card-hint.data-v-41b5703e{display:block;font-size:22rpx;color:#9a8b7a}.memory-form.data-v-41b5703e{display:flex;flex-direction:column;gap:20rpx}.form-item.data-v-41b5703e{display:flex;flex-direction:column}.item-label.data-v-41b5703e{display:flex;align-items:center;margin-bottom:12rpx}.label-text.data-v-41b5703e{font-size:26rpx;color:#5d4e37;font-weight:500}.label-required.data-v-41b5703e{color:#e57373;margin-left:6rpx;font-size:28rpx}.form-input.data-v-41b5703e{padding:20rpx;background:rgba(255,255,255,.95);border:1rpx solid rgba(212,185,150,.3);border-radius:16rpx;font-size:26rpx;transition:all .3s;color:#5d4e37}.form-input.data-v-41b5703e:focus{border-color:#6d8b8b;background:#fff;box-shadow:0 2rpx 8rpx rgba(109,139,139,.1)}.form-textarea.data-v-41b5703e{min-height:100rpx;padding:18rpx;background:rgba(255,255,255,.95);border:1rpx solid rgba(212,185,150,.3);border-radius:16rpx;font-size:24rpx;line-height:1.5;transition:all .3s;color:#5d4e37}.form-textarea.data-v-41b5703e:focus{border-color:#6d8b8b;background:#fff;box-shadow:0 2rpx 8rpx rgba(109,139,139,.1)}.form-count.data-v-41b5703e{font-size:20rpx;color:#9a8b7a;text-align:right;margin-top:8rpx}.apply-btn.data-v-41b5703e{display:flex;align-items:center;justify-content:center;gap:10rpx;padding:22rpx;background:linear-gradient(135deg,#6d8b8b,#8b7355);color:#fff;border:none;border-radius:20rpx;font-size:28rpx;font-weight:500;box-shadow:0 4rpx 12rpx rgba(109,139,139,.25);transition:all .3s}.apply-btn.data-v-41b5703e:active{transform:translateY(1rpx);box-shadow:0 2rpx 8rpx rgba(109,139,139,.25)}.btn-icon.data-v-41b5703e{font-size:32rpx;font-weight:600}.textarea.data-v-41b5703e{width:100%;min-height:200rpx;padding:20rpx;border:1rpx solid rgba(212,185,150,.3);border-radius:18rpx;font-size:26rpx;margin-bottom:12rpx;box-sizing:border-box;background:rgba(255,255,255,.95);box-shadow:0 2rpx 6rpx rgba(139,115,85,.06);transition:all .3s;color:#5d4e37;line-height:1.6;max-width:100%}.textarea.data-v-41b5703e:focus{border-color:#6d8b8b;background:#fff;box-shadow:0 2rpx 10rpx rgba(109,139,139,.12)}.char-count.data-v-41b5703e{text-align:right;font-size:20rpx;color:#9a8b7a;margin-bottom:20rpx}.char-warning.data-v-41b5703e{color:#e57373!important;font-weight:600}.tips-card.data-v-41b5703e{background:linear-gradient(135deg,rgba(248,244,238,.9),rgba(240,235,228,.9));padding:22rpx;border-radius:18rpx;margin-bottom:28rpx;border-left:4rpx solid #6D8B8B;box-shadow:0 2rpx 8rpx rgba(139,115,85,.08)}.tips-header.data-v-41b5703e{font-size:26rpx;font-weight:600;color:#5d4e37;margin-bottom:14rpx}.tips-list.data-v-41b5703e{display:flex;flex-direction:column;gap:10rpx}.tip-item.data-v-41b5703e{font-size:24rpx;color:#7a6b5a;line-height:1.5}.primary-btn.data-v-41b5703e{width:100%;max-width:100%;padding:26rpx;background:linear-gradient(135deg,#6d8b8b,#8b7355);color:#fff!important;border:none;border-radius:24rpx;font-size:30rpx;font-weight:600;box-shadow:0 6rpx 20rpx rgba(109,139,139,.3),inset 0 1rpx rgba(255,255,255,.2);transition:all .3s cubic-bezier(.4,0,.2,1);letter-spacing:1rpx;box-sizing:border-box}.primary-btn.data-v-41b5703e:active{transform:translateY(-2rpx);box-shadow:0 10rpx 28rpx rgba(109,139,139,.35),inset 0 1rpx rgba(255,255,255,.2)}.primary-btn[disabled].data-v-41b5703e{opacity:.5;transform:none!important;box-shadow:0 4rpx 12rpx rgba(139,115,85,.15)!important;color:#fff!important}.ai-disclaimer.data-v-41b5703e{display:block;text-align:center;font-size:22rpx;color:rgba(100,100,100,.6);margin-top:16rpx;letter-spacing:.5rpx}.small-btn.data-v-41b5703e{flex:0 0 auto;width:80rpx;height:80rpx;padding:0;background:rgba(180,170,160,.9);color:#fff;border:none;border-radius:18rpx;display:flex;align-items:center;justify-content:center;box-shadow:0 2rpx 8rpx rgba(139,115,85,.2);transition:all .3s;font-size:22rpx}.small-btn.data-v-41b5703e:active{transform:scale(.95)}.small-btn.disabled.data-v-41b5703e{opacity:.5;background:rgba(160,155,150,.6);pointer-events:none}.refresh-btn.data-v-41b5703e{width:80rpx!important;height:80rpx!important;min-width:80rpx!important;min-height:80rpx!important;border-radius:18rpx!important;background:linear-gradient(135deg,#6d8b8b,#8b7355)!important;color:#fff!important;border:none!important;box-shadow:0 2rpx 8rpx rgba(109,139,139,.25)!important;font-size:36rpx!important;display:flex!important;align-items:center!important;justify-content:center!important;padding:0!important;flex-shrink:0!important;transition:all .3s!important}.refresh-btn.data-v-41b5703e:active{transform:scale(.95)!important;box-shadow:0 1rpx 4rpx rgba(109,139,139,.25)!important}.danger-btn.data-v-41b5703e{background:linear-gradient(135deg,#ef5350,#e53935);box-shadow:0 2rpx 8rpx rgba(239,83,80,.25)}.audio-result.data-v-41b5703e{background:linear-gradient(135deg,rgba(232,245,233,.95),rgba(200,230,201,.95));padding:24rpx;border-radius:18rpx;margin-top:24rpx;box-shadow:0 2rpx 10rpx rgba(76,175,80,.1);border:1rpx solid rgba(76,175,80,.15)}.result-title.data-v-41b5703e{font-size:26rpx;color:#2e7d32;font-weight:600;margin-bottom:18rpx}.prompt-section.data-v-41b5703e{margin-bottom:24rpx}.label.data-v-41b5703e{display:block;font-size:22rpx;color:#7a6b5a;margin-bottom:12rpx}.prompt-input-group.data-v-41b5703e{display:flex;gap:16rpx}.flex-1.data-v-41b5703e{flex:1;margin-bottom:0!important}.record-buttons.data-v-41b5703e{display:flex;gap:16rpx;margin-bottom:24rpx;align-items:center;justify-content:space-between;flex-wrap:nowrap}.record-btn.data-v-41b5703e{flex:1;padding:24rpx 32rpx;border:none;border-radius:22rpx;font-size:28rpx;font-weight:600;color:#fff;box-shadow:0 4rpx 14rpx rgba(0,0,0,.12);transition:all .25s ease;display:flex;align-items:center;justify-content:center;text-align:center;letter-spacing:.5rpx}.record-btn.data-v-41b5703e:active{transform:scale(.97);box-shadow:0 2rpx 10rpx rgba(0,0,0,.15)}.record-btn.start.data-v-41b5703e{background:linear-gradient(135deg,#4db6ac,#26a69a)}.record-btn.stop.data-v-41b5703e{background:linear-gradient(135deg,#ef5350,#e53935)}.record-btn.processing.data-v-41b5703e{background:linear-gradient(135deg,#9e9e9e,#757575)}.record-btn.disabled.data-v-41b5703e{opacity:.5;pointer-events:none}.result-box.data-v-41b5703e{padding:22rpx;border-radius:18rpx;margin-bottom:18rpx;box-shadow:0 2rpx 10rpx rgba(0,0,0,.06)}.result-box.user.data-v-41b5703e{background:linear-gradient(135deg,rgba(227,242,253,.95),rgba(187,222,251,.95));border-left:4rpx solid #42A5F5}.result-box.ai.data-v-41b5703e{background:linear-gradient(135deg,rgba(232,245,233,.95),rgba(200,230,201,.95));border-left:4rpx solid #66BB6A}.result-box.audio.data-v-41b5703e{background:linear-gradient(135deg,rgba(243,229,245,.95),rgba(225,190,231,.95));border-left:4rpx solid #AB47BC}.result-label.data-v-41b5703e{font-size:24rpx;font-weight:600;margin-bottom:12rpx;color:#424242}.list-header.data-v-41b5703e{width:100%;display:flex;justify-content:space-between;align-items:center;margin-bottom:24rpx;padding-bottom:14rpx;border-bottom:1rpx solid rgba(212,185,150,.2)}.loading.data-v-41b5703e,.empty.data-v-41b5703e{text-align:center;padding:80rpx 32rpx;color:#9a8b7a;font-size:26rpx}.voice-item.data-v-41b5703e{background:rgba(255,255,255,.95);border-radius:18rpx;padding:24rpx;margin-bottom:16rpx;display:flex;justify-content:space-between;align-items:center;box-shadow:0 2rpx 10rpx rgba(139,115,85,.08);border:1rpx solid rgba(212,185,150,.15);transition:all .3s}.voice-item.data-v-41b5703e:active{transform:translateY(-1rpx);box-shadow:0 4rpx 14rpx rgba(139,115,85,.12)}.voice-info.data-v-41b5703e{flex:1}.voice-name.data-v-41b5703e{font-size:28rpx;font-weight:600;color:#5d4e37;display:block;margin-bottom:8rpx}.public-badge.data-v-41b5703e{display:inline-block;margin-left:10rpx;padding:4rpx 10rpx;background:linear-gradient(135deg,#6d8b8b,#8b7355);color:#fff;font-size:18rpx;border-radius:6rpx;font-weight:400}.voice-detail.data-v-41b5703e{font-size:22rpx;color:#9a8b7a;display:block}.delete-btn.data-v-41b5703e{width:80rpx;height:80rpx;min-width:80rpx;min-height:80rpx;background:linear-gradient(135deg,#ef5350,#e53935);color:#fff;border:none;border-radius:18rpx;font-size:22rpx;box-shadow:0 2rpx 8rpx rgba(239,83,80,.25);transition:all .3s;display:flex;align-items:center;justify-content:center;padding:0;flex-shrink:0;margin-left:12rpx}.delete-btn.data-v-41b5703e:active{transform:scale(.95);box-shadow:0 1rpx 4rpx rgba(239,83,80,.25)}.delete-icon.data-v-41b5703e{width:40rpx;height:40rpx}
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/upload-audio/upload-audio.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/upload-audio/upload-audio.js
index c29e448..39319c7 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/upload-audio/upload-audio.js
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/upload-audio/upload-audio.js
@@ -1 +1 @@
-"use strict";const e=require("../../common/vendor.js"),t=require("../../config/api.js"),o={data:()=>({voiceName:"",audioPath:"",audioName:"",audioSize:0,useCosyVoice:!1,referenceTexts:["我想和你说说最近的生活。今天的天气很好,我也在努力让自己过得更开心。希望你也一切都好。","你好呀,最近我过得还不错。今天我想和你聊聊我的心情,也想听听你的近况。","我在一个安静的房间里,正在认真朗读这段文字。希望声音清晰自然,能够帮助创建更好的音色。","今天我精神很好,说话也很清楚。我会保持语速适中、情绪自然,尽量减少停顿与杂音。"],referenceTextIndex:0,uploading:!1,isPlaying:!1,isRecording:!1,recordDuration:0,recordTimer:null,recorderManager:null,innerAudioContext:null}),computed:{canSubmit(){return this.voiceName.trim()&&this.audioPath},referenceText(){return(this.referenceTexts||[])[this.referenceTextIndex]||""}},onLoad(){this.checkLogin(),this.initRecorder()},onUnload(){this.innerAudioContext&&(this.innerAudioContext.stop(),this.innerAudioContext.destroy()),this.recordTimer&&clearInterval(this.recordTimer),this.recorderManager&&this.isRecording&&this.recorderManager.stop()},methods:{onUseCosyVoiceChange(e){this.useCosyVoice=!!(e&&e.detail&&e.detail.value)},copyReferenceText(){e.index.setClipboardData({data:this.referenceText,success:()=>{e.index.showToast({title:"已复制",icon:"success"})}})},switchReferenceText(){const e=this.referenceTexts||[];e.length<=1||(this.referenceTextIndex=(this.referenceTextIndex+1)%e.length)},checkLogin(){const t=e.index.getStorageSync("userId"),o=e.index.getStorageSync("token");return!(!t||!o)||(e.index.showModal({title:"需要登录",content:"请先登录后再创建音色",showCancel:!1,success:()=>{e.index.reLaunch({url:"/pages/login/login"})}}),!1)},initRecorder(){this.recorderManager=e.index.getRecorderManager(),this.recorderManager.onStart((()=>{console.log("录音开始"),this.isRecording=!0,this.recordDuration=0,this.recordTimer=setInterval((()=>{this.recordDuration++,this.recordDuration>=60&&this.stopRecord()}),1e3)})),this.recorderManager.onStop((t=>{console.log("录音停止",t),this.isRecording=!1,this.recordTimer&&(clearInterval(this.recordTimer),this.recordTimer=null),this.recordDuration<3?e.index.showToast({title:"录音时长至少3秒",icon:"none"}):(this.audioPath=t.tempFilePath,this.audioName=`录音_${this.recordDuration}秒.mp3`,e.index.showToast({title:"录音完成",icon:"success"}))})),this.recorderManager.onError((t=>{console.error("录音错误:",t),this.isRecording=!1,this.recordTimer&&(clearInterval(this.recordTimer),this.recordTimer=null),e.index.showToast({title:"录音失败,请重试",icon:"none"})}))},chooseAudioFile(){this.checkLogin()&&e.index.chooseMessageFile({count:1,type:"file",extension:[".mp3",".wav",".m4a",".aac"],success:t=>{const o=t.tempFiles&&t.tempFiles[0];o?o.size>10485760?e.index.showToast({title:"文件大小不能超过10MB",icon:"none"}):(this.audioPath=o.path,this.audioName=o.name||"audio",this.audioSize=o.size||0,this.recordDuration=0,e.index.showToast({title:"已选择音频",icon:"success"})):e.index.showToast({title:"选择文件失败",icon:"none"})},fail:t=>{console.error("选择文件失败:",t),e.index.showToast({title:t.errMsg||"选择文件失败",icon:"none"})}})},startRecord(){this.checkLogin()&&(this.recorderManager||this.initRecorder(),e.index.getSetting({success:t=>{t.authSetting["scope.record"]?this.doStartRecord():!1===t.authSetting["scope.record"]?e.index.showModal({title:"需要录音权限",content:"请在设置中开启录音权限",confirmText:"去设置",success:t=>{t.confirm&&e.index.openSetting({success:e=>{e.authSetting["scope.record"]&&this.doStartRecord()}})}}):e.index.authorize({scope:"scope.record",success:()=>{this.doStartRecord()},fail:()=>{e.index.showModal({title:"需要录音权限",content:"请允许使用麦克风进行录音",confirmText:"去设置",success:t=>{t.confirm&&e.index.openSetting()}})}})},fail:()=>{this.doStartRecord()}}))},doStartRecord(){if(this.recorderManager)try{this.recorderManager.start({duration:6e4,sampleRate:16e3,numberOfChannels:1,encodeBitRate:96e3,format:"mp3"})}catch(t){console.error("启动录音失败:",t),e.index.showModal({title:"时光意境",content:"麦克风被其他应用占用\n\n请关闭其他使用麦克风的应用",confirmText:"确定",showCancel:!1})}else e.index.showToast({title:"录音初始化失败",icon:"none"})},stopRecord(){this.recorderManager&&this.isRecording&&this.recorderManager.stop()},playAudio(){this.innerAudioContext||(this.innerAudioContext=e.index.createInnerAudioContext(),this.innerAudioContext.src=this.audioPath,this.innerAudioContext.onPlay((()=>{this.isPlaying=!0})),this.innerAudioContext.onPause((()=>{this.isPlaying=!1})),this.innerAudioContext.onEnded((()=>{this.isPlaying=!1})),this.innerAudioContext.onError((t=>{console.error("音频播放失败:",t),this.isPlaying=!1,e.index.showToast({title:"播放失败",icon:"none"})}))),this.isPlaying?this.innerAudioContext.pause():this.innerAudioContext.play()},deleteAudio(){this.innerAudioContext&&(this.innerAudioContext.stop(),this.innerAudioContext.destroy(),this.innerAudioContext=null),this.audioPath="",this.audioName="",this.isPlaying=!1},handleSubmit(){if(this.uploading)return;if(!this.canSubmit)return void e.index.showToast({title:this.voiceName.trim()?"请先录制音频":"请填写音色名称",icon:"none"});const o=e.index.getStorageSync("userId");if(!o)return e.index.showToast({title:"请先登录",icon:"none"}),void setTimeout((()=>{e.index.navigateTo({url:"/pages/login/login"})}),1500);(()=>{this.uploading=!0;const i=e.index.getStorageSync("token")||"",n=`recording_${Date.now()}.mp3`,r=this.useCosyVoice?"/api/voice/cosy-create":"/api/voice/create";e.index.uploadFile({url:`${t.API_BASE}${r}`,filePath:this.audioPath,name:"audio",fileName:n,formData:{name:this.voiceName,displayName:this.voiceName},header:{"X-User-Id":o,Authorization:i?`Bearer ${i}`:""},success:t=>{console.log("上传响应:",t);try{const o="string"==typeof t.data?JSON.parse(t.data):t.data;if(console.log("解析后的数据:",o),console.log("状态码:",t.statusCode),200===t.statusCode&&o.success)return e.index.showToast({title:"音色创建成功",icon:"success",duration:2e3}),void setTimeout((()=>{e.index.navigateBack()}),2e3);if(402===t.statusCode)return void e.index.showModal({title:"需要付费",content:o&&o.message?o.message:"免费次数已用完,请先完成支付",showCancel:!1});console.error("服务器错误:",o&&(o.message||o.error)?o.message||o.error:`服务器错误 (${t.statusCode})`,o),e.index.showModal({title:"创建失败",content:o&&o.message?o.message:"创建失败,请重试",showCancel:!1})}catch(o){console.error("处理响应失败:",o),e.index.showModal({title:"创建失败",content:"创建失败,请重试",showCancel:!1})}},fail:t=>{console.error("上传失败:",t),e.index.showModal({title:"创建失败",content:"网络请求失败,请检查网络连接",showCancel:!1})},complete:()=>{this.uploading=!1}})})()}}};const i=e._export_sfc(o,[["render",function(t,o,i,n,r,s){return e.e({a:r.voiceName,b:e.o((e=>r.voiceName=e.detail.value)),c:r.useCosyVoice,d:e.o(((...e)=>s.onUseCosyVoiceChange&&s.onUseCosyVoiceChange(...e))),e:e.o(((...e)=>s.switchReferenceText&&s.switchReferenceText(...e))),f:e.t(s.referenceText),g:e.o(((...e)=>s.copyReferenceText&&s.copyReferenceText(...e))),h:!r.audioPath},r.audioPath?{}:{i:r.isRecording,j:e.o(((...e)=>s.startRecord&&s.startRecord(...e)))},{k:!r.audioPath},r.audioPath?{o:e.t(r.audioName),p:e.t(r.isPlaying?"暂停":"播放"),q:e.o(((...e)=>s.playAudio&&s.playAudio(...e))),r:e.o(((...e)=>s.deleteAudio&&s.deleteAudio(...e)))}:e.e({l:r.isRecording},r.isRecording?{m:e.t(r.recordDuration),n:e.o(((...e)=>s.stopRecord&&s.stopRecord(...e)))}:{}),{s:r.uploading},(r.uploading,{}),{t:!s.canSubmit||r.uploading,v:e.o(((...e)=>s.handleSubmit&&s.handleSubmit(...e)))})}],["__scopeId","data-v-84d46214"]]);wx.createPage(i);
+"use strict";const e=require("../../common/vendor.js"),t=require("../../config/api.js"),o={data:()=>({voiceName:"",audioPath:"",audioName:"",audioSize:0,useCosyVoice:!1,referenceTexts:["我想和你说说最近的生活。今天的天气很好,我也在努力让自己过得更开心。希望你也一切都好。","你好呀,最近我过得还不错。今天我想和你聊聊我的心情,也想听听你的近况。","我在一个安静的房间里,正在认真朗读这段文字。希望声音清晰自然,能够帮助创建更好的音色。","今天我精神很好,说话也很清楚。我会保持语速适中、情绪自然,尽量减少停顿与杂音。"],referenceTextIndex:0,uploading:!1,isPlaying:!1,isRecording:!1,recordDuration:0,recordTimer:null,recorderManager:null,innerAudioContext:null}),computed:{canSubmit(){return this.voiceName.trim()&&this.audioPath},referenceText(){return(this.referenceTexts||[])[this.referenceTextIndex]||""}},onLoad(){this.checkLogin(),this.initRecorder()},onUnload(){this.innerAudioContext&&(this.innerAudioContext.stop(),this.innerAudioContext.destroy()),this.recordTimer&&clearInterval(this.recordTimer),this.recorderManager&&this.isRecording&&this.recorderManager.stop()},methods:{onUseCosyVoiceChange(e){this.useCosyVoice=!!(e&&e.detail&&e.detail.value)},copyReferenceText(){e.index.setClipboardData({data:this.referenceText,success:()=>{e.index.showToast({title:"已复制",icon:"success"})}})},switchReferenceText(){const e=this.referenceTexts||[];e.length<=1||(this.referenceTextIndex=(this.referenceTextIndex+1)%e.length)},checkLogin(){const t=e.index.getStorageSync("userId"),o=e.index.getStorageSync("token");return!(!t||!o)||(e.index.showModal({title:"需要登录",content:"请先登录后再创建音色",showCancel:!1,success:()=>{e.index.reLaunch({url:"/pages/login/login"})}}),!1)},initRecorder(){this.recorderManager=e.index.getRecorderManager(),this.recorderManager.onStart((()=>{console.log("录音开始"),this.isRecording=!0,this.recordDuration=0,this.recordTimer=setInterval((()=>{this.recordDuration++,this.recordDuration>=60&&this.stopRecord()}),1e3)})),this.recorderManager.onStop((t=>{console.log("录音停止",t),this.isRecording=!1,this.recordTimer&&(clearInterval(this.recordTimer),this.recordTimer=null),this.recordDuration<3?e.index.showToast({title:"录音时长至少3秒",icon:"none"}):(this.audioPath=t.tempFilePath,this.audioName=`录音_${this.recordDuration}秒.mp3`,e.index.showToast({title:"录音完成",icon:"success"}))})),this.recorderManager.onError((t=>{console.error("录音错误:",t),this.isRecording=!1,this.recordTimer&&(clearInterval(this.recordTimer),this.recordTimer=null),e.index.showToast({title:"录音失败,请重试",icon:"none"})}))},chooseAudioFile(){this.checkLogin()&&e.index.chooseMessageFile({count:1,type:"file",extension:[".mp3",".wav",".m4a",".aac"],success:t=>{const o=t.tempFiles&&t.tempFiles[0];o?o.size>10485760?e.index.showToast({title:"文件大小不能超过10MB",icon:"none"}):(this.audioPath=o.path,this.audioName=o.name||"audio",this.audioSize=o.size||0,this.recordDuration=0,e.index.showToast({title:"已选择音频",icon:"success"})):e.index.showToast({title:"选择文件失败",icon:"none"})},fail:t=>{console.error("选择文件失败:",t),e.index.showToast({title:t.errMsg||"选择文件失败",icon:"none"})}})},startRecord(){this.checkLogin()&&(this.recorderManager||this.initRecorder(),e.index.getSetting({success:t=>{t.authSetting["scope.record"]?this.doStartRecord():!1===t.authSetting["scope.record"]?e.index.showModal({title:"需要录音权限",content:"请在设置中开启录音权限",confirmText:"去设置",success:t=>{t.confirm&&e.index.openSetting({success:e=>{e.authSetting["scope.record"]&&this.doStartRecord()}})}}):e.index.authorize({scope:"scope.record",success:()=>{this.doStartRecord()},fail:()=>{e.index.showModal({title:"需要录音权限",content:"请允许使用麦克风进行录音",confirmText:"去设置",success:t=>{t.confirm&&e.index.openSetting()}})}})},fail:()=>{this.doStartRecord()}}))},doStartRecord(){if(this.recorderManager)try{this.recorderManager.start({duration:6e4,sampleRate:16e3,numberOfChannels:1,encodeBitRate:96e3,format:"mp3"})}catch(t){console.error("启动录音失败:",t),e.index.showModal({title:"时光意境",content:"麦克风被其他应用占用\n\n请关闭其他使用麦克风的应用",confirmText:"确定",showCancel:!1})}else e.index.showToast({title:"录音初始化失败",icon:"none"})},stopRecord(){this.recorderManager&&this.isRecording&&this.recorderManager.stop()},playAudio(){this.innerAudioContext||(this.innerAudioContext=e.index.createInnerAudioContext(),this.innerAudioContext.src=this.audioPath,this.innerAudioContext.onPlay((()=>{this.isPlaying=!0})),this.innerAudioContext.onPause((()=>{this.isPlaying=!1})),this.innerAudioContext.onEnded((()=>{this.isPlaying=!1})),this.innerAudioContext.onError((t=>{console.error("音频播放失败:",t),this.isPlaying=!1,e.index.showToast({title:"播放失败",icon:"none"})}))),this.isPlaying?this.innerAudioContext.pause():this.innerAudioContext.play()},deleteAudio(){this.innerAudioContext&&(this.innerAudioContext.stop(),this.innerAudioContext.destroy(),this.innerAudioContext=null),this.audioPath="",this.audioName="",this.isPlaying=!1},handleSubmit(){if(this.uploading)return;if(!this.canSubmit)return void e.index.showToast({title:this.voiceName.trim()?"请先录制音频":"请填写音色名称",icon:"none"});const o=e.index.getStorageSync("userId");if(!o)return e.index.showToast({title:"请先登录",icon:"none"}),void setTimeout((()=>{e.index.navigateTo({url:"/pages/login/login"})}),1500);(()=>{this.uploading=!0;const i=e.index.getStorageSync("token")||"",n=`recording_${Date.now()}.mp3`,r=this.useCosyVoice?"/api/voice/cosy-create":"/api/voice/create";e.index.uploadFile({url:`${t.API_BASE}${r}`,filePath:this.audioPath,name:"audio",fileName:n,formData:{name:this.voiceName,displayName:this.voiceName},header:{"X-User-Id":o,Authorization:i?`Bearer ${i}`:""},success:t=>{console.log("上传响应:",t);try{const o="string"==typeof t.data?JSON.parse(t.data):t.data;if(console.log("解析后的数据:",o),console.log("状态码:",t.statusCode),200===t.statusCode&&o.success)return e.index.showToast({title:"音色创建成功",icon:"success",duration:2e3}),void setTimeout((()=>{e.index.navigateBack()}),2e3);if(402===t.statusCode)return void e.index.showModal({title:"需要付费",content:o&&o.message?o.message:"免费次数已用完,请先完成支付",showCancel:!1});console.error("服务器错误:",o&&(o.message||o.error)?o.message||o.error:`服务器错误 (${t.statusCode})`,o),e.index.showModal({title:"创建失败",content:o&&o.message?o.message:"创建失败,请重试",showCancel:!1})}catch(o){console.error("处理响应失败:",o),e.index.showModal({title:"创建失败",content:"创建失败,请重试",showCancel:!1})}},fail:t=>{console.error("上传失败:",t),e.index.showModal({title:"创建失败",content:"网络请求失败,请检查网络连接",showCancel:!1})},complete:()=>{this.uploading=!1}})})()}}};const i=e._export_sfc(o,[["render",function(t,o,i,n,r,s){return e.e({a:r.voiceName,b:e.o((e=>r.voiceName=e.detail.value)),c:r.useCosyVoice,d:e.o(((...e)=>s.onUseCosyVoiceChange&&s.onUseCosyVoiceChange(...e))),e:e.o(((...e)=>s.switchReferenceText&&s.switchReferenceText(...e))),f:e.t(s.referenceText),g:e.o(((...e)=>s.copyReferenceText&&s.copyReferenceText(...e))),h:!r.audioPath},r.audioPath?{}:{i:r.isRecording,j:e.o(((...e)=>s.startRecord&&s.startRecord(...e)))},{k:!r.audioPath},r.audioPath?{o:e.t(r.audioName),p:e.t(r.isPlaying?"暂停":"播放"),q:e.o(((...e)=>s.playAudio&&s.playAudio(...e))),r:e.o(((...e)=>s.deleteAudio&&s.deleteAudio(...e)))}:e.e({l:r.isRecording},r.isRecording?{m:e.t(r.recordDuration),n:e.o(((...e)=>s.stopRecord&&s.stopRecord(...e)))}:{}),{s:r.uploading},(r.uploading,{}),{t:!s.canSubmit||r.uploading,v:e.o(((...e)=>s.handleSubmit&&s.handleSubmit(...e)))})}],["__scopeId","data-v-fe732786"]]);wx.createPage(i);
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/upload-audio/upload-audio.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/upload-audio/upload-audio.wxml
index dff9b14..d8f1719 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/upload-audio/upload-audio.wxml
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/upload-audio/upload-audio.wxml
@@ -1 +1 @@
-音色名称使用 CosyVoice v3 plus开启后将使用 cosyvoice-v3-plus 创建音色📄 参考文案(可直接朗读){{f}}上传音频样本可录制,建议10-20秒清晰人声🔴录音中... {{m}}秒🎤点击“录音”开始录制🎵{{o}}📝 温馨提示• 音频时长建议10-20秒(最长60秒)• 必须包含至少3秒连续清晰朗读• 避免背景音乐、噪音或其他人声• 音频内容建议为普通话朗读• 创建成功后可在"声音克隆"中使用
\ No newline at end of file
+音色名称使用 CosyVoice v3 plus开启后将使用 cosyvoice-v3-plus 创建音色📄 参考文案(可直接朗读){{f}}上传音频样本可录制,建议10-20秒清晰人声🔴录音中... {{m}}秒🎤点击“录音”开始录制🎵{{o}}本服务为AI生成内容,结果仅供参考📝 温馨提示• 音频时长建议10-20秒(最长60秒)• 必须包含至少3秒连续清晰朗读• 避免背景音乐、噪音或其他人声• 音频内容建议为普通话朗读• 创建成功后可在"声音克隆"中使用
\ No newline at end of file
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/upload-audio/upload-audio.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/upload-audio/upload-audio.wxss
index 4965ca9..de19380 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/upload-audio/upload-audio.wxss
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/upload-audio/upload-audio.wxss
@@ -1 +1 @@
-.upload-container.data-v-84d46214{min-height:100vh;background:linear-gradient(135deg,#fdf8f2,#f5ede0);padding:30rpx}.page-header.data-v-84d46214{text-align:center;margin-bottom:40rpx}.page-header .header-title.data-v-84d46214{display:block;font-size:44rpx;font-weight:700;color:#333;margin-bottom:15rpx}.page-header .header-subtitle.data-v-84d46214{display:block;font-size:26rpx;color:#999}.upload-mode.data-v-84d46214{display:flex;gap:20rpx;margin:15rpx 0 25rpx}.mode-btn.data-v-84d46214{flex:1;height:80rpx;border-radius:15rpx;font-size:28rpx;background:#f5f5f5;color:#333}.toggle-row.data-v-84d46214{display:flex;align-items:center;gap:20rpx}.toggle-hint.data-v-84d46214{font-size:24rpx;color:#999}.reference-box.data-v-84d46214{background:#f5f5f5;border-radius:15rpx;padding:20rpx;margin-top:10rpx}.reference-text.data-v-84d46214{font-size:26rpx;color:#333;line-height:1.6}.copy-btn.data-v-84d46214{margin-top:20rpx;height:80rpx;border-radius:15rpx;font-size:28rpx;background:#6d8b8b;color:#fff}.tips-title-row.data-v-84d46214{display:flex;align-items:center;justify-content:space-between}.switch-btn.data-v-84d46214{height:60rpx;line-height:60rpx;padding:0 20rpx;border-radius:12rpx;font-size:24rpx;background:#f5f5f5;color:#666}.form-section.data-v-84d46214{background:#fff;border-radius:20rpx;padding:30rpx;margin-bottom:30rpx;box-shadow:0 4rpx 20rpx rgba(0,0,0,.05)}.form-item .form-label.data-v-84d46214{display:block;font-size:28rpx;color:#666;margin-bottom:15rpx;font-weight:600}.form-item .form-input.data-v-84d46214{width:100%;height:80rpx;background:#f5f5f5;border-radius:15rpx;padding:0 20rpx;font-size:28rpx;color:#333}.upload-section.data-v-84d46214{background:#fff;border-radius:20rpx;padding:30rpx;margin-bottom:30rpx;box-shadow:0 4rpx 20rpx rgba(0,0,0,.05)}.upload-section .section-title.data-v-84d46214{display:block;font-size:28rpx;color:#666;margin-bottom:10rpx;font-weight:600}.upload-section .section-tip.data-v-84d46214{display:block;font-size:24rpx;color:#999;margin-bottom:25rpx}.upload-box.data-v-84d46214{border:2rpx dashed #8B7355;border-radius:20rpx;padding:60rpx 30rpx;text-align:center;background:#fafafa}.upload-box .upload-icon.data-v-84d46214{font-size:80rpx;margin-bottom:20rpx}.upload-box .upload-text.data-v-84d46214{display:block;font-size:28rpx;color:#8b7355}.upload-box .recording-box.data-v-84d46214{display:flex;flex-direction:column;align-items:center}.upload-box .recording-box .recording-icon.data-v-84d46214{font-size:80rpx;margin-bottom:20rpx;animation:pulse-84d46214 1.5s ease-in-out infinite}.upload-box .recording-box .recording-text.data-v-84d46214{display:block;font-size:28rpx;color:#ff6b6b;margin-bottom:30rpx;font-weight:600}.upload-box .recording-box .stop-btn.data-v-84d46214{width:200rpx;height:70rpx;background:#ff6b6b;color:#fff;border-radius:35rpx;font-size:28rpx;border:none;box-shadow:0 4rpx 15rpx rgba(255,107,107,.3)}@keyframes pulse-84d46214{0%,to{transform:scale(1);opacity:1}50%{transform:scale(1.1);opacity:.8}}.audio-preview.data-v-84d46214{background:#f5f5f5;border-radius:20rpx;padding:25rpx}.audio-preview .audio-info.data-v-84d46214{display:flex;align-items:center;margin-bottom:20rpx}.audio-preview .audio-info .audio-icon.data-v-84d46214{font-size:40rpx;margin-right:15rpx}.audio-preview .audio-info .audio-name.data-v-84d46214{flex:1;font-size:26rpx;color:#333}.audio-preview .audio-actions.data-v-84d46214{display:flex;gap:15rpx}.audio-preview .audio-actions .action-btn.data-v-84d46214{flex:1;height:60rpx;line-height:60rpx;border-radius:10rpx;font-size:26rpx;border:none}.audio-preview .audio-actions .play-btn.data-v-84d46214{background:#8b7355;color:#fff}.audio-preview .audio-actions .delete-btn.data-v-84d46214{background:#ff6b6b;color:#fff}.submit-section.data-v-84d46214{margin-bottom:30rpx}.submit-btn.data-v-84d46214{width:100%;height:90rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);border-radius:45rpx;color:#fff;font-size:32rpx;font-weight:600;border:none;box-shadow:0 8rpx 20rpx rgba(139,115,85,.3)}.submit-btn[disabled].data-v-84d46214{opacity:.5;box-shadow:none}.tips-section.data-v-84d46214{background:rgba(255,255,255,.8);border-radius:20rpx;padding:25rpx}.tips-section .tips-title.data-v-84d46214{display:block;font-size:26rpx;color:#8b7355;font-weight:600;margin-bottom:15rpx}.tips-section .tips-item.data-v-84d46214{display:block;font-size:24rpx;color:#666;line-height:2;padding-left:10rpx}
+.upload-container.data-v-fe732786{min-height:100vh;background:linear-gradient(135deg,#fdf8f2,#f5ede0);padding:30rpx}.page-header.data-v-fe732786{text-align:center;margin-bottom:40rpx}.page-header .header-title.data-v-fe732786{display:block;font-size:44rpx;font-weight:700;color:#333;margin-bottom:15rpx}.page-header .header-subtitle.data-v-fe732786{display:block;font-size:26rpx;color:#999}.upload-mode.data-v-fe732786{display:flex;gap:20rpx;margin:15rpx 0 25rpx}.mode-btn.data-v-fe732786{flex:1;height:80rpx;border-radius:15rpx;font-size:28rpx;background:#f5f5f5;color:#333}.toggle-row.data-v-fe732786{display:flex;align-items:center;gap:20rpx}.toggle-hint.data-v-fe732786{font-size:24rpx;color:#999}.reference-box.data-v-fe732786{background:#f5f5f5;border-radius:15rpx;padding:20rpx;margin-top:10rpx}.reference-text.data-v-fe732786{font-size:26rpx;color:#333;line-height:1.6}.copy-btn.data-v-fe732786{margin-top:20rpx;height:80rpx;border-radius:15rpx;font-size:28rpx;background:#6d8b8b;color:#fff}.tips-title-row.data-v-fe732786{display:flex;align-items:center;justify-content:space-between}.switch-btn.data-v-fe732786{height:60rpx;line-height:60rpx;padding:0 20rpx;border-radius:12rpx;font-size:24rpx;background:#f5f5f5;color:#666}.form-section.data-v-fe732786{background:#fff;border-radius:20rpx;padding:30rpx;margin-bottom:30rpx;box-shadow:0 4rpx 20rpx rgba(0,0,0,.05)}.form-item .form-label.data-v-fe732786{display:block;font-size:28rpx;color:#666;margin-bottom:15rpx;font-weight:600}.form-item .form-input.data-v-fe732786{width:100%;height:80rpx;background:#f5f5f5;border-radius:15rpx;padding:0 20rpx;font-size:28rpx;color:#333}.upload-section.data-v-fe732786{background:#fff;border-radius:20rpx;padding:30rpx;margin-bottom:30rpx;box-shadow:0 4rpx 20rpx rgba(0,0,0,.05)}.upload-section .section-title.data-v-fe732786{display:block;font-size:28rpx;color:#666;margin-bottom:10rpx;font-weight:600}.upload-section .section-tip.data-v-fe732786{display:block;font-size:24rpx;color:#999;margin-bottom:25rpx}.upload-box.data-v-fe732786{border:2rpx dashed #8B7355;border-radius:20rpx;padding:60rpx 30rpx;text-align:center;background:#fafafa}.upload-box .upload-icon.data-v-fe732786{font-size:80rpx;margin-bottom:20rpx}.upload-box .upload-text.data-v-fe732786{display:block;font-size:28rpx;color:#8b7355}.upload-box .recording-box.data-v-fe732786{display:flex;flex-direction:column;align-items:center}.upload-box .recording-box .recording-icon.data-v-fe732786{font-size:80rpx;margin-bottom:20rpx;animation:pulse-fe732786 1.5s ease-in-out infinite}.upload-box .recording-box .recording-text.data-v-fe732786{display:block;font-size:28rpx;color:#ff6b6b;margin-bottom:30rpx;font-weight:600}.upload-box .recording-box .stop-btn.data-v-fe732786{width:200rpx;height:70rpx;background:#ff6b6b;color:#fff;border-radius:35rpx;font-size:28rpx;border:none;box-shadow:0 4rpx 15rpx rgba(255,107,107,.3)}@keyframes pulse-fe732786{0%,to{transform:scale(1);opacity:1}50%{transform:scale(1.1);opacity:.8}}.audio-preview.data-v-fe732786{background:#f5f5f5;border-radius:20rpx;padding:25rpx}.audio-preview .audio-info.data-v-fe732786{display:flex;align-items:center;margin-bottom:20rpx}.audio-preview .audio-info .audio-icon.data-v-fe732786{font-size:40rpx;margin-right:15rpx}.audio-preview .audio-info .audio-name.data-v-fe732786{flex:1;font-size:26rpx;color:#333}.audio-preview .audio-actions.data-v-fe732786{display:flex;gap:15rpx}.audio-preview .audio-actions .action-btn.data-v-fe732786{flex:1;height:60rpx;line-height:60rpx;border-radius:10rpx;font-size:26rpx;border:none}.audio-preview .audio-actions .play-btn.data-v-fe732786{background:#8b7355;color:#fff}.audio-preview .audio-actions .delete-btn.data-v-fe732786{background:#ff6b6b;color:#fff}.submit-section.data-v-fe732786{margin-bottom:30rpx}.ai-disclaimer.data-v-fe732786{display:block;text-align:center;font-size:22rpx;color:rgba(100,100,100,.6);margin-top:16rpx;letter-spacing:.5rpx}.submit-btn.data-v-fe732786{width:100%;height:90rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);border-radius:45rpx;color:#fff!important;font-size:32rpx;font-weight:600;border:none;box-shadow:0 8rpx 20rpx rgba(139,115,85,.3)}.submit-btn[disabled].data-v-fe732786{opacity:.5;box-shadow:none;color:#fff!important}.tips-section.data-v-fe732786{background:rgba(255,255,255,.8);border-radius:20rpx;padding:25rpx}.tips-section .tips-title.data-v-fe732786{display:block;font-size:26rpx;color:#8b7355;font-weight:600;margin-bottom:15rpx}.tips-section .tips-item.data-v-fe732786{display:block;font-size:24rpx;color:#666;line-height:2;padding-left:10rpx}
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call-new/video-call-new.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call-new/video-call-new.js
index 0fc0ca1..c8e4c2c 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call-new/video-call-new.js
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call-new/video-call-new.js
@@ -1 +1 @@
-"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);
+"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","5a549494-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-5a549494"]]);wx.createPage(s);
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call-new/video-call-new.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call-new/video-call-new.wxml
index 87df966..c36198a 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call-new/video-call-new.wxml
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call-new/video-call-new.wxml
@@ -1 +1 @@
-⏳ 加载视频列表...📹{{video.g}}✓ 已就绪✓ 已缓存{{video.l}}%{{video.m}}📞📹{{k}}{{l}}📹视频加载中...{{v}}{{w}}💗TA在听你说方言{{z}}语言提示(可选){{D}}💡 仅处理第一个值;不设置不生效清空{{O}}挂断💭 记忆设定(可选)设置对话记忆,让AI更真实地模拟对方身份性格特点
\ No newline at end of file
+⏳ 加载视频列表...📹{{video.g}}✓ 已就绪✓ 已缓存{{video.l}}%{{video.m}}📞📹{{k}}{{l}}📹视频加载中...AI生成{{v}}{{w}}💗TA在听你说方言{{z}}语言提示(可选){{D}}💡 仅处理第一个值;不设置不生效清空{{O}}挂断💭 记忆设定(可选)设置对话记忆,让AI更真实地模拟对方身份性格特点
\ No newline at end of file
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call-new/video-call-new.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call-new/video-call-new.wxss
index 01a7b31..681eab1 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call-new/video-call-new.wxss
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call-new/video-call-new.wxss
@@ -1 +1 @@
-.video-call-container.data-v-125ef3e1{min-height:100vh;background:#fdf8f2;background-image:radial-gradient(circle at 10% 20%,rgba(212,185,150,.1) 0%,transparent 20%),radial-gradient(circle at 90% 80%,rgba(109,139,139,.1) 0%,transparent 20%);display:flex;flex-direction:column}.header.data-v-125ef3e1{background:linear-gradient(135deg,#8b7355,#6d8b8b);padding:30rpx;padding-top:calc(30rpx + constant(safe-area-inset-top));padding-top:calc(30rpx + env(safe-area-inset-top));display:flex;justify-content:space-between;align-items:center;box-shadow:0 8rpx 30rpx rgba(0,0,0,.16)}.back-btn.data-v-125ef3e1{font-size:28rpx;color:#fff;font-weight:600;padding:10rpx}.header-title.data-v-125ef3e1{font-size:32rpx;font-weight:700;color:#fff}.placeholder.data-v-125ef3e1{width:100rpx}.select-video-section.data-v-125ef3e1{flex:1;display:flex;flex-direction:column}.loading-box.data-v-125ef3e1{flex:1;display:flex;justify-content:center;align-items:center}.loading-text.data-v-125ef3e1{font-size:28rpx;color:#999}.video-list.data-v-125ef3e1{flex:1;padding:0 32rpx}.list-header.data-v-125ef3e1{padding:40rpx 0 24rpx;display:flex;justify-content:space-between;align-items:center}.list-title.data-v-125ef3e1{font-size:32rpx;font-weight:700;color:#333}.list-count.data-v-125ef3e1{font-size:24rpx;color:#999}.video-item.data-v-125ef3e1{background:#fff;border-radius:16rpx;padding:24rpx;margin-bottom:20rpx;display:flex;align-items:center;box-shadow:0 2rpx 12rpx rgba(0,0,0,.06);transition:all .3s}.video-item.data-v-125ef3e1:active{transform:scale(.98);box-shadow:0 4rpx 16rpx rgba(0,0,0,.12)}.item-cover.data-v-125ef3e1{width:120rpx;height:160rpx;border-radius:12rpx;overflow:hidden;background:#f5f5f5;flex-shrink:0;margin-right:24rpx}.cover-img.data-v-125ef3e1{width:100%;height:100%}.cover-placeholder.data-v-125ef3e1{width:100%;height:100%;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#f5f5f5,#e8e8e8)}.placeholder-icon.data-v-125ef3e1{font-size:48rpx;opacity:.5}.preload-video.data-v-125ef3e1{position:absolute;top:0;left:0;width:1px;height:1px;opacity:0;pointer-events:none;z-index:-1}.item-info.data-v-125ef3e1{flex:1;display:flex;flex-direction:column;justify-content:center;min-width:0;margin-right:16rpx}.info-name-row.data-v-125ef3e1{display:flex;align-items:center;gap:12rpx;margin-bottom:12rpx}.info-name.data-v-125ef3e1{font-size:30rpx;font-weight:600;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-shrink:1}.cache-badge.data-v-125ef3e1{flex-shrink:0}.cache-badge-text.data-v-125ef3e1{font-size:20rpx;padding:4rpx 12rpx;border-radius:20rpx;white-space:nowrap}.cache-badge-text.completed.data-v-125ef3e1{background:linear-gradient(135deg,#e8f5e9,#c8e6c9);color:#2e7d32;font-weight:500}.cache-badge-text.downloading.data-v-125ef3e1{background:linear-gradient(135deg,#fff3e0,#ffe0b2);color:#e65100;font-weight:500}.info-text.data-v-125ef3e1{font-size:24rpx;color:#999;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item-action.data-v-125ef3e1{flex-shrink:0}.call-icon.data-v-125ef3e1{width:88rpx;height:88rpx;background:linear-gradient(135deg,#07c160,#06ae56);border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 4rpx 12rpx rgba(7,193,96,.3)}.icon-text.data-v-125ef3e1{font-size:40rpx}.empty-box.data-v-125ef3e1{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:100rpx 40rpx}.empty-icon.data-v-125ef3e1{font-size:120rpx;margin-bottom:32rpx}.empty-text.data-v-125ef3e1{font-size:32rpx;color:#666;margin-bottom:16rpx}.empty-hint.data-v-125ef3e1{font-size:26rpx;color:#999;margin-bottom:40rpx}.go-revival-btn.data-v-125ef3e1{padding:24rpx 48rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:40rpx;font-size:28rpx;font-weight:700;box-shadow:0 8rpx 16rpx rgba(139,115,85,.3)}.call-active-section.data-v-125ef3e1{position:fixed;top:0;left:0;right:0;bottom:0;background:#000;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;padding:0;overflow:hidden;z-index:1}.video-fullscreen.data-v-125ef3e1{position:fixed;top:220rpx;left:40rpx;right:40rpx;bottom:calc(360rpx + constant(safe-area-inset-bottom));bottom:calc(360rpx + env(safe-area-inset-bottom));border-radius:32rpx;overflow:hidden;background:#000;box-shadow:0 20rpx 60rpx rgba(0,0,0,.5);z-index:1}.video-player.data-v-125ef3e1{width:100%;height:100%;background:#000;border-radius:32rpx;object-fit:cover;position:relative;z-index:1;pointer-events:none}.video-placeholder.data-v-125ef3e1{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;background:linear-gradient(135deg,#1a1a1a,#2d2d2d)}.placeholder-text.data-v-125ef3e1{font-size:28rpx;color:rgba(255,255,255,.6);margin-top:20rpx}.call-status-bar.data-v-125ef3e1{position:fixed;top:0;left:0;right:0;padding:80rpx 40rpx 40rpx;background:linear-gradient(180deg,rgba(0,0,0,.7) 0%,transparent 100%);z-index:1000;pointer-events:none}.call-status-bar .listening-chip.data-v-125ef3e1{pointer-events:auto}.status-info.data-v-125ef3e1{display:flex;flex-direction:column;align-items:center;gap:8rpx}.call-name.data-v-125ef3e1{font-size:32rpx;font-weight:600;color:#fff;text-shadow:0 2rpx 8rpx rgba(0,0,0,.5)}.call-time.data-v-125ef3e1{font-size:26rpx;color:rgba(255,255,255,.9);font-family:Courier New,monospace;text-shadow:0 2rpx 4rpx rgba(0,0,0,.5)}.listening-chip.data-v-125ef3e1{margin-top:12rpx;padding:18rpx 28rpx;background:linear-gradient(135deg,#ffb6c1,pink,#ffd4e5);border-radius:50rpx;border:2rpx solid rgba(255,255,255,.8);box-shadow:0 8rpx 24rpx rgba(255,182,193,.4),0 0 20rpx rgba(255,192,203,.3);display:inline-flex;align-items:center;gap:12rpx;transition:all .3s ease;animation:listeningGlow-125ef3e1 1.5s ease-in-out infinite,listeningPulse-125ef3e1 2s ease-in-out infinite;position:relative;z-index:1001;pointer-events:auto;opacity:1;visibility:visible}.listening-chip.inline-chip.data-v-125ef3e1{margin-top:0}.listening-icon.data-v-125ef3e1{font-size:32rpx;animation:iconBounce-125ef3e1 1s ease-in-out infinite;filter:drop-shadow(0 2rpx 4rpx rgba(0,0,0,.3))}.listening-text.data-v-125ef3e1{font-size:28rpx;color:#fff;font-weight:700;letter-spacing:1rpx;text-shadow:0 2rpx 6rpx rgba(0,0,0,.4),0 0 10rpx rgba(255,255,255,.3)}.chat-section.data-v-125ef3e1{flex:1;background:#fff;border-radius:24rpx;padding:30rpx;box-shadow:0 4rpx 12rpx rgba(0,0,0,.08);min-height:150rpx}.chat-messages.data-v-125ef3e1{height:100%}.message-item.data-v-125ef3e1{display:flex;margin-bottom:20rpx;animation:fadeIn-125ef3e1 .3s}.message-item.user.data-v-125ef3e1{justify-content:flex-end}.message-item.ai.data-v-125ef3e1{justify-content:flex-start}.message-bubble.data-v-125ef3e1{max-width:70%;padding:20rpx 24rpx;border-radius:16rpx}.message-item.user .message-bubble.data-v-125ef3e1{background:linear-gradient(135deg,#667eea,#764ba2);border-bottom-right-radius:4rpx}.message-item.ai .message-bubble.data-v-125ef3e1{background:#f0f0f0;border-bottom-left-radius:4rpx}.message-text.data-v-125ef3e1{font-size:28rpx;line-height:1.5;color:#fff}.message-item.ai .message-text.data-v-125ef3e1{color:#333}.empty-chat.data-v-125ef3e1{height:100%;display:flex;align-items:center;justify-content:center}.empty-chat-text.data-v-125ef3e1{font-size:26rpx;color:#999}.call-controls.data-v-125ef3e1{position:fixed;bottom:0;left:0;right:0;height:320rpx;padding:40rpx 60rpx calc(80rpx + constant(safe-area-inset-bottom));padding:40rpx 60rpx calc(80rpx + env(safe-area-inset-bottom));background:linear-gradient(0deg,rgba(0,0,0,.95) 0%,rgba(0,0,0,.6) 60%,transparent 100%);z-index:1001;pointer-events:none;display:flex;flex-direction:column;justify-content:flex-end}.recording-hint.data-v-125ef3e1{text-align:center;margin-bottom:30rpx}.hint-box.data-v-125ef3e1{display:inline-flex;align-items:center;gap:12rpx;padding:16rpx 32rpx;border-radius:50rpx;box-shadow:0 8rpx 24rpx rgba(0,0,0,.4);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.hint-box.listening-pulse.data-v-125ef3e1{background:linear-gradient(135deg,rgba(7,193,96,.9),rgba(6,174,86,.9));animation:listeningPulse-125ef3e1 1.5s ease-in-out infinite}.hint-box.processing-pulse.data-v-125ef3e1{background:linear-gradient(135deg,rgba(255,193,7,.9),rgba(255,152,0,.9));animation:processingPulse 1.5s ease-in-out infinite}.hint-icon.data-v-125ef3e1{font-size:32rpx;animation:iconBounce-125ef3e1 1s ease-in-out infinite}.hint-text.data-v-125ef3e1{font-size:28rpx;color:#fff;font-weight:600;text-shadow:0 2rpx 4rpx rgba(0,0,0,.3)}.control-buttons.data-v-125ef3e1{display:flex;align-items:flex-end;justify-content:space-around;gap:40rpx;position:relative;z-index:1002;pointer-events:auto}.control-btn.data-v-125ef3e1{display:flex;flex-direction:column;align-items:center;gap:12rpx;cursor:pointer;user-select:none;-webkit-user-select:none;touch-action:manipulation;position:relative;z-index:1003;pointer-events:auto}.btn-circle.data-v-125ef3e1{width:100rpx;height:100rpx;border-radius:50%;background:rgba(255,255,255,.95);-webkit-backdrop-filter:blur(20rpx);backdrop-filter:blur(20rpx);display:flex;align-items:center;justify-content:center;transition:all .3s;box-shadow:0 8rpx 24rpx rgba(0,0,0,.5),0 0 0 4rpx rgba(255,255,255,.3);position:relative;z-index:1004}.btn-circle.large.data-v-125ef3e1{width:130rpx;height:130rpx;background:rgba(255,255,255,.95)}.btn-circle.recording.data-v-125ef3e1{background:rgba(235,51,73,.95);animation:recordingPulse-125ef3e1 1s ease-in-out infinite}.btn-circle.processing.data-v-125ef3e1{background:rgba(200,200,200,.95)}.speak-button.data-v-125ef3e1{position:relative;width:240rpx;height:160rpx;display:flex;align-items:center;justify-content:center;transition:all .3s cubic-bezier(.4,0,.2,1);z-index:1005}.speak-button-inner.data-v-125ef3e1{width:240rpx;height:160rpx;border-radius:80rpx;background:linear-gradient(135deg,#ff6b6b,#ffe66d);display:flex;align-items:center;justify-content:center;box-shadow:0 8rpx 32rpx rgba(255,107,107,.6),0 4rpx 16rpx rgba(255,230,109,.5),0 0 0 6rpx rgba(255,255,255,.3);transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;z-index:1006}.speak-button.recording .speak-button-inner.data-v-125ef3e1{background:linear-gradient(135deg,#4ecdc4,#44a08d);box-shadow:0 12rpx 48rpx rgba(78,205,196,.6),0 6rpx 24rpx rgba(68,160,141,.5),0 0 0 6rpx rgba(255,255,255,.3);transform:scale(1.05);width:260rpx;height:180rpx}.speak-button.processing .speak-button-inner.data-v-125ef3e1{background:linear-gradient(135deg,#a8a8a8,#7a7a7a);box-shadow:0 8rpx 32rpx rgba(168,168,168,.3)}.speak-ring.data-v-125ef3e1{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:240rpx;height:160rpx;border-radius:80rpx;border:4rpx solid rgba(78,205,196,.6);animation:speakRingPulse-125ef3e1 1.5s ease-out infinite;z-index:1}.speak-ring-outer.data-v-125ef3e1{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:240rpx;height:160rpx;border-radius:80rpx;border:3rpx solid rgba(68,160,141,.5);animation:speakRingPulse-125ef3e1 1.5s ease-out infinite .3s;z-index:0}@keyframes speakRingPulse-125ef3e1{0%{width:240rpx;height:160rpx;opacity:1}to{width:320rpx;height:220rpx;opacity:0}}.btn-circle.end-call.data-v-125ef3e1{background:rgba(235,51,73,.98);box-shadow:0 8rpx 24rpx rgba(235,51,73,.6),0 0 0 4rpx rgba(255,255,255,.3)}.btn-circle.data-v-125ef3e1:active{transform:scale(.95)}.btn-icon.data-v-125ef3e1{font-size:40rpx}.btn-icon.large.data-v-125ef3e1{font-size:52rpx}.btn-icon.pulse.data-v-125ef3e1{animation:pulse-125ef3e1 1s infinite}.btn-label.data-v-125ef3e1{font-size:22rpx;color:rgba(255,255,255,.98);font-weight:600;text-shadow:0 2rpx 8rpx rgba(0,0,0,.6),0 0 20rpx rgba(0,0,0,.4)}.btn-label-new.data-v-125ef3e1{font-size:24rpx;color:rgba(255,255,255,.95);font-weight:600;text-shadow:0 2rpx 8rpx rgba(0,0,0,.4);transition:all .3s;margin-top:8rpx}.btn-label-new.active.data-v-125ef3e1{color:#4ecdc4;text-shadow:0 2rpx 8rpx rgba(78,205,196,.6);transform:scale(1.05)}.icon-delete.data-v-125ef3e1{width:40rpx;height:40rpx;position:relative}.icon-delete.data-v-125ef3e1:before,.icon-delete.data-v-125ef3e1:after{content:"";position:absolute;left:50%;top:50%;width:32rpx;height:4rpx;background:#333;border-radius:2rpx;box-shadow:0 2rpx 4rpx rgba(0,0,0,.2)}.icon-delete.data-v-125ef3e1:before{transform:translate(-50%,-50%) rotate(45deg)}.icon-delete.data-v-125ef3e1:after{transform:translate(-50%,-50%) rotate(-45deg)}.icon-mic.data-v-125ef3e1{width:40rpx;height:52rpx;border:4rpx solid #333;border-radius:20rpx;position:relative}.icon-mic.data-v-125ef3e1:after{content:"";position:absolute;bottom:-12rpx;left:50%;transform:translate(-50%);width:30rpx;height:12rpx;border:4rpx solid #333;border-top:none;border-radius:0 0 15rpx 15rpx}.icon-mic.data-v-125ef3e1:before{content:"";position:absolute;bottom:-20rpx;left:50%;transform:translate(-50%);width:3rpx;height:8rpx;background:#333}.icon-mic-new.data-v-125ef3e1{width:48rpx;height:64rpx;border:5rpx solid white;border-radius:24rpx;position:relative;animation:micFloat-125ef3e1 2s ease-in-out infinite}.icon-mic-new.data-v-125ef3e1:after{content:"";position:absolute;bottom:-16rpx;left:50%;transform:translate(-50%);width:36rpx;height:16rpx;border:5rpx solid white;border-top:none;border-radius:0 0 18rpx 18rpx}.icon-mic-new.data-v-125ef3e1:before{content:"";position:absolute;bottom:-26rpx;left:50%;transform:translate(-50%);width:4rpx;height:10rpx;background:#fff}@keyframes micFloat-125ef3e1{0%,to{transform:translateY(0)}50%{transform:translateY(-6rpx)}}.icon-recording.data-v-125ef3e1{width:48rpx;height:48rpx;background:#fff;border-radius:50%;position:relative}.icon-recording.data-v-125ef3e1:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:32rpx;height:32rpx;background:#eb3349;border-radius:50%}.icon-wave-container.data-v-125ef3e1{display:flex;align-items:center;justify-content:center;gap:6rpx;height:60rpx}.wave-bar.data-v-125ef3e1{width:6rpx;background:#fff;border-radius:3rpx;animation:waveAnimation-125ef3e1 1s ease-in-out infinite}@keyframes waveAnimation-125ef3e1{0%,to{height:20rpx}50%{height:50rpx}}.icon-loading.data-v-125ef3e1{width:48rpx;height:48rpx;border:4rpx solid rgba(255,255,255,.3);border-top-color:#666;border-radius:50%;animation:spin-125ef3e1 1s linear infinite}.icon-loading-new.data-v-125ef3e1{width:56rpx;height:56rpx;border:5rpx solid rgba(255,255,255,.2);border-top-color:#fff;border-right-color:#fff;border-radius:50%;animation:spin-125ef3e1 .8s linear infinite}.icon-hangup.data-v-125ef3e1{width:48rpx;height:20rpx;border:5rpx solid white;border-radius:12rpx;position:relative;transform:rotate(-135deg);filter:drop-shadow(0 2rpx 4rpx rgba(0,0,0,.3))}.icon-hangup.data-v-125ef3e1:before{content:"";position:absolute;right:-8rpx;top:-12rpx;width:16rpx;height:16rpx;border:5rpx solid white;border-left:none;border-bottom:none;border-radius:0 8rpx 0 0}@keyframes spin-125ef3e1{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes listeningGlow-125ef3e1{0%,to{box-shadow:0 8rpx 24rpx rgba(255,182,193,.4),0 0 20rpx rgba(255,192,203,.3);border-color:rgba(255,255,255,.8)}50%{box-shadow:0 12rpx 36rpx rgba(255,182,193,.6),0 0 40rpx rgba(255,192,203,.5),0 0 60rpx rgba(255,212,229,.4);border-color:#fff}}@keyframes listeningPulse-125ef3e1{0%,to{transform:scale(1)}50%{transform:scale(1.05)}}@keyframes iconBounce-125ef3e1{0%,to{transform:translateY(0)}50%{transform:translateY(-4rpx)}}.settings-dialog-mask.data-v-125ef3e1{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;z-index:9999;padding:40rpx}.settings-dialog.data-v-125ef3e1{width:92vw;max-width:640rpx;max-height:80vh;background:#fff;border-radius:32rpx;overflow:hidden;box-shadow:0 20rpx 60rpx rgba(0,0,0,.3);display:flex;flex-direction:column;box-sizing:border-box}.dialog-header.data-v-125ef3e1{padding:40rpx 40rpx 30rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);display:flex;justify-content:space-between;align-items:center;border-bottom:1rpx solid rgba(255,255,255,.1)}.dialog-title.data-v-125ef3e1{font-size:36rpx;font-weight:700;color:#fff}.dialog-close.data-v-125ef3e1{font-size:40rpx;color:#fff;opacity:.9;padding:0 10rpx;font-weight:300}.dialog-content.data-v-125ef3e1{flex:1;overflow-y:auto;padding:32rpx;box-sizing:border-box}.dialog-section.data-v-125ef3e1{margin-bottom:30rpx}.section-label.data-v-125ef3e1{font-size:30rpx;font-weight:700;color:#333;margin-bottom:12rpx}.section-hint.data-v-125ef3e1{font-size:24rpx;color:#999;margin-bottom:24rpx;display:block;line-height:1.6}.memory-item.data-v-125ef3e1{margin-bottom:24rpx;width:100%}.memory-label.data-v-125ef3e1{font-size:26rpx;color:#666;margin-bottom:12rpx;display:block;font-weight:500}.memory-input.data-v-125ef3e1{width:100%;padding:28rpx 24rpx;min-height:88rpx;background:#fdf8f2;border-radius:16rpx;font-size:28rpx;border:2rpx solid #e8dcc8;transition:all .3s;box-sizing:border-box;max-width:100%}.memory-input.data-v-125ef3e1:focus{border-color:#8b7355;background:#fff}.memory-textarea.data-v-125ef3e1{width:100%;min-height:140rpx;max-height:none;padding:24rpx;background:#fdf8f2;border-radius:16rpx;font-size:28rpx;border:2rpx solid #e8dcc8;line-height:1.6;transition:all .3s;box-sizing:border-box;max-width:100%}.memory-textarea.data-v-125ef3e1:focus{border-color:#8b7355;background:#fff}.dialog-footer.data-v-125ef3e1{padding:30rpx 40rpx;padding-bottom:calc(30rpx + env(safe-area-inset-bottom));display:flex;gap:20rpx;border-top:1rpx solid #f0f0f0;background:#fafafa}.dialog-btn.data-v-125ef3e1{flex:1;height:88rpx;border:none;border-radius:44rpx;font-size:30rpx;font-weight:600;display:flex;align-items:center;justify-content:center;transition:all .3s}.dialog-btn.cancel.data-v-125ef3e1{background:#f5f5f5;color:#666}.dialog-btn.cancel.data-v-125ef3e1:active{background:#e0e0e0}.dialog-btn.confirm.data-v-125ef3e1{background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;box-shadow:0 8rpx 20rpx rgba(139,115,85,.3)}.dialog-btn.confirm.data-v-125ef3e1:active{transform:translateY(-2rpx);box-shadow:0 12rpx 28rpx rgba(139,115,85,.4)}@keyframes fadeIn-125ef3e1{0%{opacity:0;transform:translateY(20rpx)}to{opacity:1;transform:translateY(0)}}@keyframes pulse-125ef3e1{0%,to{transform:scale(1)}50%{transform:scale(1.1)}}@keyframes statusBlink-125ef3e1{0%,to{opacity:1}50%{opacity:.6}}@keyframes recordingPulse-125ef3e1{0%,to{transform:scale(1);box-shadow:0 8rpx 16rpx rgba(235,51,73,.3)}50%{transform:scale(1.02);box-shadow:0 12rpx 24rpx rgba(235,51,73,.5),0 0 0 8rpx rgba(235,51,73,.2)}}.connecting-overlay.data-v-125ef3e1{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;display:flex;align-items:center;justify-content:center;animation:fadeIn-125ef3e1 .3s ease}.connecting-bg.data-v-125ef3e1{position:absolute;top:0;left:0;right:0;bottom:0;overflow:hidden}.bg-avatar.data-v-125ef3e1{width:100%;height:100%;filter:blur(40rpx) brightness(.4);transform:scale(1.2)}.connecting-content.data-v-125ef3e1{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;gap:40rpx;padding:60rpx}.avatar-container.data-v-125ef3e1{width:240rpx;height:240rpx;border-radius:50%;overflow:hidden;background:rgba(255,255,255,.1);border:6rpx solid rgba(255,255,255,.3);box-shadow:0 20rpx 60rpx rgba(0,0,0,.5);animation:avatarPulse-125ef3e1 2s ease-in-out infinite}.avatar-img.data-v-125ef3e1{width:100%;height:100%}.avatar-placeholder.data-v-125ef3e1{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:80rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b)}.connecting-name.data-v-125ef3e1{font-size:40rpx;font-weight:600;color:#fff;text-shadow:0 4rpx 12rpx rgba(0,0,0,.5)}.connecting-status.data-v-125ef3e1{display:flex;flex-direction:column;align-items:center;gap:20rpx}.status-dots.data-v-125ef3e1{display:flex;gap:12rpx;align-items:center}.dot.data-v-125ef3e1{width:12rpx;height:12rpx;border-radius:50%;background:#fff;animation:dotBounce-125ef3e1 1.4s ease-in-out infinite}.dot-1.data-v-125ef3e1{animation-delay:0s}.dot-2.data-v-125ef3e1{animation-delay:.2s}.dot-3.data-v-125ef3e1{animation-delay:.4s}.status-text.data-v-125ef3e1{font-size:32rpx;color:rgba(255,255,255,.9);text-shadow:0 2rpx 8rpx rgba(0,0,0,.5)}.video-hidden.data-v-125ef3e1{opacity:0;pointer-events:none}@keyframes avatarPulse-125ef3e1{0%,to{transform:scale(1);box-shadow:0 20rpx 60rpx rgba(0,0,0,.5)}50%{transform:scale(1.05);box-shadow:0 20rpx 60rpx rgba(0,0,0,.5),0 0 0 20rpx rgba(255,255,255,.1)}}@keyframes dotBounce-125ef3e1{0%,80%,to{transform:translateY(0);opacity:1}40%{transform:translateY(-16rpx);opacity:.7}}.video-fullscreen.data-v-125ef3e1{box-shadow:0 8rpx 24rpx rgba(0,0,0,.35)}.call-controls.data-v-125ef3e1{-webkit-backdrop-filter:none;backdrop-filter:none}.hint-box.data-v-125ef3e1{-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:0 4rpx 12rpx rgba(0,0,0,.35)}.btn-circle.data-v-125ef3e1{-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:0 4rpx 12rpx rgba(0,0,0,.4)}.speak-button-inner.data-v-125ef3e1{box-shadow:0 6rpx 20rpx rgba(0,0,0,.35)}.listening-chip.data-v-125ef3e1{box-shadow:0 4rpx 12rpx rgba(0,0,0,.35)}.listening-icon.data-v-125ef3e1{filter:none}.bg-avatar.data-v-125ef3e1{filter:blur(16rpx) brightness(.4)}
+.video-call-container.data-v-5a549494{min-height:100vh;background:#fdf8f2;background-image:radial-gradient(circle at 10% 20%,rgba(212,185,150,.1) 0%,transparent 20%),radial-gradient(circle at 90% 80%,rgba(109,139,139,.1) 0%,transparent 20%);display:flex;flex-direction:column}.header.data-v-5a549494{background:linear-gradient(135deg,#8b7355,#6d8b8b);padding:30rpx;padding-top:calc(30rpx + constant(safe-area-inset-top));padding-top:calc(30rpx + env(safe-area-inset-top));display:flex;justify-content:space-between;align-items:center;box-shadow:0 8rpx 30rpx rgba(0,0,0,.16)}.back-btn.data-v-5a549494{font-size:28rpx;color:#fff;font-weight:600;padding:10rpx}.header-title.data-v-5a549494{font-size:32rpx;font-weight:700;color:#fff}.placeholder.data-v-5a549494{width:100rpx}.select-video-section.data-v-5a549494{flex:1;display:flex;flex-direction:column}.loading-box.data-v-5a549494{flex:1;display:flex;justify-content:center;align-items:center}.loading-text.data-v-5a549494{font-size:28rpx;color:#999}.video-list.data-v-5a549494{flex:1;padding:0 32rpx}.list-header.data-v-5a549494{padding:40rpx 0 24rpx;display:flex;justify-content:space-between;align-items:center}.list-title.data-v-5a549494{font-size:32rpx;font-weight:700;color:#333}.list-count.data-v-5a549494{font-size:24rpx;color:#999}.video-item.data-v-5a549494{background:#fff;border-radius:16rpx;padding:24rpx;margin-bottom:20rpx;display:flex;align-items:center;box-shadow:0 2rpx 12rpx rgba(0,0,0,.06);transition:all .3s}.video-item.data-v-5a549494:active{transform:scale(.98);box-shadow:0 4rpx 16rpx rgba(0,0,0,.12)}.item-cover.data-v-5a549494{width:120rpx;height:160rpx;border-radius:12rpx;overflow:hidden;background:#f5f5f5;flex-shrink:0;margin-right:24rpx}.cover-img.data-v-5a549494{width:100%;height:100%}.cover-placeholder.data-v-5a549494{width:100%;height:100%;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#f5f5f5,#e8e8e8)}.placeholder-icon.data-v-5a549494{font-size:48rpx;opacity:.5}.preload-video.data-v-5a549494{position:absolute;top:0;left:0;width:1px;height:1px;opacity:0;pointer-events:none;z-index:-1}.item-info.data-v-5a549494{flex:1;display:flex;flex-direction:column;justify-content:center;min-width:0;margin-right:16rpx}.info-name-row.data-v-5a549494{display:flex;align-items:center;gap:12rpx;margin-bottom:12rpx}.info-name.data-v-5a549494{font-size:30rpx;font-weight:600;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-shrink:1}.cache-badge.data-v-5a549494{flex-shrink:0}.cache-badge-text.data-v-5a549494{font-size:20rpx;padding:4rpx 12rpx;border-radius:20rpx;white-space:nowrap}.cache-badge-text.completed.data-v-5a549494{background:linear-gradient(135deg,#e8f5e9,#c8e6c9);color:#2e7d32;font-weight:500}.cache-badge-text.downloading.data-v-5a549494{background:linear-gradient(135deg,#fff3e0,#ffe0b2);color:#e65100;font-weight:500}.info-text.data-v-5a549494{font-size:24rpx;color:#999;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item-action.data-v-5a549494{flex-shrink:0}.call-icon.data-v-5a549494{width:88rpx;height:88rpx;background:linear-gradient(135deg,#07c160,#06ae56);border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 4rpx 12rpx rgba(7,193,96,.3)}.icon-text.data-v-5a549494{font-size:40rpx}.empty-box.data-v-5a549494{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:100rpx 40rpx}.empty-icon.data-v-5a549494{font-size:120rpx;margin-bottom:32rpx}.empty-text.data-v-5a549494{font-size:32rpx;color:#666;margin-bottom:16rpx}.empty-hint.data-v-5a549494{font-size:26rpx;color:#999;margin-bottom:40rpx}.go-revival-btn.data-v-5a549494{padding:24rpx 48rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;border:none;border-radius:40rpx;font-size:28rpx;font-weight:700;box-shadow:0 8rpx 16rpx rgba(139,115,85,.3)}.call-active-section.data-v-5a549494{position:fixed;top:0;left:0;right:0;bottom:0;background:#000;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;padding:0;overflow:hidden;z-index:1}.video-fullscreen.data-v-5a549494{position:fixed;top:220rpx;left:40rpx;right:40rpx;bottom:calc(360rpx + constant(safe-area-inset-bottom));bottom:calc(360rpx + env(safe-area-inset-bottom));border-radius:32rpx;overflow:hidden;background:#000;box-shadow:0 20rpx 60rpx rgba(0,0,0,.5);z-index:1}.video-player.data-v-5a549494{width:100%;height:100%;background:#000;border-radius:32rpx;object-fit:cover;position:relative;z-index:1;pointer-events:none}.video-placeholder.data-v-5a549494{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;background:linear-gradient(135deg,#1a1a1a,#2d2d2d)}.placeholder-text.data-v-5a549494{font-size:28rpx;color:rgba(255,255,255,.6);margin-top:20rpx}.call-status-bar.data-v-5a549494{position:fixed;top:0;left:0;right:0;padding:80rpx 40rpx 40rpx;background:linear-gradient(180deg,rgba(0,0,0,.7) 0%,transparent 100%);z-index:1000;pointer-events:none}.call-status-bar .listening-chip.data-v-5a549494{pointer-events:auto}.status-info.data-v-5a549494{display:flex;flex-direction:column;align-items:center;gap:8rpx}.call-name.data-v-5a549494{font-size:32rpx;font-weight:600;color:#fff;text-shadow:0 2rpx 8rpx rgba(0,0,0,.5)}.call-time.data-v-5a549494{font-size:26rpx;color:rgba(255,255,255,.9);font-family:Courier New,monospace;text-shadow:0 2rpx 4rpx rgba(0,0,0,.5)}.listening-chip.data-v-5a549494{margin-top:12rpx;padding:18rpx 28rpx;background:linear-gradient(135deg,#ffb6c1,pink,#ffd4e5);border-radius:50rpx;border:2rpx solid rgba(255,255,255,.8);box-shadow:0 8rpx 24rpx rgba(255,182,193,.4),0 0 20rpx rgba(255,192,203,.3);display:inline-flex;align-items:center;gap:12rpx;transition:all .3s ease;animation:listeningGlow-5a549494 1.5s ease-in-out infinite,listeningPulse-5a549494 2s ease-in-out infinite;position:relative;z-index:1001;pointer-events:auto;opacity:1;visibility:visible}.listening-chip.inline-chip.data-v-5a549494{margin-top:0}.listening-icon.data-v-5a549494{font-size:32rpx;animation:iconBounce-5a549494 1s ease-in-out infinite;filter:drop-shadow(0 2rpx 4rpx rgba(0,0,0,.3))}.listening-text.data-v-5a549494{font-size:28rpx;color:#fff;font-weight:700;letter-spacing:1rpx;text-shadow:0 2rpx 6rpx rgba(0,0,0,.4),0 0 10rpx rgba(255,255,255,.3)}.chat-section.data-v-5a549494{flex:1;background:#fff;border-radius:24rpx;padding:30rpx;box-shadow:0 4rpx 12rpx rgba(0,0,0,.08);min-height:150rpx}.chat-messages.data-v-5a549494{height:100%}.message-item.data-v-5a549494{display:flex;margin-bottom:20rpx;animation:fadeIn-5a549494 .3s}.message-item.user.data-v-5a549494{justify-content:flex-end}.message-item.ai.data-v-5a549494{justify-content:flex-start}.message-bubble.data-v-5a549494{max-width:70%;padding:20rpx 24rpx;border-radius:16rpx}.message-item.user .message-bubble.data-v-5a549494{background:linear-gradient(135deg,#667eea,#764ba2);border-bottom-right-radius:4rpx}.message-item.ai .message-bubble.data-v-5a549494{background:#f0f0f0;border-bottom-left-radius:4rpx}.message-text.data-v-5a549494{font-size:28rpx;line-height:1.5;color:#fff}.message-item.ai .message-text.data-v-5a549494{color:#333}.empty-chat.data-v-5a549494{height:100%;display:flex;align-items:center;justify-content:center}.empty-chat-text.data-v-5a549494{font-size:26rpx;color:#999}.call-controls.data-v-5a549494{position:fixed;bottom:0;left:0;right:0;height:320rpx;padding:40rpx 60rpx calc(80rpx + constant(safe-area-inset-bottom));padding:40rpx 60rpx calc(80rpx + env(safe-area-inset-bottom));background:linear-gradient(0deg,rgba(0,0,0,.95) 0%,rgba(0,0,0,.6) 60%,transparent 100%);z-index:1001;pointer-events:none;display:flex;flex-direction:column;justify-content:flex-end}.recording-hint.data-v-5a549494{text-align:center;margin-bottom:30rpx}.hint-box.data-v-5a549494{display:inline-flex;align-items:center;gap:12rpx;padding:16rpx 32rpx;border-radius:50rpx;box-shadow:0 8rpx 24rpx rgba(0,0,0,.4);-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.hint-box.listening-pulse.data-v-5a549494{background:linear-gradient(135deg,rgba(7,193,96,.9),rgba(6,174,86,.9));animation:listeningPulse-5a549494 1.5s ease-in-out infinite}.hint-box.processing-pulse.data-v-5a549494{background:linear-gradient(135deg,rgba(255,193,7,.9),rgba(255,152,0,.9));animation:processingPulse 1.5s ease-in-out infinite}.hint-icon.data-v-5a549494{font-size:32rpx;animation:iconBounce-5a549494 1s ease-in-out infinite}.hint-text.data-v-5a549494{font-size:28rpx;color:#fff;font-weight:600;text-shadow:0 2rpx 4rpx rgba(0,0,0,.3)}.control-buttons.data-v-5a549494{display:flex;align-items:flex-end;justify-content:space-around;gap:40rpx;position:relative;z-index:1002;pointer-events:auto}.control-btn.data-v-5a549494{display:flex;flex-direction:column;align-items:center;gap:12rpx;cursor:pointer;user-select:none;-webkit-user-select:none;touch-action:manipulation;position:relative;z-index:1003;pointer-events:auto}.btn-circle.data-v-5a549494{width:100rpx;height:100rpx;border-radius:50%;background:rgba(255,255,255,.95);-webkit-backdrop-filter:blur(20rpx);backdrop-filter:blur(20rpx);display:flex;align-items:center;justify-content:center;transition:all .3s;box-shadow:0 8rpx 24rpx rgba(0,0,0,.5),0 0 0 4rpx rgba(255,255,255,.3);position:relative;z-index:1004}.btn-circle.large.data-v-5a549494{width:130rpx;height:130rpx;background:rgba(255,255,255,.95)}.btn-circle.recording.data-v-5a549494{background:rgba(235,51,73,.95);animation:recordingPulse-5a549494 1s ease-in-out infinite}.btn-circle.processing.data-v-5a549494{background:rgba(200,200,200,.95)}.speak-button.data-v-5a549494{position:relative;width:240rpx;height:160rpx;display:flex;align-items:center;justify-content:center;transition:all .3s cubic-bezier(.4,0,.2,1);z-index:1005}.speak-button-inner.data-v-5a549494{width:240rpx;height:160rpx;border-radius:80rpx;background:linear-gradient(135deg,#ff6b6b,#ffe66d);display:flex;align-items:center;justify-content:center;box-shadow:0 8rpx 32rpx rgba(255,107,107,.6),0 4rpx 16rpx rgba(255,230,109,.5),0 0 0 6rpx rgba(255,255,255,.3);transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;z-index:1006}.speak-button.recording .speak-button-inner.data-v-5a549494{background:linear-gradient(135deg,#4ecdc4,#44a08d);box-shadow:0 12rpx 48rpx rgba(78,205,196,.6),0 6rpx 24rpx rgba(68,160,141,.5),0 0 0 6rpx rgba(255,255,255,.3);transform:scale(1.05);width:260rpx;height:180rpx}.speak-button.processing .speak-button-inner.data-v-5a549494{background:linear-gradient(135deg,#a8a8a8,#7a7a7a);box-shadow:0 8rpx 32rpx rgba(168,168,168,.3)}.speak-ring.data-v-5a549494{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:240rpx;height:160rpx;border-radius:80rpx;border:4rpx solid rgba(78,205,196,.6);animation:speakRingPulse-5a549494 1.5s ease-out infinite;z-index:1}.speak-ring-outer.data-v-5a549494{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:240rpx;height:160rpx;border-radius:80rpx;border:3rpx solid rgba(68,160,141,.5);animation:speakRingPulse-5a549494 1.5s ease-out infinite .3s;z-index:0}@keyframes speakRingPulse-5a549494{0%{width:240rpx;height:160rpx;opacity:1}to{width:320rpx;height:220rpx;opacity:0}}.btn-circle.end-call.data-v-5a549494{background:rgba(235,51,73,.98);box-shadow:0 8rpx 24rpx rgba(235,51,73,.6),0 0 0 4rpx rgba(255,255,255,.3)}.btn-circle.data-v-5a549494:active{transform:scale(.95)}.btn-icon.data-v-5a549494{font-size:40rpx}.btn-icon.large.data-v-5a549494{font-size:52rpx}.btn-icon.pulse.data-v-5a549494{animation:pulse-5a549494 1s infinite}.btn-label.data-v-5a549494{font-size:22rpx;color:rgba(255,255,255,.98);font-weight:600;text-shadow:0 2rpx 8rpx rgba(0,0,0,.6),0 0 20rpx rgba(0,0,0,.4)}.btn-label-new.data-v-5a549494{font-size:24rpx;color:rgba(255,255,255,.95);font-weight:600;text-shadow:0 2rpx 8rpx rgba(0,0,0,.4);transition:all .3s;margin-top:8rpx}.btn-label-new.active.data-v-5a549494{color:#4ecdc4;text-shadow:0 2rpx 8rpx rgba(78,205,196,.6);transform:scale(1.05)}.icon-delete.data-v-5a549494{width:40rpx;height:40rpx;position:relative}.icon-delete.data-v-5a549494:before,.icon-delete.data-v-5a549494:after{content:"";position:absolute;left:50%;top:50%;width:32rpx;height:4rpx;background:#333;border-radius:2rpx;box-shadow:0 2rpx 4rpx rgba(0,0,0,.2)}.icon-delete.data-v-5a549494:before{transform:translate(-50%,-50%) rotate(45deg)}.icon-delete.data-v-5a549494:after{transform:translate(-50%,-50%) rotate(-45deg)}.icon-mic.data-v-5a549494{width:40rpx;height:52rpx;border:4rpx solid #333;border-radius:20rpx;position:relative}.icon-mic.data-v-5a549494:after{content:"";position:absolute;bottom:-12rpx;left:50%;transform:translate(-50%);width:30rpx;height:12rpx;border:4rpx solid #333;border-top:none;border-radius:0 0 15rpx 15rpx}.icon-mic.data-v-5a549494:before{content:"";position:absolute;bottom:-20rpx;left:50%;transform:translate(-50%);width:3rpx;height:8rpx;background:#333}.icon-mic-new.data-v-5a549494{width:48rpx;height:64rpx;border:5rpx solid white;border-radius:24rpx;position:relative;animation:micFloat-5a549494 2s ease-in-out infinite}.icon-mic-new.data-v-5a549494:after{content:"";position:absolute;bottom:-16rpx;left:50%;transform:translate(-50%);width:36rpx;height:16rpx;border:5rpx solid white;border-top:none;border-radius:0 0 18rpx 18rpx}.icon-mic-new.data-v-5a549494:before{content:"";position:absolute;bottom:-26rpx;left:50%;transform:translate(-50%);width:4rpx;height:10rpx;background:#fff}@keyframes micFloat-5a549494{0%,to{transform:translateY(0)}50%{transform:translateY(-6rpx)}}.icon-recording.data-v-5a549494{width:48rpx;height:48rpx;background:#fff;border-radius:50%;position:relative}.icon-recording.data-v-5a549494:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:32rpx;height:32rpx;background:#eb3349;border-radius:50%}.icon-wave-container.data-v-5a549494{display:flex;align-items:center;justify-content:center;gap:6rpx;height:60rpx}.wave-bar.data-v-5a549494{width:6rpx;background:#fff;border-radius:3rpx;animation:waveAnimation-5a549494 1s ease-in-out infinite}@keyframes waveAnimation-5a549494{0%,to{height:20rpx}50%{height:50rpx}}.icon-loading.data-v-5a549494{width:48rpx;height:48rpx;border:4rpx solid rgba(255,255,255,.3);border-top-color:#666;border-radius:50%;animation:spin-5a549494 1s linear infinite}.icon-loading-new.data-v-5a549494{width:56rpx;height:56rpx;border:5rpx solid rgba(255,255,255,.2);border-top-color:#fff;border-right-color:#fff;border-radius:50%;animation:spin-5a549494 .8s linear infinite}.icon-hangup.data-v-5a549494{width:48rpx;height:20rpx;border:5rpx solid white;border-radius:12rpx;position:relative;transform:rotate(-135deg);filter:drop-shadow(0 2rpx 4rpx rgba(0,0,0,.3))}.icon-hangup.data-v-5a549494:before{content:"";position:absolute;right:-8rpx;top:-12rpx;width:16rpx;height:16rpx;border:5rpx solid white;border-left:none;border-bottom:none;border-radius:0 8rpx 0 0}@keyframes spin-5a549494{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes listeningGlow-5a549494{0%,to{box-shadow:0 8rpx 24rpx rgba(255,182,193,.4),0 0 20rpx rgba(255,192,203,.3);border-color:rgba(255,255,255,.8)}50%{box-shadow:0 12rpx 36rpx rgba(255,182,193,.6),0 0 40rpx rgba(255,192,203,.5),0 0 60rpx rgba(255,212,229,.4);border-color:#fff}}@keyframes listeningPulse-5a549494{0%,to{transform:scale(1)}50%{transform:scale(1.05)}}@keyframes iconBounce-5a549494{0%,to{transform:translateY(0)}50%{transform:translateY(-4rpx)}}.settings-dialog-mask.data-v-5a549494{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;z-index:9999;padding:40rpx}.settings-dialog.data-v-5a549494{width:92vw;max-width:640rpx;max-height:80vh;background:#fff;border-radius:32rpx;overflow:hidden;box-shadow:0 20rpx 60rpx rgba(0,0,0,.3);display:flex;flex-direction:column;box-sizing:border-box}.dialog-header.data-v-5a549494{padding:40rpx 40rpx 30rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b);display:flex;justify-content:space-between;align-items:center;border-bottom:1rpx solid rgba(255,255,255,.1)}.dialog-title.data-v-5a549494{font-size:36rpx;font-weight:700;color:#fff}.dialog-close.data-v-5a549494{font-size:40rpx;color:#fff;opacity:.9;padding:0 10rpx;font-weight:300}.dialog-content.data-v-5a549494{flex:1;overflow-y:auto;padding:32rpx;box-sizing:border-box}.dialog-section.data-v-5a549494{margin-bottom:30rpx}.section-label.data-v-5a549494{font-size:30rpx;font-weight:700;color:#333;margin-bottom:12rpx}.section-hint.data-v-5a549494{font-size:24rpx;color:#999;margin-bottom:24rpx;display:block;line-height:1.6}.memory-item.data-v-5a549494{margin-bottom:24rpx;width:100%}.memory-label.data-v-5a549494{font-size:26rpx;color:#666;margin-bottom:12rpx;display:block;font-weight:500}.memory-input.data-v-5a549494{width:100%;padding:28rpx 24rpx;min-height:88rpx;background:#fdf8f2;border-radius:16rpx;font-size:28rpx;border:2rpx solid #e8dcc8;transition:all .3s;box-sizing:border-box;max-width:100%}.memory-input.data-v-5a549494:focus{border-color:#8b7355;background:#fff}.memory-textarea.data-v-5a549494{width:100%;min-height:140rpx;max-height:none;padding:24rpx;background:#fdf8f2;border-radius:16rpx;font-size:28rpx;border:2rpx solid #e8dcc8;line-height:1.6;transition:all .3s;box-sizing:border-box;max-width:100%}.memory-textarea.data-v-5a549494:focus{border-color:#8b7355;background:#fff}.dialog-footer.data-v-5a549494{padding:30rpx 40rpx;padding-bottom:calc(30rpx + env(safe-area-inset-bottom));display:flex;gap:20rpx;border-top:1rpx solid #f0f0f0;background:#fafafa}.dialog-btn.data-v-5a549494{flex:1;height:88rpx;border:none;border-radius:44rpx;font-size:30rpx;font-weight:600;display:flex;align-items:center;justify-content:center;transition:all .3s}.dialog-btn.cancel.data-v-5a549494{background:#f5f5f5;color:#666}.dialog-btn.cancel.data-v-5a549494:active{background:#e0e0e0}.dialog-btn.confirm.data-v-5a549494{background:linear-gradient(135deg,#8b7355,#6d8b8b);color:#fff;box-shadow:0 8rpx 20rpx rgba(139,115,85,.3)}.dialog-btn.confirm.data-v-5a549494:active{transform:translateY(-2rpx);box-shadow:0 12rpx 28rpx rgba(139,115,85,.4)}@keyframes fadeIn-5a549494{0%{opacity:0;transform:translateY(20rpx)}to{opacity:1;transform:translateY(0)}}@keyframes pulse-5a549494{0%,to{transform:scale(1)}50%{transform:scale(1.1)}}@keyframes statusBlink-5a549494{0%,to{opacity:1}50%{opacity:.6}}@keyframes recordingPulse-5a549494{0%,to{transform:scale(1);box-shadow:0 8rpx 16rpx rgba(235,51,73,.3)}50%{transform:scale(1.02);box-shadow:0 12rpx 24rpx rgba(235,51,73,.5),0 0 0 8rpx rgba(235,51,73,.2)}}.connecting-overlay.data-v-5a549494{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;display:flex;align-items:center;justify-content:center;animation:fadeIn-5a549494 .3s ease}.connecting-bg.data-v-5a549494{position:absolute;top:0;left:0;right:0;bottom:0;overflow:hidden}.bg-avatar.data-v-5a549494{width:100%;height:100%;filter:blur(40rpx) brightness(.4);transform:scale(1.2)}.connecting-content.data-v-5a549494{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;gap:40rpx;padding:60rpx}.avatar-container.data-v-5a549494{width:240rpx;height:240rpx;border-radius:50%;overflow:hidden;background:rgba(255,255,255,.1);border:6rpx solid rgba(255,255,255,.3);box-shadow:0 20rpx 60rpx rgba(0,0,0,.5);animation:avatarPulse-5a549494 2s ease-in-out infinite}.avatar-img.data-v-5a549494{width:100%;height:100%}.avatar-placeholder.data-v-5a549494{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:80rpx;background:linear-gradient(135deg,#8b7355,#6d8b8b)}.connecting-name.data-v-5a549494{font-size:40rpx;font-weight:600;color:#fff;text-shadow:0 4rpx 12rpx rgba(0,0,0,.5)}.connecting-status.data-v-5a549494{display:flex;flex-direction:column;align-items:center;gap:20rpx}.status-dots.data-v-5a549494{display:flex;gap:12rpx;align-items:center}.dot.data-v-5a549494{width:12rpx;height:12rpx;border-radius:50%;background:#fff;animation:dotBounce-5a549494 1.4s ease-in-out infinite}.dot-1.data-v-5a549494{animation-delay:0s}.dot-2.data-v-5a549494{animation-delay:.2s}.dot-3.data-v-5a549494{animation-delay:.4s}.status-text.data-v-5a549494{font-size:32rpx;color:rgba(255,255,255,.9);text-shadow:0 2rpx 8rpx rgba(0,0,0,.5)}.video-hidden.data-v-5a549494{opacity:0;pointer-events:none}@keyframes avatarPulse-5a549494{0%,to{transform:scale(1);box-shadow:0 20rpx 60rpx rgba(0,0,0,.5)}50%{transform:scale(1.05);box-shadow:0 20rpx 60rpx rgba(0,0,0,.5),0 0 0 20rpx rgba(255,255,255,.1)}}.ai-tag.data-v-5a549494{position:absolute;top:100rpx;right:24rpx;z-index:100;background:rgba(0,0,0,.6);padding:8rpx 20rpx;border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.ai-tag-text.data-v-5a549494{font-size:22rpx;color:#fff;font-weight:500}@keyframes dotBounce-5a549494{0%,80%,to{transform:translateY(0);opacity:1}40%{transform:translateY(-16rpx);opacity:.7}}.video-fullscreen.data-v-5a549494{box-shadow:0 8rpx 24rpx rgba(0,0,0,.35)}.call-controls.data-v-5a549494{-webkit-backdrop-filter:none;backdrop-filter:none}.hint-box.data-v-5a549494{-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:0 4rpx 12rpx rgba(0,0,0,.35)}.btn-circle.data-v-5a549494{-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:0 4rpx 12rpx rgba(0,0,0,.4)}.speak-button-inner.data-v-5a549494{box-shadow:0 6rpx 20rpx rgba(0,0,0,.35)}.listening-chip.data-v-5a549494{box-shadow:0 4rpx 12rpx rgba(0,0,0,.35)}.listening-icon.data-v-5a549494{filter:none}.bg-avatar.data-v-5a549494{filter:blur(16rpx) brightness(.4)}
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call/video-call.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call/video-call.js
index 6bbeecf..6a1a360 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call/video-call.js
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call/video-call.js
@@ -1 +1 @@
-"use strict";const e=require("../../common/vendor.js"),i=require("../../config/api.js"),o={data:()=>({API_BASE:i.API_BASE,idleVideoUrl:"",talkingVideoUrl:"",currentVideoUrl:"",isVideoLoading:!0,videoContext:null,hasPlayedInitial:!1,callerName:"对方",voiceId:"",selectedDialect:"",selectedLanguageHint:"",selectedLanguageHintLabel:"",languageHintOptions:["中文(zh)","英文(en)","法语(fr)","德语(de)","日语(ja)","韩语(ko)","俄语(ru)"],dialectOptions:["广东话","东北话","甘肃话","贵州话","河南话","湖北话","江西话","闽南话","宁夏话","山西话","陕西话","山东话","上海话","四川话","天津话","云南话"],callDuration:"00:00",callStartTime:null,durationTimer:null,isIdle:!0,isSpeaking:!1,isRecording:!1,isProcessing:!1,processingText:"处理中...",messages:[],systemPrompt:"你是一位温暖的对话者,用亲切的语气与对方交流。",recorderManager:null,audioFilePath:"",audioContext:null,vadEnabled:!0,vadVoiceThreshold:.004,vadSilenceMs:2500,vadMaxDurationMs:6e4,vadSpeaking:!1,vadSilenceStart:null,vadMaxTimer:null,recordingStartTime:null,vadLastSoundTime:null,vadLastFrameTime:null,vadWatchTimer:null,autoListen:!0,autoLoopTimer:null,scrollTop:0}),onLoad(e){console.log("[VideoCall] 页面参数:",e),this.idleVideoUrl=decodeURIComponent(e.idleVideo||""),this.talkingVideoUrl=decodeURIComponent(e.talkingVideo||this.idleVideoUrl),this.voiceId=e.voiceId||"",this.callerName=decodeURIComponent(e.callerName||"对方"),console.log("[VideoCall] 待机视频URL:",this.idleVideoUrl),console.log("[VideoCall] 说话视频URL:",this.talkingVideoUrl),console.log("[VideoCall] 音色ID:",this.voiceId),this.downloadAndConvertVideo(),this.startCallTimer(),this.initRecorder(),this.initAudioContext(),this.initVideoContext(),this.startAutoLoop()},onUnload(){this.durationTimer&&clearInterval(this.durationTimer),this.vadMaxTimer&&(clearTimeout(this.vadMaxTimer),this.vadMaxTimer=null),this.vadWatchTimer&&(clearInterval(this.vadWatchTimer),this.vadWatchTimer=null),this.autoLoopTimer&&(clearInterval(this.autoLoopTimer),this.autoLoopTimer=null),this.audioContext&&this.audioContext.destroy()},methods:{async downloadAndConvertVideo(){if(!this.idleVideoUrl)return void e.index.showToast({title:"视频URL无效",icon:"none"});console.log("[VideoCall] ========== 视频加载 =========="),console.log("[VideoCall] 原始URL:",this.idleVideoUrl);const o=new URL(i.API_BASE).hostname,t=this.idleVideoUrl.includes("/static/videos/")||this.idleVideoUrl.includes(o);return this.idleVideoUrl.includes("grsai.com")||this.idleVideoUrl.includes("file49")?(console.log("[VideoCall] 检测到外部视频链接,直接使用URL播放"),this.currentVideoUrl=this.idleVideoUrl,this.talkingVideoUrl=this.idleVideoUrl,void console.log("[VideoCall] ========== 视频准备完成 ==========")):t?(console.log("[VideoCall] 检测到本地服务器视频,直接使用URL播放"),this.currentVideoUrl=this.idleVideoUrl,this.talkingVideoUrl=this.idleVideoUrl,void console.log("[VideoCall] ========== 视频准备完成 ==========")):(console.log("[VideoCall] 本地服务器视频,开始下载..."),e.index.showLoading({title:"视频加载中...",mask:!0}),void e.index.downloadFile({url:this.idleVideoUrl,success:i=>{console.log("[VideoCall] 下载响应状态码:",i.statusCode),200===i.statusCode?(console.log("[VideoCall] ✅ 视频下载成功"),console.log("[VideoCall] 临时路径:",i.tempFilePath),console.log("[VideoCall] 非APP环境,使用临时路径"),this.currentVideoUrl=i.tempFilePath,this.idleVideoUrl=i.tempFilePath,this.talkingVideoUrl=i.tempFilePath,e.index.hideLoading()):(console.error("[VideoCall] ❌ 视频下载失败,状态码:",i.statusCode),this.handleDownloadError())},fail:e=>{console.error("[VideoCall] ❌ 视频下载失败:",e),console.error("[VideoCall] 错误详情:",JSON.stringify(e)),this.handleDownloadError()}}))},handleDownloadError(){e.index.hideLoading(),console.log("[VideoCall] 下载失败,直接使用原URL播放"),this.currentVideoUrl=this.idleVideoUrl,e.index.showToast({title:"将直接播放网络视频",icon:"none",duration:2e3})},initRecorder(){this.recorderManager=e.index.getRecorderManager(),this.recorderManager.onStart((()=>{console.log("[VideoCall] 开始录音")})),this.recorderManager.onStop((e=>{console.log("[VideoCall] 录音完成:",e.tempFilePath),this.resetVADState();if((e.duration||Date.now()-(this.recordingStartTime||Date.now()))<400)return console.warn("[VideoCall] 录音过短,忽略本次"),void(this.isProcessing=!1);this.audioFilePath=e.tempFilePath,this.processConversation()})),this.recorderManager.onFrameRecorded&&this.recorderManager.onFrameRecorded((e=>{this.vadEnabled&&!this.isProcessing&&this.handleVADFrame(e.frameBuffer)})),this.recorderManager.onError((i=>{console.error("[VideoCall] 录音失败:",i),console.error("[VideoCall] 错误详情:",JSON.stringify(i)),this.isRecording=!1,this.resetVADState();let o="录音失败";i.errMsg&&(o=i.errMsg.includes("permission")?"录音权限被拒绝,请在设置中允许录音权限":i.errMsg.includes("busy")?"录音设备忙,请稍后再试":`录音失败: ${i.errMsg}`),e.index.showModal({title:"录音失败",content:o+"\n\n请检查:\n1. 是否授予录音权限\n2. 麦克风是否被其他应用占用\n3. 设备是否支持录音",showCancel:!1,confirmText:"知道了"})}))},initVideoContext(){this.$nextTick((()=>{this.videoContext=e.index.createVideoContext("videoPlayer",this),console.log("[VideoCall] 视频控制器初始化完成")}))},initAudioContext(){this.audioContext=e.index.createInnerAudioContext(),this.audioContext.onPlay((()=>{console.log("[VideoCall] 开始播放AI回复")})),this.audioContext.onEnded((()=>{console.log("[VideoCall] AI回复播放完成"),this.isSpeaking=!1,this.isIdle=!0})),this.audioContext.onError((e=>{console.error("[VideoCall] 音频播放失败:",e),this.isSpeaking=!1,this.isIdle=!0}))},startCallTimer(){this.callStartTime=Date.now(),this.durationTimer=setInterval((()=>{const e=Math.floor((Date.now()-this.callStartTime)/1e3),i=Math.floor(e/60).toString().padStart(2,"0"),o=(e%60).toString().padStart(2,"0");this.callDuration=`${i}:${o}`}),1e3)},startTalking(){this.isProcessing||(this.resetVADState(),this.recordingStartTime=Date.now(),this.vadLastSoundTime=this.recordingStartTime,this.vadLastFrameTime=this.recordingStartTime,this.isRecording=!0,this.vadMaxTimer=setTimeout((()=>{this.stopTalkingFromVAD("max_duration")}),this.vadMaxDurationMs),this.vadWatchTimer=setInterval((()=>{if(!this.isRecording)return;const e=Date.now(),i=e-(this.recordingStartTime||e);e-(this.vadLastFrameTime||e)>12e3?this.stopTalkingFromVAD("no_frame"):i>1500&&this.vadSpeaking&&e-(this.vadLastSoundTime||e)>this.vadSilenceMs&&this.stopTalkingFromVAD("silence")}),300),this.recorderManager.start({format:"mp3",sampleRate:16e3,numberOfChannels:1,encodeBitRate:48e3,frameSize:32}),e.index.showToast({title:"正在聆听(自动识别说话)",icon:"none",duration:1e4}))},stopTalking(){this.stopTalkingFromVAD("manual")},stopTalkingFromVAD(e="vad"){this.isRecording=!1,this.recorderManager.stop(),this.isProcessing=!0,this.processingText="识别中...",this.resetVADState(),console.log("[VideoCall] 停止录音,原因:",e)},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)},onDialectChange(e){this.selectedDialect=this.dialectOptions[e.detail.value]||""},onLanguageHintChange(e){const i=this.languageHintOptions[e.detail.value]||"";this.selectedLanguageHintLabel=i;const o=i.match(/\(([^)]+)\)/);this.selectedLanguageHint=o&&o[1]?o[1]:""},handleVADFrame(e){if(!e||0===e.byteLength)return;this.vadLastFrameTime=Date.now();if(this.calculateRms(e)>this.vadVoiceThreshold)return this.vadSpeaking=!0,this.vadSilenceStart=null,void(this.vadLastSoundTime=Date.now());this.vadSpeaking&&(this.vadSilenceStart?Date.now()-this.vadSilenceStart>this.vadSilenceMs&&this.stopTalkingFromVAD("silence"):this.vadSilenceStart=Date.now())},calculateRms(e){const i=new DataView(e),o=i.byteLength/2;if(0===o)return 0;let t=0;for(let s=0;s{this.autoListen&&(this.isRecording||this.isProcessing||this.startTalking())}),2e3))},async processConversation(){try{this.processingText="正在识别...",console.log("[VideoCall] 开始对话请求"),console.log("[VideoCall] 音频文件:",this.audioFilePath),console.log("[VideoCall] 音色ID:",this.voiceId);const i=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.uploadFile({url:`${this.API_BASE}/api/conversation/talk`,filePath:this.audioFilePath,name:"audio",header:{"X-User-Id":i,Authorization:o?`Bearer ${o}`:""},formData:(()=>{const e=this.voiceId||"",i=(()=>{const i=(e||"").trim();if(!i)return"CLONE";return["Cherry","Kai","Mochi","Bunny","Jada","Dylan","Li","Marcus","Roy","Peter","Sunny","Eric","Rocky","Kiki"].includes(i)||i.startsWith("BV")||i.endsWith("_streaming")||i.endsWith("_offline")||i.endsWith("_bigtts")?"OFFICIAL":"CLONE"})(),o={voiceId:e,voiceType:i};return this.voiceId&&this.voiceId.startsWith("cosyvoice-v3-plus-")&&this.selectedDialect&&(o.dialect=this.selectedDialect),this.voiceId&&this.voiceId.startsWith("cosyvoice-v3-plus-")&&this.selectedLanguageHint&&(o.languageHints=this.selectedLanguageHint),o})(),success:i=>{console.log("[VideoCall] 对话响应状态码:",i.statusCode),console.log("[VideoCall] 对话响应数据:",i.data);try{const o="string"==typeof i.data?JSON.parse(i.data):i.data;o.success?(console.log("[VideoCall] 对话成功"),console.log("[VideoCall] 识别文本:",o.recognizedText),console.log("[VideoCall] AI回复:",o.aiResponse),console.log("[VideoCall] 音频文件:",o.audioFile),this.addMessage("user",o.recognizedText),this.addMessage("ai",o.aiResponse),this.playAIResponse(o.audioFile)):(console.error("[VideoCall] 对话失败:",o.message),e.index.showToast({title:o.message||"对话失败",icon:"none"}),this.isProcessing=!1)}catch(o){console.error("[VideoCall] JSON解析失败:",o),console.error("[VideoCall] 原始响应:",i.data),e.index.showToast({title:"服务器响应格式错误",icon:"none"}),this.isProcessing=!1}},fail:i=>{console.error("[VideoCall] 对话失败:",i),e.index.showToast({title:"对话失败",icon:"none"}),this.isProcessing=!1}})}catch(i){console.error("[VideoCall] 对话失败:",i),e.index.showToast({title:"对话失败: "+i.message,icon:"none"}),this.isProcessing=!1}},playAIResponse(e){this.processingText="正在回复...",this.isIdle=!1,this.isSpeaking=!0,this.audioContext.src=`${this.API_BASE}/api/conversation/audio/${e}`,this.audioContext.play(),this.isProcessing=!1},addMessage(e,i){const o=new Date,t=`${o.getHours()}:${o.getMinutes().toString().padStart(2,"0")}`;this.messages.push({role:e,content:i,time:t}),this.$nextTick((()=>{this.scrollTop=999999}))},onVideoPlay(){console.log("[VideoCall] 视频开始播放"),this.isVideoLoading=!1},onVideoPause(){console.log("[VideoCall] 视频暂停")},onVideoEnded(){console.log("[VideoCall] 视频播放结束"),!this.isIdle&&this.isSpeaking&&console.log("[VideoCall] 视频循环播放")},onVideoLoaded(e){console.log("[VideoCall] 视频元数据加载成功:",e),this.isVideoLoading=!1},onVideoCanPlay(){console.log("[VideoCall] 视频可以播放"),this.isVideoLoading=!1},onVideoWaiting(){console.log("[VideoCall] 视频缓冲中..."),this.isVideoLoading=!0},onVideoTimeUpdate(e){!this.hasPlayedInitial&&e.detail&&e.detail.currentTime>=1&&(console.log("[VideoCall] 视频已播放1秒,暂停等待AI回复"),this.hasPlayedInitial=!0,this.videoContext&&this.videoContext.pause())},onVideoError(i){console.error("[VideoCall] 视频加载失败:",i),console.error("[VideoCall] 视频URL:",this.currentVideoUrl),console.error("[VideoCall] 错误详情:",JSON.stringify(i)),this.isVideoLoading=!1;const o=i.detail&&i.detail.errMsg?i.detail.errMsg:"未知错误",t=i.detail&&i.detail.errCode?i.detail.errCode:"N/A";e.index.showModal({title:"视频加载失败",content:`错误代码: ${t}\n错误信息: ${o}\n\n视频URL:\n${this.currentVideoUrl}\n\n请检查:\n1. URL是否有效\n2. 网络连接\n3. 视频格式是否支持\n4. HTTP权限配置`,showCancel:!1,confirmText:"知道了"})},hangUp(){e.index.showModal({title:"结束通话",content:"确定要结束通话吗?",success:i=>{i.confirm&&(this.isRecording&&this.recorderManager.stop(),this.audioContext&&this.audioContext.stop(),e.index.navigateBack())}})}}};const t=e._export_sfc(o,[["render",function(i,o,t,s,a,n){return e.e({a:e.t(a.callerName),b:e.t(a.callDuration),c:a.currentVideoUrl},a.currentVideoUrl?{d:a.currentVideoUrl,e:e.o(((...e)=>n.onVideoPlay&&n.onVideoPlay(...e))),f:e.o(((...e)=>n.onVideoPause&&n.onVideoPause(...e))),g:e.o(((...e)=>n.onVideoEnded&&n.onVideoEnded(...e))),h:e.o(((...e)=>n.onVideoError&&n.onVideoError(...e))),i:e.o(((...e)=>n.onVideoLoaded&&n.onVideoLoaded(...e))),j:e.o(((...e)=>n.onVideoWaiting&&n.onVideoWaiting(...e))),k:e.o(((...e)=>n.onVideoCanPlay&&n.onVideoCanPlay(...e))),l:e.o(((...e)=>n.onVideoTimeUpdate&&n.onVideoTimeUpdate(...e)))}:{},{m:a.isVideoLoading},(a.isVideoLoading,{}),{n:a.isSpeaking},(a.isSpeaking,{}),{o:e.f(a.messages,((i,o,t)=>({a:e.t("user"===i.role?"👤":"🤖"),b:e.t(i.content),c:e.t(i.time),d:o,e:e.n("user"===i.role?"user-message":"ai-message")}))),p:0===a.messages.length},(a.messages.length,{}),{q:a.scrollTop,r:a.voiceId&&a.voiceId.startsWith("cosyvoice-v3-plus-")},a.voiceId&&a.voiceId.startsWith("cosyvoice-v3-plus-")?{s:e.t(a.selectedDialect||"请选择方言(可选)"),t:a.dialectOptions,v:e.o(((...e)=>n.onDialectChange&&n.onDialectChange(...e)))}:{},{w:a.voiceId&&a.voiceId.startsWith("cosyvoice-v3-plus-")},a.voiceId&&a.voiceId.startsWith("cosyvoice-v3-plus-")?{x:e.t(a.selectedLanguageHintLabel||"请选择语言(可选)"),y:a.languageHintOptions,z:e.o(((...e)=>n.onLanguageHintChange&&n.onLanguageHintChange(...e)))}:{},{A:!a.isRecording&&!a.isProcessing},a.isRecording||a.isProcessing?{}:{B:e.o(((...e)=>n.startTalking&&n.startTalking(...e)))},{C:a.isRecording},a.isRecording?{D:e.o(((...e)=>n.stopTalking&&n.stopTalking(...e)))}:{},{E:a.isProcessing},a.isProcessing?{F:e.t(a.processingText)}:{},{G:e.o(((...e)=>n.hangUp&&n.hangUp(...e)))})}],["__scopeId","data-v-ced34889"]]);wx.createPage(t);
+"use strict";const e=require("../../common/vendor.js"),i=require("../../config/api.js"),o={data:()=>({API_BASE:i.API_BASE,idleVideoUrl:"",talkingVideoUrl:"",currentVideoUrl:"",isVideoLoading:!0,videoContext:null,hasPlayedInitial:!1,callerName:"对方",voiceId:"",selectedDialect:"",selectedLanguageHint:"",selectedLanguageHintLabel:"",languageHintOptions:["中文(zh)","英文(en)","法语(fr)","德语(de)","日语(ja)","韩语(ko)","俄语(ru)"],dialectOptions:["广东话","东北话","甘肃话","贵州话","河南话","湖北话","江西话","闽南话","宁夏话","山西话","陕西话","山东话","上海话","四川话","天津话","云南话"],callDuration:"00:00",callStartTime:null,durationTimer:null,isIdle:!0,isSpeaking:!1,isRecording:!1,isProcessing:!1,processingText:"处理中...",messages:[],systemPrompt:"你是一位温暖的对话者,用亲切的语气与对方交流。",recorderManager:null,audioFilePath:"",audioContext:null,vadEnabled:!0,vadVoiceThreshold:.004,vadSilenceMs:2500,vadMaxDurationMs:6e4,vadSpeaking:!1,vadSilenceStart:null,vadMaxTimer:null,recordingStartTime:null,vadLastSoundTime:null,vadLastFrameTime:null,vadWatchTimer:null,autoListen:!0,autoLoopTimer:null,scrollTop:0}),onLoad(e){console.log("[VideoCall] 页面参数:",e),this.idleVideoUrl=decodeURIComponent(e.idleVideo||""),this.talkingVideoUrl=decodeURIComponent(e.talkingVideo||this.idleVideoUrl),this.voiceId=e.voiceId||"",this.callerName=decodeURIComponent(e.callerName||"对方"),console.log("[VideoCall] 待机视频URL:",this.idleVideoUrl),console.log("[VideoCall] 说话视频URL:",this.talkingVideoUrl),console.log("[VideoCall] 音色ID:",this.voiceId),this.downloadAndConvertVideo(),this.startCallTimer(),this.initRecorder(),this.initAudioContext(),this.initVideoContext(),this.startAutoLoop()},onUnload(){this.durationTimer&&clearInterval(this.durationTimer),this.vadMaxTimer&&(clearTimeout(this.vadMaxTimer),this.vadMaxTimer=null),this.vadWatchTimer&&(clearInterval(this.vadWatchTimer),this.vadWatchTimer=null),this.autoLoopTimer&&(clearInterval(this.autoLoopTimer),this.autoLoopTimer=null),this.audioContext&&this.audioContext.destroy()},methods:{async downloadAndConvertVideo(){if(!this.idleVideoUrl)return void e.index.showToast({title:"视频URL无效",icon:"none"});console.log("[VideoCall] ========== 视频加载 =========="),console.log("[VideoCall] 原始URL:",this.idleVideoUrl);const o=new URL(i.API_BASE).hostname,t=this.idleVideoUrl.includes("/static/videos/")||this.idleVideoUrl.includes(o);return this.idleVideoUrl.includes("grsai.com")||this.idleVideoUrl.includes("file49")?(console.log("[VideoCall] 检测到外部视频链接,直接使用URL播放"),this.currentVideoUrl=this.idleVideoUrl,this.talkingVideoUrl=this.idleVideoUrl,void console.log("[VideoCall] ========== 视频准备完成 ==========")):t?(console.log("[VideoCall] 检测到本地服务器视频,直接使用URL播放"),this.currentVideoUrl=this.idleVideoUrl,this.talkingVideoUrl=this.idleVideoUrl,void console.log("[VideoCall] ========== 视频准备完成 ==========")):(console.log("[VideoCall] 本地服务器视频,开始下载..."),e.index.showLoading({title:"视频加载中...",mask:!0}),void e.index.downloadFile({url:this.idleVideoUrl,success:i=>{console.log("[VideoCall] 下载响应状态码:",i.statusCode),200===i.statusCode?(console.log("[VideoCall] ✅ 视频下载成功"),console.log("[VideoCall] 临时路径:",i.tempFilePath),console.log("[VideoCall] 非APP环境,使用临时路径"),this.currentVideoUrl=i.tempFilePath,this.idleVideoUrl=i.tempFilePath,this.talkingVideoUrl=i.tempFilePath,e.index.hideLoading()):(console.error("[VideoCall] ❌ 视频下载失败,状态码:",i.statusCode),this.handleDownloadError())},fail:e=>{console.error("[VideoCall] ❌ 视频下载失败:",e),console.error("[VideoCall] 错误详情:",JSON.stringify(e)),this.handleDownloadError()}}))},handleDownloadError(){e.index.hideLoading(),console.log("[VideoCall] 下载失败,直接使用原URL播放"),this.currentVideoUrl=this.idleVideoUrl,e.index.showToast({title:"将直接播放网络视频",icon:"none",duration:2e3})},initRecorder(){this.recorderManager=e.index.getRecorderManager(),this.recorderManager.onStart((()=>{console.log("[VideoCall] 开始录音")})),this.recorderManager.onStop((e=>{console.log("[VideoCall] 录音完成:",e.tempFilePath),this.resetVADState();if((e.duration||Date.now()-(this.recordingStartTime||Date.now()))<400)return console.warn("[VideoCall] 录音过短,忽略本次"),void(this.isProcessing=!1);this.audioFilePath=e.tempFilePath,this.processConversation()})),this.recorderManager.onFrameRecorded&&this.recorderManager.onFrameRecorded((e=>{this.vadEnabled&&!this.isProcessing&&this.handleVADFrame(e.frameBuffer)})),this.recorderManager.onError((i=>{console.error("[VideoCall] 录音失败:",i),console.error("[VideoCall] 错误详情:",JSON.stringify(i)),this.isRecording=!1,this.resetVADState();let o="录音失败";i.errMsg&&(o=i.errMsg.includes("permission")?"录音权限被拒绝,请在设置中允许录音权限":i.errMsg.includes("busy")?"录音设备忙,请稍后再试":`录音失败: ${i.errMsg}`),e.index.showModal({title:"录音失败",content:o+"\n\n请检查:\n1. 是否授予录音权限\n2. 麦克风是否被其他应用占用\n3. 设备是否支持录音",showCancel:!1,confirmText:"知道了"})}))},initVideoContext(){this.$nextTick((()=>{this.videoContext=e.index.createVideoContext("videoPlayer",this),console.log("[VideoCall] 视频控制器初始化完成")}))},initAudioContext(){this.audioContext=e.index.createInnerAudioContext(),this.audioContext.onPlay((()=>{console.log("[VideoCall] 开始播放AI回复")})),this.audioContext.onEnded((()=>{console.log("[VideoCall] AI回复播放完成"),this.isSpeaking=!1,this.isIdle=!0})),this.audioContext.onError((e=>{console.error("[VideoCall] 音频播放失败:",e),this.isSpeaking=!1,this.isIdle=!0}))},startCallTimer(){this.callStartTime=Date.now(),this.durationTimer=setInterval((()=>{const e=Math.floor((Date.now()-this.callStartTime)/1e3),i=Math.floor(e/60).toString().padStart(2,"0"),o=(e%60).toString().padStart(2,"0");this.callDuration=`${i}:${o}`}),1e3)},startTalking(){this.isProcessing||(this.resetVADState(),this.recordingStartTime=Date.now(),this.vadLastSoundTime=this.recordingStartTime,this.vadLastFrameTime=this.recordingStartTime,this.isRecording=!0,this.vadMaxTimer=setTimeout((()=>{this.stopTalkingFromVAD("max_duration")}),this.vadMaxDurationMs),this.vadWatchTimer=setInterval((()=>{if(!this.isRecording)return;const e=Date.now(),i=e-(this.recordingStartTime||e);e-(this.vadLastFrameTime||e)>12e3?this.stopTalkingFromVAD("no_frame"):i>1500&&this.vadSpeaking&&e-(this.vadLastSoundTime||e)>this.vadSilenceMs&&this.stopTalkingFromVAD("silence")}),300),this.recorderManager.start({format:"mp3",sampleRate:16e3,numberOfChannels:1,encodeBitRate:48e3,frameSize:32}),e.index.showToast({title:"正在聆听(自动识别说话)",icon:"none",duration:1e4}))},stopTalking(){this.stopTalkingFromVAD("manual")},stopTalkingFromVAD(e="vad"){this.isRecording=!1,this.recorderManager.stop(),this.isProcessing=!0,this.processingText="识别中...",this.resetVADState(),console.log("[VideoCall] 停止录音,原因:",e)},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)},onDialectChange(e){this.selectedDialect=this.dialectOptions[e.detail.value]||""},onLanguageHintChange(e){const i=this.languageHintOptions[e.detail.value]||"";this.selectedLanguageHintLabel=i;const o=i.match(/\(([^)]+)\)/);this.selectedLanguageHint=o&&o[1]?o[1]:""},handleVADFrame(e){if(!e||0===e.byteLength)return;this.vadLastFrameTime=Date.now();if(this.calculateRms(e)>this.vadVoiceThreshold)return this.vadSpeaking=!0,this.vadSilenceStart=null,void(this.vadLastSoundTime=Date.now());this.vadSpeaking&&(this.vadSilenceStart?Date.now()-this.vadSilenceStart>this.vadSilenceMs&&this.stopTalkingFromVAD("silence"):this.vadSilenceStart=Date.now())},calculateRms(e){const i=new DataView(e),o=i.byteLength/2;if(0===o)return 0;let t=0;for(let s=0;s{this.autoListen&&(this.isRecording||this.isProcessing||this.startTalking())}),2e3))},async processConversation(){try{this.processingText="正在识别...",console.log("[VideoCall] 开始对话请求"),console.log("[VideoCall] 音频文件:",this.audioFilePath),console.log("[VideoCall] 音色ID:",this.voiceId);const i=e.index.getStorageSync("userId")||"",o=e.index.getStorageSync("token")||"";e.index.uploadFile({url:`${this.API_BASE}/api/conversation/talk`,filePath:this.audioFilePath,name:"audio",header:{"X-User-Id":i,Authorization:o?`Bearer ${o}`:""},formData:(()=>{const e=this.voiceId||"",i=(()=>{const i=(e||"").trim();if(!i)return"CLONE";return["Cherry","Kai","Mochi","Bunny","Jada","Dylan","Li","Marcus","Roy","Peter","Sunny","Eric","Rocky","Kiki"].includes(i)||i.startsWith("BV")||i.endsWith("_streaming")||i.endsWith("_offline")||i.endsWith("_bigtts")?"OFFICIAL":"CLONE"})(),o={voiceId:e,voiceType:i};return this.voiceId&&this.voiceId.startsWith("cosyvoice-v3-plus-")&&this.selectedDialect&&(o.dialect=this.selectedDialect),this.voiceId&&this.voiceId.startsWith("cosyvoice-v3-plus-")&&this.selectedLanguageHint&&(o.languageHints=this.selectedLanguageHint),o})(),success:i=>{console.log("[VideoCall] 对话响应状态码:",i.statusCode),console.log("[VideoCall] 对话响应数据:",i.data);try{const o="string"==typeof i.data?JSON.parse(i.data):i.data;o.success?(console.log("[VideoCall] 对话成功"),console.log("[VideoCall] 识别文本:",o.recognizedText),console.log("[VideoCall] AI回复:",o.aiResponse),console.log("[VideoCall] 音频文件:",o.audioFile),this.addMessage("user",o.recognizedText),this.addMessage("ai",o.aiResponse),this.playAIResponse(o.audioFile)):(console.error("[VideoCall] 对话失败:",o.message),e.index.showToast({title:o.message||"对话失败",icon:"none"}),this.isProcessing=!1)}catch(o){console.error("[VideoCall] JSON解析失败:",o),console.error("[VideoCall] 原始响应:",i.data),e.index.showToast({title:"服务器响应格式错误",icon:"none"}),this.isProcessing=!1}},fail:i=>{console.error("[VideoCall] 对话失败:",i),e.index.showToast({title:"对话失败",icon:"none"}),this.isProcessing=!1}})}catch(i){console.error("[VideoCall] 对话失败:",i),e.index.showToast({title:"对话失败: "+i.message,icon:"none"}),this.isProcessing=!1}},playAIResponse(e){this.processingText="正在回复...",this.isIdle=!1,this.isSpeaking=!0,this.audioContext.src=`${this.API_BASE}/api/conversation/audio/${e}`,this.audioContext.play(),this.isProcessing=!1},addMessage(e,i){const o=new Date,t=`${o.getHours()}:${o.getMinutes().toString().padStart(2,"0")}`;this.messages.push({role:e,content:i,time:t}),this.$nextTick((()=>{this.scrollTop=999999}))},onVideoPlay(){console.log("[VideoCall] 视频开始播放"),this.isVideoLoading=!1},onVideoPause(){console.log("[VideoCall] 视频暂停")},onVideoEnded(){console.log("[VideoCall] 视频播放结束"),!this.isIdle&&this.isSpeaking&&console.log("[VideoCall] 视频循环播放")},onVideoLoaded(e){console.log("[VideoCall] 视频元数据加载成功:",e),this.isVideoLoading=!1},onVideoCanPlay(){console.log("[VideoCall] 视频可以播放"),this.isVideoLoading=!1},onVideoWaiting(){console.log("[VideoCall] 视频缓冲中..."),this.isVideoLoading=!0},onVideoTimeUpdate(e){!this.hasPlayedInitial&&e.detail&&e.detail.currentTime>=1&&(console.log("[VideoCall] 视频已播放1秒,暂停等待AI回复"),this.hasPlayedInitial=!0,this.videoContext&&this.videoContext.pause())},onVideoError(i){console.error("[VideoCall] 视频加载失败:",i),console.error("[VideoCall] 视频URL:",this.currentVideoUrl),console.error("[VideoCall] 错误详情:",JSON.stringify(i)),this.isVideoLoading=!1;const o=i.detail&&i.detail.errMsg?i.detail.errMsg:"未知错误",t=i.detail&&i.detail.errCode?i.detail.errCode:"N/A";e.index.showModal({title:"视频加载失败",content:`错误代码: ${t}\n错误信息: ${o}\n\n视频URL:\n${this.currentVideoUrl}\n\n请检查:\n1. URL是否有效\n2. 网络连接\n3. 视频格式是否支持\n4. HTTP权限配置`,showCancel:!1,confirmText:"知道了"})},hangUp(){e.index.showModal({title:"结束通话",content:"确定要结束通话吗?",success:i=>{i.confirm&&(this.isRecording&&this.recorderManager.stop(),this.audioContext&&this.audioContext.stop(),e.index.navigateBack())}})}}};const t=e._export_sfc(o,[["render",function(i,o,t,s,a,n){return e.e({a:e.t(a.callerName),b:e.t(a.callDuration),c:a.currentVideoUrl},a.currentVideoUrl?{d:a.currentVideoUrl,e:e.o(((...e)=>n.onVideoPlay&&n.onVideoPlay(...e))),f:e.o(((...e)=>n.onVideoPause&&n.onVideoPause(...e))),g:e.o(((...e)=>n.onVideoEnded&&n.onVideoEnded(...e))),h:e.o(((...e)=>n.onVideoError&&n.onVideoError(...e))),i:e.o(((...e)=>n.onVideoLoaded&&n.onVideoLoaded(...e))),j:e.o(((...e)=>n.onVideoWaiting&&n.onVideoWaiting(...e))),k:e.o(((...e)=>n.onVideoCanPlay&&n.onVideoCanPlay(...e))),l:e.o(((...e)=>n.onVideoTimeUpdate&&n.onVideoTimeUpdate(...e)))}:{},{m:a.isVideoLoading},(a.isVideoLoading,{}),{n:a.isSpeaking},(a.isSpeaking,{}),{o:e.f(a.messages,((i,o,t)=>({a:e.t("user"===i.role?"👤":"🤖"),b:e.t(i.content),c:e.t(i.time),d:o,e:e.n("user"===i.role?"user-message":"ai-message")}))),p:0===a.messages.length},(a.messages.length,{}),{q:a.scrollTop,r:a.voiceId&&a.voiceId.startsWith("cosyvoice-v3-plus-")},a.voiceId&&a.voiceId.startsWith("cosyvoice-v3-plus-")?{s:e.t(a.selectedDialect||"请选择方言(可选)"),t:a.dialectOptions,v:e.o(((...e)=>n.onDialectChange&&n.onDialectChange(...e)))}:{},{w:a.voiceId&&a.voiceId.startsWith("cosyvoice-v3-plus-")},a.voiceId&&a.voiceId.startsWith("cosyvoice-v3-plus-")?{x:e.t(a.selectedLanguageHintLabel||"请选择语言(可选)"),y:a.languageHintOptions,z:e.o(((...e)=>n.onLanguageHintChange&&n.onLanguageHintChange(...e)))}:{},{A:!a.isRecording&&!a.isProcessing},a.isRecording||a.isProcessing?{}:{B:e.o(((...e)=>n.startTalking&&n.startTalking(...e)))},{C:a.isRecording},a.isRecording?{D:e.o(((...e)=>n.stopTalking&&n.stopTalking(...e)))}:{},{E:a.isProcessing},a.isProcessing?{F:e.t(a.processingText)}:{},{G:e.o(((...e)=>n.hangUp&&n.hangUp(...e)))})}],["__scopeId","data-v-0f1482ae"]]);wx.createPage(t);
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call/video-call.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call/video-call.wxml
index 10567cc..5c36c60 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call/video-call.wxml
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call/video-call.wxml
@@ -1 +1 @@
-📹 视频加载中...🔊 正在说话...{{msg.a}}{{msg.b}}{{msg.c}}👋 开始对话吧方言{{s}}语言提示(可选){{x}}💡 仅处理第一个值;不设置不生效
\ No newline at end of file
+AI生成📹 视频加载中...🔊 正在说话...{{msg.a}}{{msg.b}}{{msg.c}}👋 开始对话吧方言{{s}}语言提示(可选){{x}}💡 仅处理第一个值;不设置不生效
\ No newline at end of file
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call/video-call.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call/video-call.wxss
index 2a38766..c23721f 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call/video-call.wxss
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-call/video-call.wxss
@@ -1 +1 @@
-.video-call-container.data-v-ced34889{height:100vh;display:flex;flex-direction:column;background:#000}.header.data-v-ced34889{padding:40rpx 40rpx 40rpx 24rpx;padding-top:calc(40rpx + constant(safe-area-inset-top));padding-top:calc(40rpx + env(safe-area-inset-top));background:rgba(0,0,0,.8);display:flex;justify-content:space-between;align-items:center;position:relative;z-index:10}.caller-name.data-v-ced34889{font-size:32rpx;font-weight:700;color:#fff}.call-duration.data-v-ced34889{font-size:28rpx;color:#4caf50;font-family:monospace}.video-section.data-v-ced34889{flex:1;position:relative;background:#000;overflow:hidden;z-index:1}.video-player.data-v-ced34889{width:100%;height:100%;position:relative;z-index:1;pointer-events:none}.video-loading.data-v-ced34889{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:rgba(0,0,0,.7);padding:30rpx 50rpx;border-radius:20rpx;color:#fff;font-size:28rpx;z-index:20;pointer-events:auto}.speaking-indicator.data-v-ced34889{position:absolute;top:20rpx;right:20rpx;background:rgba(76,175,80,.9);padding:16rpx 32rpx;border-radius:40rpx;box-shadow:0 4rpx 12rpx rgba(0,0,0,.3);z-index:20;pointer-events:auto}.pulse.data-v-ced34889{color:#fff;font-size:24rpx;font-weight:700;animation:pulse-ced34889 1s infinite}@keyframes pulse-ced34889{0%,to{opacity:1}50%{opacity:.5}}.chat-history.data-v-ced34889{height:300rpx;background:rgba(255,255,255,.95);padding:20rpx 20rpx 20rpx 10rpx;position:relative;z-index:10}.empty-hint.data-v-ced34889{text-align:center;padding:60rpx 0;color:#999;font-size:28rpx}.message.data-v-ced34889{display:flex;margin-bottom:20rpx;animation:slideIn-ced34889 .3s ease}@keyframes slideIn-ced34889{0%{opacity:0;transform:translateY(20rpx)}to{opacity:1;transform:translateY(0)}}.user-message.data-v-ced34889{flex-direction:row-reverse}.message-avatar.data-v-ced34889{font-size:40rpx;margin:0 16rpx}.message-content.data-v-ced34889{max-width:70%;padding:20rpx;border-radius:16rpx;background:#e3f2fd}.user-message .message-content.data-v-ced34889{background:#c8e6c9}.message-text.data-v-ced34889{font-size:28rpx;color:#333;display:block;margin-bottom:8rpx;line-height:1.5}.message-time.data-v-ced34889{font-size:22rpx;color:#999}.controls.data-v-ced34889{padding:30rpx 30rpx 30rpx 14rpx;background:rgba(0,0,0,.8);position:relative;z-index:10}.control-row.data-v-ced34889{margin-bottom:20rpx}.control-row.data-v-ced34889:last-child{margin-bottom:0}.talk-btn.data-v-ced34889{width:100%;padding:32rpx;background:#4caf50;color:#fff;border:none;border-radius:50rpx;font-size:32rpx;font-weight:700;box-shadow:0 8rpx 16rpx rgba(76,175,80,.3)}.talk-btn.recording.data-v-ced34889{background:#f44336;animation:pulse-ced34889 1s infinite}.talk-btn.processing.data-v-ced34889{background:#999}.talk-btn[disabled].data-v-ced34889{opacity:.6}.hangup-btn.data-v-ced34889{width:100%;padding:32rpx;background:#f44336;color:#fff;border:none;border-radius:50rpx;font-size:32rpx;font-weight:700;box-shadow:0 8rpx 16rpx rgba(244,67,54,.3)}
+.video-call-container.data-v-0f1482ae{height:100vh;display:flex;flex-direction:column;background:#000}.header.data-v-0f1482ae{padding:40rpx 40rpx 40rpx 24rpx;padding-top:calc(40rpx + constant(safe-area-inset-top));padding-top:calc(40rpx + env(safe-area-inset-top));background:rgba(0,0,0,.8);display:flex;justify-content:space-between;align-items:center;position:relative;z-index:10}.caller-name.data-v-0f1482ae{font-size:32rpx;font-weight:700;color:#fff}.call-duration.data-v-0f1482ae{font-size:28rpx;color:#4caf50;font-family:monospace}.video-section.data-v-0f1482ae{flex:1;position:relative;background:#000;overflow:hidden;z-index:1}.ai-tag.data-v-0f1482ae{position:absolute;top:100rpx;right:24rpx;z-index:100;background:rgba(0,0,0,.6);padding:8rpx 20rpx;border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.ai-tag-text.data-v-0f1482ae{font-size:22rpx;color:#fff;font-weight:500}.video-player.data-v-0f1482ae{width:100%;height:100%;position:relative;z-index:1;pointer-events:none}.video-loading.data-v-0f1482ae{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:rgba(0,0,0,.7);padding:30rpx 50rpx;border-radius:20rpx;color:#fff;font-size:28rpx;z-index:20;pointer-events:auto}.speaking-indicator.data-v-0f1482ae{position:absolute;top:20rpx;right:20rpx;background:rgba(76,175,80,.9);padding:16rpx 32rpx;border-radius:40rpx;box-shadow:0 4rpx 12rpx rgba(0,0,0,.3);z-index:20;pointer-events:auto}.pulse.data-v-0f1482ae{color:#fff;font-size:24rpx;font-weight:700;animation:pulse-0f1482ae 1s infinite}@keyframes pulse-0f1482ae{0%,to{opacity:1}50%{opacity:.5}}.chat-history.data-v-0f1482ae{height:300rpx;background:rgba(255,255,255,.95);padding:20rpx 20rpx 20rpx 10rpx;position:relative;z-index:10}.empty-hint.data-v-0f1482ae{text-align:center;padding:60rpx 0;color:#999;font-size:28rpx}.message.data-v-0f1482ae{display:flex;margin-bottom:20rpx;animation:slideIn-0f1482ae .3s ease}@keyframes slideIn-0f1482ae{0%{opacity:0;transform:translateY(20rpx)}to{opacity:1;transform:translateY(0)}}.user-message.data-v-0f1482ae{flex-direction:row-reverse}.message-avatar.data-v-0f1482ae{font-size:40rpx;margin:0 16rpx}.message-content.data-v-0f1482ae{max-width:70%;padding:20rpx;border-radius:16rpx;background:#e3f2fd}.user-message .message-content.data-v-0f1482ae{background:#c8e6c9}.message-text.data-v-0f1482ae{font-size:28rpx;color:#333;display:block;margin-bottom:8rpx;line-height:1.5}.message-time.data-v-0f1482ae{font-size:22rpx;color:#999}.controls.data-v-0f1482ae{padding:30rpx 30rpx 30rpx 14rpx;background:rgba(0,0,0,.8);position:relative;z-index:10}.control-row.data-v-0f1482ae{margin-bottom:20rpx}.control-row.data-v-0f1482ae:last-child{margin-bottom:0}.talk-btn.data-v-0f1482ae{width:100%;padding:32rpx;background:#4caf50;color:#fff;border:none;border-radius:50rpx;font-size:32rpx;font-weight:700;box-shadow:0 8rpx 16rpx rgba(76,175,80,.3)}.talk-btn.recording.data-v-0f1482ae{background:#f44336;animation:pulse-0f1482ae 1s infinite}.talk-btn.processing.data-v-0f1482ae{background:#999}.talk-btn[disabled].data-v-0f1482ae{opacity:.6}.hangup-btn.data-v-0f1482ae{width:100%;padding:32rpx;background:#f44336;color:#fff;border:none;border-radius:50rpx;font-size:32rpx;font-weight:700;box-shadow:0 8rpx 16rpx rgba(244,67,54,.3)}
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.js
index 2124f51..c9bf10a 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.js
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.js
@@ -1 +1 @@
-"use strict";const e=require("../../common/vendor.js"),s=require("../../config/api.js"),t={data:()=>({imageUrl:"",imageFile:null,prompt:"",promptPlaceholder:"描述你想要的视频效果,支持中文,例如:一个人在微笑着说话,背景是温馨的客厅",duration:10,durations:[2,3,4,5,6,8,10,12],videoName:"",generating:!1,progress:0,progressText:"准备中...",generatedVideo:"",message:{text:"",type:"info"}}),methods:{chooseImage(){e.index.chooseImage({count:1,sizeType:["compressed"],sourceType:["album","camera"],success:s=>{const t=s.tempFilePaths[0],r=s.tempFiles&&s.tempFiles[0]?s.tempFiles[0]:null,o=e=>{this.imageUrl=e,this.imageFile=r,this.showMessage("照片已选择","success")};e.index.getFileInfo({filePath:t,success:s=>{const r=2097152;if(s.size&&s.size>r){this.showMessage("图片超过2MB,正在自动压缩...","info");const s=[60,40,20],i=(t,a)=>{t>=s.length?this.showMessage("图片压缩后仍超过2MB,请换一张更小的图片(建议拍照/截图后再上传)","error"):e.index.compressImage({src:a,quality:s[t],success:s=>{e.index.getFileInfo({filePath:s.tempFilePath,success:e=>{e.size&&e.size<=r?o(s.tempFilePath):i(t+1,s.tempFilePath)},fail:e=>{console.error("获取压缩后文件信息失败:",e),i(t+1,s.tempFilePath)}})},fail:e=>{console.error("压缩图片失败:",e),this.showMessage("图片过大且压缩失败,请换一张更小的图片","error")}})};i(0,t)}else o(t)},fail:e=>{console.error("获取文件信息失败:",e),o(t)}})},fail:e=>{console.error("选择图片失败:",e),this.showMessage("选择图片失败","error")}})},async generateVideo(){if(this.imageUrl){this.generating=!0,this.progress=0,this.progressText="正在上传照片...";try{this.progress=10,this.progressText="照片上传中...";const e=await s.uploadFile({url:"/api/photo-revival/volcengine-video",filePath:this.imageUrl,name:"photo",formData:{text:"",prompt:this.prompt||"",duration:this.duration,name:this.videoName||"火山引擎视频"}});this.progress=30,this.progressText="视频生成中,请稍候...";const t=setInterval((()=>{this.progress<90&&(this.progress+=2)}),2e3);setTimeout((()=>{if(clearInterval(t),this.progress=100,this.progressText="视频生成完成!","success"!==e.status)throw new Error(e.message||"视频生成失败");this.generatedVideo=s.API_BASE+e.videoUrl,this.showMessage("视频生成成功!","success"),this.generating=!1}),3e3)}catch(e){console.error("生成视频失败:",e),this.showMessage("生成失败: "+(e.message||"未知错误"),"error"),this.generating=!1,this.progress=0}}else this.showMessage("请先上传照片","error")},saveToAlbum(){this.generatedVideo?e.index.downloadFile({url:this.generatedVideo,success:s=>{200===s.statusCode&&e.index.saveVideoToPhotosAlbum({filePath:s.tempFilePath,success:()=>{this.showMessage("已保存到相册","success")},fail:e=>{console.error("保存失败:",e),this.showMessage("保存失败,请检查相册权限","error")}})},fail:e=>{console.error("下载失败:",e),this.showMessage("下载失败","error")}}):this.showMessage("没有可保存的视频","error")},reset(){this.imageUrl="",this.imageFile=null,this.prompt="",this.duration=10,this.videoName="",this.generatedVideo="",this.progress=0,this.progressText="准备中...",this.message.text=""},showMessage(e,s="info"){this.message={text:e,type:s},setTimeout((()=>{this.message.text=""}),3e3)}}};const r=e._export_sfc(t,[["render",function(s,t,r,o,i,a){return e.e({a:i.message.text},i.message.text?{b:e.t(i.message.text),c:e.n(i.message.type)}:{},{d:i.imageUrl},i.imageUrl?{e:i.imageUrl}:{},{f:e.o(((...e)=>a.chooseImage&&a.chooseImage(...e))),g:i.promptPlaceholder,h:i.prompt,i:e.o((e=>i.prompt=e.detail.value)),j:e.t(i.prompt.length),k:e.f(i.durations,((s,t,r)=>({a:e.t(s),b:s,c:e.n(i.duration===s?"active":""),d:e.o((e=>i.duration=s),s)}))),l:i.videoName,m:e.o((e=>i.videoName=e.detail.value)),n:i.generating},(i.generating,{}),{o:!i.imageUrl||i.generating,p:e.o(((...e)=>a.generateVideo&&a.generateVideo(...e))),q:i.generating},i.generating?{r:e.t(i.progressText),s:i.progress+"%"}:{},{t:i.generatedVideo},i.generatedVideo?{v:i.generatedVideo,w:e.o(((...e)=>a.saveToAlbum&&a.saveToAlbum(...e))),x:e.o(((...e)=>a.reset&&a.reset(...e)))}:{})}],["__scopeId","data-v-2ed74c00"]]);wx.createPage(r);
+"use strict";const e=require("../../common/vendor.js"),s=require("../../config/api.js"),t={data:()=>({imageUrl:"",imageFile:null,prompt:"",promptPlaceholder:"描述你想要的视频效果,支持中文,例如:一个人在微笑着说话,背景是温馨的客厅",duration:10,durations:[2,3,4,5,6,8,10,12],videoName:"",generating:!1,progress:0,progressText:"准备中...",generatedVideo:"",message:{text:"",type:"info"}}),methods:{chooseImage(){e.index.chooseImage({count:1,sizeType:["compressed"],sourceType:["album","camera"],success:s=>{const t=s.tempFilePaths[0],r=s.tempFiles&&s.tempFiles[0]?s.tempFiles[0]:null,o=e=>{this.imageUrl=e,this.imageFile=r,this.showMessage("照片已选择","success")};e.index.getFileInfo({filePath:t,success:s=>{const r=2097152;if(s.size&&s.size>r){this.showMessage("图片超过2MB,正在自动压缩...","info");const s=[60,40,20],i=(t,a)=>{t>=s.length?this.showMessage("图片压缩后仍超过2MB,请换一张更小的图片(建议拍照/截图后再上传)","error"):e.index.compressImage({src:a,quality:s[t],success:s=>{e.index.getFileInfo({filePath:s.tempFilePath,success:e=>{e.size&&e.size<=r?o(s.tempFilePath):i(t+1,s.tempFilePath)},fail:e=>{console.error("获取压缩后文件信息失败:",e),i(t+1,s.tempFilePath)}})},fail:e=>{console.error("压缩图片失败:",e),this.showMessage("图片过大且压缩失败,请换一张更小的图片","error")}})};i(0,t)}else o(t)},fail:e=>{console.error("获取文件信息失败:",e),o(t)}})},fail:e=>{console.error("选择图片失败:",e),this.showMessage("选择图片失败","error")}})},async generateVideo(){if(this.imageUrl){this.generating=!0,this.progress=0,this.progressText="正在上传照片...";try{this.progress=10,this.progressText="照片上传中...";const e=await s.uploadFile({url:"/api/photo-revival/volcengine-video",filePath:this.imageUrl,name:"photo",formData:{text:"",prompt:this.prompt||"",duration:this.duration,name:this.videoName||"火山引擎视频"}});this.progress=30,this.progressText="视频生成中,请稍候...";const t=setInterval((()=>{this.progress<90&&(this.progress+=2)}),2e3);setTimeout((()=>{if(clearInterval(t),this.progress=100,this.progressText="视频生成完成!","success"!==e.status)throw new Error(e.message||"视频生成失败");this.generatedVideo=s.API_BASE+e.videoUrl,this.showMessage("视频生成成功!","success"),this.generating=!1}),3e3)}catch(e){console.error("生成视频失败:",e),this.showMessage("生成失败: "+(e.message||"未知错误"),"error"),this.generating=!1,this.progress=0}}else this.showMessage("请先上传照片","error")},saveToAlbum(){this.generatedVideo?e.index.downloadFile({url:this.generatedVideo,success:s=>{200===s.statusCode&&e.index.saveVideoToPhotosAlbum({filePath:s.tempFilePath,success:()=>{this.showMessage("已保存到相册","success")},fail:e=>{console.error("保存失败:",e),this.showMessage("保存失败,请检查相册权限","error")}})},fail:e=>{console.error("下载失败:",e),this.showMessage("下载失败","error")}}):this.showMessage("没有可保存的视频","error")},reset(){this.imageUrl="",this.imageFile=null,this.prompt="",this.duration=10,this.videoName="",this.generatedVideo="",this.progress=0,this.progressText="准备中...",this.message.text=""},showMessage(e,s="info"){this.message={text:e,type:s},setTimeout((()=>{this.message.text=""}),3e3)}}};const r=e._export_sfc(t,[["render",function(s,t,r,o,i,a){return e.e({a:i.message.text},i.message.text?{b:e.t(i.message.text),c:e.n(i.message.type)}:{},{d:i.imageUrl},i.imageUrl?{e:i.imageUrl}:{},{f:e.o(((...e)=>a.chooseImage&&a.chooseImage(...e))),g:i.promptPlaceholder,h:i.prompt,i:e.o((e=>i.prompt=e.detail.value)),j:e.t(i.prompt.length),k:e.f(i.durations,((s,t,r)=>({a:e.t(s),b:s,c:e.n(i.duration===s?"active":""),d:e.o((e=>i.duration=s),s)}))),l:i.videoName,m:e.o((e=>i.videoName=e.detail.value)),n:i.generating},(i.generating,{}),{o:!i.imageUrl||i.generating,p:e.o(((...e)=>a.generateVideo&&a.generateVideo(...e))),q:i.generating},i.generating?{r:e.t(i.progressText),s:i.progress+"%"}:{},{t:i.generatedVideo},i.generatedVideo?{v:i.generatedVideo,w:e.o(((...e)=>a.saveToAlbum&&a.saveToAlbum(...e))),x:e.o(((...e)=>a.reset&&a.reset(...e)))}:{})}],["__scopeId","data-v-041223dc"]]);wx.createPage(r);
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.wxml
index baa7486..83cea0e 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.wxml
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.wxml
@@ -1 +1 @@
-{{b}}📸 上传照片📷点击上传照片支持 JPG、PNG 格式✍️ 提示词(可选){{j}}/500⏱️ 视频时长{{d.a}}秒 📝 视频名称(可选){{r}}✅ 生成成功💡 使用提示• 支持 JPG、PNG 格式的照片• 提示词支持中文,可描述动作、表情、场景等• 视频时长支持 2-12 秒• 生成时间约 1-3 分钟,请耐心等待• 使用火山引擎 doubao-seedance-1.0-pro 模型
\ No newline at end of file
+{{b}}📸 上传照片📷点击上传照片支持 JPG、PNG 格式✍️ 提示词(可选){{j}}/500⏱️ 视频时长{{d.a}}秒 📝 视频名称(可选)本服务为AI生成内容,结果仅供参考{{r}}✅ 生成成功AI生成💡 使用提示• 支持 JPG、PNG 格式的照片• 提示词支持中文,可描述动作、表情、场景等• 视频时长支持 2-12 秒• 生成时间约 1-3 分钟,请耐心等待• 使用火山引擎 doubao-seedance-1.0-pro 模型
\ No newline at end of file
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.wxss
index 7762d57..1eda904 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.wxss
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-gen/video-gen.wxss
@@ -1 +1 @@
-.video-gen-page.data-v-2ed74c00{min-height:100vh;background:linear-gradient(135deg,#667eea,#764ba2);padding:20rpx}.header.data-v-2ed74c00{text-align:center;padding:40rpx 20rpx;color:#fff}.title.data-v-2ed74c00{font-size:48rpx;font-weight:700;display:block;margin-bottom:10rpx}.subtitle.data-v-2ed74c00{font-size:28rpx;opacity:.9}.message.data-v-2ed74c00{margin:20rpx;padding:20rpx;border-radius:10rpx;text-align:center;font-size:28rpx}.message.success.data-v-2ed74c00{background:#d4edda;color:#155724}.message.error.data-v-2ed74c00{background:#f8d7da;color:#721c24}.message.info.data-v-2ed74c00{background:#d1ecf1;color:#0c5460}.content.data-v-2ed74c00{height:calc(100vh - 200rpx);padding:20rpx}.section.data-v-2ed74c00{background:#fff;border-radius:20rpx;padding:30rpx;margin-bottom:20rpx}.section-title.data-v-2ed74c00{font-size:32rpx;font-weight:700;margin-bottom:20rpx;color:#333}.upload-area.data-v-2ed74c00{border:2rpx dashed #ddd;border-radius:15rpx;min-height:400rpx;display:flex;align-items:center;justify-content:center;background:#f8f9fa}.upload-placeholder.data-v-2ed74c00{text-align:center}.upload-icon.data-v-2ed74c00{font-size:80rpx;display:block;margin-bottom:20rpx}.upload-text.data-v-2ed74c00{font-size:32rpx;color:#666;display:block;margin-bottom:10rpx}.upload-hint.data-v-2ed74c00{font-size:24rpx;color:#999}.preview-image.data-v-2ed74c00{width:100%;max-height:400rpx;border-radius:15rpx}.prompt-input.data-v-2ed74c00{width:100%;min-height:200rpx;padding:20rpx;border:1rpx solid #e0e0e0;border-radius:10rpx;font-size:28rpx;background:#f8f9fa}.char-count.data-v-2ed74c00{text-align:right;font-size:24rpx;color:#999;margin-top:10rpx}.duration-selector.data-v-2ed74c00{display:flex;flex-wrap:wrap;gap:15rpx}.duration-item.data-v-2ed74c00{flex:0 0 calc(25% - 12rpx);padding:20rpx;text-align:center;border:2rpx solid #e0e0e0;border-radius:10rpx;font-size:28rpx;background:#f8f9fa}.duration-item.active.data-v-2ed74c00{background:#667eea;color:#fff;border-color:#667eea}.name-input.data-v-2ed74c00{width:100%;padding:20rpx;border:1rpx solid #e0e0e0;border-radius:10rpx;font-size:28rpx;background:#f8f9fa}.action-section.data-v-2ed74c00{padding:0 20rpx;margin-bottom:20rpx}.generate-btn.data-v-2ed74c00{width:100%;padding:30rpx;background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;border:none;border-radius:15rpx;font-size:32rpx;font-weight:700}.generate-btn[disabled].data-v-2ed74c00{opacity:.6}.progress-section.data-v-2ed74c00{background:#fff;border-radius:20rpx;padding:30rpx;margin:0 20rpx 20rpx}.progress-text.data-v-2ed74c00{text-align:center;font-size:28rpx;color:#666;margin-bottom:20rpx}.progress-bar.data-v-2ed74c00{height:20rpx;background:#e0e0e0;border-radius:10rpx;overflow:hidden}.progress-fill.data-v-2ed74c00{height:100%;background:linear-gradient(90deg,#667eea,#764ba2);transition:width .3s}.result-section.data-v-2ed74c00{background:#fff;border-radius:20rpx;padding:30rpx;margin:0 20rpx 20rpx}.result-video.data-v-2ed74c00{width:100%;height:500rpx;border-radius:15rpx;margin:20rpx 0}.result-actions.data-v-2ed74c00{display:flex;gap:20rpx}.action-btn.data-v-2ed74c00{flex:1;padding:25rpx;background:#667eea;color:#fff;border:none;border-radius:10rpx;font-size:28rpx}.action-btn.secondary.data-v-2ed74c00{background:#6c757d}.tips-section.data-v-2ed74c00{background:rgba(255,255,255,.95);border-radius:20rpx;padding:30rpx;margin:0 20rpx 40rpx}.tips-title.data-v-2ed74c00{font-size:32rpx;font-weight:700;margin-bottom:20rpx;color:#333}.tip-item.data-v-2ed74c00{font-size:26rpx;color:#666;line-height:1.8;margin-bottom:10rpx}
+.video-gen-page.data-v-041223dc{min-height:100vh;background:linear-gradient(135deg,#667eea,#764ba2);padding:20rpx}.header.data-v-041223dc{text-align:center;padding:40rpx 20rpx;color:#fff}.title.data-v-041223dc{font-size:48rpx;font-weight:700;display:block;margin-bottom:10rpx}.subtitle.data-v-041223dc{font-size:28rpx;opacity:.9}.message.data-v-041223dc{margin:20rpx;padding:20rpx;border-radius:10rpx;text-align:center;font-size:28rpx}.message.success.data-v-041223dc{background:#d4edda;color:#155724}.message.error.data-v-041223dc{background:#f8d7da;color:#721c24}.message.info.data-v-041223dc{background:#d1ecf1;color:#0c5460}.content.data-v-041223dc{height:calc(100vh - 200rpx);padding:20rpx}.section.data-v-041223dc{background:#fff;border-radius:20rpx;padding:30rpx;margin-bottom:20rpx}.section-title.data-v-041223dc{font-size:32rpx;font-weight:700;margin-bottom:20rpx;color:#333}.upload-area.data-v-041223dc{border:2rpx dashed #ddd;border-radius:15rpx;min-height:400rpx;display:flex;align-items:center;justify-content:center;background:#f8f9fa}.upload-placeholder.data-v-041223dc{text-align:center}.upload-icon.data-v-041223dc{font-size:80rpx;display:block;margin-bottom:20rpx}.upload-text.data-v-041223dc{font-size:32rpx;color:#666;display:block;margin-bottom:10rpx}.upload-hint.data-v-041223dc{font-size:24rpx;color:#999}.preview-image.data-v-041223dc{width:100%;max-height:400rpx;border-radius:15rpx}.prompt-input.data-v-041223dc{width:100%;min-height:200rpx;padding:20rpx;border:1rpx solid #e0e0e0;border-radius:10rpx;font-size:28rpx;background:#f8f9fa}.char-count.data-v-041223dc{text-align:right;font-size:24rpx;color:#999;margin-top:10rpx}.duration-selector.data-v-041223dc{display:flex;flex-wrap:wrap;gap:15rpx}.duration-item.data-v-041223dc{flex:0 0 calc(25% - 12rpx);padding:20rpx;text-align:center;border:2rpx solid #e0e0e0;border-radius:10rpx;font-size:28rpx;background:#f8f9fa}.duration-item.active.data-v-041223dc{background:#667eea;color:#fff;border-color:#667eea}.name-input.data-v-041223dc{width:100%;padding:20rpx;border:1rpx solid #e0e0e0;border-radius:10rpx;font-size:28rpx;background:#f8f9fa}.action-section.data-v-041223dc{padding:0 20rpx;margin-bottom:20rpx}.generate-btn.data-v-041223dc{width:100%;padding:30rpx;background:linear-gradient(135deg,#667eea,#764ba2);color:#fff!important;border:none;border-radius:15rpx;font-size:32rpx;font-weight:700}.generate-btn[disabled].data-v-041223dc{opacity:.6;color:#fff!important}.ai-disclaimer.data-v-041223dc{display:block;text-align:center;font-size:22rpx;color:rgba(100,100,100,.6);margin-top:16rpx;letter-spacing:.5rpx}.progress-section.data-v-041223dc{background:#fff;border-radius:20rpx;padding:30rpx;margin:0 20rpx 20rpx}.progress-text.data-v-041223dc{text-align:center;font-size:28rpx;color:#666;margin-bottom:20rpx}.progress-bar.data-v-041223dc{height:20rpx;background:#e0e0e0;border-radius:10rpx;overflow:hidden}.progress-fill.data-v-041223dc{height:100%;background:linear-gradient(90deg,#667eea,#764ba2);transition:width .3s}.result-section.data-v-041223dc{background:#fff;border-radius:20rpx;padding:30rpx;margin:0 20rpx 20rpx}.result-section.data-v-041223dc{position:relative}.video-container.data-v-041223dc{position:relative;width:100%;height:500rpx;border-radius:15rpx;overflow:hidden;margin:20rpx 0}.result-video.data-v-041223dc{width:100%;height:100%;border-radius:15rpx}.ai-tag.data-v-041223dc{position:absolute;top:16rpx;right:16rpx;z-index:100;background:rgba(0,0,0,.6);padding:8rpx 20rpx;border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.ai-tag-text.data-v-041223dc{font-size:22rpx;color:#fff;font-weight:500}.result-actions.data-v-041223dc{display:flex;gap:20rpx}.action-btn.data-v-041223dc{flex:1;padding:25rpx;background:#667eea;color:#fff;border:none;border-radius:10rpx;font-size:28rpx}.action-btn.secondary.data-v-041223dc{background:#6c757d}.tips-section.data-v-041223dc{background:rgba(255,255,255,.95);border-radius:20rpx;padding:30rpx;margin:0 20rpx 40rpx}.tips-title.data-v-041223dc{font-size:32rpx;font-weight:700;margin-bottom:20rpx;color:#333}.tip-item.data-v-041223dc{font-size:26rpx;color:#666;line-height:1.8;margin-bottom:10rpx}
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.js b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.js
index f021743..b53dc19 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.js
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.js
@@ -1 +1 @@
-"use strict";const i=require("../../common/vendor.js"),e=require("../../config/api.js"),t={computed:{showLoadingOverlay(){return!this.hasVideoError&&(!this.videoEnded&&!this.pausedByAudioEnd&&(!this.localVideoPath||!this.isVideoPlaying&&(!(this.userPaused&&!this.videoHasStarted&&!this.isVideoDownloading&&!this.videoWaiting)&&(!(!this.isVideoDownloading||this.videoHasStarted)||(!this.videoHasStarted||!(this.lastVideoTime>0)&&!!this.videoWaiting)))))},shouldShowPlayButton(){return!this.videoHasStarted||!this.isLoopingRestart&&!this.videoWaiting&&(!this.isVideoPlaying&&!!this.userPaused)},loadingText(){return this.isVideoDownloading?this.downloadProgress>0?`下载中 ${this.downloadProgress}%`:"准备下载...":this.videoWaiting?"缓冲中...":"加载中..."},loadingHint(){return this.waitingNeedsUserAction?"点击屏幕重试":this.isVideoDownloading&&this.downloadProgress>0?"首次播放需要下载,请稍候":""},videoError(){return this.hasVideoError},errorMessage(){return this.videoErrorMessage||"请检查网络连接后重试"}},data:()=>({API_BASE:e.API_BASE,videoId:"",videoUrl:"",audioUrl:"",videoTitle:"视频播放",audioInVideo:!1,hasAudio:!1,audioContext:null,videoContext:null,audioDuration:0,videoDuration:0,isAudioPlaying:!1,videoLoopTimer:null,audioStarted:!1,audioReady:!1,audioEnded:!1,pendingAudioStart:!1,pendingVideoPlay:!1,audioStartDelaySec:1,lastVideoTime:0,enableSilencePause:!1,silenceSegments:[],silenceLoaded:!1,pausedBySilence:!1,lastAudioTime:0,isLoopingRestart:!1,userPaused:!1,pausedByAudioEnd:!1,videoEndedWaitingAudio:!1,videoWaiting:!1,videoEnded:!1,lastVideoTimeUpdateAt:0,playbackWatchdogTimer:null,lastWaitingRecoverAt:0,localVideoPath:"",isVideoDownloading:!1,isVideoReady:!1,downloadProgress:0,downloadTask:null,pendingCacheSaveTempPath:"",pendingCacheSaveTimer:null,waitingTimer:null,waitingSince:0,waitingNeedsUserAction:!1,videoHasStarted:!1,isVideoPlaying:!1,appNetworkFallbackTimer:null,appFallbackTriggered:!1,appNetworkFallbackDelayMs:900,hasShownStorageLimitToast:!1,cacheKey:"",audioCacheKey:"",audioStartTime:0,videoStartTime:0,audioPauseTime:0,hasVideoError:!1,videoErrorMessage:"",retryCount:0,maxRetryCount:3,isRestarting:!1}),onLoad(e){console.log("[VideoPlayer] 接收参数:",e),console.log("[VideoPlayer] BUILD_MARK_NO_EXTERNAL_AUDIO=2026-01-08-01");const t="1"===e.audioInVideo||"true"===e.audioInVideo;if(void 0!==e.id&&null!==e.id&&""!==String(e.id).trim()&&(this.videoId=String(e.id).trim()),e.videoUrl?this.videoUrl=decodeURIComponent(e.videoUrl):e.url&&(this.videoUrl=decodeURIComponent(e.url)),void 0!==e.audioDelay&&null!==e.audioDelay&&""!==String(e.audioDelay).trim()){const i=Number(e.audioDelay);!Number.isNaN(i)&&i>=0&&(this.audioStartDelaySec=i)}if(void 0!==e.silencePause&&null!==e.silencePause&&""!==String(e.silencePause).trim()){const i=String(e.silencePause).trim();this.enableSilencePause="1"===i||"true"===i}if(this.videoUrl=this.normalizeMediaUrl(this.videoUrl),this.videoEnded=!1,this.userPaused=!0,this.videoId)this.loadVideoFromDb(t,e);else{const i=!(!this.videoUrl||-1===this.videoUrl.indexOf("/static/videos/revival_")),e=t||i;this.audioInVideo=e,console.log("[VideoPlayer] audioInVideo判定: audioInVideoParam=",t,"matchInVideo=",i,"videoUrl=",this.videoUrl),this.cacheKey=this.generateCacheKey(this.videoUrl),this.loadVideo()}e.title&&(this.videoTitle=decodeURIComponent(e.title)),this.hasAudio=!1,this.audioUrl="",audioInVideo?(this.hasAudio=!0,console.log("[VideoPlayer] audioInVideo=1,使用视频自带音轨")):e.audioUrl&&console.log("[VideoPlayer] 已忽略外部 audioUrl 参数(禁用外部音频)"),this.$nextTick((()=>{this.videoContext=i.index.createVideoContext("videoPlayer",this)}))},onUnload(){this.stopVideoLoop(),this.stopPlaybackWatchdog(),this.pendingCacheSaveTimer&&(clearTimeout(this.pendingCacheSaveTimer),this.pendingCacheSaveTimer=null),this.waitingTimer&&(clearTimeout(this.waitingTimer),this.waitingTimer=null);try{this.downloadTask&&"function"==typeof this.downloadTask.abort&&this.downloadTask.abort()}catch(i){}this.downloadTask=null,this.audioContext&&(this.audioContext.stop(),this.audioContext.destroy())},methods:{handleLoadingOverlayClick(){if(!this.videoWaiting)return;if(!this.videoContext)return;if(this.userPaused)return;if(this.videoEnded)return;if(!this.audioInVideo&&this.hasAudio&&this.audioContext&&!this.audioEnded)try{this.isAudioPlaying&&(this.audioPauseTime=this.audioContext.currentTime,this.audioContext.pause())}catch(t){}const i=Number(this.lastVideoTime)||0,e=Math.max(0,i-.3);console.log("[VideoPlayer] waiting手动重试: seekTo=",e);try{this.videoContext.seek&&this.videoContext.seek(e)}catch(t){}setTimeout((()=>{this.videoContext&&this.videoContext.play&&this.videoContext.play()}),120)},scheduleSaveVideoToCache(e,t){if(!e)return;this.pendingCacheSaveTempPath=e,this.pendingCacheSaveTimer&&(clearTimeout(this.pendingCacheSaveTimer),this.pendingCacheSaveTimer=null);const o="number"==typeof t?t:1600;this.pendingCacheSaveTimer=setTimeout((()=>{this.pendingCacheSaveTimer=null;const e=this.pendingCacheSaveTempPath;e&&(this.isVideoPlaying||this.videoWaiting?this.scheduleSaveVideoToCache(e,2e3):(this.pendingCacheSaveTempPath="",i.index.saveFile({tempFilePath:e,success:e=>{const t=e.savedFilePath;console.log("[VideoPlayer] 视频已缓存:",t),i.index.setStorageSync(this.cacheKey,t);const o=i.index.getStorageSync("video_cache_info")||{};o[this.cacheKey]={path:t,url:this.videoUrl,time:Date.now()},i.index.setStorageSync("video_cache_info",o)},fail:()=>{console.log("[VideoPlayer] 视频缓存失败,使用临时文件播放")}})))}),Math.max(300,o))},async loadVideoFromDb(e,t){try{const t=i.index.getStorageSync("token")||"",o=i.index.getStorageSync("userId")||"",s=`${this.API_BASE}/api/photo-revival/videos/${encodeURIComponent(this.videoId)}`;console.log("[VideoPlayer] 从数据库加载视频详情:",s);const d=await new Promise(((e,d)=>{i.index.request({url:s,method:"GET",header:{"X-User-Id":o,Authorization:t?`Bearer ${t}`:""},success:e,fail:d})})),a=d&&d.data?d.data:null,n=a&&a.success&&a.video||{},h=n.edited_video_url||n.local_video_path||n.video_url||"";h?(this.videoUrl=this.normalizeMediaUrl(String(h)),console.log("[VideoPlayer] 使用数据库视频URL:",this.videoUrl)):console.log("[VideoPlayer] 数据库未返回视频URL,回退使用参数videoUrl:",this.videoUrl);const r=!(!this.videoUrl||-1===this.videoUrl.indexOf("/static/videos/revival_")),l=e||r;this.audioInVideo=l,console.log("[VideoPlayer] audioInVideo判定(DB): audioInVideoParam=",e,"matchInVideo=",r,"videoUrl=",this.videoUrl),this.cacheKey=this.generateCacheKey(this.videoUrl),this.loadVideo()}catch(o){console.error("[VideoPlayer] 数据库加载视频详情失败,回退使用参数videoUrl:",o);const i=!(!this.videoUrl||-1===this.videoUrl.indexOf("/static/videos/revival_")),t=e||i;this.audioInVideo=t,this.cacheKey=this.generateCacheKey(this.videoUrl),this.loadVideo()}},handleTogglePlay(){if(this.videoContext){if(this.videoEnded||this.pausedByAudioEnd){console.log("[VideoPlayer] 视频已结束,从头播放"),this.isRestarting=!0,this.videoEnded=!1,this.audioEnded=!1,this.pausedByAudioEnd=!1,this.videoEndedWaitingAudio=!1,this.videoWaiting=!1,this.userPaused=!1,this.videoHasStarted=!1,this.lastVideoTime=0,this.isVideoPlaying=!1,this.retryCount=0,this.stopPlaybackWatchdog();try{this.videoContext.stop&&this.videoContext.stop()}catch(e){}try{this.videoContext.seek&&this.videoContext.seek(0)}catch(e){}return setTimeout((()=>{this.videoContext&&this.videoContext.play&&this.videoContext.play(),setTimeout((()=>{this.isRestarting=!1}),500)}),100),void(i.index.vibrateShort&&i.index.vibrateShort({type:"light"}))}if(this.isVideoPlaying)return this.userPaused=!0,this.videoContext.pause(),void(i.index.vibrateShort&&i.index.vibrateShort({type:"light"}));this.userPaused=!1,this.videoContext.play(),i.index.vibrateShort&&i.index.vibrateShort({type:"light"})}else this.$nextTick((()=>{this.videoContext=i.index.createVideoContext("videoPlayer",this),this.userPaused=!1,this.videoContext&&this.videoContext.play&&this.videoContext.play()}))},startPlaybackWatchdog(){this.playbackWatchdogTimer||(this.lastVideoTimeUpdateAt=Date.now(),this.playbackWatchdogTimer=setInterval((()=>{if(!this.videoContext)return;if(this.userPaused)return;if(this.videoEnded)return;if(!this.videoHasStarted)return;if(this.audioEnded)return;const i=Date.now();this.isVideoPlaying&&this.lastVideoTimeUpdateAt&&i-this.lastVideoTimeUpdateAt>2500&&(console.log("[VideoPlayer] 检测到视频疑似卡住(无timeupdate),尝试恢复播放。lastVideoTime=",this.lastVideoTime),this.videoContext.play())}),1500))},stopPlaybackWatchdog(){this.playbackWatchdogTimer&&(clearInterval(this.playbackWatchdogTimer),this.playbackWatchdogTimer=null)},goBack(){try{const e=getCurrentPages?getCurrentPages():[];if(e&&e.length>1)return void i.index.navigateBack()}catch(e){}i.index.switchTab({url:"/pages/history/history"})},generateCacheKey(i){let e=0;for(let t=0;t{console.log("[VideoPlayer] 缓存文件有效,直接使用"),this.localVideoPath=this.toPlayableLocalPath(e),this.isVideoReady=!0,this.isVideoDownloading=!1,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)}))},fail:()=>{console.log("[VideoPlayer] 缓存文件已失效,重新下载"),i.index.removeStorageSync(this.cacheKey),this.localVideoPath=this.videoUrl,this.downloadAndCacheVideo(),this.isVideoReady=!0,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)}))}});else{if(console.log("[VideoPlayer] 无缓存,先在线播放,后台下载缓存"),"undefined"!=typeof plus)return void this.tryAppNetworkPlaybackThenFallback();this.localVideoPath=this.videoUrl,this.isVideoReady=!0,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)}))}},tryAppNetworkPlaybackThenFallback(){this.appFallbackTriggered=!1,this.appNetworkFallbackTimer&&(clearTimeout(this.appNetworkFallbackTimer),this.appNetworkFallbackTimer=null),this.localVideoPath=this.videoUrl,this.isVideoReady=!0,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)}));const e=Number(this.appNetworkFallbackDelayMs)||900;this.appNetworkFallbackTimer=setTimeout((()=>{this.videoHasStarted||this.appFallbackTriggered||(console.log("[VideoPlayer] App网络直连未能快速开始播放,切换为下载兜底"),this.appFallbackTriggered=!0,this.downloadForPlaybackAndCache())}),Math.max(300,e))},downloadForPlaybackAndCache(){console.log("[VideoPlayer] App无缓存:先下载临时文件播放,再写入缓存:",this.videoUrl),this.isVideoDownloading=!0,this.downloadProgress=0;const e=i.index.downloadFile({url:this.videoUrl,success:e=>{if(200!==e.statusCode)return console.error("[VideoPlayer] App临时下载失败,状态码:",e.statusCode),this.isVideoDownloading=!1,this.isVideoReady=!0,this.localVideoPath=this.videoUrl,void(this.downloadTask=null);const t=e.tempFilePath;this.localVideoPath=this.toPlayableLocalPath(t),this.isVideoReady=!0,this.isVideoDownloading=!1,this.downloadTask=null,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)})),this.scheduleSaveVideoToCache(t,1800)},fail:i=>{console.error("[VideoPlayer] App临时下载失败:",i),this.isVideoDownloading=!1,this.isVideoReady=!0,this.localVideoPath=this.videoUrl,this.downloadTask=null}});this.downloadTask=e||null,this.downloadTask&&"function"==typeof this.downloadTask.onProgressUpdate&&this.downloadTask.onProgressUpdate((i=>{i&&"number"==typeof i.progress&&(this.downloadProgress=Math.max(0,Math.min(100,Math.floor(i.progress))))}))},downloadAndCacheVideo(){},initAudio(){if(!this.audioUrl)return;this.audioContext=i.index.createInnerAudioContext(),this.audioContext.src=this.audioUrl,this.audioContext.autoplay=!1,this.audioReady=!1,this.audioEnded=!1,this.pausedBySilence=!1,this.lastAudioTime=0,this.lastAudioTimeUpdateAt=0,this.silenceSegments=[],this.silenceLoaded=!1,this.audioCacheKey=this.generateAudioCacheKey(this.audioUrl);const e=i.index.getStorageSync(this.audioCacheKey);e&&i.index.getSavedFileInfo({filePath:e,success:()=>{console.log("[VideoPlayer] 找到缓存音频:",e),this.audioContext&&(this.audioContext.src=e)},fail:()=>{i.index.removeStorageSync(this.audioCacheKey)}}),e||i.index.downloadFile({url:this.audioUrl,timeout:6e4,success:e=>{200===e.statusCode&&this.audioContext&&i.index.saveFile({tempFilePath:e.tempFilePath,success:e=>{const t=e.savedFilePath;console.log("[VideoPlayer] 音频已缓存:",t),i.index.setStorageSync(this.audioCacheKey,t),this.audioContext&&(this.audioContext.src=t)},fail:()=>{console.log("[VideoPlayer] 音频缓存失败,使用临时文件播放"),this.audioContext.src=e.tempFilePath}})},fail:i=>{console.error("[VideoPlayer] 音频下载失败,回退到URL直连:",i)}}),this.enableSilencePause&&this.fetchSilenceSegments(),this.audioContext.onCanplay((()=>{this.audioReady=!0;const i=Number(this.audioContext.duration);if(!Number.isNaN(i)&&i>0&&(this.audioDuration=i),console.log("[VideoPlayer] 音频时长:",this.audioDuration,"秒"),!this.audioStarted&&!this.audioEnded&&this.videoHasStarted&&this.lastVideoTime>=this.audioStartDelaySec){const i=Math.max(0,(this.lastVideoTime||0)-(this.audioStartDelaySec||0));return console.log("[VideoPlayer] 音频已就绪且视频已到达延迟点,开始播放音频,seek=",i),void this.startAudioFromVideoTime(i)}})),setTimeout((()=>{if(this.audioContext){const i=Number(this.audioContext.duration);!Number.isNaN(i)&&i>0&&(this.audioDuration=i),console.log("[VideoPlayer] 音频时长(延迟校准):",this.audioDuration,"秒")}}),200),this.audioContext.onPlay((()=>{console.log("[VideoPlayer] 音频开始播放"),this.isAudioPlaying=!0})),this.audioContext.onTimeUpdate&&this.audioContext.onTimeUpdate((()=>{if(!this.audioContext)return;const i=Number(this.audioContext.currentTime)||0;this.lastAudioTime=i,this.lastAudioTimeUpdateAt=Date.now(),this.enableSilencePause&&this.handleAudioTimeUpdate(i)})),this.audioContext.onPause((()=>{console.log("[VideoPlayer] 音频被暂停,当前位置:",this.audioContext.currentTime,"秒"),this.isAudioPlaying=!1})),this.audioContext.onStop((()=>{console.log("[VideoPlayer] 音频被停止"),this.isAudioPlaying=!1})),this.audioContext.onWaiting((()=>{console.log("[VideoPlayer] 音频加载中...")})),this.audioContext.onError((i=>{console.error("[VideoPlayer] 音频播放失败:",i)})),this.audioContext.onEnded((()=>{console.log("[VideoPlayer] 音频播放结束,总时长:",this.audioContext.duration,"秒,播放到:",this.audioContext.currentTime,"秒"),this.isAudioPlaying=!1,this.audioEnded=!0,this.pausedBySilence=!1,this.videoEndedWaitingAudio=!1,this.stopVideoLoop();const i=Number(this.audioContext.currentTime)||0,e=Math.max(i,Number(this.lastAudioTime)||0),t=Number(this.audioDuration)||Number(this.audioContext.duration)||0,o=t>0&&(e>=t-.6||e/t>=.95),s=this.videoDuration&&this.lastVideoTime>=this.videoDuration-.3;this.videoContext&&(o||s)?(console.log("[VideoPlayer] 音频结束,联动停止视频。audioEndedForSure=",o,"videoNearEnd=",s),this.videoWaiting=!1,this.userPaused=!0,this.pausedByAudioEnd=!0,this.stopPlaybackWatchdog(),this.videoContext.pause(),setTimeout((()=>{this.videoContext&&this.audioEnded&&this.pausedByAudioEnd&&this.videoContext.pause&&this.videoContext.pause()}),180),this.isVideoPlaying=!1):console.log("[VideoPlayer] 音频 onEnded 触发但无法确认已到结尾,跳过联动停止视频。audioDur=",t,"audioCur=",i,"lastAudioTime=",this.lastAudioTime)}))},fetchSilenceSegments(){if(!this.audioUrl)return;const e=i.index.getStorageSync("userId")||"",t=i.index.getStorageSync("token")||"";t&&i.index.request({url:`${this.API_BASE}/api/video/silence-detect`,method:"POST",timeout:12e4,header:{"X-User-Id":e,Authorization:t?`Bearer ${t}`:"","Content-Type":"application/json"},data:{audioUrl:this.audioUrl},success:i=>{var e,t,o,s,d;if(!(200===i.statusCode&&(!0===(null==(e=i.data)?void 0:e.success)||"true"===(null==(t=i.data)?void 0:t.success)||1===(null==(o=i.data)?void 0:o.success)||"1"===(null==(s=i.data)?void 0:s.success))))return void console.warn("[VideoPlayer] 静音检测失败:",i.data);const a=Array.isArray(null==(d=i.data)?void 0:d.segments)?i.data.segments:[];this.silenceSegments=a.map((i=>({start:Number(i.start)||0,end:Number(i.end)||0}))).filter((i=>i.end>i.start)).sort(((i,e)=>i.start-e.start)),this.silenceLoaded=!0,console.log("[VideoPlayer] 静音区间数量:",this.silenceSegments.length)},fail:i=>{console.error("[VideoPlayer] 静音检测请求失败:",i)}})},handleAudioTimeUpdate(i){if(!this.videoContext||!this.hasAudio)return;if(!this.enableSilencePause)return;if(!this.silenceLoaded||0===this.silenceSegments.length)return;if(this.audioEnded)return;let e=!1;for(const t of this.silenceSegments){if(i>=t.start&&i{this.loadVideo()}))},onVideoError(e){console.error("[VideoPlayer] 视频加载失败:",e),e&&e.detail&&e.detail.errMsg&&String(e.detail.errMsg);const t=e&&e.detail&&void 0!==e.detail.errCode&&null!==e.detail.errCode?String(e.detail.errCode):"",o=this.localVideoPath||this.videoUrl||"";if(this.videoWaiting=!1,this.videoEnded||this.pausedByAudioEnd)console.log("[VideoPlayer] 视频已结束,忽略错误事件,不重试");else if(this.videoDuration>0&&this.lastVideoTime>=this.videoDuration-1)console.log("[VideoPlayer] 视频已播放到结尾,忽略错误事件,不重试");else{if("undefined"!=typeof plus&&!this.appFallbackTriggered&&o===this.videoUrl)return console.log("[VideoPlayer] App网络直连播放失败,切换为下载兜底"),this.appFallbackTriggered=!0,void this.downloadForPlaybackAndCache();if(this.retryCount{if(this.videoEnded||this.pausedByAudioEnd)console.log("[VideoPlayer] 重试前检测到视频已结束,取消重试");else if(this.videoDuration>0&&this.lastVideoTime>=this.videoDuration-1)console.log("[VideoPlayer] 重试前检测到视频已播放到结尾,取消重试");else{if(this.cacheKey)try{i.index.removeStorageSync(this.cacheKey)}catch(e){}this.isRestarting=!0,this.isVideoPlaying=!1,this.videoWaiting=!1,this.localVideoPath=this.videoUrl,this.isVideoReady=!0,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{!this.videoContext||this.userPaused||this.videoEnded||this.videoContext.play&&this.videoContext.play(),setTimeout((()=>{this.isRestarting=!1}),800)}),100)}))}}),1e3*this.retryCount);this.hasVideoError=!0,this.videoErrorMessage=t?`错误代码: ${t}`:"网络连接失败或视频格式不支持"}},onVideoLoadedMetadata(i){i&&i.detail&&i.detail.duration&&(this.videoDuration=i.detail.duration,console.log("[VideoPlayer] 视频时长:",this.videoDuration,"秒")),this.videoWaiting=!1},onVideoPlay(){if(console.log("[VideoPlayer] 视频开始播放"),this.hasVideoError){console.log("[VideoPlayer] 视频加载失败,阻止播放");try{this.videoContext&&this.videoContext.pause&&this.videoContext.pause()}catch(i){}}else if(this.appNetworkFallbackTimer&&(clearTimeout(this.appNetworkFallbackTimer),this.appNetworkFallbackTimer=null),this.waitingNeedsUserAction=!1,this.waitingTimer&&(clearTimeout(this.waitingTimer),this.waitingTimer=null),this.videoEnded&&this.pausedByAudioEnd){console.log("[VideoPlayer] 视频已结束且被音频结束暂停,阻止继续播放");try{this.videoContext&&this.videoContext.pause&&this.videoContext.pause()}catch(i){}}else{if(this.videoHasStarted=!0,this.isVideoPlaying=!0,this.videoWaiting=!1,this.lastVideoTimeUpdateAt=Date.now(),this.startPlaybackWatchdog(),this.audioEnded&&this.pausedByAudioEnd&&this.videoContext)return console.log("[VideoPlayer] 音频已结束,阻止视频继续播放"),this.videoWaiting=!1,this.userPaused=!0,this.videoContext.pause(),void(this.isVideoPlaying=!1);if(this.hasAudio&&this.audioContext)if(0!==this.audioStartDelaySec||this.audioStarted||this.audioEnded){if(!this.audioReady)return this.pendingAudioStart=!0,void console.log("[VideoPlayer] 音频未就绪,等待音频就绪后在指定延迟点播放");!this.audioStarted||this.isAudioPlaying||this.audioEnded||(console.log("[VideoPlayer] 恢复音频播放,当前位置:",this.audioContext.currentTime,"秒"),this.audioContext.play())}else{if(this.audioReady){const i=Math.max(0,this.lastVideoTime||0);return console.log("[VideoPlayer] 无延迟模式:视频开始播放,启动音频,seek=",i),void this.startAudioFromVideoTime(i)}this.pendingAudioStart=!0}}},onVideoPause(){if(console.log("[VideoPlayer] 视频暂停"),!this.isLoopingRestart)return this.videoWaiting||!this.userPaused?(console.log("[VideoPlayer] 非用户暂停(可能缓冲/系统暂停),不联动暂停音频"),void(this.isVideoPlaying=!1)):void(this.audioContext&&this.hasAudio&&this.isAudioPlaying&&(console.log("[VideoPlayer] 暂停音频,当前位置:",this.audioContext.currentTime,"秒"),this.audioPauseTime=this.audioContext.currentTime,this.audioContext.pause()))},onVideoWaiting(){const i=Date.now();if(this.isVideoPlaying&&this.lastVideoTimeUpdateAt&&i-this.lastVideoTimeUpdateAt<500)return void console.log("[VideoPlayer] 视频正在播放中,忽略偶发 waiting 事件");if(this.videoWaiting=!0,this.waitingNeedsUserAction=!1,this.waitingSince=i,console.log("[VideoPlayer] 视频缓冲中(waiting),lastVideoTime=",this.lastVideoTime),!this.videoContext)return;if(this.waitingTimer&&(clearTimeout(this.waitingTimer),this.waitingTimer=null),this.waitingTimer=setTimeout((()=>{if(this.waitingTimer=null,!this.videoWaiting)return;if(!this.videoContext)return;if(this.userPaused)return;if(this.videoEnded)return;if(!this.audioInVideo&&this.hasAudio&&!this.audioEnded)return void(this.waitingNeedsUserAction=!0);const i=Number(this.lastVideoTime)||0,e=Math.max(0,i-.3);console.log("[VideoPlayer] waiting超时自动恢复: seekTo=",e);try{this.videoContext.seek&&this.videoContext.seek(e)}catch(t){}setTimeout((()=>{this.videoContext&&this.videoContext.play&&this.videoContext.play()}),120)}),6e3),"undefined"!=typeof plus&&!this.videoHasStarted&&!this.appFallbackTriggered&&this.localVideoPath===this.videoUrl)return console.log("[VideoPlayer] App首帧 waiting,立即切换为下载兜底"),this.appFallbackTriggered=!0,void this.downloadForPlaybackAndCache();if(this.videoEnded)return;if(this.videoEndedWaitingAudio&&this.hasAudio&&!this.audioEnded)return void console.log("[VideoPlayer] 视频已结束且音频未结束:忽略 waiting");if(!this.audioInVideo&&this.hasAudio&&!this.audioEnded)return void console.log("[VideoPlayer] 存在音频且未结束,跳过 waiting 自动恢复,以避免音频被系统 stop");const e=Date.now();this.lastWaitingRecoverAt&&e-this.lastWaitingRecoverAt<1500||(this.lastWaitingRecoverAt=e,setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.pausedBySilence||this.audioEnded||(console.log("[VideoPlayer] waiting后尝试恢复视频播放"),this.videoContext.play()))}),600))},onVideoEnded(){if(console.log("[VideoPlayer] 视频播放结束","lastVideoTime=",this.lastVideoTime,"videoDuration=",this.videoDuration,"audioEnded=",this.audioEnded,"isRestarting=",this.isRestarting),this.isRestarting)return void console.log("[VideoPlayer] 正在重新播放,忽略 ended 事件");if(this.hasVideoError||this.retryCount>=this.maxRetryCount)return console.log("[VideoPlayer] 视频加载失败或重试次数已达上限,阻止自动重播"),this.isVideoPlaying=!1,this.videoEnded=!0,void this.stopPlaybackWatchdog();if(this.isVideoPlaying=!1,this.videoEnded=!0,this.stopPlaybackWatchdog(),this.audioInVideo){this.videoWaiting=!1,this.userPaused=!0,this.pausedByAudioEnd=!0,this.audioEnded=!0,this.stopPlaybackWatchdog(),this.stopVideoLoop();try{this.videoContext&&this.videoContext.seek&&this.videoDuration&&this.videoContext.seek(Math.max(0,Number(this.videoDuration)-.05))}catch(s){}return void(this.videoContext&&this.videoContext.pause&&this.videoContext.pause())}if(this.hasAudio&&this.audioContext&&!this.audioEnded){this.videoEndedWaitingAudio=!0,this.videoWaiting=!1,console.log("[VideoPlayer] 音频未结束:视频停在末帧等待音频播完(不循环不重播)");try{this.videoContext&&this.videoContext.seek&&this.videoDuration&&this.videoContext.seek(Math.max(0,Number(this.videoDuration)-.05))}catch(s){}return void(this.videoContext&&this.videoContext.pause&&this.videoContext.pause())}if(this.hasAudio&&this.audioContext&&!this.audioEnded){const i=Number(this.audioContext.currentTime)||0,e=Math.max(i,Number(this.lastAudioTime)||0),t=Number(this.audioDuration)||Number(this.audioContext.duration)||0;if(t>0&&(e>=t-.6||e/t>=.95))return console.log("[VideoPlayer] 检测到音频已到结尾(兜底推断),停止视频循环并暂停视频。audioCurStable=",e,"audioDur=",t),this.audioEnded=!0,this.stopVideoLoop(),void(this.videoContext&&this.videoContext.pause&&this.videoContext.pause())}const e=Number(this.videoDuration)||0,t=Number(this.lastVideoTime)||0,o=!e&&t>0&&t<3||e>0&&t>0&&t{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&this.videoContext.play&&this.videoContext.play()}),120)}))}},onTimeUpdate(i){if(!i||!i.detail)return;const e=i.detail.currentTime;if(this.lastVideoTime=e,this.lastVideoTimeUpdateAt=Date.now(),!this.videoHasStarted&&(Number(e)||0)>0&&(this.videoHasStarted=!0),!this.userPaused&&(Number(e)||0)>0&&(this.isVideoPlaying=!0),this.videoWaiting&&(console.log("[VideoPlayer] timeupdate 清除 waiting 状态,currentTime=",e),this.videoWaiting=!1,this.waitingNeedsUserAction=!1),this.waitingTimer&&(clearTimeout(this.waitingTimer),this.waitingTimer=null),this.isVideoPlaying||this.userPaused||(this.isVideoPlaying=!0),this.hasAudio&&this.audioContext&&!this.audioStarted&&!this.audioEnded&&e>=this.audioStartDelaySec){if(this.audioReady){const i=Math.max(0,(e||0)-(this.audioStartDelaySec||0));return console.log("[VideoPlayer] 视频到达延迟点,开始播放音频,seek=",i),void this.startAudioFromVideoTime(i)}this.pendingAudioStart=!0}},startVideoLoop(){this.videoLoopTimer||console.log("[VideoPlayer] 视频循环已启动")},stopVideoLoop(){this.videoLoopTimer&&(clearInterval(this.videoLoopTimer),this.videoLoopTimer=null,console.log("[VideoPlayer] 视频循环已停止"))}}};const o=i._export_sfc(t,[["render",function(e,t,o,s,d,a){return i.e({a:i.o(((...i)=>a.goBack&&a.goBack(...i))),b:i.t(d.videoTitle),c:a.videoError},a.videoError?{d:i.t(a.errorMessage),e:i.o(((...i)=>a.retryVideo&&a.retryVideo(...i))),f:i.o(((...i)=>a.goBack&&a.goBack(...i)))}:{},{g:a.showLoadingOverlay&&!a.videoError},a.showLoadingOverlay&&!a.videoError?i.e({h:i.t(a.loadingText),i:a.loadingHint},a.loadingHint?{j:i.t(a.loadingHint)}:{},{k:d.isVideoDownloading&&d.downloadProgress>0},d.isVideoDownloading&&d.downloadProgress>0?{l:d.downloadProgress+"%"}:{},{m:i.o(((...i)=>a.handleLoadingOverlayClick&&a.handleLoadingOverlayClick(...i)))}):{},{n:d.localVideoPath},d.localVideoPath?{o:d.localVideoPath,p:!!d.audioUrl,q:i.o(((...i)=>a.onVideoError&&a.onVideoError(...i))),r:i.o(((...i)=>a.onVideoPlay&&a.onVideoPlay(...i))),s:i.o(((...i)=>a.onVideoPause&&a.onVideoPause(...i))),t:i.o(((...i)=>a.onVideoWaiting&&a.onVideoWaiting(...i))),v:i.o(((...i)=>a.onVideoEnded&&a.onVideoEnded(...i))),w:i.o(((...i)=>a.onTimeUpdate&&a.onTimeUpdate(...i))),x:i.o(((...i)=>a.onVideoLoadedMetadata&&a.onVideoLoadedMetadata(...i)))}:{},{y:d.localVideoPath&&!a.showLoadingOverlay},d.localVideoPath&&!a.showLoadingOverlay?i.e({z:a.shouldShowPlayButton},(a.shouldShowPlayButton,{}),{A:i.o(((...i)=>a.handleTogglePlay&&a.handleTogglePlay(...i)))}):{})}],["__scopeId","data-v-d19743cf"]]);wx.createPage(o);
+"use strict";const i=require("../../common/vendor.js"),e=require("../../config/api.js"),t={computed:{showLoadingOverlay(){return!this.hasVideoError&&(!this.videoEnded&&!this.pausedByAudioEnd&&(!this.localVideoPath||!this.isVideoPlaying&&(!(this.userPaused&&!this.videoHasStarted&&!this.isVideoDownloading&&!this.videoWaiting)&&(!(!this.isVideoDownloading||this.videoHasStarted)||(!this.videoHasStarted||!(this.lastVideoTime>0)&&!!this.videoWaiting)))))},shouldShowPlayButton(){return!this.videoHasStarted||!this.isLoopingRestart&&!this.videoWaiting&&(!this.isVideoPlaying&&!!this.userPaused)},loadingText(){return this.isVideoDownloading?this.downloadProgress>0?`下载中 ${this.downloadProgress}%`:"准备下载...":this.videoWaiting?"缓冲中...":"加载中..."},loadingHint(){return this.waitingNeedsUserAction?"点击屏幕重试":this.isVideoDownloading&&this.downloadProgress>0?"首次播放需要下载,请稍候":""},videoError(){return this.hasVideoError},errorMessage(){return this.videoErrorMessage||"请检查网络连接后重试"}},data:()=>({API_BASE:e.API_BASE,videoId:"",videoUrl:"",audioUrl:"",videoTitle:"视频播放",audioInVideo:!1,hasAudio:!1,audioContext:null,videoContext:null,audioDuration:0,videoDuration:0,isAudioPlaying:!1,videoLoopTimer:null,audioStarted:!1,audioReady:!1,audioEnded:!1,pendingAudioStart:!1,pendingVideoPlay:!1,audioStartDelaySec:1,lastVideoTime:0,enableSilencePause:!1,silenceSegments:[],silenceLoaded:!1,pausedBySilence:!1,lastAudioTime:0,isLoopingRestart:!1,userPaused:!1,pausedByAudioEnd:!1,videoEndedWaitingAudio:!1,videoWaiting:!1,videoEnded:!1,lastVideoTimeUpdateAt:0,playbackWatchdogTimer:null,lastWaitingRecoverAt:0,localVideoPath:"",isVideoDownloading:!1,isVideoReady:!1,downloadProgress:0,downloadTask:null,pendingCacheSaveTempPath:"",pendingCacheSaveTimer:null,waitingTimer:null,waitingSince:0,waitingNeedsUserAction:!1,videoHasStarted:!1,isVideoPlaying:!1,appNetworkFallbackTimer:null,appFallbackTriggered:!1,appNetworkFallbackDelayMs:900,hasShownStorageLimitToast:!1,cacheKey:"",audioCacheKey:"",audioStartTime:0,videoStartTime:0,audioPauseTime:0,hasVideoError:!1,videoErrorMessage:"",retryCount:0,maxRetryCount:3,isRestarting:!1}),onLoad(e){console.log("[VideoPlayer] 接收参数:",e),console.log("[VideoPlayer] BUILD_MARK_NO_EXTERNAL_AUDIO=2026-01-08-01");const t="1"===e.audioInVideo||"true"===e.audioInVideo;if(void 0!==e.id&&null!==e.id&&""!==String(e.id).trim()&&(this.videoId=String(e.id).trim()),e.videoUrl?this.videoUrl=decodeURIComponent(e.videoUrl):e.url&&(this.videoUrl=decodeURIComponent(e.url)),void 0!==e.audioDelay&&null!==e.audioDelay&&""!==String(e.audioDelay).trim()){const i=Number(e.audioDelay);!Number.isNaN(i)&&i>=0&&(this.audioStartDelaySec=i)}if(void 0!==e.silencePause&&null!==e.silencePause&&""!==String(e.silencePause).trim()){const i=String(e.silencePause).trim();this.enableSilencePause="1"===i||"true"===i}if(this.videoUrl=this.normalizeMediaUrl(this.videoUrl),this.videoEnded=!1,this.userPaused=!0,this.videoId)this.loadVideoFromDb(t,e);else{const i=!(!this.videoUrl||-1===this.videoUrl.indexOf("/static/videos/revival_")),e=t||i;this.audioInVideo=e,console.log("[VideoPlayer] audioInVideo判定: audioInVideoParam=",t,"matchInVideo=",i,"videoUrl=",this.videoUrl),this.cacheKey=this.generateCacheKey(this.videoUrl),this.loadVideo()}e.title&&(this.videoTitle=decodeURIComponent(e.title)),this.hasAudio=!1,this.audioUrl="",audioInVideo?(this.hasAudio=!0,console.log("[VideoPlayer] audioInVideo=1,使用视频自带音轨")):e.audioUrl&&console.log("[VideoPlayer] 已忽略外部 audioUrl 参数(禁用外部音频)"),this.$nextTick((()=>{this.videoContext=i.index.createVideoContext("videoPlayer",this)}))},onUnload(){this.stopVideoLoop(),this.stopPlaybackWatchdog(),this.pendingCacheSaveTimer&&(clearTimeout(this.pendingCacheSaveTimer),this.pendingCacheSaveTimer=null),this.waitingTimer&&(clearTimeout(this.waitingTimer),this.waitingTimer=null);try{this.downloadTask&&"function"==typeof this.downloadTask.abort&&this.downloadTask.abort()}catch(i){}this.downloadTask=null,this.audioContext&&(this.audioContext.stop(),this.audioContext.destroy())},methods:{handleLoadingOverlayClick(){if(!this.videoWaiting)return;if(!this.videoContext)return;if(this.userPaused)return;if(this.videoEnded)return;if(!this.audioInVideo&&this.hasAudio&&this.audioContext&&!this.audioEnded)try{this.isAudioPlaying&&(this.audioPauseTime=this.audioContext.currentTime,this.audioContext.pause())}catch(t){}const i=Number(this.lastVideoTime)||0,e=Math.max(0,i-.3);console.log("[VideoPlayer] waiting手动重试: seekTo=",e);try{this.videoContext.seek&&this.videoContext.seek(e)}catch(t){}setTimeout((()=>{this.videoContext&&this.videoContext.play&&this.videoContext.play()}),120)},scheduleSaveVideoToCache(e,t){if(!e)return;this.pendingCacheSaveTempPath=e,this.pendingCacheSaveTimer&&(clearTimeout(this.pendingCacheSaveTimer),this.pendingCacheSaveTimer=null);const o="number"==typeof t?t:1600;this.pendingCacheSaveTimer=setTimeout((()=>{this.pendingCacheSaveTimer=null;const e=this.pendingCacheSaveTempPath;e&&(this.isVideoPlaying||this.videoWaiting?this.scheduleSaveVideoToCache(e,2e3):(this.pendingCacheSaveTempPath="",i.index.saveFile({tempFilePath:e,success:e=>{const t=e.savedFilePath;console.log("[VideoPlayer] 视频已缓存:",t),i.index.setStorageSync(this.cacheKey,t);const o=i.index.getStorageSync("video_cache_info")||{};o[this.cacheKey]={path:t,url:this.videoUrl,time:Date.now()},i.index.setStorageSync("video_cache_info",o)},fail:()=>{console.log("[VideoPlayer] 视频缓存失败,使用临时文件播放")}})))}),Math.max(300,o))},async loadVideoFromDb(e,t){try{const t=i.index.getStorageSync("token")||"",o=i.index.getStorageSync("userId")||"",s=`${this.API_BASE}/api/photo-revival/videos/${encodeURIComponent(this.videoId)}`;console.log("[VideoPlayer] 从数据库加载视频详情:",s);const d=await new Promise(((e,d)=>{i.index.request({url:s,method:"GET",header:{"X-User-Id":o,Authorization:t?`Bearer ${t}`:""},success:e,fail:d})})),a=d&&d.data?d.data:null,n=a&&a.success&&a.video||{},h=n.edited_video_url||n.local_video_path||n.video_url||"";h?(this.videoUrl=this.normalizeMediaUrl(String(h)),console.log("[VideoPlayer] 使用数据库视频URL:",this.videoUrl)):console.log("[VideoPlayer] 数据库未返回视频URL,回退使用参数videoUrl:",this.videoUrl);const r=!(!this.videoUrl||-1===this.videoUrl.indexOf("/static/videos/revival_")),l=e||r;this.audioInVideo=l,console.log("[VideoPlayer] audioInVideo判定(DB): audioInVideoParam=",e,"matchInVideo=",r,"videoUrl=",this.videoUrl),this.cacheKey=this.generateCacheKey(this.videoUrl),this.loadVideo()}catch(o){console.error("[VideoPlayer] 数据库加载视频详情失败,回退使用参数videoUrl:",o);const i=!(!this.videoUrl||-1===this.videoUrl.indexOf("/static/videos/revival_")),t=e||i;this.audioInVideo=t,this.cacheKey=this.generateCacheKey(this.videoUrl),this.loadVideo()}},handleTogglePlay(){if(this.videoContext){if(this.videoEnded||this.pausedByAudioEnd){console.log("[VideoPlayer] 视频已结束,从头播放"),this.isRestarting=!0,this.videoEnded=!1,this.audioEnded=!1,this.pausedByAudioEnd=!1,this.videoEndedWaitingAudio=!1,this.videoWaiting=!1,this.userPaused=!1,this.videoHasStarted=!1,this.lastVideoTime=0,this.isVideoPlaying=!1,this.retryCount=0,this.stopPlaybackWatchdog();try{this.videoContext.stop&&this.videoContext.stop()}catch(e){}try{this.videoContext.seek&&this.videoContext.seek(0)}catch(e){}return setTimeout((()=>{this.videoContext&&this.videoContext.play&&this.videoContext.play(),setTimeout((()=>{this.isRestarting=!1}),500)}),100),void(i.index.vibrateShort&&i.index.vibrateShort({type:"light"}))}if(this.isVideoPlaying)return this.userPaused=!0,this.videoContext.pause(),void(i.index.vibrateShort&&i.index.vibrateShort({type:"light"}));this.userPaused=!1,this.videoContext.play(),i.index.vibrateShort&&i.index.vibrateShort({type:"light"})}else this.$nextTick((()=>{this.videoContext=i.index.createVideoContext("videoPlayer",this),this.userPaused=!1,this.videoContext&&this.videoContext.play&&this.videoContext.play()}))},startPlaybackWatchdog(){this.playbackWatchdogTimer||(this.lastVideoTimeUpdateAt=Date.now(),this.playbackWatchdogTimer=setInterval((()=>{if(!this.videoContext)return;if(this.userPaused)return;if(this.videoEnded)return;if(!this.videoHasStarted)return;if(this.audioEnded)return;const i=Date.now();this.isVideoPlaying&&this.lastVideoTimeUpdateAt&&i-this.lastVideoTimeUpdateAt>2500&&(console.log("[VideoPlayer] 检测到视频疑似卡住(无timeupdate),尝试恢复播放。lastVideoTime=",this.lastVideoTime),this.videoContext.play())}),1500))},stopPlaybackWatchdog(){this.playbackWatchdogTimer&&(clearInterval(this.playbackWatchdogTimer),this.playbackWatchdogTimer=null)},goBack(){try{const e=getCurrentPages?getCurrentPages():[];if(e&&e.length>1)return void i.index.navigateBack()}catch(e){}i.index.switchTab({url:"/pages/history/history"})},generateCacheKey(i){let e=0;for(let t=0;t{console.log("[VideoPlayer] 缓存文件有效,直接使用"),this.localVideoPath=this.toPlayableLocalPath(e),this.isVideoReady=!0,this.isVideoDownloading=!1,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)}))},fail:()=>{console.log("[VideoPlayer] 缓存文件已失效,重新下载"),i.index.removeStorageSync(this.cacheKey),this.localVideoPath=this.videoUrl,this.downloadAndCacheVideo(),this.isVideoReady=!0,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)}))}});else{if(console.log("[VideoPlayer] 无缓存,先在线播放,后台下载缓存"),"undefined"!=typeof plus)return void this.tryAppNetworkPlaybackThenFallback();this.localVideoPath=this.videoUrl,this.isVideoReady=!0,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)}))}},tryAppNetworkPlaybackThenFallback(){this.appFallbackTriggered=!1,this.appNetworkFallbackTimer&&(clearTimeout(this.appNetworkFallbackTimer),this.appNetworkFallbackTimer=null),this.localVideoPath=this.videoUrl,this.isVideoReady=!0,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)}));const e=Number(this.appNetworkFallbackDelayMs)||900;this.appNetworkFallbackTimer=setTimeout((()=>{this.videoHasStarted||this.appFallbackTriggered||(console.log("[VideoPlayer] App网络直连未能快速开始播放,切换为下载兜底"),this.appFallbackTriggered=!0,this.downloadForPlaybackAndCache())}),Math.max(300,e))},downloadForPlaybackAndCache(){console.log("[VideoPlayer] App无缓存:先下载临时文件播放,再写入缓存:",this.videoUrl),this.isVideoDownloading=!0,this.downloadProgress=0;const e=i.index.downloadFile({url:this.videoUrl,success:e=>{if(200!==e.statusCode)return console.error("[VideoPlayer] App临时下载失败,状态码:",e.statusCode),this.isVideoDownloading=!1,this.isVideoReady=!0,this.localVideoPath=this.videoUrl,void(this.downloadTask=null);const t=e.tempFilePath;this.localVideoPath=this.toPlayableLocalPath(t),this.isVideoReady=!0,this.isVideoDownloading=!1,this.downloadTask=null,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.videoHasStarted||this.videoContext.play&&this.videoContext.play())}),80)})),this.scheduleSaveVideoToCache(t,1800)},fail:i=>{console.error("[VideoPlayer] App临时下载失败:",i),this.isVideoDownloading=!1,this.isVideoReady=!0,this.localVideoPath=this.videoUrl,this.downloadTask=null}});this.downloadTask=e||null,this.downloadTask&&"function"==typeof this.downloadTask.onProgressUpdate&&this.downloadTask.onProgressUpdate((i=>{i&&"number"==typeof i.progress&&(this.downloadProgress=Math.max(0,Math.min(100,Math.floor(i.progress))))}))},downloadAndCacheVideo(){},initAudio(){if(!this.audioUrl)return;this.audioContext=i.index.createInnerAudioContext(),this.audioContext.src=this.audioUrl,this.audioContext.autoplay=!1,this.audioReady=!1,this.audioEnded=!1,this.pausedBySilence=!1,this.lastAudioTime=0,this.lastAudioTimeUpdateAt=0,this.silenceSegments=[],this.silenceLoaded=!1,this.audioCacheKey=this.generateAudioCacheKey(this.audioUrl);const e=i.index.getStorageSync(this.audioCacheKey);e&&i.index.getSavedFileInfo({filePath:e,success:()=>{console.log("[VideoPlayer] 找到缓存音频:",e),this.audioContext&&(this.audioContext.src=e)},fail:()=>{i.index.removeStorageSync(this.audioCacheKey)}}),e||i.index.downloadFile({url:this.audioUrl,timeout:6e4,success:e=>{200===e.statusCode&&this.audioContext&&i.index.saveFile({tempFilePath:e.tempFilePath,success:e=>{const t=e.savedFilePath;console.log("[VideoPlayer] 音频已缓存:",t),i.index.setStorageSync(this.audioCacheKey,t),this.audioContext&&(this.audioContext.src=t)},fail:()=>{console.log("[VideoPlayer] 音频缓存失败,使用临时文件播放"),this.audioContext.src=e.tempFilePath}})},fail:i=>{console.error("[VideoPlayer] 音频下载失败,回退到URL直连:",i)}}),this.enableSilencePause&&this.fetchSilenceSegments(),this.audioContext.onCanplay((()=>{this.audioReady=!0;const i=Number(this.audioContext.duration);if(!Number.isNaN(i)&&i>0&&(this.audioDuration=i),console.log("[VideoPlayer] 音频时长:",this.audioDuration,"秒"),!this.audioStarted&&!this.audioEnded&&this.videoHasStarted&&this.lastVideoTime>=this.audioStartDelaySec){const i=Math.max(0,(this.lastVideoTime||0)-(this.audioStartDelaySec||0));return console.log("[VideoPlayer] 音频已就绪且视频已到达延迟点,开始播放音频,seek=",i),void this.startAudioFromVideoTime(i)}})),setTimeout((()=>{if(this.audioContext){const i=Number(this.audioContext.duration);!Number.isNaN(i)&&i>0&&(this.audioDuration=i),console.log("[VideoPlayer] 音频时长(延迟校准):",this.audioDuration,"秒")}}),200),this.audioContext.onPlay((()=>{console.log("[VideoPlayer] 音频开始播放"),this.isAudioPlaying=!0})),this.audioContext.onTimeUpdate&&this.audioContext.onTimeUpdate((()=>{if(!this.audioContext)return;const i=Number(this.audioContext.currentTime)||0;this.lastAudioTime=i,this.lastAudioTimeUpdateAt=Date.now(),this.enableSilencePause&&this.handleAudioTimeUpdate(i)})),this.audioContext.onPause((()=>{console.log("[VideoPlayer] 音频被暂停,当前位置:",this.audioContext.currentTime,"秒"),this.isAudioPlaying=!1})),this.audioContext.onStop((()=>{console.log("[VideoPlayer] 音频被停止"),this.isAudioPlaying=!1})),this.audioContext.onWaiting((()=>{console.log("[VideoPlayer] 音频加载中...")})),this.audioContext.onError((i=>{console.error("[VideoPlayer] 音频播放失败:",i)})),this.audioContext.onEnded((()=>{console.log("[VideoPlayer] 音频播放结束,总时长:",this.audioContext.duration,"秒,播放到:",this.audioContext.currentTime,"秒"),this.isAudioPlaying=!1,this.audioEnded=!0,this.pausedBySilence=!1,this.videoEndedWaitingAudio=!1,this.stopVideoLoop();const i=Number(this.audioContext.currentTime)||0,e=Math.max(i,Number(this.lastAudioTime)||0),t=Number(this.audioDuration)||Number(this.audioContext.duration)||0,o=t>0&&(e>=t-.6||e/t>=.95),s=this.videoDuration&&this.lastVideoTime>=this.videoDuration-.3;this.videoContext&&(o||s)?(console.log("[VideoPlayer] 音频结束,联动停止视频。audioEndedForSure=",o,"videoNearEnd=",s),this.videoWaiting=!1,this.userPaused=!0,this.pausedByAudioEnd=!0,this.stopPlaybackWatchdog(),this.videoContext.pause(),setTimeout((()=>{this.videoContext&&this.audioEnded&&this.pausedByAudioEnd&&this.videoContext.pause&&this.videoContext.pause()}),180),this.isVideoPlaying=!1):console.log("[VideoPlayer] 音频 onEnded 触发但无法确认已到结尾,跳过联动停止视频。audioDur=",t,"audioCur=",i,"lastAudioTime=",this.lastAudioTime)}))},fetchSilenceSegments(){if(!this.audioUrl)return;const e=i.index.getStorageSync("userId")||"",t=i.index.getStorageSync("token")||"";t&&i.index.request({url:`${this.API_BASE}/api/video/silence-detect`,method:"POST",timeout:12e4,header:{"X-User-Id":e,Authorization:t?`Bearer ${t}`:"","Content-Type":"application/json"},data:{audioUrl:this.audioUrl},success:i=>{var e,t,o,s,d;if(!(200===i.statusCode&&(!0===(null==(e=i.data)?void 0:e.success)||"true"===(null==(t=i.data)?void 0:t.success)||1===(null==(o=i.data)?void 0:o.success)||"1"===(null==(s=i.data)?void 0:s.success))))return void console.warn("[VideoPlayer] 静音检测失败:",i.data);const a=Array.isArray(null==(d=i.data)?void 0:d.segments)?i.data.segments:[];this.silenceSegments=a.map((i=>({start:Number(i.start)||0,end:Number(i.end)||0}))).filter((i=>i.end>i.start)).sort(((i,e)=>i.start-e.start)),this.silenceLoaded=!0,console.log("[VideoPlayer] 静音区间数量:",this.silenceSegments.length)},fail:i=>{console.error("[VideoPlayer] 静音检测请求失败:",i)}})},handleAudioTimeUpdate(i){if(!this.videoContext||!this.hasAudio)return;if(!this.enableSilencePause)return;if(!this.silenceLoaded||0===this.silenceSegments.length)return;if(this.audioEnded)return;let e=!1;for(const t of this.silenceSegments){if(i>=t.start&&i{this.loadVideo()}))},onVideoError(e){console.error("[VideoPlayer] 视频加载失败:",e),e&&e.detail&&e.detail.errMsg&&String(e.detail.errMsg);const t=e&&e.detail&&void 0!==e.detail.errCode&&null!==e.detail.errCode?String(e.detail.errCode):"",o=this.localVideoPath||this.videoUrl||"";if(this.videoWaiting=!1,this.videoEnded||this.pausedByAudioEnd)console.log("[VideoPlayer] 视频已结束,忽略错误事件,不重试");else if(this.videoDuration>0&&this.lastVideoTime>=this.videoDuration-1)console.log("[VideoPlayer] 视频已播放到结尾,忽略错误事件,不重试");else{if("undefined"!=typeof plus&&!this.appFallbackTriggered&&o===this.videoUrl)return console.log("[VideoPlayer] App网络直连播放失败,切换为下载兜底"),this.appFallbackTriggered=!0,void this.downloadForPlaybackAndCache();if(this.retryCount{if(this.videoEnded||this.pausedByAudioEnd)console.log("[VideoPlayer] 重试前检测到视频已结束,取消重试");else if(this.videoDuration>0&&this.lastVideoTime>=this.videoDuration-1)console.log("[VideoPlayer] 重试前检测到视频已播放到结尾,取消重试");else{if(this.cacheKey)try{i.index.removeStorageSync(this.cacheKey)}catch(e){}this.isRestarting=!0,this.isVideoPlaying=!1,this.videoWaiting=!1,this.localVideoPath=this.videoUrl,this.isVideoReady=!0,this.$nextTick((()=>{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{!this.videoContext||this.userPaused||this.videoEnded||this.videoContext.play&&this.videoContext.play(),setTimeout((()=>{this.isRestarting=!1}),800)}),100)}))}}),1e3*this.retryCount);this.hasVideoError=!0,this.videoErrorMessage=t?`错误代码: ${t}`:"网络连接失败或视频格式不支持"}},onVideoLoadedMetadata(i){i&&i.detail&&i.detail.duration&&(this.videoDuration=i.detail.duration,console.log("[VideoPlayer] 视频时长:",this.videoDuration,"秒")),this.videoWaiting=!1},onVideoPlay(){if(console.log("[VideoPlayer] 视频开始播放"),this.hasVideoError){console.log("[VideoPlayer] 视频加载失败,阻止播放");try{this.videoContext&&this.videoContext.pause&&this.videoContext.pause()}catch(i){}}else if(this.appNetworkFallbackTimer&&(clearTimeout(this.appNetworkFallbackTimer),this.appNetworkFallbackTimer=null),this.waitingNeedsUserAction=!1,this.waitingTimer&&(clearTimeout(this.waitingTimer),this.waitingTimer=null),this.videoEnded&&this.pausedByAudioEnd){console.log("[VideoPlayer] 视频已结束且被音频结束暂停,阻止继续播放");try{this.videoContext&&this.videoContext.pause&&this.videoContext.pause()}catch(i){}}else{if(this.videoHasStarted=!0,this.isVideoPlaying=!0,this.videoWaiting=!1,this.lastVideoTimeUpdateAt=Date.now(),this.startPlaybackWatchdog(),this.audioEnded&&this.pausedByAudioEnd&&this.videoContext)return console.log("[VideoPlayer] 音频已结束,阻止视频继续播放"),this.videoWaiting=!1,this.userPaused=!0,this.videoContext.pause(),void(this.isVideoPlaying=!1);if(this.hasAudio&&this.audioContext)if(0!==this.audioStartDelaySec||this.audioStarted||this.audioEnded){if(!this.audioReady)return this.pendingAudioStart=!0,void console.log("[VideoPlayer] 音频未就绪,等待音频就绪后在指定延迟点播放");!this.audioStarted||this.isAudioPlaying||this.audioEnded||(console.log("[VideoPlayer] 恢复音频播放,当前位置:",this.audioContext.currentTime,"秒"),this.audioContext.play())}else{if(this.audioReady){const i=Math.max(0,this.lastVideoTime||0);return console.log("[VideoPlayer] 无延迟模式:视频开始播放,启动音频,seek=",i),void this.startAudioFromVideoTime(i)}this.pendingAudioStart=!0}}},onVideoPause(){if(console.log("[VideoPlayer] 视频暂停"),!this.isLoopingRestart)return this.videoWaiting||!this.userPaused?(console.log("[VideoPlayer] 非用户暂停(可能缓冲/系统暂停),不联动暂停音频"),void(this.isVideoPlaying=!1)):void(this.audioContext&&this.hasAudio&&this.isAudioPlaying&&(console.log("[VideoPlayer] 暂停音频,当前位置:",this.audioContext.currentTime,"秒"),this.audioPauseTime=this.audioContext.currentTime,this.audioContext.pause()))},onVideoWaiting(){const i=Date.now();if(this.isVideoPlaying&&this.lastVideoTimeUpdateAt&&i-this.lastVideoTimeUpdateAt<500)return void console.log("[VideoPlayer] 视频正在播放中,忽略偶发 waiting 事件");if(this.videoWaiting=!0,this.waitingNeedsUserAction=!1,this.waitingSince=i,console.log("[VideoPlayer] 视频缓冲中(waiting),lastVideoTime=",this.lastVideoTime),!this.videoContext)return;if(this.waitingTimer&&(clearTimeout(this.waitingTimer),this.waitingTimer=null),this.waitingTimer=setTimeout((()=>{if(this.waitingTimer=null,!this.videoWaiting)return;if(!this.videoContext)return;if(this.userPaused)return;if(this.videoEnded)return;if(!this.audioInVideo&&this.hasAudio&&!this.audioEnded)return void(this.waitingNeedsUserAction=!0);const i=Number(this.lastVideoTime)||0,e=Math.max(0,i-.3);console.log("[VideoPlayer] waiting超时自动恢复: seekTo=",e);try{this.videoContext.seek&&this.videoContext.seek(e)}catch(t){}setTimeout((()=>{this.videoContext&&this.videoContext.play&&this.videoContext.play()}),120)}),6e3),"undefined"!=typeof plus&&!this.videoHasStarted&&!this.appFallbackTriggered&&this.localVideoPath===this.videoUrl)return console.log("[VideoPlayer] App首帧 waiting,立即切换为下载兜底"),this.appFallbackTriggered=!0,void this.downloadForPlaybackAndCache();if(this.videoEnded)return;if(this.videoEndedWaitingAudio&&this.hasAudio&&!this.audioEnded)return void console.log("[VideoPlayer] 视频已结束且音频未结束:忽略 waiting");if(!this.audioInVideo&&this.hasAudio&&!this.audioEnded)return void console.log("[VideoPlayer] 存在音频且未结束,跳过 waiting 自动恢复,以避免音频被系统 stop");const e=Date.now();this.lastWaitingRecoverAt&&e-this.lastWaitingRecoverAt<1500||(this.lastWaitingRecoverAt=e,setTimeout((()=>{this.videoContext&&(this.userPaused||this.videoEnded||this.pausedBySilence||this.audioEnded||(console.log("[VideoPlayer] waiting后尝试恢复视频播放"),this.videoContext.play()))}),600))},onVideoEnded(){if(console.log("[VideoPlayer] 视频播放结束","lastVideoTime=",this.lastVideoTime,"videoDuration=",this.videoDuration,"audioEnded=",this.audioEnded,"isRestarting=",this.isRestarting),this.isRestarting)return void console.log("[VideoPlayer] 正在重新播放,忽略 ended 事件");if(this.hasVideoError||this.retryCount>=this.maxRetryCount)return console.log("[VideoPlayer] 视频加载失败或重试次数已达上限,阻止自动重播"),this.isVideoPlaying=!1,this.videoEnded=!0,void this.stopPlaybackWatchdog();if(this.isVideoPlaying=!1,this.videoEnded=!0,this.stopPlaybackWatchdog(),this.audioInVideo){this.videoWaiting=!1,this.userPaused=!0,this.pausedByAudioEnd=!0,this.audioEnded=!0,this.stopPlaybackWatchdog(),this.stopVideoLoop();try{this.videoContext&&this.videoContext.seek&&this.videoDuration&&this.videoContext.seek(Math.max(0,Number(this.videoDuration)-.05))}catch(s){}return void(this.videoContext&&this.videoContext.pause&&this.videoContext.pause())}if(this.hasAudio&&this.audioContext&&!this.audioEnded){this.videoEndedWaitingAudio=!0,this.videoWaiting=!1,console.log("[VideoPlayer] 音频未结束:视频停在末帧等待音频播完(不循环不重播)");try{this.videoContext&&this.videoContext.seek&&this.videoDuration&&this.videoContext.seek(Math.max(0,Number(this.videoDuration)-.05))}catch(s){}return void(this.videoContext&&this.videoContext.pause&&this.videoContext.pause())}if(this.hasAudio&&this.audioContext&&!this.audioEnded){const i=Number(this.audioContext.currentTime)||0,e=Math.max(i,Number(this.lastAudioTime)||0),t=Number(this.audioDuration)||Number(this.audioContext.duration)||0;if(t>0&&(e>=t-.6||e/t>=.95))return console.log("[VideoPlayer] 检测到音频已到结尾(兜底推断),停止视频循环并暂停视频。audioCurStable=",e,"audioDur=",t),this.audioEnded=!0,this.stopVideoLoop(),void(this.videoContext&&this.videoContext.pause&&this.videoContext.pause())}const e=Number(this.videoDuration)||0,t=Number(this.lastVideoTime)||0,o=!e&&t>0&&t<3||e>0&&t>0&&t{this.videoContext||(this.videoContext=i.index.createVideoContext("videoPlayer",this)),setTimeout((()=>{this.videoContext&&this.videoContext.play&&this.videoContext.play()}),120)}))}},onTimeUpdate(i){if(!i||!i.detail)return;const e=i.detail.currentTime;if(this.lastVideoTime=e,this.lastVideoTimeUpdateAt=Date.now(),!this.videoHasStarted&&(Number(e)||0)>0&&(this.videoHasStarted=!0),!this.userPaused&&(Number(e)||0)>0&&(this.isVideoPlaying=!0),this.videoWaiting&&(console.log("[VideoPlayer] timeupdate 清除 waiting 状态,currentTime=",e),this.videoWaiting=!1,this.waitingNeedsUserAction=!1),this.waitingTimer&&(clearTimeout(this.waitingTimer),this.waitingTimer=null),this.isVideoPlaying||this.userPaused||(this.isVideoPlaying=!0),this.hasAudio&&this.audioContext&&!this.audioStarted&&!this.audioEnded&&e>=this.audioStartDelaySec){if(this.audioReady){const i=Math.max(0,(e||0)-(this.audioStartDelaySec||0));return console.log("[VideoPlayer] 视频到达延迟点,开始播放音频,seek=",i),void this.startAudioFromVideoTime(i)}this.pendingAudioStart=!0}},startVideoLoop(){this.videoLoopTimer||console.log("[VideoPlayer] 视频循环已启动")},stopVideoLoop(){this.videoLoopTimer&&(clearInterval(this.videoLoopTimer),this.videoLoopTimer=null,console.log("[VideoPlayer] 视频循环已停止"))}}};const o=i._export_sfc(t,[["render",function(e,t,o,s,d,a){return i.e({a:i.o(((...i)=>a.goBack&&a.goBack(...i))),b:i.t(d.videoTitle),c:a.videoError},a.videoError?{d:i.t(a.errorMessage),e:i.o(((...i)=>a.retryVideo&&a.retryVideo(...i))),f:i.o(((...i)=>a.goBack&&a.goBack(...i)))}:{},{g:a.showLoadingOverlay&&!a.videoError},a.showLoadingOverlay&&!a.videoError?i.e({h:i.t(a.loadingText),i:a.loadingHint},a.loadingHint?{j:i.t(a.loadingHint)}:{},{k:d.isVideoDownloading&&d.downloadProgress>0},d.isVideoDownloading&&d.downloadProgress>0?{l:d.downloadProgress+"%"}:{},{m:i.o(((...i)=>a.handleLoadingOverlayClick&&a.handleLoadingOverlayClick(...i)))}):{},{n:d.localVideoPath},d.localVideoPath?{o:d.localVideoPath,p:!!d.audioUrl,q:i.o(((...i)=>a.onVideoError&&a.onVideoError(...i))),r:i.o(((...i)=>a.onVideoPlay&&a.onVideoPlay(...i))),s:i.o(((...i)=>a.onVideoPause&&a.onVideoPause(...i))),t:i.o(((...i)=>a.onVideoWaiting&&a.onVideoWaiting(...i))),v:i.o(((...i)=>a.onVideoEnded&&a.onVideoEnded(...i))),w:i.o(((...i)=>a.onTimeUpdate&&a.onTimeUpdate(...i))),x:i.o(((...i)=>a.onVideoLoadedMetadata&&a.onVideoLoadedMetadata(...i)))}:{},{y:d.localVideoPath&&!a.showLoadingOverlay},d.localVideoPath&&!a.showLoadingOverlay?i.e({z:a.shouldShowPlayButton},(a.shouldShowPlayButton,{}),{A:i.o(((...i)=>a.handleTogglePlay&&a.handleTogglePlay(...i)))}):{})}],["__scopeId","data-v-60f68b50"]]);wx.createPage(o);
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxml b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxml
index f525620..885d2da 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxml
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxml
@@ -1 +1 @@
-⚠️视频加载失败{{d}}重新加载返回{{h}}{{j}}
\ No newline at end of file
+⚠️视频加载失败{{d}}重新加载返回{{h}}{{j}}AI生成
\ No newline at end of file
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxss b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxss
index 074c329..5754827 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxss
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/pages/video-player/video-player.wxss
@@ -1 +1 @@
-.player-container.data-v-d19743cf{width:100%;height:100vh;background:#000;display:flex;flex-direction:column;position:relative}.loading-overlay.data-v-d19743cf{position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.8);display:flex;align-items:center;justify-content:center;z-index:999}.loading-content.data-v-d19743cf{text-align:center;display:flex;flex-direction:column;align-items:center;gap:20rpx}.loading-spinner.data-v-d19743cf{width:80rpx;height:80rpx;border:6rpx solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin-d19743cf 1s linear infinite}@keyframes spin-d19743cf{to{transform:rotate(360deg)}}.loading-text.data-v-d19743cf{color:#fff;font-size:32rpx;font-weight:700}.loading-hint.data-v-d19743cf{color:rgba(255,255,255,.7);font-size:24rpx;margin-top:10rpx}.progress-bar.data-v-d19743cf{width:400rpx;height:8rpx;background:rgba(255,255,255,.2);border-radius:4rpx;overflow:hidden;margin-top:20rpx}.progress-fill.data-v-d19743cf{height:100%;background:linear-gradient(90deg,#667eea,#764ba2);border-radius:4rpx;transition:width .3s ease}.header.data-v-d19743cf{background:rgba(0,0,0,.8);padding:60rpx 40rpx 20rpx;padding-top:calc(60rpx + constant(safe-area-inset-top));padding-top:calc(60rpx + env(safe-area-inset-top));display:flex;justify-content:space-between;align-items:center;color:#fff;position:absolute;top:0;left:0;right:0;z-index:100}.back-btn.data-v-d19743cf{font-size:32rpx;padding:16rpx;cursor:pointer}.title.data-v-d19743cf{font-size:32rpx;font-weight:700;flex:1;text-align:center}.placeholder.data-v-d19743cf{width:80rpx}.video-player.data-v-d19743cf{width:100%;height:100vh;background:#000}.play-overlay.data-v-d19743cf{position:absolute;top:0;left:0;right:0;bottom:0;z-index:50;display:flex;align-items:center;justify-content:center}.play-button.data-v-d19743cf{width:140rpx;height:140rpx;border-radius:999rpx;background:rgba(0,0,0,.45);position:relative}.play-button.data-v-d19743cf:after{content:"";position:absolute;top:50%;left:54%;transform:translate(-50%,-50%);width:0;height:0;border-top:22rpx solid transparent;border-bottom:22rpx solid transparent;border-left:34rpx solid #fff}.error-overlay.data-v-d19743cf{position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.95);display:flex;align-items:center;justify-content:center;z-index:1000}.error-content.data-v-d19743cf{text-align:center;padding:60rpx;display:flex;flex-direction:column;align-items:center;gap:24rpx}.error-icon.data-v-d19743cf{font-size:120rpx;margin-bottom:20rpx}.error-title.data-v-d19743cf{color:#fff;font-size:36rpx;font-weight:700}.error-message.data-v-d19743cf{color:rgba(255,255,255,.7);font-size:28rpx;line-height:1.6}.error-actions.data-v-d19743cf{display:flex;gap:24rpx;margin-top:40rpx}.error-btn.data-v-d19743cf{padding:24rpx 48rpx;border-radius:12rpx;font-size:28rpx;cursor:pointer;transition:all .3s ease}.retry-btn.data-v-d19743cf{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff}.retry-btn.data-v-d19743cf:active{transform:scale(.95);opacity:.8}.back-btn-error.data-v-d19743cf{background:rgba(255,255,255,.1);color:#fff;border:2rpx solid rgba(255,255,255,.3)}.back-btn-error.data-v-d19743cf:active{transform:scale(.95);background:rgba(255,255,255,.15)}
+.player-container.data-v-60f68b50{width:100%;height:100vh;background:#000;display:flex;flex-direction:column;position:relative}.loading-overlay.data-v-60f68b50{position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.8);display:flex;align-items:center;justify-content:center;z-index:999}.loading-content.data-v-60f68b50{text-align:center;display:flex;flex-direction:column;align-items:center;gap:20rpx}.loading-spinner.data-v-60f68b50{width:80rpx;height:80rpx;border:6rpx solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin-60f68b50 1s linear infinite}@keyframes spin-60f68b50{to{transform:rotate(360deg)}}.loading-text.data-v-60f68b50{color:#fff;font-size:32rpx;font-weight:700}.loading-hint.data-v-60f68b50{color:rgba(255,255,255,.7);font-size:24rpx;margin-top:10rpx}.progress-bar.data-v-60f68b50{width:400rpx;height:8rpx;background:rgba(255,255,255,.2);border-radius:4rpx;overflow:hidden;margin-top:20rpx}.progress-fill.data-v-60f68b50{height:100%;background:linear-gradient(90deg,#667eea,#764ba2);border-radius:4rpx;transition:width .3s ease}.header.data-v-60f68b50{background:rgba(0,0,0,.8);padding:60rpx 40rpx 20rpx;padding-top:calc(60rpx + constant(safe-area-inset-top));padding-top:calc(60rpx + env(safe-area-inset-top));display:flex;justify-content:space-between;align-items:center;color:#fff;position:absolute;top:0;left:0;right:0;z-index:100}.back-btn.data-v-60f68b50{font-size:32rpx;padding:16rpx;cursor:pointer}.title.data-v-60f68b50{font-size:32rpx;font-weight:700;flex:1;text-align:center}.placeholder.data-v-60f68b50{width:80rpx}.video-player.data-v-60f68b50{width:100%;height:100vh;background:#000}.play-overlay.data-v-60f68b50{position:absolute;top:0;left:0;right:0;bottom:0;z-index:50;display:flex;align-items:center;justify-content:center}.play-button.data-v-60f68b50{width:140rpx;height:140rpx;border-radius:999rpx;background:rgba(0,0,0,.45);position:relative}.play-button.data-v-60f68b50:after{content:"";position:absolute;top:50%;left:54%;transform:translate(-50%,-50%);width:0;height:0;border-top:22rpx solid transparent;border-bottom:22rpx solid transparent;border-left:34rpx solid #fff}.error-overlay.data-v-60f68b50{position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.95);display:flex;align-items:center;justify-content:center;z-index:1000}.error-content.data-v-60f68b50{text-align:center;padding:60rpx;display:flex;flex-direction:column;align-items:center;gap:24rpx}.error-icon.data-v-60f68b50{font-size:120rpx;margin-bottom:20rpx}.error-title.data-v-60f68b50{color:#fff;font-size:36rpx;font-weight:700}.error-message.data-v-60f68b50{color:rgba(255,255,255,.7);font-size:28rpx;line-height:1.6}.error-actions.data-v-60f68b50{display:flex;gap:24rpx;margin-top:40rpx}.error-btn.data-v-60f68b50{padding:24rpx 48rpx;border-radius:12rpx;font-size:28rpx;cursor:pointer;transition:all .3s ease}.retry-btn.data-v-60f68b50{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff}.retry-btn.data-v-60f68b50:active{transform:scale(.95);opacity:.8}.back-btn-error.data-v-60f68b50{background:rgba(255,255,255,.1);color:#fff;border:2rpx solid rgba(255,255,255,.3)}.back-btn-error.data-v-60f68b50:active{transform:scale(.95);background:rgba(255,255,255,.15)}.ai-tag.data-v-60f68b50{position:absolute;top:140rpx;right:24rpx;z-index:100;background:rgba(0,0,0,.6);padding:8rpx 20rpx;border-radius:30rpx;-webkit-backdrop-filter:blur(10rpx);backdrop-filter:blur(10rpx)}.ai-tag-text.data-v-60f68b50{font-size:22rpx;color:#fff;font-weight:500}
diff --git a/frontend-ai/unpackage/dist/build/mp-weixin/project.private.config.json b/frontend-ai/unpackage/dist/build/mp-weixin/project.private.config.json
index 2941c87..132e29a 100644
--- a/frontend-ai/unpackage/dist/build/mp-weixin/project.private.config.json
+++ b/frontend-ai/unpackage/dist/build/mp-weixin/project.private.config.json
@@ -1,6 +1,6 @@
{
"libVersion": "3.12.1",
- "projectname": "mp-weixin",
+ "projectname": "frontend-ai",
"setting": {
"urlCheck": true,
"coverView": true,