liujiaxin 3 周之前
父節點
當前提交
cc08cbd0a6

+ 1 - 1
core/config/defaultConfig.js

@@ -14,10 +14,10 @@ const productionUrl = 'https://wanbei.monvkeji.cn/'
 // 测试环境
 const testUrl = 'https://wanbei.monvkeji.cn/'
 // 开发环境
+// const developUrl = 'https://live.test.ylrztop.com/live-api/'//余红奇
 const developUrl = 'http://192.168.10.166:7114/'//余红奇
 // const developUrl = 'http://v56c9b8e.natappfree.cc/'//余红奇
 // const developUrl = 'http://nd383294.natappfree.cc/'//余红奇
-// const developUrl = 'https://live.test.ylrztop.com/live-api/'//余红奇
 // const developUrl = 'http://192.168.10.170:7114/'//陈果
 export default {
 	// 系统名称

+ 239 - 144
pages/home/living.vue

@@ -7,11 +7,11 @@
 					<view class="blackbg"></view>
 					<view class="content">
 						<!-- 页面内容 -->
-						<view style=" position: fixed;top: 0;z-index: 5;" class="content-top">
+						<view style="position: fixed;top: 0;z-index: 5;" class="content-top">
 							<view class="u-flex-y-center">
 								<image @click="goBack" style="width: 60rpx;height: 64rpx;margin-right: 26rpx;"
-									src="@/static/images/live/return.png"></image>
-								<view class=" align-center"
+									src="/static/images/live/return.png"></image>
+								<view class="align-center"
 									style="padding: 6rpx 4rpx;height: 64rpx;background: rgba(0,0,0,0.5);border-radius: 32rpx;">
 									<u-avatar :src="liveItem.liveImgUrl||$img.logo" size="32"></u-avatar>
 									<view class="colorf ml10 mr6">
@@ -19,7 +19,7 @@
 									</view>
 								</view>
 							</view>
-							<view class="u-flex-end align-center" @click="showadd=!showadd" style="margin-top: 100rpx;">
+							<view class="u-flex-end align-center" @click="toggleViewerList" style="margin-top: 100rpx;">
 								<image class="w52 h52 mr4" v-for="(item,viewerIndex) in filteredViewers"
 									:key="viewerIndex" style="border-radius: 26rpx;" :src="item.avatar||$img.logo">
 								</image>
@@ -27,32 +27,14 @@
 							</view>
 						</view>
 
-						<!-- 页面内容 -->
-						<view style=" position: fixed;top:120rpx;left: 0rpx; z-index: 5;" class="content-top">
+						<!-- 红包内容 -->
+						<view style="position: fixed;top:120rpx;left: 0rpx; z-index: 5;" class="content-top">
 							<view class="u-flex-y-center">
 								<image @click="onRed(liveItem)" v-if="liveItem.redInfo?.redStatus==1"
-									style="width: 70rpx;height: 70rpx;" src="@/static/images/hongbao.png"></image>
+									style="width: 70rpx;height: 70rpx;" src="/static/images/hongbao.png"></image>
 							</view>
 						</view>
 
-						<!-- 右边的 -->
-						<!-- <view :class=" liveItem.showType==1 ? 'siderow-group' : 'side-group'">
-							<view class="side-item">
-								<image class="image" @click="onLike(liveItem)" src="/static/images/live/like.png"></image>
-								<view>{{liveItem.liveViewData?.like||0}}</view>
-							</view>
-							<view class="side-item">
-								<button open-type="share" class="button">
-									<image class="image" src="/static/images/live/share.png" mode="widthFix"></image>
-								</button>
-								<view>分享</view>
-							</view>
-							<view class="side-item">
-								<image @click="goStore(liveItem)" src="/static/images/live/shop.png"></image>
-								<view>店铺</view>
-							</view>
-						</view> -->
-
 						<view class="shop-prompt u-flex-y-center" v-if="showPurchasePrompt&&orderUser?.count">
 							<image class="w32 h32 mr8" src="/static/images/live/shopping.png"></image>
 							<text> {{orderUser.userName ? maskString(orderUser.userName) : ''}} 等
@@ -60,10 +42,9 @@
 								人正在去购买</text>
 						</view>
 
-						<view class="videolist " style="margin: auto 0">
+						<view class="videolist" style="margin: auto 0">
 							<view class="video" style="height:100vh">
-								<!-- 修改video组件以支持HLS -->
-								<!-- showType 1 横屏   2 竖屏 -->
+								<!-- 视频组件 -->
 								<video v-if="liveItem.livingUrl" :id="'myVideo_' + liveItem.liveId"
 									:class="liveItem.showType == 1 ? 'video_row' : 'videotop'" :src="liveItem.livingUrl"
 									:autoplay="currentSwiperIndex === index" :controls='false' object-fit='contain'
@@ -79,7 +60,7 @@
 									vslide-gesture-in-fullscreen='true' :show-center-play-btn="false"
 									:http-cache="false" loop @error="videoError">
 								</video>
-
+								<view v-if="liveItem.videoUrl" class="time">{{liveItem.totalTime}}</view>
 								<!-- 加载提示 -->
 								<view v-if="liveItem.loading" class="loading-tip">
 									<u-loading mode="circle" color="#ffffff" size="36"></u-loading>
@@ -87,7 +68,9 @@
 								</view>
 							</view>
 						</view>
-						<view class="pb40  mt90" style="position: fixed;bottom: 0;width: 100%;">
+
+						<!-- 底部聊天区域 -->
+						<view class="pb40 mt90" style="position: fixed;bottom: 0;width: 100%;">
 							<view class="w100 h300 mt20">
 								<scroll-view enable-flex scroll-y="true" class="talk p20 scrolly flex-1 column"
 									style="width: calc(100% - 40rpx);height: calc(100% - 40rpx);"
@@ -120,8 +103,6 @@
 											<view class="talk-list ml16 justify-start">
 												<view class="fs24">
 													<text style="color: #ff89d6;">{{item.nickName}} </text>
-													<!-- <text class='fs24 colorf'>
-														{{item.msg}}直播间{{liveItem.messageContent}}</text> -->
 													<text class='fs24 colorf'>
 														{{item.msg}}直播间{{liveItem.messageContent}}</text>
 												</view>
@@ -131,6 +112,7 @@
 								</scroll-view>
 							</view>
 
+							<!-- 底部输入框和操作按钮 -->
 							<view class="justify-between p24">
 								<view class="u-flex-y-center"
 									style="background:rgba(57, 57, 57, 0.8);padding:10rpx 14rpx 10rpx 32rpx;width: 500rpx;box-sizing:border-box;border-radius:36rpx;">
@@ -140,18 +122,7 @@
 									</u-input>
 									<view class="send" @click="sendMsg(liveItem)">发送</view>
 								</view>
-								<view class="justify-between mr15  align-center">
-									<!-- <view class="side-item">
-										<image class="image" @click="onLike(liveItem)" src="/static/images/live/like.png"></image>
-										<view>{{liveItem.liveViewData?.like||0}}</view>
-									</view>
-									<view class="side-item">
-										<button open-type="share" class="button">
-											<image class="image" src="/static/images/live/share.png" mode="widthFix"></image>
-										</button>
-										<view>分享</view>
-									</view>
-									 -->
+								<view class="justify-between mr15 align-center">
 									<view class="icon ml20" @click="onLike(liveItem)">
 										<image src="/static/images/live/like.png" class="w56 h56"></image>
 										<view>{{liveItem.liveViewData?.like||0}}</view>
@@ -162,36 +133,29 @@
 										</button>
 										<view>分享</view>
 									</view>
-
-									<!-- <view class="icon-bg ml20" @click="openCart(liveItem)">
-										<image src="/static/images/shopping.png" class="w48 h48"></image>
-									</view> -->
-									<!-- <view class="icon-bg ml20" @click="liveItem.showziliao=!liveItem.showziliao">
-										<image src="/static/images/more-icon.png" class="w48 h48"></image>
-									</view> -->
 								</view>
 							</view>
 						</view>
 
 						<!-- 弹出商品 -->
-						<view @click="" class="goods">
+						<!--  v-if="liveItem.goodsCard.isShow" -->
+						<view  class="goods">
 							<view class="top">
 								<view class="left">
-									<image class="w30 h30" src="/static/images/signal.png"></image>讲解中
+									<image class="w30 h30 mr8" src="/static/images/signal.png"></image>讲解中
 								</view>
-								<image class="w30 h30" src="/static/images/close.png"></image>
+								<image class="w30 h30" src="/static/images/close.png" @click="liveItem.goodsCard.isShow=false"></image>
 							</view>
-							<image class="photo" src="@/static/images/a.jpg"></image>
+							<image class="photo" :src="liveItem.goodsCard.imgUrl"></image>
 							<view class="item">
-								<view class="price"><text class="red">23.55</text><text class="del">26.66</text></view>
-								<view class="title">新鲜土鸡蛋</view>
+								<view class="price"><text class="red">¥{{liveItem.goodsCard.price}} </text><text class="del">¥{{liveItem.goodsCard.otPrice}}</text></view>
+								<view class="title oneline-hide">{{liveItem.goodsCard.productName}}</view>
 								<view class="button">立即抢购</view>
 							</view>
 						</view>
 					</view>
 
-
-
+					<!-- 观众列表弹窗 -->
 					<u-popup :show="showadd" @close="close" @open="openViews" round='20rpx' bgColor='#ffffff'>
 						<view class="view-box">
 							<view class="t-c fs30">在线观众</view>
@@ -209,21 +173,17 @@
 									<text>没有更多了</text>
 								</view>
 							</scroll-view>
-							<!-- <view class="fs24 u-flex-y-center bottom">
-								<view class="mr10" style="width:50rpx">我</view>
-								<u-avatar :src="livedata.liveImgUrl||$img.logo" size="32"></u-avatar>
-								<text class="ml16">{{livedata.liveName||"未命名"}}</text>
-							</view> -->
 						</view>
 					</u-popup>
 
+					<!-- 商品弹窗 -->
 					<u-popup :show="liveItem.shopping" @close="closeShop" @open="openShop" round='20rpx'
 						bgColor='f3f5f9'>
 						<view class="shoppop">
 							<view class="shoppop-top">
 								<u-avatar :src="store.logoUrl" size="36" class="ml16"></u-avatar>
 								<view class="search-input u-flex-y-center">
-									<image style="width: 24rpx;margin-right: 16rpx;" src="@/static/images/search.png"
+									<image style="width: 24rpx;margin-right: 16rpx;" src="/static/images/search.png"
 										mode="widthFix">
 									</image>
 									<input placeholder="请搜索商品" v-model="liveItem.inputInfo"
@@ -231,20 +191,20 @@
 								</view>
 								<view class="t-c search-top" style="margin-right: 48rpx;">
 									<image @click="onStoreCollect(liveItem)" v-if="store.isFavorite"
-										style="width:40rpx;height: 40rpx;" src="@/static/images/collect_select.png">
+										style="width:40rpx;height: 40rpx;" src="/static/images/collect_select.png">
 									</image>
 									<image v-else @click="onStoreCollect(liveItem)" style="width: 32rpx;height: 32rpx;"
-										src="@/static/images/collect.png"></image>
+										src="/static/images/collect.png"></image>
 									<view>收藏</view>
 								</view>
 								<view class="t-c search-top" @click="goOrderList(liveItem)">
-									<image style="width: 40rpx;height: 40rpx;" src="@/static/images/order.png"></image>
+									<image style="width: 40rpx;height: 40rpx;" src="/static/images/order.png"></image>
 									<view>订单</view>
 								</view>
 							</view>
 
 							<scroll-view enable-flex scroll-y class="shop-list" :style="{ height: boxHeight + 'px' }">
-								<view class="list-item " v-for="(item,index) in products" :key="index">
+								<view class="list-item" v-for="(item,index) in products" :key="index">
 									<view class="goods-img">
 										<image :src="item.imgUrl" mode="widthFix"></image>
 										<view class="goods-label">{{index+1}}</view>
@@ -256,7 +216,7 @@
 											<text class="nummber"><text
 													style="font-size: 20rpx;font-weight: 600;">¥</text><text
 													style="font-size: 36rpx;font-weight: bold;">{{Math.trunc(item.price)}}</text>.{{getPureDecimal(item.price)?getPureDecimal(item.price):'00'}}/日</text>
-											<view class="btn-group  u-flex-y-center">
+											<view class="btn-group u-flex-y-center">
 												<view class="collect-btn">
 													<image v-if="item.isFavorite" @click="onGoodsCollect(item)"
 														style="width: 32rpx;height: 32rpx;"
@@ -285,7 +245,6 @@
 		</swiper>
 	</view>
 </template>
-
 <script>
 	import Hls from 'hls.js';
 	import CryptoJS from 'crypto-js'
@@ -322,10 +281,9 @@
 		getAnswerlist,
 		submitAnswer
 	} from '@/api/home'
-
+	// var wsUrl = "wss://live.test.ylrztop.com/ws/live-api/app/webSocket"; //余红奇
 	var wsUrl = "ws://192.168.10.166:7114/app/webSocket"; //余红奇
 	// var wsUrl = "ws://192.168.10.125:7114/app/webSocket"; //涂小龙
-	// var wsUrl = "wss://live.test.ylrztop.com/ws/live-api/app/webSocket"; //余红奇
 	// var wsUrl = "ws://live.test.ylrztop.com/prod-api/app/webSocket"; //余红奇
 	// var wsUrl = "ws://nd383294.natappfree.cc/app/webSocket"; //余红奇
 	// var wsUrl = "ws://v56c9b8e.natappfree.cc/app/webSocket"; //余红奇
@@ -339,6 +297,11 @@
 	export default {
 		data() {
 			return {
+				// 新增:滑动节流相关变量
+				lastSwiperChangeTime: 0, // 上次切换时间戳
+				swiperChangeThrottle: 300, // 切换节流阈值(毫秒)
+
+
 				lastClickTime: 0,
 				clickDelay: 300, // 300ms内只响应一次点击
 
@@ -484,10 +447,15 @@
 			const currentLive = this.list[this.currentSwiperIndex];
 			if (currentLive) {
 				this.pauseVideo(currentLive);
+				this.clearTimeTimer(currentLive); // 隐藏时清除当前直播间定时器
 			} // 隐藏时关闭所有连接
 			this.closeAllWebSockets();
 		},
 		onUnload() {
+			// 清除所有直播间的时间定时器
+			this.list.forEach(liveItem => {
+				this.clearTimeTimer(liveItem);
+			});
 			// 关闭所有WebSocket连接
 			this.closeAllWebSockets();
 			this.socketInstances = {}; // 强制清空实例对象
@@ -523,7 +491,68 @@
 				immediate: true
 			}
 		},
-		methods: {
+		methods: { // 计算当前时间与 liveItem.startTime 的差值,并更新 totalTime
+			calculateTimeDiff(liveItem) {
+				// 1. 校验 startTime 格式(防止无效时间)
+				if (!liveItem.startTime) {
+					liveItem.totalTime = '00小时00分钟00秒';
+					return;
+				}
+				const iosCompatibleTime = liveItem.startTime
+					.replace(/-/g, '/') // 把所有 "-" 替换为 "/"
+					.replace(' ', ' '); // 保留空格(也可替换为 "T",即 "yyyy-MM-ddTHH:mm:ss")
+				// 2. 转换时间格式(字符串转 Date 对象)
+				const startTime = new Date(liveItem.startTime);
+				const now = new Date();
+				// 4. 容错处理:防止时间解析失败(极端情况)
+				if (isNaN(startTime.getTime())) {
+					console.warn(`iOS 时间解析失败,原始时间:${liveItem.startTime},转换后:${iosCompatibleTime}`);
+					liveItem.totalTime = '00小时00分钟00秒';
+					return;
+				}
+				// 3. 计算毫秒级差值(确保差值非负,避免未来时间出现负数)
+				const diffMs = Math.max(0, now - startTime);
+
+				// 4. 转换为 小时:分钟:秒(补零确保两位数)
+				const totalSeconds = Math.floor(diffMs / 1000);
+				const hours = this.padZero(Math.floor(totalSeconds / 3600));
+				const minutes = this.padZero(Math.floor((totalSeconds % 3600) / 60));
+				const seconds = this.padZero(totalSeconds % 60);
+
+				// 5. 更新当前直播间的 totalTime(响应式更新)
+				this.$set(liveItem, 'totalTime', `${hours}:${minutes}:${seconds}`);
+			},
+
+			// 辅助方法:数字补零(如 9 → 09)
+			padZero(num) {
+				return num < 10 ? `0${num}` : num;
+			},
+
+			// 启动当前直播间的时间差值定时器
+			startTimeTimer(liveItem) {
+				// 先清除当前直播间的旧定时器(避免重复)
+				if (liveItem.timeTimer) {
+					clearInterval(liveItem.timeTimer);
+				}
+
+				// 1. 立即计算一次(避免等待1秒才显示)
+				this.calculateTimeDiff(liveItem);
+
+				// 2. 每秒更新一次(实时刷新)
+				liveItem.timeTimer = setInterval(() => {
+					this.calculateTimeDiff(liveItem);
+				}, 1000);
+			},
+			// 清除指定直播间的时间定时器
+			clearTimeTimer(liveItem) {
+				if (liveItem.timeTimer) {
+					clearInterval(liveItem.timeTimer);
+					liveItem.timeTimer = null; // 清空定时器标识
+				}
+			},
+
+
+
 			toggleViewerList() {
 				const now = Date.now()
 				if (now - this.lastClickTime > this.clickDelay) {
@@ -616,6 +645,8 @@
 					]);
 
 					currentLive.loaded = true;
+					// 初始化完成后,启动当前直播间的时间差值定时器
+					this.startTimeTimer(currentLive);
 				} catch (error) {
 					console.error("初始化直播间数据失败:", error);
 				} finally {
@@ -676,14 +707,25 @@
 
 			// Swiper切换事件
 			async onSwiperChange(e) {
+				const now = Date.now();
 				const newIndex = e.detail.current;
 				const oldIndex = this.currentSwiperIndex;
+
+				// 相同索引或节流期间,不处理
 				if (newIndex === oldIndex) return;
+				if (now - this.lastSwiperChangeTime < this.swiperChangeThrottle) {
+					console.log('Swiper切换过快,已节流');
+					return;
+				}
+
+				// 更新最后切换时间
+				this.lastSwiperChangeTime = now;
 
 				// 1. 立即关闭旧直播间的WebSocket(同步操作)
 				const oldLive = this.list[oldIndex];
 				if (oldLive) {
 					this.pauseVideo(oldLive);
+					this.clearTimeTimer(oldLive); // 清除旧直播间的时间定时器
 					// 强制关闭并删除实例,确保连接被释放
 					if (this.socketInstances[oldLive.liveId]) {
 						try {
@@ -706,7 +748,7 @@
 
 				this.liveId = newLive.liveId;
 				this.resetUserListParams();
-				await this.initCurrentLiveData();
+				await this.initCurrentLiveData(); // 内部会启动新直播间的定时器
 				this.getliveUser(false);
 				setTimeout(() => {
 					this.playVideo(newLive);
@@ -729,7 +771,12 @@
 							shopping: false,
 							inputInfo: '',
 							showWelcomeMessage: false,
-							redInfo: {}
+							redInfo: {},
+							goodsCard:{},
+							totalTime: '00小时00分钟00秒', // 初始化差值为0
+							timeTimer: null, // 存储当前直播间的定时器,用于后续清理
+							// 预处理:统一将 startTime 转换为 iOS 兼容格式(避免重复转换)
+							startTime: item.startTime ? item.startTime.replace(/-/g, '/') : ''
 							// 其他初始化字段...
 						}));
 						console.log("直播间列表加载成功,数量:", this.list.length); // 确认数量是否 > 0
@@ -870,7 +917,8 @@
 							return;
 						}
 
-						this.liveViewers = isLoadMore ? [...this.liveViewers, ...res.rows] :res.rows; // 首次加载/切换直播间时重置数据
+						this.liveViewers = isLoadMore ? [...this.liveViewers, ...res.rows] : res
+							.rows; // 首次加载/切换直播间时重置数据
 						this.viewPageNum++;
 						// console.log("在线观众", this.liveViewers)
 					}
@@ -1010,20 +1058,31 @@
 
 			// 视频错误处理
 			videoError(e, liveItem) {
-				// 检查是否是当前直播间,避免处理非活跃直播间的错误
 				if (!liveItem || liveItem.liveId !== this.liveId) return;
 
+				// 初始化重试计数
+				if (this.videoRetryCounts[liveItem.liveId] === undefined) {
+					this.videoRetryCounts[liveItem.liveId] = 0;
+				}
+
 				// 限制重试次数
 				if (this.videoRetryCounts[liveItem.liveId] >= 3) {
-					console.error(`直播间 ${liveItem.liveId} 视频加载失败`);
+					console.error(`直播间 ${liveItem.liveId} 视频加载失败,停止重试`);
+					// 显示错误提示
+					uni.showToast({
+						title: "视频加载失败,请检查网络",
+						icon: 'none',
+						duration: 2000
+					});
 					return;
 				}
 
 				this.videoRetryCounts[liveItem.liveId]++;
 
-				// 延迟重试,避免与切换操作冲突
+				// 延迟重试
 				setTimeout(() => {
 					if (liveItem.liveId === this.liveId) {
+						console.log(`第${this.videoRetryCounts[liveItem.liveId]}次重试播放视频`);
 						this.playVideo(liveItem);
 					}
 				}, 2000);
@@ -1182,54 +1241,71 @@
 
 			// 点赞
 			async onLike(liveItem) {
-				// 基础校验
 				if (!liveItem || !liveItem.liveId) return;
-
-				// 确保liveViewData存在(初始化默认值)
-				if (!liveItem.liveViewData) {
-					await this.getliveViewData(liveItem);
-					if (!liveItem.liveViewData) {
-						uni.showToast({
-							title: "数据加载中,请稍后再试",
-							icon: 'none'
-						});
-						return;
-					}
-					// 初始化点赞数(防止undefined)
-					liveItem.liveViewData.like = liveItem.liveViewData.like || 0;
-				}
-
-				// 限制最多10次点赞
-				const maxLikeCount = 10;
-				if (liveItem.liveViewData.like >= maxLikeCount) {
-					uni.showToast({
-						title: "最多可点赞10次哦~",
-						icon: 'none'
-					});
-					return;
-				}
-
 				try {
 					const res = await liveDataLike(liveItem.liveId);
-					if (res.code === 200) {
-						// 无论后端是否返回res.like,前端按规则累加(最多到10次)
-						const newLikeCount = Math.min(liveItem.liveViewData.like + 1, maxLikeCount);
-						liveItem.liveViewData.like = newLikeCount;
-
+					if (res?.like) {
+						liveItem.liveViewData.like++; // 只更新当前直播间的点赞数
 					} else {
 						uni.showToast({
-							title: res.msg || "点赞失败",
+							title: res.msg,
 							icon: 'none'
 						});
 					}
 				} catch (error) {
 					console.error('点赞失败:', error);
-					uni.showToast({
-						title: "网络异常,点赞失败",
-						icon: 'none'
-					});
 				}
 			},
+			// 点赞
+			// async onLike(liveItem) {
+			// 	// 基础校验
+			// 	if (!liveItem || !liveItem.liveId) return;
+
+			// 	// 确保liveViewData存在(初始化默认值)
+			// 	if (!liveItem.liveViewData) {
+			// 		await this.getliveViewData(liveItem);
+			// 		if (!liveItem.liveViewData) {
+			// 			uni.showToast({
+			// 				title: "数据加载中,请稍后再试",
+			// 				icon: 'none'
+			// 			});
+			// 			return;
+			// 		}
+			// 		// 初始化点赞数(防止undefined)
+			// 		liveItem.liveViewData.like = liveItem.liveViewData.like || 0;
+			// 	}
+
+			// 	// 限制最多10次点赞
+			// 	const maxLikeCount = 10;
+			// 	if (liveItem.liveViewData.like >= maxLikeCount) {
+			// 		uni.showToast({
+			// 			title: "最多可点赞10次哦~",
+			// 			icon: 'none'
+			// 		});
+			// 		return;
+			// 	}
+
+			// 	try {
+			// 		const res = await liveDataLike(liveItem.liveId);
+			// 		if (res.code === 200) {
+			// 			// 无论后端是否返回res.like,前端按规则累加(最多到10次)
+			// 			const newLikeCount = Math.min(liveItem.liveViewData.like + 1, maxLikeCount);
+			// 			liveItem.liveViewData.like = newLikeCount;
+
+			// 		} else {
+			// 			uni.showToast({
+			// 				title: res.msg || "点赞失败",
+			// 				icon: 'none'
+			// 			});
+			// 		}
+			// 	} catch (error) {
+			// 		console.error('点赞失败:', error);
+			// 		uni.showToast({
+			// 			title: "网络异常,点赞失败",
+			// 			icon: 'none'
+			// 		});
+			// 	}
+			// },
 			//直播间点赞、关注、在线人数数据
 			async getliveViewData(liveItem) {
 				if (!liveItem || !liveItem.liveId) return;
@@ -1412,38 +1488,34 @@
 			// 修改关闭WebSocket方法
 			closeWebSocket(liveId = null) {
 				this.isManualClose = true;
-
-				// 清除所有定时器
 				clearInterval(this.pingpangTimes);
 				clearInterval(this.reconnectTimer);
 
-				// 关闭指定或所有WebSocket连接
 				if (liveId) {
-					// 关闭指定直播间的连接
+					// 添加空值检查
 					if (this.socketInstances[liveId] && this.socketInstances[liveId].instance) {
 						try {
-							this.socketInstances[liveId].instance.close(); // socketTask.close()
+							this.socketInstances[liveId].instance.close();
 							console.log(`直播间 ${liveId} WebSocket 已安全关闭`);
 						} catch (e) {
-							console.error('关闭失败', e);
+							console.error(`关闭直播间 ${liveId} WebSocket 时出错:`, e);
 						}
-						delete this.socketInstances[liveId];
 					}
+					delete this.socketInstances[liveId];
 				} else {
-					// 关闭所有连接
-					Object.keys(this.socketInstances).forEach(liveId => {
-						try {
-							uni.closeSocket({
-								instance: this.socketInstances[liveId]
-							});
-							console.log(`直播间 ${liveId} WebSocket 已安全关闭`);
-						} catch (e) {
-							console.error('关闭 WebSocket 时出错:', e);
+					Object.keys(this.socketInstances).forEach(id => {
+						// 添加空值检查
+						if (this.socketInstances[id] && this.socketInstances[id].instance) {
+							try {
+								this.socketInstances[id].instance.close();
+								console.log(`直播间 ${id} WebSocket 已安全关闭`);
+							} catch (e) {
+								console.error(`关闭直播间 ${id} WebSocket 时出错:`, e);
+							}
 						}
 					});
 					this.socketInstances = {};
 				}
-
 				isSocketOpen = false;
 			},
 			reConnect() {
@@ -1515,7 +1587,12 @@
 				}
 
 				this.isManualClose = false;
-
+				const connectTimeout = setTimeout(() => {
+					if (!this.socketInstances[liveId]?.isOpen) {
+						console.error(`WebSocket连接超时: ${liveId}`);
+						this.scheduleReconnect(liveId);
+					}
+				}, 10000); // 10秒超时
 				// 生成签名
 				const signature = CryptoJS.HmacSHA256(
 					`${liveId}${this.userinfo.userId}${this.userType}${this.timestamp}`,
@@ -1545,7 +1622,7 @@
 						console.log('WebSocket 连接已成功建立', res);
 						this.socketInstances[liveId].instance = socketTask;
 						this.socketInstances[liveId].isOpen = true;
-
+						clearTimeout(connectTimeout);
 						isSocketOpen = true;
 						this.connectingLiveId = null;
 						this.reconnectCount = 0;
@@ -1562,6 +1639,7 @@
 					});
 
 					socketTask.onError((err) => {
+						clearTimeout(connectTimeout);
 						console.error('WebSocket 连接错误:', err);
 						this.connectingLiveId = null;
 						this.scheduleReconnect(liveId);
@@ -1620,12 +1698,13 @@
 							// console.log("关闭欢迎消息:", liveItem.showWelcomeMessage);
 						}, 1000); // 1秒后隐藏
 					} else if (socketMessage.cmd == 'Integral') {
+						// 观看奖励事件 弹出框2s 显示msg
 						uni.showToast({
 							title: socketMessage.msg,
 							icon: 'none',
-							duration: 20000
+							duration: 2000
 						});
-						// 观看奖励事件 弹出框2s 显示msg
+
 					} else if (socketMessage.cmd == 'blockUser') {
 						//拉黑事件 主动删除用户token,强制跳转到登录页面
 						uni.removeStorage({
@@ -1640,10 +1719,12 @@
 								console.error('Token 删除失败:', err);
 							}
 						});
+					} else if (socketMessage.cmd == 'goods') {
+						this.$set(liveItem, 'goodsCard', JSON.parse(socketMessage.data));
 					}
-					// else if (socketMessage.data.cmd == 'deleteId') {
+					// else if (socketMessage.cmd == 'deleteId') {
 
-					// } else if (socketMessage.data.cmd =='sendRedPacketQuestion') {
+					// } else if (socketMessage.cmd =='sendRedPacketQuestion') {
 
 					// }
 				} else {
@@ -1654,15 +1735,17 @@
 				}
 
 			},
-			scheduleReconnect() {
+			scheduleReconnect(liveId) {
 				if (this.isManualClose || this.reconnectCount >= this.maxReconnectAttempts) return;
 				this.reconnectCount++;
 				const delay = Math.min(3000 * this.reconnectCount, 30000);
 				clearInterval(this.reconnectTimer);
 				this.reconnectTimer = setTimeout(() => {
-					this.initSocket(this.list.find(item => item.liveId === liveId) || {
+					// 使用传入的liveId
+					const liveItem = this.list.find(item => item.liveId === liveId) || {
 						liveId
-					});
+					};
+					this.initSocket(liveItem);
 				}, delay);
 			},
 			sendMsg(liveItem) {
@@ -1979,6 +2062,15 @@
 			width: 100%;
 			background-color: rgba(57, 57, 57, 0.4);
 
+			.time {
+				position: relative;
+				z-index: 999;
+				margin-top: -40rpx;
+				color: #ffffff;
+				font-size: 20rpx;
+				margin-left: 10rpx;
+			}
+
 			.videotop {
 				width: 100%;
 				height: 100%;
@@ -1996,8 +2088,11 @@
 
 	.goods {
 		position: fixed;
-		bottom: 160rpx;
-		right: 10rpx;
+		// bottom: 160rpx;
+		// right: 10rpx;
+		top: 50%;
+		left: 50%;
+		transform: translate(-50%,-50%);
 		z-index: 5;
 		background-color: #fff;
 		border-radius: 20rpx;

文件差異過大導致無法顯示
+ 0 - 0
unpackage/dist/dev/mp-weixin/common/assets.js


文件差異過大導致無法顯示
+ 0 - 0
unpackage/dist/dev/mp-weixin/pages/home/living.js


文件差異過大導致無法顯示
+ 0 - 0
unpackage/dist/dev/mp-weixin/pages/home/living.wxml


文件差異過大導致無法顯示
+ 0 - 0
unpackage/dist/dev/mp-weixin/pages/home/living.wxss


文件差異過大導致無法顯示
+ 0 - 0
unpackage/dist/dev/mp-weixin/pages_no/zuizao.js


部分文件因文件數量過多而無法顯示