<template>
	<view>
		<view class="body">
			<view class="body_content">
				<uni-nav-bar fixed statusBar background-color="transparent" :border="false" color="#ffffff" right-icon="gear"
					@clickRight="setUp" :showMenuButtonWidth="true">
					<!-- 左侧插槽 -->
					<template v-slot:left>
						<view class="custom_left">
							<view class="left_content">
								<image class="left_return" @click="back" src="/static/images/chat_return.png" mode="widthFix">
								</image>
								<view class="left_module">
									<image class="left_avatar"
										:src="loverBasicList.image_url ? loverBasicList.image_url : '/static/images/avatar.png'"
										mode="aspectFill"></image>
									<view class="left_count">
										<view class="left_dight faj" @click="tointimacy">
											<image src="/static/images/intimacy_logo.png" mode="widthFix"></image>
											<text class="faj">{{ level ? level : '0' }}</text>
										</view>
									</view>
								</view>
							</view>
						</view>
					</template>
				</uni-nav-bar>
				
				<!-- Tab 栏 -->
				<view class="tab-bar">
					<scroll-view class="tab-scroll" scroll-x="true" :scroll-left="tabScrollLeft" scroll-with-animation>
						<view class="tab-list">
							<view 
								v-for="(tab, index) in tabList" 
								:key="index" 
								class="tab-item" 
								:class="{ 'active': currentTab === index }"
								@click="switchTab(index)">
								<text class="tab-text">{{ tab.name }}</text>
								<view v-if="currentTab === index" class="tab-indicator"></view>
							</view>
						</view>
					</scroll-view>
				</view>
				
				<!-- 聊天内容区域 -->
				<view v-show="currentTab === 0" class="tab-content">
				<image class="back"
					:src="loverBasicList.image_url ? loverBasicList.image_url : 'https://nvlovers.oss-cn-qingdao.aliyuncs.com/uploads/20251226/39c6f8899c15f60fc59207835f95e07a.png'"
					mode="aspectFill"></image>
				<scroll-view class="list" scroll-y="true" :scroll-top="scrollTop" scroll-with-animation="true"
					@scrolltoupper="onScrollToUpper">
					<!-- 聊天消息列表 -->
					<view class="message-list">
						<!-- 动态渲染消息列表 -->
						<view v-for="(item, index) in sessionInitList.messages" :key="index" class="message-item"
							:class="{ 'left-message': item.role === 'lover', 'right-message': item.role !== 'lover' }">

							<image class="avatar" :src="item.role === 'lover'
                                ? (loverBasicList.image_url ? loverBasicList.image_url : '/static/images/avatar.png')
                                : (myavatar ? myavatar : '/static/images/avatar.png')" mode="aspectFill">
							</image>
							<view class="message-content">
								<view class="message-bubble">
									<!-- 视频消息特殊处理 -->
									<view v-if="isVideoMessage(item.content)" class="video-message-container">
										<!-- 提取并显示文本部分 -->
										<view class="message-text">{{ extractTextFromVideoMessage(item.content) }}</view>
										<!-- 视频部分 -->
										<view class="message-video-container">
											<!-- #ifdef APP -->
											<view v-html="item.contentVideo"></view>
											<!-- #endif -->
											 <!-- #ifdef MP -->
											 <video class="message-video" :src="extractVideoUrlFromMessage(item.content)"
												@play="onVideoPlay(item.id)" @pause="onVideoPause(item.id)"
												@longpress="onVideoLongPress(item)"></video>
											 <!-- #endif -->
											
												<!-- {{ item.contentVideo }} -->
										</view>
									</view>
									<view v-else-if="isVideoMessage1(item.content)" class="video-message-container">
										<!-- 提取并显示文本部分 -->
										<view class="message-text">{{ item.content }}</view>
										<!-- 视频部分 -->
										<view class="">
											<uni-icons class="spinner-cycle-box" type="spinner-cycle" size="28"></uni-icons>
										</view>
									</view>
									<!-- 普通图片消息 -->
									<view v-else-if="isImageUrl(item.content)" class="message-image-container">
										<image class="message-image" :src="item.content" mode="aspectFit"
											@click="previewImage(item.content)"></image>
									</view>
									<!-- 其他视频URL消息（非格式化消息） -->
									<view v-else-if="isVideoUrl(item.content)" class="message-video-container">
										<video class="message-video" :src="item.content" @play="onVideoPlay(item.id)"
											@pause="onVideoPause(item.id)" @longpress="onVideoLongPress(item)"></video>
									</view>
									<!-- 普通文本消息 -->
									<view v-else class="message-text">{{ item.content }}</view>

									<!-- 语音容器独立存在，仅对lover角色显示 -->
									<view
										v-if="item.role === 'lover' && !isVideoMessage(item.content) && !isVideoMessage1(item.content) && !isVideoUrl(item.content)"
										class="voice-container" @click="playVoice(item.id)">
										<view class="voice-wave"
											:class="{ 'playing': currentPlayingId === item.id, 'black-wave': currentPlayingId !== item.id }">
											<view class="wave-bar wave-bar-1"></view>
											<view class="wave-bar wave-bar-2"></view>
											<view class="wave-bar wave-bar-3"></view>
											<view class="wave-bar wave-bar-4"></view>
											<view class="wave-bar wave-bar-5"></view>
										</view>
									</view>
								</view>
							</view>
						</view>
					</view>
				</scroll-view>
				<!-- 底部按钮区域 -->
				<view class="textbox fa">
					<image class="textbox_voice" src="/static/images/chat_voice.png" mode="widthFix" @click="alertState = true">
					</image>
					<view class="btn_content" style="display: flex;align-items: center;">
						<view class="btn_module faj" @click="chatSingClick(1)">
							<image class="textbox_image" src="/static/images/chat_a6.png" mode="widthFix"></image>
						</view>
						<view class="btn_module faj" @click="chatSingClick(2)">
							<image class="textbox_image" style="background-color: #fff;border-radius: 10rpx;"
								src="/static/images/chat_a7.png" mode="widthFix"></image>
						</view>
					</view>
					<view class="textbox_content fa f1">
						<input class="f1" v-model="form.message" placeholder="与她聊天" placeholder-class="textbox_input"
							@confirm="sendMessage" confirm-type="send" :cursor-spacing="15" />
						<image class="textbox_add" src="/static/images/chat_add.png" mode="widthFix" @click="toggleBottomBtns">
						</image>
					</view>
					<view class="textbox_send faj" @click="sendingMessage">发送</view>
				</view>
				<view class="black"></view>
			</view>
			<!-- 底部按钮区域，通过 v-show 控制显示/隐藏 -->
			<view class="btn fa sb" v-if="showBottomBtns">
				<view class="btn_content">
					<view class="btn_module faj" @click="pictureClick">
						<image class="btn_image" src="/static/images/chat_a1.png" mode="widthFix"></image>
						<image class="btn_lock" v-if="level < 3" src="/static/images/chat_lock.png" mode="widthFix">
						</image>
					</view>
					<view class="btn_title">照片</view>
				</view>
				<view class="btn_content" @click="togift">
					<view class="btn_module faj">
						<image class="btn_image" src="/static/images/chat_a2.png" mode="widthFix"></image>
					</view>
					<view class="btn_title">礼物</view>
				</view>
				<view class="btn_content">
					<view class="btn_module faj" @click="tochatPhone">
						<image class="btn_image" src="/static/images/chat_a3.png" mode="widthFix"></image>
						<image class="btn_lock" v-if="level < 2" src="/static/images/chat_lock.png" mode="widthFix">
						</image>
					</view>
					<view class="btn_title">通话</view>
				</view>
				<!-- <view class="btn_content">
                    <view class="btn_module faj" @click="tochatDiary">
                        <image class="btn_image" src="/static/images/chat_a4.png" mode="widthFix"></image>
                        <image class="btn_lock" v-if="level < 5" src="/static/images/chat_lock.png" mode="widthFix">
                        </image>
                    </view>
                    <view class="btn_title">日记</view>
                </view> -->
				<!-- <view class="btn_content" @click="chatSingClick">
                    <view class="btn_module faj">
                        <image class="btn_image" src="/static/images/chat_a6.png" mode="widthFix"></image>
                        <image class="btn_lock" v-if="level < 5" src="/static/images/chat_lock.png" mode="widthFix">
                        </image>
                    </view>
                    <view class="btn_title">载歌载舞</view>
                </view> -->
			</view>
		</view>
		
		<!-- 唱歌页面 -->
		<view v-show="currentTab === 1" class="tab-content">
			<view class="feature-page">
				<view class="feature-title">唱歌功能</view>
				<view class="feature-desc">让她为你唱一首歌</view>
				<view class="song-list">
					<view class="song-item" v-for="(item,index) in singSongsList" :key="index" @click="selectSongDirect(item)">
						<view class="song-info">
							<text class="song-title">{{item.title}}</text>
						</view>
						<image class="song-icon" src="/static/images/chat_a6.png" mode="widthFix"></image>
					</view>
				</view>
			</view>
		</view>
		
		<!-- 跳舞页面 -->
		<view v-show="currentTab === 2" class="tab-content">
			<view class="feature-page">
				<view class="feature-title">跳舞功能</view>
				<view class="feature-desc">让她为你跳一支舞</view>
				<view class="dance-input">
					<input type="text" v-model="dancePrompt" placeholder="描述你想看的舞蹈动作" class="dance-input-field" />
					<view class="dance-btn" @click="requestDance">生成舞蹈</view>
				</view>
			</view>
		</view>
		
		<!-- 换服装页面 -->
		<view v-show="currentTab === 3" class="tab-content">
			<view class="feature-page">
				<view class="feature-title">换服装</view>
				<view class="feature-desc">为她挑选不同的服装</view>
				<view class="outfit-grid">
					<view class="outfit-item" v-for="i in 6" :key="i">
						<image class="outfit-image" src="/static/images/avatar.png" mode="aspectFill"></image>
						<text class="outfit-name">服装 {{i}}</text>
					</view>
				</view>
			</view>
		</view>
		
		<!-- 刷礼物页面 -->
		<view v-show="currentTab === 4" class="tab-content">
			<view class="feature-page">
				<view class="feature-title">送礼物</view>
				<view class="feature-desc">送她一份心意</view>
				<view class="gift-grid">
					<view class="gift-item" v-for="i in 8" :key="i" @click="sendGift(i)">
						<image class="gift-image" src="/static/images/chat_a2.png" mode="widthFix"></image>
						<text class="gift-name">礼物 {{i}}</text>
						<text class="gift-price">{{i * 10}} 金币</text>
					</view>
				</view>
			</view>
		</view>
		
		<!-- 商城页面 -->
		<view v-show="currentTab === 5" class="tab-content">
			<view class="feature-page">
				<view class="feature-title">商城</view>
				<view class="feature-desc">购买更多功能和道具</view>
				<view class="shop-list">
					<view class="shop-item" v-for="i in 4" :key="i">
						<view class="shop-info">
							<text class="shop-title">套餐 {{i}}</text>
							<text class="shop-desc">包含多种功能和道具</text>
						</view>
						<view class="shop-price">
							<text class="price-value">¥{{i * 30}}</text>
							<view class="shop-buy-btn">购买</view>
						</view>
					</view>
				</view>
			</view>
		</view>
		
		<!-- 短剧页面 -->
		<view v-show="currentTab === 6" class="tab-content">
			<view class="feature-page">
				<view class="feature-title">短剧</view>
				<view class="feature-desc">观看精彩短剧内容</view>
				<view class="drama-list">
					<view class="drama-item" v-for="i in 3" :key="i">
						<image class="drama-cover" src="/static/images/avatar.png" mode="aspectFill"></image>
						<view class="drama-info">
							<text class="drama-title">短剧标题 {{i}}</text>
							<text class="drama-desc">精彩剧情简介...</text>
							<view class="drama-play-btn">播放</view>
						</view>
					</view>
				</view>
			</view>
		</view>
		
		<!-- 唱歌/跳舞弹框提示 -->
		<view class="alert" v-if="alertState">
			<view class="alert_hide" @click="alertState = false"></view>
			<view v-if="videoState" class="alert_opt fa sb">
				<view class="alert_a1"></view>
				<view class="alert_a2"></view>
				<view class="alert_a3"></view>
				<view class="alert_a4"></view>
				<view class="alert_a5"></view>
				<view class="alert_a5"></view>
				<view class="alert_a4"></view>
				<view class="alert_a3"></view>
				<view class="alert_a2"></view>
				<view class="alert_a1"></view>
			</view>
			<view class="alert_module">
				<view class="alert_title">按住说话</view>
				<view @touchstart='touchStart' @touchend='touchEnd' class="alert_btn faj">
					<image src="../../static/images/chat_text.png" />
				</view>
			</view>
		</view>
		<!-- 唱歌/跳舞弹框提示 -->
		<view class="chatSing faj" v-if="chatSingStats">
			<view class="chatSing_content">
				<image src="/static/images/close.png" mode="widthFix" @click="closechatSing()"></image>
				<view class="chatSing_detail fa">
					<input type="nickchatSing" class="f1" v-model="messageprompt" placeholder="请输入跳舞详情"
						placeholder-class="chatSing_input" />
				</view>
				<view class="chatSing_sure faj"><text class="faj" @click="savechatSing()">确定</text></view>
			</view>
		</view>
		<!-- 歌曲列表 -->
		<view class="chatSing faj" v-if="chatSingStats1">
			<view class="" style="position: relative;background: #FFFFFF;border-radius: 20rpx;padding: 60rpx;">
				<image src="/static/images/close.png" mode="widthFix"
					style="position: absolute;right: 20rpx;top: 20rpx;width: 30rpx;height: 30rpx;"
					@click="chatSingStats1 = false"></image>
				<view class="" style="width: 70vw;max-height: 100vw;overflow: auto;margin-top: 40rpx;">
					<view class="fa" style="justify-content: space-between;margin-bottom: 30rpx;"
						v-for="(item,index) in singSongsList" :key="index" @click="selectSong(item,index)">
						<view class="" style="font-size: 28rpx;">{{item.title}}</view>
						<image style="width: 40rpx;height: 40rpx;"
							:src="item.id == songId?'/static/images/selectA.png':'/static/images/select.png'" mode=""></image>
					</view>
				</view>

				<view class="chatSing_sure faj"><text class="faj" @click="savechatSing1()">确定</text></view>
			</view>
		</view>
		<view class="bottom" v-if="bottomStats">
			<view class="bottom_content">
				<view class="bottom_title">发布动态
					<image src="/static/images/close.png" @click="noClick()"></image>
				</view>
				<video class="bottom_video faj" :src="currentVideoUrl ? currentVideoUrl : ''" mode="widthFix"
					v-if="currentVideoUrl"></video>
				<view class="bottom_module">
					<input class="f1" v-model="dynamicShareform.content" placeholder="请输入动态内容" placeholder-class="bottom_input" />
				</view>
				<view class="bottom_item fa sb">
					<view class="bottom_btn faj" @click="noClick()">取消</view>
					<view class="bottom_btn faj" @click="yesClick()">确认</view>
				</view>
			</view>
		</view>
		<ai ref="aiRef" @renderText="renderText" />
	</view>
</template>

<script>
	import {
		SessionInit,
		SessionSend,
		AddBond,
		SessionMessages,
		ChatMessagesTts,
		SessionSendImage,
		DanceGenerate,
		DanceGenerateTask,
		DynamicShare,
		SingSongs,
		SingGenerate,
		SingGenerateTask
	} from '@/utils/api.js'
	import notHave from '@/components/not-have.vue';
	import topSafety from '@/components/top-safety.vue';
	import ai from '@/components/ai.vue';
	//#ifdef MP-WEIXIN
	const plugin = requirePlugin('WechatSI');
	console.log('plugin:', plugin)
	const manager = plugin.getRecordRecognitionManager();
	// #endif


	export default {
		components: {
			notHave,
			topSafety,
			ai,
		},
		data() {
			return {
				// Tab 相关
				currentTab: 0,
				tabScrollLeft: 0,
				tabList: [
					{ name: '聊天', icon: '' },
					{ name: '唱歌', icon: '' },
					{ name: '跳舞', icon: '' },
					{ name: '换服装', icon: '' },
					{ name: '刷礼物', icon: '' },
					{ name: '商城', icon: '' },
					{ name: '短剧', icon: '' }
				],
				dancePrompt: '', // 跳舞描述
				// 可以在这里添加聊天数据
				// messages: [],
				loverBasicList: uni.getStorageSync('loverBasicList'),
				myavatar: uni.getStorageSync('userinfo').avatar,
				level: uni.getStorageSync('userinfo').level,
				getMenuInfoList: '',
				form: {
					message: '',
					session_id: '',
				},
				addBondform: {
					type: '',
					num: '',
				},
				sessionMessagesform: {
					session_id: '',
					page: 1,
					size: 15,
				},
				chatMessagesTtsform: {
					id: '',
				},
				sessionSendImageform: {
					session_id: '',
					image_url: '',
				},
				dynamicShareform: {
					source_message_id: '',
					content: '',
				},
				sessionInitList: '',
				scrollTop: 0,
				scrollTimer: null,
				showBottomBtns: false, // 控制底部按钮显示/隐藏
				loadingMore: false, // 控制是否正在加载更多
				noMoreData: false, // 控制是否还有更多数据
				lastScrollTop: 0, // 记录上次滚动位置
				currentAudioContext: null, // 添加当前音频上下文实例
				recorderManager: null, // 录音管理器
				isRecording: false, // 是否正在录音
				voiceStartTime: 0, // 录音开始时间
				voiceCancel: false, // 是否取消录音
				chatMessagesTtsList: '',
				currentPlayingId: null, // 当前正在播放的语音ID
				isPlaying: false, // 播放状态
				alertState: false,
				onState: true,
				videoState: false,
				shouldAutoScroll: true, // 添加自动滚动标志
				chatSingStats: false, //跳舞
				chatSingStats1: false, //唱歌
				messageprompt: '',
				bottomStats: false,
				currentVideoUrl: '', // 添加当前视频URL变量
				singSongsList: [], //歌曲列表
				songId: 0
			}
		},
		onLoad() {
			// #ifdef MP
			this.initSI();
			// #endif
		},
		onShow() {
			// #ifdef MP-WEIXIN
			this.getMenuInfo()
			// #endif
			this.sessionInit() //恋人聊天初始化
			this.initRecorder() //初始化录音管理器
			this.getSingSongs() //歌曲列表
			// this.initAudio()
		},
		onUnload() {
			this.stopCurrentAudio();
		},

		onHide() {
			this.stopCurrentAudio();
		},
		methods: {
			// Tab 切换方法
			switchTab(index) {
				this.currentTab = index;
				// 计算滚动位置，使当前 tab 居中
				const tabWidth = 120; // 每个 tab 的宽度（rpx）
				const screenWidth = 750; // 屏幕宽度（rpx）
				this.tabScrollLeft = Math.max(0, (index * tabWidth) - (screenWidth / 2) + (tabWidth / 2));
			},
			// 直接选择歌曲并生成
			selectSongDirect(song) {
				this.songId = song.id;
				uni.showLoading({
					title: '生成中...'
				});
				SingGenerate({
					song_id: song.id
				}).then(res => {
					if (res.code == 1) {
						this.getSingGenerateTask(res.data.task_id);
					} else {
						uni.hideLoading();
						uni.showToast({
							title: res.msg,
							icon: 'none'
						});
					}
				});
			},
			// 请求跳舞
			requestDance() {
				if (!this.dancePrompt || !this.dancePrompt.trim()) {
					uni.showToast({
						title: '请输入舞蹈描述',
						icon: 'none'
					});
					return;
				}
				this.messageprompt = this.dancePrompt;
				this.savechatSing();
			},
			// 送礼物
			sendGift(giftId) {
				uni.showToast({
					title: `送出礼物 ${giftId}`,
					icon: 'success'
				});
				// 这里可以调用送礼物的 API
			},
			initAudio() {
				// 销毁旧的音频上下文（如果存在）
				if (this.audioContext) {
					this.audioContext.destroy();
				}
				// 创建新的音频上下文
				this.audioContext = uni.createInnerAudioContext()
				this.audioContext.volume = 1
				// 设置音频源类型
				this.audioContext.srcType = 'auto'
				// 添加音频事件监听
				this.audioContext.onError((err) => {
					console.error('音频播放失败:', err)
					console.error('错误详情:', JSON.stringify(err))
					uni.showToast({
						title: '音频播放失败',
						icon: 'none'
					})
				})
				this.audioContext.onPlay(() => {
					console.log('音频开始播放')
				})
				this.audioContext.onEnded(() => {
					console.log('音频播放结束')
				})
				this.audioContext.onCanplay(() => {
					console.log('音频可以播放了')
				})
			},
			initSI() {
				const that = this;
				// 有新的识别内容返回，则会调用此事件
				manager.onRecognize = function(res) {
					console.log(res);
				};
				// 正常开始录音识别时会调用此事件
				manager.onStart = function(res) {
					console.log('成功开始录音识别', res);
					// 开始录音时-抖动一下手机
					wx.vibrateShort({
						type: 'medium'
					});
				};
				// 识别错误事件
				manager.onError = function(res) {
					console.error('error msg', res);
					const tips = {
						'-30003': '说话时间间隔太短，无法识别语音',
						'-30004': '没有听清，请再说一次~',
						'-30011': '上个录音正在识别中，请稍后尝试',
					};
					const retcode = res?.retcode.toString();
					retcode &&
						wx.showToast({
							title: tips[`${retcode}`],
							icon: 'none',
							duration: 2000,
						});
				};
				//识别结束事件
				manager.onStop = function(res) {
					console.log('..............结束录音', res);
					console.log('录音临时文件地址 -->', res.tempFilePath);
					console.log('录音总时长 -->', res.duration, 'ms');
					console.log('文件大小 --> ', res.fileSize, 'B');
					console.log('语音内容 --> ', res.result);
					if (res.result === '') {
						wx.showModal({
							title: '提示',
							content: '没有听清，请再说一次~',
							showCancel: false,
						});
						return;
					}
					that.form.message = res.result
					// that.audioContext.src = res.tempFilePath;
					// that.audioContext.play();
				};
			},
			renderText(res){
				console.log('renderText返回的：',res)
				this.form.message = res
			},
			touchStart() {
				this.videoState = true;
				// #ifdef MP
				// 语音识别开始
				manager.start({
					duration: 30000,
					lang: 'zh_CN',
				});
				// #endif
				
				// #ifdef APP
				// this.recorderManager.start({
				// 	format: 'mp3',
				// 	sampleRate: 16000,
				// 	numberOfChannels: 1
				// });
				this.$refs.aiRef.openMedia();
				// #endif
			},
			// 手指触摸动作-结束录制
			touchEnd() {
				this.videoState = false;
				this.alertState = false;
				// #ifdef MP
				// 语音识别结束
				manager.stop();
				// #endif
				// #ifdef APP
				// this.recorderManager.stop();
				this.$refs.aiRef.stopMedia();
				// #endif
			},
			// 恋人聊天初始化
			sessionInit() {
				SessionInit().then(res => {
					if (res.code == 1) {
						this.sessionInitList = res.data
						console.log(this.sessionInitList)
						this.sessionInitList.messages.forEach((item,index)=>{
							let src = this.extractVideoUrlFromMessage(item.content)
							console.log(src)
							item.contentVideo = `<video src="${src}" :webkit-playsinline="false" controls initialTime="1.5s" style="width:300rpx;height:200px;border-radius: 10px;"></video>`
						})
						this.form.session_id = res.data.session_id
						this.sessionMessagesform.session_id = res.data.session_id
						this.sessionSendImageform.session_id = res.data.session_id
						// 只在初始化时滚动到底部
						this.$nextTick(() => {
							this.scrollToBottom();
						})
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							position: 'top'
						})
					}
				})
			},
			sessionSend() {
				SessionSend(this.form).then(res => {
					if (res.code == 1) {
						uni.showToast({
							title: '发送成功',
							icon: 'none',
							position: 'top'
						})
						this.addBond()
						this.form.message = '';
						this.form.session_id = '';
						this.$refs.aiRef.renderText = ''
						this.$refs.aiRef.resultTextTemp = ''
						this.$refs.aiRef.renderText = ''
						// 重新获取会话数据以包含AI回复，这会自动滚动到底部
						// 为确保滚动到最新消息，我们稍微延迟一下滚动
						this.refreshSessionData(true); // 传递参数表示需要滚动到底部
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							position: 'top'
						})
					}
				})
			},
			chatMessagesTts() {
				ChatMessagesTts(this.chatMessagesTtsform.id).then(res => {
					console.log('TTS，文字转语音:', res)
					if (res.code == 1) {
						this.chatMessagesTtsList = res.data
						this.chatMessagesTtsform.id = ''
						this.chatMessagesTtsPlay(this.chatMessagesTtsList.tts_url)
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							position: 'top'
						})
					}
				})
			},
			sessionSendImage() {
				SessionSendImage(this.sessionSendImageform).then(res => {
					if (res.code == 1) {
						uni.showToast({
							title: '发送成功',
							icon: 'none',
							position: 'top'
						})
						this.sessionSendImageform.session_id = ''
						this.sessionSendImageform.image_url = ''
						this.addBond()
						// 重新获取会话数据以包含AI回复，这会自动滚动到底部
						// 为确保滚动到最新消息，我们稍微延迟一下滚动
						this.refreshSessionData(true); // 传递参数表示需要滚动到底部
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							position: 'top'
						})
					}
				})
			},
			// 生成跳舞视频
			danceGenerate() {
				let that = this
				DanceGenerate({
					prompt: this.messageprompt
				}).then(res => {
					if (res.code == 1) {
						this.messageprompt = ''
						// this.addBond()
						// // 重新获取会话数据以包含AI回复，这会自动滚动到底部
						// // 为确保滚动到最新消息，我们稍微延迟一下滚动
						this.refreshSessionData(true); // 传递参数表示需要滚动到底部

						// 轮询监听视频生成任务结果
						that.pollImageSegmentResult(res.data.generation_task_id)
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							position: 'top'
						})
					}
				})
			},
			// 轮询监听任务结果
			async pollImageSegmentResult(job_id) {
				const that = this;

				// 重置轮询计数
				that.pollingAttempts = 0;

				// 如果已有轮询在运行，先清除
				if (that.pollingTimer) {
					clearTimeout(that.pollingTimer);
					that.pollingTimer = null;
				}

				// 定义轮询函数
				const doPoll = () => {
					that.pollingAttempts++;

					// 检查是否超过最大轮询次数
					if (that.pollingAttempts > 20) {
						uni.hideLoading();
						uni.showToast({
							title: '处理超时，请稍后重试',
							icon: 'none'
						});
						that.pollingTimer = null;
						return;
					}

					// 请求接口
					DanceGenerateTask(job_id).then(res => {
						console.log('视频生成查询结果：', res)
						console.log(`第 ${that.pollingAttempts} 次轮询，任务结果:`, res);
						if (res.code == 1) {
							const data = res.data;
							// status "RUN" 表示视频生成中，"succeeded" 表示视频生成成功
							if (data.status == 'succeeded') {
								// 任务成功，停止轮询
								uni.hideLoading();
								// that.result_url = data.ResultVideoUrl
								this.addBond()
								// // 重新获取会话数据以包含AI回复，这会自动滚动到底部
								// // 为确保滚动到最新消息，我们稍微延迟一下滚动
								this.refreshSessionData(true); // 传递参数表示需要滚动到底部

								that.pollingTimer = null;
							} else if (data.status == 'failed') {
								// 任务失败
								uni.hideLoading();
								uni.showToast({
									title: data.error_msg,
									icon: 'none'
								});
								that.pollingTimer = null;
							} else {
								// 任务处理中，继续轮询
								console.log(`任务处理中 (${data.state}),${4000 / 1000}秒后重新查询...`);
								that.pollingTimer = setTimeout(doPoll, 4000);
							}
						} else {
							uni.hideLoading()
							uni.showToast({
								title: res.data,
								icon: 'none',
								duration: 5000
							})
						}
					})
				};

				// 启动轮询
				console.log('开始轮询监听视频生成任务...');
				doPoll();
			},
			chatMessagesTtsPlay(url) {
				// 如果当前有正在播放的音频，先停止它
				if (this.currentAudioContext) {
					this.currentAudioContext.stop();
					this.currentAudioContext.destroy(); // 释放资源
				}

				// 创建新的音频上下文
				this.currentAudioContext = uni.createInnerAudioContext();
				this.currentAudioContext.src = url; // 设置音频源

				// 播放音频
				this.currentAudioContext.play();

				// 监听播放结束事件，播放结束后清空当前音频上下文
				this.currentAudioContext.onEnded(() => {
					console.log('音频播放结束');
					if (this.currentAudioContext) {
						this.currentAudioContext.destroy();
						this.currentAudioContext = null;
					}
					this.currentPlayingId = null; // 清除播放状态
					this.isPlaying = false; // 设置播放状态为false
				});

				// 监听播放错误事件
				this.currentAudioContext.onError((err) => {
					console.error('音频播放失败:', err);
					if (this.currentAudioContext) {
						this.currentAudioContext.destroy();
						this.currentAudioContext = null;
					}
					this.currentPlayingId = null; // 清除播放状态
					this.isPlaying = false; // 设置播放状态为false
					uni.showToast({
						title: '播放失败',
						icon: 'none'
					});
				});
			},
			stopCurrentAudio() {
				if (this.currentAudioContext) {
					this.currentAudioContext.stop();
					this.currentAudioContext.destroy();
					this.currentAudioContext = null;
				}
				this.currentPlayingId = null;
				this.isPlaying = false;
			},
			// 专门用于刷新会话数据的方法，可选择是否滚动到底部
			refreshSessionData(shouldScrollToBottom = false) {
				SessionInit().then(res => {
					if (res.code == 1) {
						const oldMessageCount = this.sessionInitList.messages ? this.sessionInitList.messages.length : 0;
						this.sessionInitList = res.data
						// 重新为所有消息生成contentVideo属性
						this.sessionInitList.messages.forEach((item,index)=>{
							let src = this.extractVideoUrlFromMessage(item.content)
							item.contentVideo = `<video src="${src}" controls initialTime="1.5s" style="width:300rpx;height:200px;border-radius: 10px;"></video>`
						})
						this.form.session_id = res.data.session_id
						this.sessionMessagesform.session_id = res.data.session_id

						// 确保在数据更新后再滚动到底部
						this.$nextTick(() => {
							if (shouldScrollToBottom) {
								// 延迟滚动以确保新消息已渲染
								setTimeout(() => {
									this.scrollToBottom();
								}, 150);
							}
						})
					}
				})
			},

			onScrollToUpper() {
				// 防止重复加载
				if (this.loadingMore || this.noMoreData) {
					return;
				}

				// 开始加载更多数据
				this.loadMoreMessages();
			},

			loadMoreMessages() {
				if (this.noMoreData) return;

				this.loadingMore = true;

				// 更新页码
				this.sessionMessagesform.page += 1;

				SessionMessages(this.sessionMessagesform).then(res => {
					if (res.code == 1) {
						if (res.data && res.data.messages && res.data.messages.length > 0) {
							// 将新消息添加到现有消息列表的前面（因为是向上加载历史消息）
							const newMessages = res.data.messages;
							this.sessionInitList.messages = [...newMessages, ...this.sessionInitList.messages];

							// 检查是否还有更多数据
							if (!res.data.has_more) {
								this.noMoreData = true;
							}
						} else {
							// 没有更多数据
							this.noMoreData = true;
						}
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							position: 'top'
						});

						// 出错时页码回退
						this.sessionMessagesform.page -= 1;
					}
				}).catch(err => {
					console.error('加载更多消息失败:', err);
					// 出错时页码回退
					this.sessionMessagesform.page -= 1;
				}).finally(() => {
					this.loadingMore = false;
				});
			},
			addBond() {
				AddBond(this.addBondform).then(res => {
					console.log('添加', res)
					if (res.code == 1) {
						this.addBondform.type = '';
						this.addBondform.num = '';
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							position: 'top'
						})
					}
				})
			},
			sessionMessages() {
				SessionMessages(this.sessionMessagesform).then(res => {
					if (res.code == 1) {

					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							position: 'top'
						})
					}
				})
			},
			sendMessage() {
				// 检查消息是否为空
				if (this.form.message == '') {
					uni.showToast({
						title: '请输入消息内容',
						icon: 'none'
					});
					return;
				}

				uni.showLoading({
					title: '发送中...'
				});

				this.addBondform.type = 1;
				this.addBondform.num = 1;

				// 发送消息的API调用
				this.sessionSend();
			},
			scrollToBottom() {
				this.$nextTick(() => {
					// 获取最新的消息元素并滚动到它
					const lastIndex = this.sessionInitList.messages.length - 1;
					if (lastIndex >= 0) {
						setTimeout(() => {
							const query = uni.createSelectorQuery();
							query.select('.message-list').boundingClientRect();
							query.selectViewport().scrollOffset();
							query.exec((res) => {
								// 直接滚动到容器底部
								this.scrollTop = 999999; // 设置一个足够大的值
							});
						}, 100);
					}
				});
			},
			// 在滚动事件中控制是否需要自动滚动
			onScroll(e) {
				const currentScrollTop = e.detail.scrollTop;
				// 如果用户主动向上滚动查看历史消息，禁用自动滚动
				if (currentScrollTop > this.lastScrollTop) {
					this.shouldAutoScroll = false;
				} else {
					// 当用户滚动回底部附近时，重新启用自动滚动
					if (currentScrollTop < 100) {
						this.shouldAutoScroll = true;
					}
				}
				this.lastScrollTop = currentScrollTop;
			},
			pictureClick() {
				// 检查用户等级是否大于等于3级
				// if (this.level < 3) {
				// 	uni.showToast({
				// 		title: '达到Lv.3才可以解锁发送图片',
				// 		icon: 'none',
				// 		position: 'top'
				// 	});
				// 	return; // 如果等级不足，直接返回，不执行后续操作
				// }

				uni.chooseImage({
					count: 1, // 最多可以选择的图片张数，默认1
					sourceType: ['camera', 'album'], // 选择图片的来源，相机或相册
					success: (res) => {
						console.log(res.tempFilePaths[0])
						uni.uploadFile({
							url: this.baseURL + '/api/common/upload',
							header: {
								token: uni.getStorageSync("token") || "",
								'content-type': 'application/x-www-form-urlencoded;charset=UTF-8'
							},
							filePath: res.tempFilePaths[0],
							name: 'file',
						}).then((res) => {
							let data = JSON.parse(res.data)
							let item = {
								url: data.data.fullurl
							}
							console.log(item)
							this.sessionSendImageform.image_url = item.url
							this.addBondform.type = 1;
							this.addBondform.num = 1;
							this.sessionSendImage()
						}).catch(
							(response) => {
								console.error('网络请求失败', response);
							}
						)
					},
					fail: function(error) {
						console.log(error);
					}
				});
			},
			sendGift() {
				uni.navigateTo({
					url: '/pages/index/gift'
				});
			},
			back() {
				uni.navigateBack({
					delta: 1,
				});
			},
			setUp() {
				uni.navigateTo({
					url: '/pages/chat/setUp?session_id=' + this.form.session_id
				})
			},
			tointimacy() {
				uni.navigateTo({
					url: '/pages/index/intimacy'
				})
			},
			togift() {
				uni.navigateTo({
					url: '/pages/index/gift'
				});
			},
			tochatPhone() {
				// if (this.level >= 2) {
				// 	uni.navigateTo({
				// 		url: '/pages/chat/chatPhone'
				// 	});
				// } else {
				// 	uni.showToast({
				// 		title: '达到Lv.2才可以解锁通话',
				// 		icon: 'none',
				// 		position: 'top'
				// 	})
				// }
				uni.navigateTo({
					url: '/pages/chat/phone'
				});
			},
			tochatDiary() {
				// if (this.level >= 5) {
				// 	uni.navigateTo({
				// 		url: '/pages/chat/chatDiary'
				// 	});
				// } else {
				// 	uni.showToast({
				// 		title: '达到Lv.5才可以解锁日记',
				// 		icon: 'none',
				// 		position: 'top'
				// 	})
				// }
				uni.navigateTo({
					url: '/pages/chat/chatDiary'
				});
			},
			getMenuInfo() {
				const menuButtonInfo = uni.getMenuButtonBoundingClientRect();
				const systemInfo = uni.getSystemInfoSync();

				// 胶囊宽度
				const capsuleWidth = menuButtonInfo.width;

				// 胶囊距离右侧的距离 = 屏幕宽度 - 胶囊右边界的x坐标
				const distanceFromRight = systemInfo.windowWidth - menuButtonInfo.right;

				this.getMenuInfoList = capsuleWidth + distanceFromRight;

				return {
					width: capsuleWidth,
					distanceFromRight: distanceFromRight,
					menuButtonInfo: menuButtonInfo
				};
			},
			toggleBottomBtns() {
				// 切换底部按钮显示/隐藏状态
				this.showBottomBtns = !this.showBottomBtns;
			},
			sendingMessage() {
				// 检查消息是否为空
				if (this.form.message == '') {
					uni.showToast({
						title: '请输入消息内容',
						icon: 'none'
					});
					return;
				}
				

				uni.showLoading({
					title: '发送中...'
				});

				this.addBondform.type = 1;
				this.addBondform.num = 1;

				// 发送消息的API调用
				this.sessionSend();
			},
			playVoice(id) {
				// 如果点击的是当前正在播放的语音，则停止播放
				if (this.currentPlayingId === id && this.isPlaying) {
					this.stopCurrentAudio();
					return;
				}

				this.chatMessagesTtsform.id = id;
				this.currentPlayingId = id; // 设置当前播放ID
				this.isPlaying = true; // 设置播放状态
				this.chatMessagesTts();
			},
			// 初始化录音管理器
			initRecorder() {
				this.recorderManager = uni.getRecorderManager();
				console.log('this.recorderManager', )
				this.recorderManager.onStart(() => {
					console.log('录音开始');
					this.isRecording = true;
					this.voiceStartTime = Date.now();
					this.voiceCancel = false;
				});

				this.recorderManager.onPause(() => {
					console.log('录音暂停');
				});

				this.recorderManager.onResume(() => {
					console.log('录音继续');
				});

				this.recorderManager.onStop((res) => {
					console.log('录音结束', res);
					this.isRecording = false;

					const duration = Date.now() - this.voiceStartTime;
					// 如果录音时间太短，取消发送
					if (duration < 1000) {
						uni.showToast({
							title: '录音时间太短',
							icon: 'none'
						});
						return;
					}

					if (!this.voiceCancel) {
						console.log('处理录音文件',)
						// 处理录音文件
						this.handleVoiceRecord(res.tempFilePath,res.fileSize);
					}
				});

				this.recorderManager.onError((res) => {
					console.error('录音失败', res);
					this.isRecording = false;
					uni.showToast({
						title: '录音失败: ' + res.errMsg,
						icon: 'none'
					});
				});

			},

			// 切换语音输入模式
			toggleVoiceInput() {
				if (this.isRecording) {
					// 如果正在录音，则停止录音
					this.stopRecording();
				} else {
					// 开始录音
					this.startRecording();
				}
			},

			// 开始录音
			startRecording() {
				const options = {
					duration: 60000, // 最大录音时长，单位ms
					sampleRate: 16000, // 采样率
					numberOfChannels: 1, // 录音通道数
					encodeBitRate: 48000, // 编码码率
					format: 'mp3', // 音频格式
					frameSize: 50, // 指定帧大小，单位 KB
				};

				this.recorderManager.start(options);
				uni.showToast({
					title: '开始录音，请说话...',
					icon: 'none'
				});
			},

			// 停止录音
			stopRecording() {
				this.recorderManager.stop();
			},
			async getAccessToken(apiKey, secretKey) {
				const result = await uni.request({
					url: `https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${apiKey}&client_secret=${secretKey}`,
					method: 'POST'
				});
				console.log('result', result)
				return result.data.access_token;
			},
			async readFile(filePath) {
				console.log('111',filePath) //_doc/uniapp_temp_1768467761590/recorder/1768467765566.wav
				const fs = uni.getFileSystemManager();
				// 将回调式API转换为Promise式API
				return new Promise((resolve, reject) => {
					fs.readFile({
						filePath: filePath,
						encoding: 'base64',
						success: (res) => {
							console.log('readFile success:', res)
							resolve(res);
						},
						fail: (err) => {
							console.error('readFile fail:', err)
							reject(err);
						}
					});
				});
			},
			// App 端专用：使用 plus.io 读取录音文件为 Base64
			async readFileAsBase64(filePath) {
			  // 1. 去掉 file:// 前缀（App 端路径是 file:// 开头的）
			  let path = filePath.replace('file://', '');
			  console.log('读取文件路径:', path)
			 
			  return new Promise((resolve, reject) => {
			    // 2. 使用 plus.io 请求文件系统
			    plus.io.requestFileSystem(
			      plus.io.PUBLIC_DOWNLOADS, // 使用公共下载目录（根据实际情况调整）
			      (fs) => {
			        // 3. 获取文件路径
			        fs.root.getFile(
			          path,
			          { create: false },
			          (fileEntry) => {
			            // 4. 创建文件读取器
			            fileEntry.file((file) => {
			              const reader = new plus.io.FileReader();
			              
			              // 5. 设置读取完成的回调
			              reader.onloadend = (e) => {
			                console.log('文件读取完成',e);
			                // 6. 获取 Base64 数据（去掉 data:xxx/xxx;base64, 前缀）
			                const base64 = e.target.result.split(',')[1];
											console.log('base64',base64);
			                resolve(base64);
			              };
			              
			              // 7. 设置读取错误的回调
			              reader.onerror = (e) => {
			                reject(`文件读取失败: ${e.target.error.message}`);
			              };
			              
			              // 8. 以 DataURL 格式读取文件（自动转换为 Base64）
			              reader.readAsDataURL(file);
			            }, (e) => {
			              reject(`获取文件失败: ${e.message}`);
			            });
			          }, (e) => {
			            reject(`获取文件入口失败: ${e.message}`);
			          }
			        );
			      }, (e) => {
			        reject(`请求文件系统失败: ${e.message}`);
			      }
			    );
			  });
			},
			// 处理录音记录
			async handleVoiceRecord(tempFilePath,fileSize) {
				console.log('录音文件路径:', tempFilePath,'fileSize',fileSize);
				
				// 显示加载提示
				uni.showLoading({
					title: '正在识别语音...'
				});
				
				try {
					// 1. 获取访问令牌
					const token = await this.getAccessToken('OquhIAdglSa2oescqXH7ZUmC', 'LOylGQlc5M895MoXq27zGLT2tmbtHcMl');
					console.log('token', token)
					
					// 2. 读取音频文件
					// const fileData = await this.readFile(tempFilePath);
					const fileData = await this.readFileAsBase64(tempFilePath);
					console.log('fileData:', fileData)
					
					// 3. 调用百度语音识别API
					// 确保speech参数是正确的base64编码字符串
					// const speechData = typeof fileData.data === 'string' ? fileData.data.trim() : '';
					
					let a = uni.getSystemInfoSync().deviceId
					console.log('a:',a)
					// 调用百度语音识别API
					const cuid = uni.getSystemInfoSync().deviceId || 'unknown_device';
					console.log('token:', token);
					console.log('cuid:', cuid);
					console.log('fileData长度:', fileData.length);
					console.log('录音格式:', 'mp3');
					
					const result = await uni.request({
						url: `https://vop.baidu.com/server_api`,
						data: {
							'format': 'mp3', // 与录音格式保持一致
							'rate': 16000,
							'channel': 1,
							'len': fileSize, // 使用正确的文件大小
							'speech': fileData,
							'cuid': cuid,
							'token': token // 只在JSON数据中传递token
						},
						method: 'POST',
						header: {
							'Content-Type': 'application/json' // 百度语音API要求JSON格式
						}
					});
					
					console.log('语音识别结果:', result)
					
					// 4. 处理识别结果
					if (result.data && result.data.err_no === 0) {
						// 识别成功
						const voiceText = result.data.result[0];
						console.log('识别到的文本:', voiceText);
						
						// 将识别结果设置到输入框
						this.form.message = voiceText;
						
						// 自动发送消息
						this.sendMessage();
					} else {
						// 识别失败
						const errorMsg = result.data?.err_msg || '识别失败';
						console.error('语音识别失败:', errorMsg);
						uni.showToast({
							title: `识别失败: ${errorMsg}`,
							icon: 'none',
							duration: 3000
						});
					}
				} catch (error) {
					// 处理异常
					console.error('语音处理失败:', error);
					uni.showToast({
						title: '语音处理失败，请重试',
						icon: 'none',
						duration: 3000
					});
				} finally {
					// 隐藏加载提示
					uni.hideLoading();
				}
			},
			
			initWebSocket(token, tempFilePath) {
				console.log('initWebSocket', token, tempFilePath)
				const ws = new WebSocket(`wss://vop.baidu.com/websocket_api?token=${token}`);
				console.log('ws', ws)
				ws.onopen = () => {
					console.log('WebSocket连接已建立');

					// 1. 发送开始识别的配置信息
					const params = {
						"common": {
							"app_id": 7404135,
						},
						"business": {
							"language": "zh",
							"domain": "general",
							"accent": "mandarin",
							"format": "mp3"
						},
						"data": {
							"status": 0
						}
					};

					ws.send(JSON.stringify(params));
					console.log('已发送配置信息');

					// 2. 读取并分块发送语音数据
					const fs = uni.getFileSystemManager();

					// 使用异步方式获取文件信息
					fs.getFileInfo({
						filePath: tempFilePath,
						success: (res) => {
							const fileSize = res.size;
							const chunkSize = 8192; // 8KB每块
							let offset = 0;

							console.log('开始发送语音数据，文件大小:', fileSize);

							// 定义发送下一块的函数
							const sendNextChunk = () => {
								if (offset >= fileSize) {
									console.log('语音数据发送完成');
									return;
								}

								const end = Math.min(offset + chunkSize, fileSize);
								try {
									// 使用同步方式读取文件块
									const chunk = fs.readFileSync(tempFilePath, {
										position: offset, // uni-app中使用position而非offset
										length: end - offset,
										encoding: 'base64'
									});

									// 发送语音数据块
									const dataParams = {
										"data": {
											"status": offset + chunkSize >= fileSize ? 2 : 1,
											"format": "mp3",
											"audio": chunk
										}
									};

									ws.send(JSON.stringify(dataParams));
									offset += chunkSize;

									// 短暂延迟，避免发送过快
									setTimeout(sendNextChunk, 10);
								} catch (error) {
									console.error('读取文件块失败:', error);
									ws.close();
								}
							};

							// 开始发送第一块
							sendNextChunk();
						},
						fail: (error) => {
							console.error('获取文件信息失败:', error);
							ws.close();
						}
					});
				};

				ws.onmessage = (e) => {
					console.log('收到WebSocket消息:', e.data);

					try {
						const data = JSON.parse(e.data);

						// 检查是否有错误
						if (data.err_no !== 0) {
							console.error('识别出错:', data.err_msg);
							uni.showToast({
								title: '语音识别失败',
								icon: 'none'
							});
							return;
						}

						// 处理识别结果
						if (data.result) {
							console.log('识别结果:', data.result);

							// 将识别结果设置为消息内容
							this.form.message = data.result;

							// 自动发送消息
							this.sendMessage();
						}

					} catch (error) {
						console.error('解析WebSocket消息失败:', error);
					}
				};

				ws.onerror = (error) => {
					console.error('WebSocket连接错误:', error);
					uni.showToast({
						title: '语音识别连接失败',
						icon: 'none'
					});
				};

				ws.onclose = () => {
					console.log('WebSocket连接已关闭');
				};

				// 不再需要返回ws，因为在当前实现中没有外部代码需要控制这个连接
				// 如果未来需要从外部控制WebSocket连接，可以取消注释下面这行
				// return ws;
			},
			handleVoiceRecord0(tempFilePath) {
				console.log('录音文件路径:', tempFilePath);

				// 这里可以上传录音文件到服务器或直接发送
				// 为演示目的，我们先显示一个提示
				uni.showLoading({
					title: '正在发送语音...'
				});

				// TODO: 实现语音文件上传逻辑
				// 上传语音文件后，将语音消息添加到聊天列表
				setTimeout(() => {
					uni.hideLoading();
					uni.showToast({
						title: '语音发送成功',
						icon: 'success'
					});

					// 添加语音消息到聊天列表
					// const newMessage = {
					//     role: 'user', // 或根据实际情况设置
					//     content: '[语音消息]',
					//     voice_path: tempFilePath,
					//     timestamp: Date.now()
					// };
					// this.sessionInitList.messages.push(newMessage);
					// this.scrollToBottom();
				}, 1000);
			},
			chatSingClick(e) {
				if (e == 1) {
					this.chatSingStats = true;
				} else {
					this.chatSingStats1 = true;
				}
				// // 发送消息的API调用
			},
			// 跳舞生成
			savechatSing() {
				if (this.messageprompt == '') {
					uni.showToast({
						title: '请输入跳舞详情',
						icon: 'none'
					});
					return;
				}
				this.addBondform.type = 1;
				this.addBondform.num = 1;
				this.chatSingStats = false;
				this.danceGenerate();
				console.log(this.messageprompt);
			},
			closechatSing() {
				this.chatSingStats = false;
				this.messageprompt = '';
			},
			// 选择歌曲
			selectSong(item, index) {
				this.songId = item.id
			},
			savechatSing1() {
				if (!this.songId) {
					return uni.showToast({
						title: '请选择歌曲',
						icon: 'none'
					});
				}
				this.addBondform.type = 1;
				this.addBondform.num = 1;
				this.chatSingStats1 = false;
				this.singGenerate()
			},
			// 生成跳舞视频
			singGenerate() {
				let that = this
				SingGenerate({
					song_id: this.songId
				}).then(res => {
					if (res.code == 1) {
						this.songId = 0
						// this.addBond()
						// // 重新获取会话数据以包含AI回复，这会自动滚动到底部
						// // 为确保滚动到最新消息，我们稍微延迟一下滚动
						this.refreshSessionData(true); // 传递参数表示需要滚动到底部

						// 轮询监听视频生成任务结果
						that.pollImageSegmentResult1(res.data.generation_task_id)
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							position: 'top'
						})
					}
				})
			},
			async pollImageSegmentResult1(job_id) {
				const that = this;

				// 重置轮询计数
				that.pollingAttempts1 = 0;

				// 如果已有轮询在运行，先清除
				if (that.pollingTimer1) {
					clearTimeout(that.pollingTimer1);
					that.pollingTimer1 = null;
				}

				// 定义轮询函数
				const doPoll = () => {
					that.pollingAttempts1++;

					// 检查是否超过最大轮询次数
					if (that.pollingAttempts1 > 20) {
						uni.hideLoading();
						uni.showToast({
							title: '处理超时，请稍后重试',
							icon: 'none'
						});
						that.pollingTimer1 = null;
						return;
					}

					// 请求接口
					SingGenerateTask(job_id).then(res => {
						console.log('视频生成查询结果：', res)
						console.log(`第 ${that.pollingAttempts1} 次轮询，任务结果:`, res);
						if (res.code == 1) {
							const data = res.data;
							// status "RUN" 表示视频生成中，"succeeded" 表示视频生成成功
							if (data.status == 'succeeded') {
								// 任务成功，停止轮询
								uni.hideLoading();
								// that.result_url = data.ResultVideoUrl
								this.addBond()
								// // 重新获取会话数据以包含AI回复，这会自动滚动到底部
								// // 为确保滚动到最新消息，我们稍微延迟一下滚动
								this.refreshSessionData(true); // 传递参数表示需要滚动到底部

								that.pollingTimer1 = null;
							} else if (data.status == 'failed') {
								// 任务失败
								uni.hideLoading();
								uni.showToast({
									title: data.error_msg,
									icon: 'none'
								});
								that.pollingTimer1 = null;
							} else {
								// 任务处理中，继续轮询
								console.log(`任务处理中 (${data.state}),${4000 / 1000}秒后重新查询...`);
								that.pollingTimer1 = setTimeout(doPoll, 4000);
							}
						} else {
							uni.hideLoading()
							uni.showToast({
								title: res.data,
								icon: 'none',
								duration: 5000
							})
						}
					})
				};

				// 启动轮询
				console.log('开始轮询监听视频生成任务...');
				doPoll();
			},
			isImageUrl(url) {
				if (!url || typeof url !== 'string') {
					return false;
				}

				// 检查是否为图片URL（通过扩展名判断）
				const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg'];
				const lowerCaseUrl = url.toLowerCase();

				return imageExtensions.some(ext => lowerCaseUrl.includes(ext));
			},

			// 预览图片
			previewImage(current) {
				uni.previewImage({
					urls: [current],
					current: current
				});
			},

			isVideoUrl(url) {
				if (!url || typeof url !== 'string') {
					return false;
				}

				// 检查是否为视频URL（通过扩展名判断）
				const videoExtensions = ['.mp4', '.mov', '.avi', '.wmv', '.flv', '.webm', '.m3u8', '.mpg', '.mpeg'];
				const lowerCaseUrl = url.toLowerCase();

				return videoExtensions.some(ext => lowerCaseUrl.includes(ext));
			},

			// 视频播放事件处理
			onVideoPlay(id) {
				// 处理视频播放逻辑
				console.log('视频开始播放:', id);
			},

			onVideoPause(id) {
				// 处理视频暂停逻辑
				console.log('视频暂停:', id);
			},

			// 判断是否为视频消息格式
			isVideoMessage(content) {
				if (!content || typeof content !== 'string') {
					return false;
				}
				// 检查是否包含视频URL的特定格式
				// return content.includes('为你生成了一段跳舞视频，点击查看：') &&
				return (content.includes('为你生成了一段') || content.includes('已生成部分视频')) &&
					(content.includes('.mp4') || content.includes('.MP4'));
			},
			// 判断是否为视频消息格式
			isVideoMessage1(content) {
				if (!content || typeof content !== 'string') {
					return false;
				}
				// 检查是否包含视频URL的特定格式
				// return content.includes('正在为你生成跳舞视频，完成后会自动更新此消息')
				return content.includes('正在为你生成')
			},
			// 从视频消息中提取文本部分
			extractTextFromVideoMessage(content) {
				if (!this.isVideoMessage(content)) {
					return content; // 如果不是视频消息格式，返回原内容
				}
				// 查找URL开始的位置
				const urlStartIndex = content.lastIndexOf('：') + 1; // 找到最后一个冒号的位置
				if (urlStartIndex > 0) {
					return content.substring(0, urlStartIndex - 1); // 返回冒号前的部分
				}
				return content;
			},
			// 从视频消息中提取视频URL
			extractVideoUrlFromMessage(content) {
				if (!this.isVideoMessage(content)) {
					return '';
				}
				// 查找URL开始的位置
				const urlStartIndex = content.lastIndexOf('：') + 1; // 找到最后一个冒号的位置
				if (urlStartIndex > 0) {
					return content.substring(urlStartIndex).trim();
				}
				return '';
			},

			bottomClick() {
				if (this.bottomStats) {
					this.bottomStats = false
				} else {
					this.bottomStats = true
				}
			},
			// 添加视频长按处理方法
			onVideoLongPress(item) {
				console.log('视频长按事件触发，消息ID:', item.id);
				// 将视频消息的ID赋值给dynamicShareform.source_message_id
				this.dynamicShareform.source_message_id = item.id;

				// 提取视频URL并存储，以便在弹窗中使用
				if (this.isVideoMessage(item.content)) {
					this.currentVideoUrl = this.extractVideoUrlFromMessage(item.content);
				} else if (this.isVideoUrl(item.content)) {
					this.currentVideoUrl = item.content;
				} else {
					this.currentVideoUrl = '';
				}

				// 显示分享弹窗
				this.bottomStats = true;
				console.log('显示分享弹窗，消息ID:', item.id);
			},
			dynamicShare() {
				DynamicShare(this.dynamicShareform).then(res => {
					if (res.code == 1) {
						uni.showToast({
							title: '分享成功',
							icon: 'success',
							position: 'top'
						})
						this.bottomStats = false
						this.dynamicShareform.content = ''
						this.dynamicShareform.source_message_id = ''
						this.currentVideoUrl = '' // 分享完成后清空当前视频URL
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							position: 'top'
						})
					}
				})
			},
			noClick() {
				this.bottomStats = false
				this.dynamicShareform.content = ''
				this.dynamicShareform.source_message_id = ''
				this.currentVideoUrl = '' // 清空当前视频URL
			},
			yesClick() {
				console.log(this.dynamicShareform);
				this.dynamicShare()
			},
			getSingSongs() {
				SingSongs({}).then(res => {
					if (res.code == 1) {
						this.singSongsList = res.data.songs
					}
				})
			},
			// 停止轮询（供外部调用，如页面销毁时）
			stopPolling() {
				if (this.pollingTimer) {
					clearTimeout(this.pollingTimer);
					this.pollingTimer = null;
					console.log('已停止轮询监听');
				}
				if (this.pollingTimer1) {
					clearTimeout(this.pollingTimer1);
					this.pollingTimer1 = null;
					console.log('已停止轮询监听1');
				}
			},
		},
		// 页面卸载时停止轮询
		onUnload() {
			this.stopPolling();
		},
	}
</script>

<style>
	page {
		height: 100%;
		/* opacity: 0.7; */
	}

	/* .uni-navbar__header-btns-left.data-v-26544265 {
    width: 0 !important;
} */
	.uni-navbar__header-btns-left {
		width: 100% !important;
	}
</style>

<style scoped>
	/* Tab 栏样式 */
	.tab-bar {
		position: relative;
		z-index: 10;
		background: rgba(0, 0, 0, 0.5);
		backdrop-filter: blur(10px);
		padding: 0;
		margin-top: 88rpx;
	}
	
	.tab-scroll {
		width: 100%;
		white-space: nowrap;
	}
	
	.tab-list {
		display: inline-flex;
		padding: 0 20rpx;
	}
	
	.tab-item {
		position: relative;
		padding: 20rpx 30rpx;
		margin: 0 10rpx;
		cursor: pointer;
		transition: all 0.3s;
	}
	
	.tab-text {
		font-size: 28rpx;
		color: rgba(255, 255, 255, 0.6);
		transition: all 0.3s;
		white-space: nowrap;
	}
	
	.tab-item.active .tab-text {
		color: #FFFFFF;
		font-weight: bold;
		font-size: 32rpx;
	}
	
	.tab-indicator {
		position: absolute;
		bottom: 10rpx;
		left: 50%;
		transform: translateX(-50%);
		width: 40rpx;
		height: 6rpx;
		background: linear-gradient(90deg, #E1C7FF, #B794F6);
		border-radius: 3rpx;
	}
	
	/* Tab 内容区域 */
	.tab-content {
		flex: 1;
		position: relative;
		overflow-y: auto;
	}
	
	/* 功能页面通用样式 */
	.feature-page {
		padding: 40rpx;
		min-height: 100%;
	}
	
	.feature-title {
		font-size: 48rpx;
		font-weight: bold;
		color: #FFFFFF;
		text-align: center;
		margin-bottom: 20rpx;
		text-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.3);
	}
	
	.feature-desc {
		font-size: 28rpx;
		color: rgba(255, 255, 255, 0.8);
		text-align: center;
		margin-bottom: 60rpx;
	}
	
	/* 歌曲列表样式 */
	.song-list {
		background: rgba(255, 255, 255, 0.1);
		backdrop-filter: blur(10px);
		border-radius: 20rpx;
		padding: 20rpx;
	}
	
	.song-item {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 30rpx;
		background: rgba(255, 255, 255, 0.05);
		border-radius: 15rpx;
		margin-bottom: 20rpx;
	}
	
	.song-info {
		flex: 1;
	}
	
	.song-title {
		font-size: 32rpx;
		color: #FFFFFF;
	}
	
	.song-icon {
		width: 60rpx;
		height: 60rpx;
	}
	
	/* 跳舞输入样式 */
	.dance-input {
		background: rgba(255, 255, 255, 0.1);
		backdrop-filter: blur(10px);
		border-radius: 20rpx;
		padding: 40rpx;
	}
	
	.dance-input-field {
		width: 100%;
		padding: 30rpx;
		background: rgba(255, 255, 255, 0.1);
		border-radius: 15rpx;
		color: #FFFFFF;
		font-size: 28rpx;
		margin-bottom: 30rpx;
	}
	
	.dance-btn {
		width: 100%;
		padding: 30rpx;
		background: linear-gradient(90deg, #E1C7FF, #B794F6);
		border-radius: 15rpx;
		text-align: center;
		color: #FFFFFF;
		font-size: 32rpx;
		font-weight: bold;
	}
	
	/* 服装网格样式 */
	.outfit-grid {
		display: grid;
		grid-template-columns: repeat(3, 1fr);
		gap: 30rpx;
	}
	
	.outfit-item {
		text-align: center;
	}
	
	.outfit-image {
		width: 100%;
		height: 200rpx;
		border-radius: 15rpx;
		background: rgba(255, 255, 255, 0.1);
		margin-bottom: 15rpx;
	}
	
	.outfit-name {
		font-size: 24rpx;
		color: rgba(255, 255, 255, 0.8);
	}
	
	/* 礼物网格样式 */
	.gift-grid {
		display: grid;
		grid-template-columns: repeat(4, 1fr);
		gap: 30rpx;
	}
	
	.gift-item {
		text-align: center;
		padding: 20rpx;
		background: rgba(255, 255, 255, 0.1);
		border-radius: 15rpx;
	}
	
	.gift-image {
		width: 80rpx;
		height: 80rpx;
		margin-bottom: 10rpx;
	}
	
	.gift-name {
		font-size: 24rpx;
		color: #FFFFFF;
		display: block;
		margin-bottom: 5rpx;
	}
	
	.gift-price {
		font-size: 20rpx;
		color: #FFD700;
	}
	
	/* 商城列表样式 */
	.shop-list {
		background: rgba(255, 255, 255, 0.1);
		backdrop-filter: blur(10px);
		border-radius: 20rpx;
		padding: 20rpx;
	}
	
	.shop-item {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 30rpx;
		background: rgba(255, 255, 255, 0.05);
		border-radius: 15rpx;
		margin-bottom: 20rpx;
	}
	
	.shop-info {
		flex: 1;
	}
	
	.shop-title {
		font-size: 32rpx;
		color: #FFFFFF;
		display: block;
		margin-bottom: 10rpx;
	}
	
	.shop-desc {
		font-size: 24rpx;
		color: rgba(255, 255, 255, 0.6);
	}
	
	.shop-price {
		display: flex;
		align-items: center;
		gap: 20rpx;
	}
	
	.price-value {
		font-size: 36rpx;
		color: #FFD700;
		font-weight: bold;
	}
	
	.shop-buy-btn {
		padding: 15rpx 30rpx;
		background: linear-gradient(90deg, #E1C7FF, #B794F6);
		border-radius: 10rpx;
		color: #FFFFFF;
		font-size: 24rpx;
	}
	
	/* 短剧列表样式 */
	.drama-list {
		background: rgba(255, 255, 255, 0.1);
		backdrop-filter: blur(10px);
		border-radius: 20rpx;
		padding: 20rpx;
	}
	
	.drama-item {
		display: flex;
		padding: 20rpx;
		background: rgba(255, 255, 255, 0.05);
		border-radius: 15rpx;
		margin-bottom: 20rpx;
	}
	
	.drama-cover {
		width: 200rpx;
		height: 280rpx;
		border-radius: 10rpx;
		background: rgba(255, 255, 255, 0.1);
		margin-right: 20rpx;
	}
	
	.drama-info {
		flex: 1;
		display: flex;
		flex-direction: column;
		justify-content: space-between;
	}
	
	.drama-title {
		font-size: 32rpx;
		color: #FFFFFF;
		font-weight: bold;
		margin-bottom: 10rpx;
	}
	
	.drama-desc {
		font-size: 24rpx;
		color: rgba(255, 255, 255, 0.6);
		line-height: 1.5;
	}
	
	.drama-play-btn {
		align-self: flex-start;
		padding: 15rpx 40rpx;
		background: linear-gradient(90deg, #E1C7FF, #B794F6);
		border-radius: 10rpx;
		color: #FFFFFF;
		font-size: 24rpx;
	}

	.body {
		position: relative;
		height: 100vh;
		display: flex;
		flex-direction: column;
	}

	.back {
		position: fixed;
		left: 0;
		top: 0;
		width: 100%;
		height: 100%;
		display: block;
	}

	.custom_left {
		position: relative;
		display: flex;
		align-items: center;
		height: 100%;
		z-index: 10;
	}

	.left_content {
		position: relative;
		display: flex;
		align-items: center;
	}

	.left_return {
		width: 48rpx;
		height: 48rpx;
		margin-right: 20rpx;
	}

	.left_module {
		position: relative;
		display: flex;
		align-items: center;
	}

	.left_avatar {
		width: 68rpx;
		height: 68rpx;
		display: block;
		border-radius: 100rpx;
	}

	.left_count {
		position: absolute;
		right: -30rpx;
		bottom: 0;
	}

	.left_count image {
		position: relative;
	}

	.left_dight {
		position: relative;
		width: 40rpx;
		height: 40rpx;
	}

	.left_dight image {
		position: absolute;
		left: 0;
		bottom: 0;
		width: 100%;
		height: 100%;
	}

	.left_dight text {
		position: relative;
		width: 48rpx;
		height: 48rpx;
	}

	.body_content {
		position: relative;
		flex: 1;
		display: flex;
		flex-direction: column;
		padding: 0 0 40rpx 0;
		min-height: 0;
	}

	.list {
		flex: 1;
		position: relative;
		z-index: 2;
		padding: 20rpx 0;
		overflow-y: auto;
	}

	.message-list {
		padding: 20rpx;
	}

	.message-item {
		display: flex;
		margin-bottom: 30rpx;
	}

	.avatar {
		width: 80rpx;
		height: 80rpx;
		border-radius: 10rpx;
		flex-shrink: 0;
	}

	/* 左侧消息（对方/AI） */
	.left-message {
		justify-content: flex-start;
	}

	.left-message .avatar {
		margin-right: 20rpx;
	}

	.left-message .message-bubble {
		background: #E1C7FF;
		color: #000000;
	}

	/* 右侧消息（自己） */
	.right-message {
		justify-content: flex-end;
	}

	.right-message .avatar {
		order: 2;
		/* 将头像移到右边 */
		margin-left: 20rpx;
	}

	.right-message .message-content {
		order: 1;
		/* 将消息内容移到左边 */
	}

	.right-message .message-bubble {
		background: rgba(0, 0, 0, 0.9);
		color: #FFFFFF;
	}

	.message-content {
		max-width: 70%;
	}

	.message-bubble {
		padding: 20rpx;
		border-radius: 10rpx;
		position: relative;
	}

	.message-text {
		font-size: 28rpx;
		line-height: 40rpx;
		word-break: break-all;
	}

	.message-image {
		max-width: 200rpx;
		max-height: 200rpx;
		border-radius: 10rpx;
	}

	.message-image-container {
		max-width: 70%;
	}

	.message-video {
		max-width: 300rpx;
		max-height: 200rpx;
		border-radius: 10rpx;
	}

	.message-video-container {
		max-width: 70%;
	}

	.textbox {
		position: relative;
		padding: 0 25rpx 0 25rpx;
		z-index: 2;
	}

	.textbox_voice {
		margin: 0 14rpx 0 0;
		width: 60rpx;
		height: 60rpx;
		display: block;
	}

	.textbox_content {
		position: relative;
		padding: 10rpx 25rpx;
		background: rgba(123, 123, 123, 0.5);
		border-radius: 12rpx;
	}

	.textbox_content input {
		font-weight: 500;
		font-size: 30rpx;
		color: #FFFFFF;
		line-height: 50rpx;
	}

	.textbox_image {
		margin: 0 14rpx 0 0;
		width: 68rpx;
		height: 68rpx;
		display: block;
		border-radius: 10rpx;
	}

	.textbox_input {
		color: #FFFFFF;
	}

	.textbox_send {
		margin: 0 0px 0 14rpx;
		padding: 15rpx 30rpx;
		font-weight: 400;
		font-size: 28rpx;
		color: #FFFFFF;
		line-height: 50rpx;
		background: linear-gradient(135deg, #9F47FF 0%, #0053FA 100%);
		border-radius: 12rpx;
	}

	.textbox_add {
		width: 60rpx;
		height: 60rpx;
		display: block;
	}

	.black {
		position: absolute;
		left: 0;
		bottom: 0;
		width: 100%;
		height: 420rpx;
		background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #4A4A4A 100%);
	}

	.btn {
		position: relative;
		padding: 42rpx 50rpx 62rpx 50rpx;
		background: #FFFFFF;
		display: grid;
		grid-template-columns: repeat(4, 1fr);
		grid-column-gap: 50rpx;
		grid-row-gap: 40rpx;
	}

	.btn_content {
		position: relative;
	}

	.btn_module {
		position: relative;
	}

	.btn_image {
		width: 88rpx;
		height: 88rpx;
		display: block;
	}

	.btn_lock {
		position: absolute;
		right: 20rpx;
		top: 0;
		width: 32rpx;
		height: 24rpx;
	}

	.btn_title {
		margin: 5rpx 0 0 0;
		font-weight: 400;
		font-size: 28rpx;
		color: #222222;
		line-height: 50rpx;
		text-align: center;
	}

	/* .uni-navbar__header-btns-right {
    padding-right: var(--right-padding, 0);
} */

	.voice-container {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 40rpx;
		height: 40rpx;
		cursor: pointer;
		margin-left: 10rpx;
	}

	.voice-wave {
		display: flex;
		align-items: center;
		justify-content: space-around;
		width: 40rpx;
		height: 20rpx;
		opacity: 0;
		visibility: hidden;
		transition: all 0.3s ease;
	}

	.voice-wave.playing {
		opacity: 1;
		visibility: visible;
	}

	.voice-wave.black-wave {
		opacity: 1;
		visibility: visible;
	}

	.video-message-container {
		display: flex;
		flex-direction: column;
	}

	.video-message-container .message-text {
		margin-bottom: 10rpx;
		/* 文字和视频之间的间距 */
	}

	.wave-bar {
		width: 3rpx;
		height: 10rpx;
		background-color: #ffffff;
		border-radius: 1.5rpx;
		animation: wave 1.2s infinite ease-in-out;
		transform-origin: bottom;
		transition: height 0.3s ease;
	}

	/* 播放状态的动画效果 */
	.voice-wave.playing .wave-bar {
		background-color: #ffffff;
		animation: wave 1.2s infinite ease-in-out;
	}

	/* 非播放状态的灰色样式 */
	.voice-wave.black-wave .wave-bar {
		background-color: #999999;
		animation: none;
	}

	/* 波形动画 - 两边高中间低 */
	@keyframes wave {

		0%,
		100% {
			transform: scaleY(0.4);
			background-color: #ffffff;
		}

		20% {
			transform: scaleY(0.8);
			background-color: #e0e0e0;
		}

		40% {
			transform: scaleY(1);
			background-color: #c0c0c0;
		}

		60% {
			transform: scaleY(0.7);
			background-color: #e0e0e0;
		}

		80% {
			transform: scaleY(0.5);
			background-color: #ffffff;
		}
	}

	/* 非播放状态下波形动画 */
	.voice-wave.black-wave.playing .wave-bar {
		animation: wave 1.2s infinite ease-in-out;
	}

	.voice-wave.black-wave.playing .wave-bar {
		background-color: #999999;
	}

	/* 为不同波形条设置不同的动画延迟，创建更自然的波形效果 */
	.wave-bar-1 {
		animation-delay: 0s;
		height: 20rpx;
		/* 最高 */
	}

	.wave-bar-2 {
		animation-delay: 0.2s;
		height: 15rpx;
		/* 较高 */
	}

	.wave-bar-3 {
		animation-delay: 0.4s;
		height: 25rpx;
		/* 最低 */
	}

	.wave-bar-4 {
		animation-delay: 0.6s;
		height: 15rpx;
		/* 较高 */
	}

	.wave-bar-5 {
		animation-delay: 0.8s;
		height: 20rpx;
		/* 最高 */
	}

	/* 播放状态下的颜色 */
	.voice-wave.playing .wave-bar-1 {
		background-color: #ff7eb9;
		height: 20rpx;
		/* 最高 */
	}

	.voice-wave.playing .wave-bar-2 {
		background-color: #ff7eb9;
		height: 15rpx;
		/* 较高 */
	}

	.voice-wave.playing .wave-bar-3 {
		background-color: #ff7eb9;
		height: 25rpx;
		/* 最低 */
	}

	.voice-wave.playing .wave-bar-4 {
		background-color: #ff7eb9;
		height: 15rpx;
		/* 较高 */
	}

	.voice-wave.playing .wave-bar-5 {
		background-color: #ff7eb9;
		height: 20rpx;
		/* 最高 */
	}

	/* 非播放状态下的颜色 - 保持两边高中间低的形状 */
	.voice-wave.black-wave .wave-bar-1 {
		background-color: #000000;
		height: 20rpx;
		/* 最高 */
	}

	.voice-wave.black-wave .wave-bar-2 {
		background-color: #000000;
		height: 15rpx;
		/* 较高 */
	}

	.voice-wave.black-wave .wave-bar-3 {
		background-color: #000000;
		height: 25rpx;
		/* 最低 */
	}

	.voice-wave.black-wave .wave-bar-4 {
		background-color: #000000;
		height: 15rpx;
		/* 较高 */
	}

	.voice-wave.black-wave .wave-bar-5 {
		background-color: #000000;
		height: 20rpx;
		/* 最高 */
	}

	.alert {
		position: fixed;
		height: 100%;
		width: 100%;
		top: 0;
		left: 0;
		background: rgba(0, 0, 0, 0.7);
		z-index: 10;
	}

	.alert_hide {
		position: absolute;
		height: 100%;
		width: 100%;
		top: 0;
	}

	.alert_module {
		position: absolute;
		width: 100%;
		padding: 50rpx 0 100rpx 0;
		background: #fff;
		bottom: 0;
		border-radius: 30rpx 30rpx 0 0;
	}

	.alert_title {
		font-size: 30rpx;
		text-align: center;
		color: #333;
	}

	.alert_opt {
		position: absolute;
		left: 0;
		right: 0;
		top: -300rpx;
		bottom: 0;
		margin: auto auto;
		height: 100rpx;
		width: 350rpx;
		background: #fff;
		padding: 0 30rpx;
		box-sizing: border-box;
		border-radius: 30rpx;
	}

	.alert_a1 {
		position: relative;
		height: 90rpx;
		width: 10rpx;
		background: #ff9b9f;
		animation: alert_a1 0.5s infinite linear;
	}

	@keyframes alert_a1 {
		0% {
			height: 90rpx;
		}

		50% {
			height: 10rpx;
		}

		100% {
			height: 90rpx;
		}
	}

	.alert_a2 {
		position: relative;
		height: 90rpx;
		width: 10rpx;
		background: #ff9b9f;
		animation: alert_a2 1s infinite linear;
	}

	@keyframes alert_a2 {
		0% {
			height: 90rpx;
		}

		50% {
			height: 10rpx;
		}

		100% {
			height: 90rpx;
		}
	}

	.alert_a3 {
		position: relative;
		height: 90rpx;
		width: 10rpx;
		background: #ff9b9f;
		animation: alert_a3 1.5s infinite linear;
	}

	@keyframes alert_a3 {
		0% {
			height: 90rpx;
		}

		50% {
			height: 10rpx;
		}

		100% {
			height: 90rpx;
		}
	}

	.alert_a4 {
		position: relative;
		height: 90rpx;
		width: 10rpx;
		background: #ff9b9f;
		animation: alert_a4 2s infinite linear;
	}

	@keyframes alert_a4 {
		0% {
			height: 90rpx;
		}

		50% {
			height: 10rpx;
		}

		100% {
			height: 90rpx;
		}
	}

	.alert_a5 {
		position: relative;
		height: 90rpx;
		width: 10rpx;
		background: #ff9b9f;
		animation: alert_a5 2.5s infinite linear;
	}

	@keyframes alert_a5 {
		0% {
			height: 90rpx;
		}

		50% {
			height: 10rpx;
		}

		100% {
			height: 90rpx;
		}
	}

	.alert_btn {
		position: relative;
		height: 150rpx;
		width: 150rpx;
		box-shadow: 0 0 10rpx #d0d0d0;
		margin: 50rpx auto 0 auto;
		border-radius: 100rpx;
	}

	.alert_btn image {
		height: 60rpx;
		width: 60rpx;
	}

	/* 旋转动画 */
	@keyframes spin {
		0% {
			transform: rotate(0deg);
		}

		100% {
			transform: rotate(360deg);
		}
	}

	/* 旋转加载器样式 */
	.spinner-cycle-box {
		display: inline-block;
		animation: spin 3s linear infinite;
	}
	
	
	.chatSing {
		position: absolute;
		width: 100%;
		height: 100%;
		left: 0;
		top: 0;
		padding: 0 40rpx;
		box-sizing: border-box;
		background: rgba(0, 0, 0, 0.2);
		z-index: 2;
	}

	.chatSing_content {
		position: relative;
		background: #FFFFFF;
		border-radius: 20rpx;
		padding: 60rpx;
	}

	.chatSing_content image {
		position: absolute;
		right: 20rpx;
		top: 20rpx;
		width: 30rpx;
		height: 30rpx;
	}

	.chatSing_title {
		font-weight: 500;
		font-size: 32rpx;
		color: #161616;
		line-height: 38rpx;
		text-align: center;
	}

	.chatSing_detail {
		position: relative;
		margin: 20rpx 0 0 0;
	}

	.chatSing_detail input {
		width: 400rpx;
		padding: 15rpx;
		font-weight: 400;
		font-size: 26rpx;
		color: #161616;
		line-height: 50rpx;
		border-radius: 12rpx;
		border: 1px solid #989898;
	}

	.chatSing_input {
		color: #161616;
	}

	.chatSing_sure {
		margin: 20rpx 0 0 0;
	}

	.chatSing_sure text {
		padding: 15rpx 60rpx;
		font-weight: 400;
		font-size: 26rpx;
		color: #FFFFFF;
		line-height: 50rpx;
		background: linear-gradient(135deg, #9F47FF 0%, #0053FA 100%);
		border-radius: 10rpx;
	}

	.bottom {
		position: fixed;
		width: 100%;
		height: 100%;
		left: 0;
		bottom: 0;
		box-sizing: border-box;
		background: rgba(0, 0, 0, 0.2);
		z-index: 2;
	}

	.bottom_content {
		position: fixed;
		bottom: 0;
		left: 0;
		right: 0;
		background: linear-gradient(180deg, #EDD6F5 0%, #FFFFFF 100%);
		border-radius: 40rpx 40rpx 0rpx 0rpx;
		padding: 46rpx 80rpx 68rpx 80rpx;
	}

	.bottom_title {
		position: relative;
		font-weight: 500;
		font-size: 36rpx;
		color: #333333;
		line-height: 50rpx;
		text-align: center;
	}

	.bottom_title image {
		position: absolute;
		right: -20rpx;
		top: 0;
		bottom: 0;
		width: 22rpx;
		height: 22rpx;
		margin: auto 0;
	}

	.bottom_video {
		margin: 50rpx auto 0 auto;
		width: 272rpx;
		height: 272rpx;
		border-radius: 20rpx;
	}

	.bottom_module {
		position: relative;
		margin: 20rpx 0 0 0;
		padding: 0 50rpx;
	}

	.bottom_module input {
		padding: 20rpx 30rpx;
		font-weight: 500;
		font-size: 30rpx;
		color: #8449FE;
		line-height: 50rpx;
		background: #FAFAFA;
		border-radius: 12rpx;
	}

	.bottom_input {
		color: #8449FE;
	}

	.bottom_item {
		position: relative;
		margin: 42rpx 0 0 0;
	}

	.bottom_btn {
		position: relative;
		padding: 15rpx 112rpx;
		font-weight: 500;
		font-size: 30rpx;
		color: #8449FE;
		line-height: 50rpx;
		border-radius: 12rpx;
		border: 2rpx solid #817EFE;
	}

	.bottom_btn:nth-child(2) {
		color: #FFFFFF;
		background: linear-gradient(135deg, #9F47FF 0%, #0053FA 100%), #D8D8D8;
	}
</style>