Преглед на файлове

静默+授权+其他改动

liujiaxin преди 2 седмици
родител
ревизия
5c38313b70

+ 1 - 1
api/living.js

@@ -224,7 +224,7 @@ export function sendliveGift(data) {
  }
 // 静默登录
 export function loginByMp(data) {
-	return request('/liveAPP/app/wx/courseLogin', data, 'POST', 'application/json;charset=UTF-8');
+	return request('/liveAPP/app/wx/login', data, 'POST', 'application/json;charset=UTF-8');
 }
 export function getUserInfo() {
 	return request('/liveAPP/app/user/getUserInfo', null, 'GET');

+ 25 - 24
pages/user/index.vue

@@ -42,33 +42,34 @@
 						</view>
 						<view class="status-box">
 							<uni-badge size="small" :text=count0 absolute="rightTop" type="error">
-								<view class="item" @click="showOrder('0')">
+								<view class="item" @click="showOrder('')">
 									<image src="../../static/images/payment.png" mode=""></image>
-									<text class="text">待付款</text>
+									<text class="text">购物订单</text>
 								</view>
 							</uni-badge>
-							<uni-badge size="small" :text=count1 absolute="rightTop" type="error">
+							<uni-badge size="small" :text=afterSalesCount absolute="rightTop" type="error">
+							<view class="item" @click="navgetTo('/pages_user/user/refundOrderList')">
+								<image src="../../static/images/after_sales.png" mode=""></image>
+								<text class="text">购物售后</text>
+							</view>
+							</uni-badge>
+							<!-- <uni-badge size="small" :text=count1 absolute="rightTop" type="error">
 							<view class="item" @click="showOrder('1')">
 								<image src="../../static/images/send_goods.png" mode=""></image>
 								<text class="text">待发货</text>
 							</view>
-							</uni-badge>
+							</uni-badge> -->
 							<uni-badge size="small" :text=count2 absolute="rightTop" type="error">
-							<view class="item" @click="showOrder('2')">
+							<view class="item" @click="navgetTo('/pages_shopping/live/order')">
 								<image src="../../static/images/sou_goods.png" mode=""></image>
-								<text class="text">待收货</text>
+								<text class="text">直播订单</text>
 							</view>
 							</uni-badge>
-							<view class="item" @click="showOrder('3')">
+							<view class="item"@click="navgetTo('/pages_shopping/live/storeOrderRefundList')">
 								<image src="../../static/images/completed.png" mode=""></image>
-								<text class="text">已完成</text>
-							</view>
-							<uni-badge size="small" :text=afterSalesCount absolute="rightTop" type="error">
-							<view class="item" @click="navgetTo('/pages_user/user/refundOrderList')">
-								<image src="../../static/images/after_sales.png" mode=""></image>
-								<text class="text">售后/退款</text>
+								<text class="text">直播售后</text>
 							</view>
-							</uni-badge>
+							
 						</view>
 					</view>
 				</view>
@@ -90,18 +91,18 @@
 								<image src="../../static/images/my_ask.png" mode=""></image>
 								<text class="text">我的问诊</text>
 							</view> -->
-							<view class="item no-marin-bottom" @click="navgetTo('/pages_shopping/live/order')">
+							<!-- <view class="item no-marin-bottom" @click="navgetTo('/pages_shopping/live/order')">
 								<image src="../../static/images/live.png" mode=""></image>
 								<text class="text">直播订单</text>
-							</view>
-							<view class="item" @click="navgetTo('/pages_user/user/prescribeOrder')">
+							</view> -->
+							<!-- <view class="item" @click="navgetTo('/pages_user/user/prescribeOrder')">
 								<image src="../../static/images/prescription.png" mode=""></image>
 								<text class="text">我的处方</text>
-							</view>
-							<view class="item" @click="navgetTo('/pages_user/user/patient')">
+							</view> -->
+							<!-- <view class="item" @click="navgetTo('/pages_user/user/patient')">
 								<image src="../../static/images/management.png" mode=""></image>
 								<text class="text">就诊人管理</text>
-							</view>
+							</view> -->
 							<view class="item" @click="navgetTo('/pages_user/user/address')">
 								<image src="../../static/images/address.png" mode=""></image>
 								<text class="text">收货地址</text>
@@ -131,10 +132,10 @@
 								<text class="text">专属客服</text>
 								<button class="contact-btn" open-type="contact"></button>
 							</view>
-							<view v-if="user.isPromoter==0" class="item no-marin-bottom"  @click="navgetTo('/pages_user/user/userTuiAdd')">
+							<!-- <view v-if="user.isPromoter==0" class="item no-marin-bottom"  @click="navgetTo('/pages_user/user/userTuiAdd')">
 								<image src="../../static/images/my_promotion.png" mode=""></image>
 								<text class="text">申请健康大使</text>
-							</view>
+							</view> -->
 							<view v-if="user.isPromoter==1" class="item no-marin-bottom"  @click="navgetTo('/pages_user/user/userTui')">
 								<image src="../../static/images/my_promotion.png" mode=""></image>
 								<text class="text">我的推广</text>
@@ -160,10 +161,10 @@
 				<view style="padding-bottom: 20rpx;" v-if="user.phone!=''">
 					<view @tap="loginOUt" class="log-out x-c" >退出登录</view>
 				</view>
-				<!-- <view class="banner">
+				<view class="banner">
 					<image src="https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20221125/71ddd95044bb46d5b27e19a5f61cf5ab.png"></image>
 					<view class="tel_btn" @click="callService()"></view>
-				</view> -->
+				</view>
 				<view class="like-product">
 					<likeProduct  ref="product" />
 				</view>

+ 1 - 1
pages_company/storeOrderDetail.vue

@@ -124,7 +124,7 @@
 								<view class="price-num">
 									<view class="price">
 										<text class="unit">¥</text>
-										<text class="num">{{JSON.parse(item.jsonInfo).price.toFixed(2)}}</text>
+										<text class="num">{{JSON.parse(item.jsonInfo).price.toFixed(2) ||'0.00'}}</text>
 									</view>
 									<view class="num">x{{JSON.parse(item.jsonInfo).num}}</view>
 								</view>

BIN
pages_course/__MACOSX/._living.vue


BIN
pages_course/living 2.vue/__MACOSX/._living.vue


+ 0 - 4473
pages_course/living 2.vue/living3333.vue

@@ -1,4473 +0,0 @@
-<template>
-	<view class="swiper-wrapper">
-		<!-- 状态栏占位 -->
-		<image src="https://fs-1323137866.cos.ap-chongqing.myqcloud.com/live_bg.jpg" class="live-bg"></image>
-		<view class="container" :class="isFullscreen ? 'fullscreen ' : ''">
-			<view class="content">
-				<view style="position: fixed; top: 0; z-index: 5" class="content-top">
-					<view class="">
-						<view class="x-f">
-							<image v-if="!scene" @click="goBack" class="w60 h64  mr6"
-								src="/static/images/return3.png" />
-							<view class="align-center"
-								style="padding: 6rpx 8rpx; height: 64rpx; background: rgba(0,0,0,0.5); border-radius: 32rpx">
-								<u-avatar :src="liveItem.liveImgUrl || '/static/images/avatar.png'"
-									:size="32"></u-avatar>
-								<view class="colorf ml10 mr6">
-									<view>{{ liveItem.liveName ? truncateString(liveItem.liveName, 8) : '未命名' }}</view>
-								</view>
-							</view>
-						</view>
-						<!-- 积分倒计时 -->
-						<view class="progress-countdown" :class="liveItem.showType==2?' progress-vertical':''"
-							:style="{ 'display':isFocus?'none':''}"
-							v-if="countdownPercentage!=100&&liveItem.completionPointsEnabled&&liveItem.status==2&&!isPreview">
-							<image class="title" src="/static/images/points_title.png"></image>
-							<view class="progress-bar-bg">
-								<view class="progress-bar-fill" :style="{ width: countdownPercentage + '%' }"></view>
-							</view>
-							<view class="progress-text">
-								倒计时{{ formattedCountdown.hours||'00' }}:{{ formattedCountdown.minutes||'00' }}:{{ formattedCountdown.seconds||'00' }}
-							</view>
-						</view>
-					</view>
-					
-					<view class="end">
-						<view v-if="Array.isArray(filteredViewers)" class="align-center" @click="toggleViewerList"
-							style="margin-top: 88rpx">
-							<view v-for="(item, viewerIndex) in filteredViewers" :key="viewerIndex">
-								<image v-if="item.avatar" class="w52 h52 mr4" style="border-radius: 26rpx"
-									:src="item.avatar" />
-								<view v-else class="w52 h52 mr4"
-									:style="{ backgroundColor: getUserRandomColor(item.userId), borderRadius: '50%' }">
-									<text class="text-white text-xs">{{ getNicknameInitial(item.nickName) }}</text>
-								</view>
-							</view>
-							<view class="sum">{{ formattedWatchCount || 0 }}</view>
-						</view>
-						
-						<view class="complaint-box" @click="navgetTo('/pages_shopping/live/complaintList')">
-							<image class="image w32 h32 mr10" src="/static/images/complaint.png" mode="widthFix" />
-							<view class="fs26">投诉</view>
-						</view>
-					</view>
-				</view>
-
-				<!-- 积分倒计时 -->
-				<!-- <view class="progress-countdown end" :class="liveItem.showType==2?' progress-vertical':''"
-					:style="{ 'display':isFocus?'none':''}"
-					v-if="countdownPercentage!=100&&liveItem.completionPointsEnabled&&liveItem.status==2&&!isPreview">
-					<image class="title" src="/static/images/points_title.png"></image>
-					<view class="progress-bar-bg">
-						<view class="progress-bar-fill" :style="{ width: countdownPercentage + '%' }"></view>
-					</view>
-					<view class="progress-text">
-						倒计时{{ formattedCountdown.hours||'00' }}:{{ formattedCountdown.minutes||'00' }}:{{ formattedCountdown.seconds||'00' }}
-					</view>
-				</view> -->
-
-				<!-- 右边的side -->
-				<view v-show="!isFocus" class="side-group" :class="{
-                  'top2': (!isShowRed && !(isShowLottery && countdown)),
-                  'top3': (isShowRed || (isShowLottery && countdown))}">
-					<view class="side-item" @click="onRed()" v-if="isShowRed">
-						<button class="button button-reset" style="height: 70rpx;">
-							<image class="image" style="width: 72rpx;" src="/static/images/redbag.png"
-								mode="widthFix" />
-						</button>
-						<view class="fs30">领红包</view>
-					</view>
-					<view class="side-item" @click="onLottery()" v-if="isShowLottery && countdown">
-						<button class="button button-reset">
-							<image class="image" src="/static/images/lottery.png" mode="widthFix" />
-						</button>
-						<view class="fs30">抽奖</view>
-					</view>
-					<view class="side-item" @click="onLike">
-						<LikeButton :initialCount="100" :heartsPerClick="5" @like="onLike" />
-						<view class="txt" style="font-size: 30rpx;">{{ formattedLikeCount || 0 }}</view>
-					</view>
-					<view class="side-item">
-						<button open-type="share" class="button button-reset">
-							<image class="image" src="/static/images/weixin1.png" mode="widthFix" />
-						</button>
-						<view class="txt" style="font-size: 30rpx;">分享</view>
-					</view>
-				</view>
-
-				<!-- 直播 -->
-				<LiveVideo class="live-video" ref="liveVideo" :isAgreement="isAgreement" :liveItem="liveItem"
-					:hasSubscribed="hasSubscribed" :liveId="liveId" :userData="userData" @liveStart="handleLiveStart"
-					@videoError="handleVideoError" @liveStateChange="handleLiveStateChange"
-					@agreementClick="handleAgreement" @fullscreen-change="handleFullscreenChange" />
-
-				<!-- 底部聊天区域 -->
-				<view class="chat-area-container" :class="{ 'chat-area-focused': isFocus }"
-					:style="{ '--keyboard-height': keyboardHeight + 'rpx' }">
-					<view class="mt20 chat-content"
-						:class="{ 'chat-content-focused': isFocus ,'chat-content-preview':liveItem.status==1}">
-						<view v-if="showPurchasePrompt && orderUser && orderUser.count && liveItem.status == 2"
-							class="shop-prompt f30 mb20">
-							<image class="w32 h32 mr8" src="/static/images/shopping.png" />
-							<text>{{ orderUser.count || 0 }}人正在去购买</text>
-						</view>
-
-						<view v-if="showWelcomeMessage" class="welcome-message" style="max-width: 100%">
-							<view class="list justify-start" v-show="inAndOut.cmd == 'entry' || inAndOut.cmd == 'out'">
-								<view class="talk-list justify-start">
-									<view class="fs30">
-										<text style="color: #ff89d6">{{ inAndOut.nickName || '未命名' }}</text>
-										<text class="colorf">{{ inAndOut.msg }}直播间</text>
-									</view>
-								</view>
-							</view>
-						</view>
-
-						<view class="notice-message" v-if="!isFocus && isShowNotice">
-							公告消息: {{ notice.msg }}
-						</view>
-
-						<scroll-view id="msgScroll" v-if="Array.isArray(talklist)" enable-flex scroll-y="true"
-							:enhanced="true" :bounces="false" :show-scrollbar="false" :fast-deceleration="false"
-							:enable-back-to-top="false" class="scrolly flex-1 column"
-							style="width: calc(100% - 20rpx); -webkit-overflow-scrolling: touch;"
-							:scroll-top="scrollTop" :scroll-into-view="scrollIntoView" @scroll="onScroll"
-							ref="scrollView" scroll-with-animation="true" :scroll-animation-duration="300">
-							<view class="list justify-start" v-for="(item, talkIndex) in talklist || []"
-								:key="item.uniqueId || talkIndex" :id="`list_${item.uniqueId || talkIndex}`"
-								v-show="item.cmd != 'red' && item.cmd != 'out' && item.cmd != 'entry'">
-								<view class="talk-list justify-start">
-									<view class="fs30 talk-item" style="max-width: 100%;">
-										<text class="nickname"
-											style="color: #ffda73;">{{ item.nickName || '未命名' }}:</text>
-										<text class="message colorf">{{ item.msg }}</text>
-									</view>
-								</view>
-							</view>
-						</scroll-view>
-
-						<!-- 一键弹幕 -->
-						<u-scroll-list :indicator="false" v-if="!isFocus">
-							<view class="barrage" v-for="(item, index) in barrageList" :key="index"
-								@click="onBarrage(item)">
-								{{ item }}
-							</view>
-						</u-scroll-list>
-					</view>
-
-					<!-- 聊天输入组件 -->
-					<ChatInput ref="chatInput" :value="value" :focused="isFocus" :placeholderText="placeholderText"
-						@focus="onInputFocus" @blur="onInputBlur" @send="onSendMessage" @open-cart="openCart"
-						@show-gift="showGift" @input="onInputChange" @show-more="handleShowMore" />
-				</view>
-			</view>
-
-			<!-- 商品卡片 -->
-			<LiveGoods class="shop-card" :isShow="isShowGoods" :goodsData="goodsCard" @goShop="handleGoShop"
-				@close="handleCloseGoods" />
-
-			<!-- 抽奖弹窗 -->
-			<LotteryPopup :show="isShowLotteryPop && countdown" :countdown="countdown" :products="lotteryProducts"
-				@close="handleLotteryClose" @claim="handleLotteryClaim" />
-
-			<u-popup :show="!!integral.status" round="20rpx" mode="center" bgColor="#ffffff" zIndex="10076">
-				<view class="integral-box">
-					<view class="top">
-						<view class="title">观看视频领芳华币</view>
-						<image class="photo" src="/static/images/integral_bg.png" mode="widthFix" />
-					</view>
-					<view class="item">
-						<view class="title">{{ integral.msg }}</view>
-						<view class="button" @click="integral.status = false">确认</view>
-					</view>
-				</view>
-			</u-popup>
-
-			<u-popup :show="shouldShowIntegralPopup" round="20rpx" mode="center" bgColor="#ffffff" zIndex="10076">
-				<view class="integral-popup color9">
-					<view class="integral-header">
-						<view class="integral-title">观看视频领积分</view>
-						<image class="integral-background-image"
-							src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/userapp/images/integral_bg.png"  mode="widthFix" />
-					</view>
-					<view class="integral-content">
-						<view class="integral-message">积分发放成功</view>
-					</view>
-				</view>
-			</u-popup>
-
-			<u-popup :show="isShowRedCard" round="20rpx" mode="center" bgColor="transparent" zIndex="10076">
-				<view class="red-card">
-					<image class="img" src="/static/images/red_card.png" />
-					<view class="red-content">
-						<view class="title">{{ redCard.msg }}</view>
-						<view class="txt">直播惊喜芳华币</view>
-						<view class="button" @click="isShowRedCard = false">确认</view>
-					</view>
-				</view>
-			</u-popup>
-
-			<!-- 中奖和未中奖 -->
-			<u-popup :show="isShowPrize && havePrize" round="20rpx" mode="center" bgColor="#fff" zIndex="10076">
-				<view class="prize-card" v-if="isCurrentUserWon">
-					<image class="nav-img" src="/static/images/red_head.png" mode="widthFix" />
-					<view class="title">恭喜您 中奖啦!</view>
-					<view class="prize-content" v-for="(item, index) in prizeInfo || []" :key="index">
-						<view class="item">{{ item.userName }}</view>
-						<view class="item">{{ item.userId }}</view>
-						<view class="txt item">{{ item.prizeLevel }}等奖</view>
-					</view>
-					<view class="tip">请填写收货地址,主播将会将奖品发给您</view>
-					<view class="button"
-						@click="navgetTo('/pages_shopping/live/confirmCreateOrder?type=win&productId='+getCurrentUserPrizeProductId+'&liveId='+liveId+'&recordId='+getCurrentUserPrizeRecordId),confirm()">
-						填写地址
-					</view>
-				</view>
-				<view class="no-prize-card" v-else>
-					<image class="img" src="/static/images/no-prize.png" mode="widthFix" />
-					<view class="tip">很遗憾 您未中奖</view>
-					<view class="button" @click="confirm">确认</view>
-				</view>
-			</u-popup>
-
-			<!-- 中奖记录 -->
-			<WinningPopup :show="winning" :prizeList="prizeAll" :liveId="liveId" @close="closeWin"
-				@fill-address="handleFillAddress" />
-
-			<!-- 观众列表弹窗 -->
-			<Viewer ref="viewer" :show="showViewerList" :viewers="liveViewers" :lookAudsCount="lookAudsCount" :loading="viewLoading" :scrollHeight="scrollHeight"
-				@close="closeViewerList" @open="openViewerList" @loadMore="handleViewerLoadMore" />
-
-			<!-- 更多弹窗 -->
-			<u-popup :show="isMore" @close="closeMore" round="20rpx" bgColor="#f3f5f9" zIndex="10076">
-				<view class="more-block">
-					<view class="item" @click="navgetTo('/pages_shopping/live/integral'), (isMore = false)">
-						<image class="w48 h48" src="/static/images/order.png" />
-						<view style="text-align: center">芳华币</view>
-					</view>
-					<view class="item"
-						@click="navgetTo('/pages_shopping/live/storeOrderRefundList?liveId=' + liveId), (isMore = false)">
-						<image class="w48 h48" src="/static/images/after_sales.png" />
-						<view style="text-align: center">售后订单</view>
-					</view>
-					<view class="item" @click="goMiniProgram(), (isMore = false)">
-						<image class="w48 h48" src="/static/images/points.png" />
-						<view style="text-align: center">兑换好礼</view>
-					</view>
-					<view class="item" @click="getMyLottery(), (isMore = false), (winning = true)">
-						<image class="w48 h48" src="/static/images/health_sel.png" />
-						<view style="text-align: center">中奖记录</view>
-					</view>
-				</view>
-			</u-popup>
-
-			<!-- 送礼物 -->
-			<u-popup :show="isShowGift" @close="closeGift" round="20rpx" bgColor="#242424" zIndex="10076">
-				<view class="gift">
-					<view class="gift-top">
-						<view class="left">
-							送花给<text class="ml8 orange">{{liveItem.liveName}}</text>
-						</view>
-						<view class="align-center" @click="navgetTo('/pages_shopping/live/integral')">
-							<image class="w32 h32" src="/static/images/coin.png" />
-							<text class="ml6 mr6 f24">{{integralNum}}</text>
-							<image class="w24 h24" src="/static/images/arrow_white.png" />
-						</view>
-					</view>
-					<view class="gift-block">
-						<view :class="['item', { 'active': activeIndex === index }]" @click="activeIndex = index"
-							v-for="(item, index) in giftList" :key="index">
-							<image class="w104 h104" :src="item.img" />
-							<view class="name">{{ item.giftName }}</view>
-							<view v-if="activeIndex === index" class="button" @click="sendliveGift(item)">赠送</view>
-							<view class="number" v-else>{{ item.price }}芳华币</view>
-						</view>
-					</view>
-				</view>
-			</u-popup>
-
-			<!-- 商品弹窗组件 -->
-			<ShopPopup class="shop" :show="shopping" :searchKeyword="inputInfo" :products="products"
-				:loading="loadingProducts" :boxHeight="boxHeight" @close="closeShop" @search="handleSearchInput"
-				@navigate-to-order="handleNavigateToOrder" @show-more="handleShowMore" @collect="onGoodsCollect"
-				@go-shop="handleGoShopFromCart" />
-
-			<!-- 优惠券弹窗 -->
-			<view class="coupon-pop" v-if="isShowCoupon">
-				<view class="coupon-block">
-					<image class="bg" src="/static/images/coupon_bg.png" />
-					<image class="nav" src="/static/images/coupon_top.png" />
-					<image @click="isShowCoupon = false" class="w40 h40 close" style="z-index: 99"
-						src="/static/images/close1.png" />
-					<view class="item">
-						<view class="title">{{ couponInfo.couponName }}</view>
-						<view class="price">
-							¥
-							<text class="bold">{{ couponInfo.couponPrice }}</text>
-						</view>
-						<view class="txt">满{{ couponInfo.useMinPrice }}元可用</view>
-						<view class="txt" style="margin-top: 26rpx">指定商品可用</view>
-						<view class="txt">自领取起{{ couponInfo.couponTime }}天内有效</view>
-						<view class="button" @click="onCoupon()">立即领券</view>
-					</view>
-				</view>
-			</view>
-			<view class="custom-toast" v-if="showToast">
-				<view class="toast-content">
-					观看奖励已到账
-				</view>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	import ChatInput from '@/pages_course/components/chatInput.vue'
-	import Viewer from '@/pages_course/components/viewer.vue'
-	import LiveVideo from '@/pages_course/components/liveVideo.vue'
-	import ShopPopup from '@/pages_course/components/shopPopup.vue'
-	import LotteryPopup from '@/pages_course/components/lotteryPopup.vue'
-	import WinningPopup from '@/pages_course/components/winningPopup.vue'
-	import LiveGoods from '@/pages_course/components/liveGoods.vue'
-	import LikeButton from '@/pages_course/components/like.vue'
-	import CryptoJS from 'crypto-js'
-	import {
-		myLottery,
-		coupon,
-		liveLottery,
-		claim,
-		liveRed,
-		liveDataLike,
-		collectStore,
-		collectGoods,
-		watchUserList,
-		liveMsg,
-		liveStore,
-		liveOrderUser,
-		getLiveInfo,
-		getLiveViewData,
-		currentActivities,
-		getlive,
-		subNotifyLive,
-		internetTraffic,
-		liveInternetTraffic,
-		remainingTime,
-		updateWatchDuration,
-		receivePoints,
-		activeList,
-		sendliveGift,
-		getUserIntegralInfo //芳华币
-	} from '@/api/living.js'
-	import {
-		getUserInfo
-	} from '@/api/user'
-	import {
-		generateRandomString
-	} from '@/utils/common.js'
-	import dayjs from 'dayjs'
-	import {
-		nextTick
-	} from 'vue'
-
-	var isSocketOpen = false
-	var socket = null
-
-	export default {
-		components: {
-			LikeButton,
-			LiveGoods,
-			LotteryPopup,
-			WinningPopup,
-			ShopPopup,
-			LiveVideo,
-			Viewer,
-			ChatInput
-		},
-		data() {
-			return {
-				hasSubscribed: false, // 已成功订阅(永久禁用)
-				integralNum: null, //礼物芳华币数量
-				isPreview: true, //是否预告
-				hasReplayGeneration: false, //是否经历回放生成
-				diffLiveStartTime: 0, //距离直播开始时间差值
-				diffLiveEndTime: 0, //距离直播结束时间差值
-				diffReplayGenerationSeconds: 0, //经历回放生成的秒速
-				completionTime: 0, //领取积分所需时间
-				hasLiveEnd: false, //是否经历过首播结束
-				isPageLoadFirst: true, //是否首次加载直播间
-				pointsRetryTimer: null, // 积分领取重试定时器
-				showToast: false,
-				videoDuration: 0, //要看的时长
-				pointsRemainingTime: 0,
-				hasReceived: false,
-				completionRate: 0,
-
-				liveBeginWatchTime: 0,
-				showPoints: false,
-				pointsRemainingTime: null,
-				remainingTime: null,
-				// receiveStatus: false,
-				watchDuration: null,
-				isFullscreen: null,
-				notice: [],
-				isShowNotice: false,
-				showViewerList: false,
-				giftList: [{
-						img: '/static/images/gift1.png',
-						name: '人气票',
-						number: 1
-					},
-					{
-						img: '/static/images/gift2.png',
-						name: '小心心',
-						number: 1
-					},
-					{
-						img: '/static/images/gift3.png',
-						name: '棒棒糖',
-						number: 9
-					},
-					{
-						img: '/static/images/gift4.png',
-						name: '玫瑰',
-						number: 50
-					},
-					{
-						img: '/static/images/gift5.png',
-						name: '鲜花',
-						number: 88
-					},
-					{
-						img: '/static/images/gift6.png',
-						name: '水晶球',
-						number: 99
-					},
-					{
-						img: '/static/images/gift7.png',
-						name: '啤酒',
-						number: 128
-					},
-					{
-						img: '/static/images/gift8.png',
-						name: '浪漫热气球',
-						number: 1000
-					}
-				],
-				activeIndex: -1,
-				barrageList: ['支持你!', '谢谢你!', '平台真好!', '666', '欢迎回家!'],
-				uuId: '',
-				totalTraffic: 0,
-				bitrate: 800,
-				bitrateLive: 1600,
-				trafficTimer: null,
-				pingTimeoutTimer: null,
-				heartBeatTimer: null,
-				liveViewDataTimer: null,
-				lookAudsCount:0,//更多的观众人数
-				reconnectTimer: null,
-				scrollTimer: null,
-				lastScrollTime: 0,
-				scrollDebounceDelay: 200,
-				searchTimer: null,
-				purchasePromptTimer: null,
-				welcomeTimer: null,
-				redTimer: null,
-				liveStartTimer: null,
-				lotteryTimer: null,
-				memoryMonitorTimer: null,
-				networkStatusTimer: null,
-				networkRetryTimer: null,
-				lastHeartBeatTime: 0,
-				connectionStartTime: 0,
-				connectionLatency: 0,
-				messageCount: 0,
-				errorCount: 0,
-				lastPerformanceCheck: 0,
-				stayTime: 0,
-				startTime: 0,
-				scrollTop: 0,
-				currentScrollTop: 0,
-				scrollIntoView: '',
-				messageIdCounter: 0,
-				scrollPending: false,
-				isOnload: false,
-				isConnecting: false,
-				hasInitialized: false,
-				liveViewersData: [],
-				liveTopViewersData: [],
-				liveUserCalled: false,
-				userRandomColors: Object.create(null),
-				heartBeatRetryCount: 0,
-				maxHeartBeatRetries: 3,
-				pingTimeout: 25000,
-				shownEntryUsers: new Set(),
-				socket: null,
-				isSocketOpen: false,
-				heartBeatInterval: 15000,
-				adaptiveHeartBeatInterval: 15000,
-				reconnectCount: 0,
-				maxReconnectAttempts: 5,
-				isManualClose: false,
-				networkType: 'unknown',
-				isNetworkAvailable: true,
-				templateId: 'bpc9DOFwugg7_cNDN260TRclIgmIjDOuvLxIbM-c0mg',
-				isAgreement: false,
-				wsNewUrl: 'wss://api.fhhx.runtzh.com/ws/app/webSocket',
-				qrFrom: null,
-				scene: '',
-				liveCountdown: {},
-				countdown: {},
-				liveViewData: {},
-				keyboardHeight: 0,
-				videoCurrentTime: 0,
-				videoProgressKey: '',
-				inAndOut: {},
-				winning: false,
-				isShowPrize: false,
-				isShowCoupon: false,
-				isShowGift: false,
-				prizeInfo: [],
-				havePrize: uni.getStorageSync('havePrize') || false,
-				countDownKey: 0,
-				lotteryProducts: [],
-				lotteryList: [],
-				talklist: [],
-				isShowLotteryPop: false,
-				liveItem: {},
-				isSending: false,
-				isMore: false,
-				value: '',
-				placeholderText: '说点什么...',
-				prizeAll: [],
-				isShowLottery: false,
-				isShowRedCard: false,
-				redCard: null,
-				integral: {},
-				lotteryInfo: {},
-				goodsCard: {},
-				couponInfo: {},
-				redInfo: {},
-				storeId: null,
-				isFocus: false,
-				shopping: false,
-				systemInfo: null,
-				inputInfo: '',
-				showWelcomeMessage: false,
-				isShowGoods: false,
-				isShowRed: false,
-				lastClickTime: 0,
-				videoRetryCounts: Object.create(null),
-				clickDelay: 300,
-				liveUserTotal: 0,
-				viewPageSize: 10,
-				viewPageNum: 1,
-				viewLoading: false,
-				scrollHeight: 0,
-				showPurchasePrompt: false,
-				prevOrderCount: 0,
-				videoUrl: null,
-				boxHeight: 300,
-				liveViewers: [],
-				products: [],
-				loadingProducts: false,
-				orderUser: {},
-				userType: 0,
-				timestamp: '',
-				liveId: null,
-				userinfo: '',
-				userData: {},
-				diffTotalTime: '',
-				virtualTotal:0,
-			}
-		},
-		async onLoad(options) {
-			if (options.liveId) {
-				this.liveId = options.liveId
-			}
-			if (options.scene) {
-				this.scene = options.scene
-				const decodedScene = decodeURIComponent(this.scene)
-				const params = {}
-				decodedScene.split('&').forEach((item) => {
-					const [key, value] = item.split('=')
-					params[key] = value
-					this.liveId = params.a
-				})
-				if (params.b && params.c) {
-					this.qrFrom = `&companyId=${params.b}&companyUserId=${params.c}`
-				}
-			}
-
-			if (options.companyId && options.companyUserId) {
-				this.qrFrom = `&companyId=${options.companyId}&companyUserId=${options.companyUserId}`
-			}
-			this.userinfo = uni.getStorageSync('userInfo')
-			this.userData = uni.getStorageSync('userData')
-			this.hasSubscribed = uni.getStorageSync('subscribe_status_' + this.liveId) || false;
-			try {
-				const isLogin = await this.utils.isLogin()
-				if (isLogin) {
-					await this.getUserInfo()
-					this.initTime()
-					if (this.liveId) {
-						const res = await this.getliving(this.liveId)
-						if (res && res.data) {
-							if (res.data.videoFileSize) {
-								this.liveItem.videoFileSize = res.data.videoFileSize
-							}
-							if (res.data.videoDuration) {
-								this.liveItem.videoDuration = res.data.videoDuration
-							}
-						}
-						this.isOnload = true
-						await this.getLiveMsg(this.liveId)
-						await this.getliveViewData()
-					}
-				}
-			} catch (error) {
-				console.error('初始化失败:', error)
-			}
-			
-			this.startMemoryMonitor();
-			
-			//获取礼物列表
-			this.getActiveList();
-
-			uni.onKeyboardHeightChange((res) => {
-				console.log('键盘高度变化:', res.height, '平台:', this.systemInfo.platform)
-				if (this.systemInfo.platform === 'ios') {
-					if (res.height > 0) {
-						this.isKeyboardShow = true
-						let calculatedHeight = res.height * 2
-						if (this.systemInfo.model) {
-							if (this.systemInfo.model.includes('iPhone X') ||
-								this.systemInfo.model.includes('iPhone 11') ||
-								this.systemInfo.model.includes('iPhone 12') ||
-								this.systemInfo.model.includes('iPhone 13') ||
-								this.systemInfo.model.includes('iPhone 14') ||
-								this.systemInfo.model.includes('iPhone 15') ||
-								this.systemInfo.model.includes('iPhone 16') ||
-								this.systemInfo.model.includes('iPhone 17')) {
-								calculatedHeight = calculatedHeight + 20
-							}
-						}
-
-						const safeAreaBottom = this.systemInfo.safeAreaInsets ? this.systemInfo.safeAreaInsets
-							.bottom : 0
-						if (safeAreaBottom > 0) {
-							calculatedHeight = calculatedHeight - (safeAreaBottom * 3.0)
-						}
-						this.keyboardHeight = Math.max(400, calculatedHeight)
-					} else {
-						this.isKeyboardShow = false
-						this.keyboardHeight = 0
-					}
-				} else {
-					console.log('手机型号是>>>>', this.systemInfo.model)
-					if (res.height > 0) {
-						this.isKeyboardShow = true
-						const safeAreaBottom = this.systemInfo.safeAreaInsets ? this.systemInfo.safeAreaInsets
-							.bottom : 0
-						if (this.systemInfo.brand == 'vivo') {
-							this.keyboardHeight = res.height * 2
-						} else {
-							this.keyboardHeight = (res.height * 1.78) + 20
-						}
-						console.log('高度是', this.keyboardHeight)
-					} else {
-						this.isKeyboardShow = false
-						this.keyboardHeight = 0
-					}
-				}
-			})
-
-			this.initNetworkStatusListener();
-			this.getUserIntegralInfo();
-		},
-		onPullDownRefresh() {
-			this.getLiveMsg(this.liveItem);
-			this.getliveUserInit();
-			setTimeout(() => {
-				uni.stopPullDownRefresh()
-			}, 1000)
-		},
-		async onShow() {
-			try {
-				const isLogin = await this.utils.isLogin()
-				if (isLogin) {
-					await this.getUserInfo()
-					this.initTime()
-					if (this.liveId) {
-						await this.getliving(this.liveId)
-						this.isOnload = true
-						await this.getLiveMsg(this.liveItem)
-						await this.getliveViewData()
-					}
-				}
-			} catch (error) {
-				console.error('初始化失败:', error)
-			}
-			if (this.liveId) {
-				await this.getLiveMsg(this.liveItem)
-			}
-			if (!this.liveViewData) {
-				this.getliveViewData()
-			}
-			this.uuId = generateRandomString(16)
-			const isLiveLogin = uni.getStorageSync('isLiveLogin')
-			this.share = uni.getStorageSync('share')
-			this.scene = uni.getStorageSync('scene')
-
-			if (this.share && this.share.length > 0) {
-				this.liveId = this.share.liveId
-				this.qrFrom = `&companyId=${this.share.companyId}&companyUserId=${this.share.companyUserId}`
-				uni.removeStorageSync('share')
-			}
-
-			if (this.scene) {
-				const decodedScene = decodeURIComponent(this.scene)
-				const params = {}
-				decodedScene.split('&').forEach((item) => {
-					const [key, value] = item.split('=')
-					params[key] = value
-					this.liveId = params.a
-				})
-				if (params.b && params.c) {
-					this.qrFrom = `&companyId=${params.b}&companyUserId=${params.c}`
-				}
-				uni.removeStorageSync('scene')
-			}
-
-			if (isLiveLogin) {
-				if (this.liveId) {
-					await this.getliving(this.liveId)
-					this.getCurrentActivities()
-					this.getliveOrder()
-					this.initSocket()
-				}
-				this.hasInitialized = true
-				uni.removeStorageSync('isLiveLogin')
-			}
-
-			await this.resumePageActivity()
-			this.userinfo = uni.getStorageSync('userInfo')
-			this.isAgreement = uni.getStorageSync('isAgreement')
-
-			this.$nextTick(() => {
-				if (this.$refs.liveVideo && this.$refs.liveVideo.setVideoProgress) {
-					this.$refs.liveVideo.setVideoProgress()
-				}
-			});
-			if (this.lookTimer) {
-				clearInterval(this.lookTimer)
-				this.lookTimer = null
-				this.stayTime = 0
-				this.startTime = 0
-			}
-			
-
-			if (this.trafficTimer) {
-				clearInterval(this.trafficTimer)
-				this.trafficTimer = null
-				this.startTime = 0
-				this.totalTraffic = 0
-			}
-
-			if (this.$refs.liveVideo && this.$refs.liveVideo.startTimer) {
-				this.$refs.liveVideo.startTimer()
-			}
-
-			this.$nextTick(() => {
-				if (!this.userData.unionId) {
-					uni.navigateTo({
-						url: '/pages/auth/login'
-					})
-				}
-			})
-			if (this.liveItem.completionPointsEnabled) {
-				setTimeout(() => {
-					this.startCountdown();
-				}, 500);
-			}
-		},
-		onShareAppMessage() {
-			return {
-				title: '邀请你来观看直播:' + this.liveItem.liveName,
-				path: '/pages_course/living?companyId=-2&companyUserId=' + this.userData.userId + '&liveId=' + this.liveId,
-				imageUrl: '/static/images/logo.png',
-				success(res) {
-					console.log('分享成功', res)
-				},
-				fail(err) {
-					console.error('分享失败', err)
-				}
-			}
-		},
-		onShareTimeline() {
-			return {
-				title: '邀请你来观看直播:' + this.liveItem.liveName,
-				query: 'companyId=-2&companyUserId=' + this.userData.userId + '&liveId=' + this.liveId
-			}
-		},
-		computed: {
-			shouldShowIntegralPopup() {
-				//只有当 showPoints 为 true 且 receiveList 有数据时才显示
-				return this.showPoints;
-			},
-			countdownPercentage() {
-				return this.getCountdownPercentage()
-			},
-			formattedCountdown() {
-				return this.formatCountdown(this.pointsRemainingTime)
-			},
-			formattedWatchCount() {
-				return this.formatNumber(this.liveUserTotal || 0)
-			},
-			formattedLikeCount() {
-				return this.formatNumber(this.liveViewData.like || 0)
-			},
-			filteredViewers() {
-				const safeLiveViewers = Array.isArray(this.liveTopViewersData) ? this.liveTopViewersData : []
-				return safeLiveViewers.slice(0, 3)
-			},
-			isCurrentUserWon() {
-				if (!Array.isArray(this.prizeInfo) || !this.userData?.userId) {
-					return false
-				}
-				return this.prizeInfo.some((item) => {
-					return String(item.userId) === String(this.userData.userId)
-				})
-			},
-			getCurrentUserPrizeProductId() {
-				if (!Array.isArray(this.prizeInfo) || !this.userData?.userId) {
-					return null
-				}
-				const userPrize = this.prizeInfo.find(item => {
-					return String(item.userId) == String(this.userData.userId)
-				})
-				return userPrize ? userPrize.productId : null
-			},
-			getCurrentUserPrizeRecordId() {
-				if (!Array.isArray(this.prizeInfo) || !this.userData?.userId) {
-					return null
-				}
-				const userPrize = this.prizeInfo.find(item => {
-					return String(item.userId) == String(this.userData.userId)
-				})
-				return userPrize ? userPrize.recordId : null
-			}
-		},
-		onHide() {
-			if (this.talklist && this.talklist.length > 20) {
-				this.talklist = this.talklist.slice(-20)
-			}
-			// 保存观看时长
-			this.updateWatchDuration();
-			this.stopCountdown();
-		},
-		onUnload() {
-			if (this.$refs.liveVideo && this.$refs.liveVideo.saveVideoProgress) {
-				this.$refs.liveVideo.saveVideoProgress()
-			}
-			if (this.liveItem) {
-				if (this.$refs.liveVideo && this.$refs.liveVideo.pauseVideo) {
-					this.$refs.liveVideo.pauseVideo()
-				}
-				if (this.liveItem.timeTimer) {
-					clearInterval(this.liveItem.timeTimer)
-					this.liveItem.timeTimer = null
-				}
-			}
-			// 更新后端观看时长
-			this.updateWatchDuration();
-			this.stopCountdown();
-			this.closeWebSocket(true);
-			this.clearAllTimersEnhanced();
-			const videoId = `myVideo_${this.liveId}`
-			const videoContext = uni.createVideoContext(videoId, this)
-			if (videoContext) {
-				videoContext.pause();
-			}
-			try {
-				uni.offNetworkStatusChange();
-			} catch (err) {
-				console.warn('移除网络状态监听失败:', err)
-			}
-			this.clearBigData();
-			this.resetAllStates();
-		},
-		mounted() {
-			this.systemInfo = uni.getSystemInfoSync()
-			console.log('系统信息:', this.systemInfo.platform, this.systemInfo.model)
-			this.getCurrentActivities()
-			this.getliveOrder()
-		},
-		watch: {
-			'orderUser.count': {
-				handler(newVal, oldVal) {
-					if (newVal !== this.prevOrderCount) {
-						this.prevOrderCount = newVal
-						this.showPurchaseMessage()
-					}
-				},
-				immediate: true
-			}
-		},
-		methods: { // 芳华币
-			getUserIntegralInfo() {
-				getUserIntegralInfo().then(res => {
-					if (res.code == 200) {
-						this.integralNum = res.data.integral
-					}
-				}).catch(error => {
-					console.error("获取芳华币数据失败:", error);
-
-				});
-			},
-			//礼物列表
-			getActiveList() {
-				activeList().then((res) => {
-					if (res.code == 200) {
-						this.giftList = res.data
-						console.log('正常状态的礼物列表', res.data)
-					}
-				}).catch((error) => {})
-			},
-			// 送礼物
-			sendliveGift(item) {
-				if (!this.liveId) return
-				const data = {
-					liveId: this.liveId,
-					giftId: item.giftId,
-					// giftId: this.giftId,
-					// cn: this.cn
-					cn: 1
-				}
-				sendliveGift(data).then((res) => {
-					if (res.code == 200) {
-						uni.showToast({
-							title: res.msg,
-							icon: 'none'
-						})
-
-						console.log('用户送礼物', res)
-						this.getUserIntegralInfo();
-
-					} else {
-						uni.showToast({
-							title: res.msg,
-							icon: 'none'
-						})
-					}
-				}).catch((error) => {})
-			},
-			// 查询当前用户当前直播间领取积分的剩余时长
-			getRemainingTime() {
-				if (!this.liveId) return
-				const data = {
-					liveId: this.liveId
-				}
-				remainingTime(data).then((res) => {
-					if (res.code == 200) {
-						this.hasReceived = res.data.hasReceived
-						this.videoDuration = res.data.videoDuration
-						this.watchDuration = res.data.watchDuration
-						this.remainingTime = res.data.remainingTime
-						this.completionRate = res.data.completionRate
-						console.log('查询当前用户当前直播间领取积分的剩余时长', res)
-					}
-				}).catch((error) => {})
-			},
-			// 查询用户积分领取记录
-			// completionRecords() {
-			// 	if (!this.liveId) return
-			// 	const data = {
-			// 		liveId: this.liveId
-			// 	}
-			// 	completionRecords(data).then((res) => {
-			// 		if (res.code == 200) {
-			// 			const targetData = res.data.find(item => item.liveId == this.liveId)
-			// 			if (targetData) {
-			// 				const receiveStatus = targetData.receiveStatus
-			// 				this.receiveStatus = receiveStatus
-			// 			} else {
-			// 				console.log('未找到liveId为', this.liveId, '的数据')
-			// 				this.receiveStatus = false
-			// 			}
-			// 			console.log('查询用户积分领取记录', res)
-			// 		}
-			// 	}).catch((error) => {})
-			// },
-			// 更新用户的看课时长
-			updateWatchDuration() {
-				if (!this.liveId) return;
-				if (this.isPreview) return;
-				//const watchDuration = Math.floor((Date.now() - this.liveBeginWatchTime) / 1000)
-				const watchDuration = this.totalWatchTime - this.watchDuration;
-				updateWatchDuration(this.liveId, watchDuration).then((res) => {
-					if (res.code == 200) {
-						console.log("更新用户的看课时长", res);
-						this.receivePoints();
-					}
-				}).catch((error) => {
-
-				});
-			},
-			// 用户领取看课积分 (传入直播间id)
-			receivePoints(retryCount = 0) {
-				if (!this.liveId) return;
-				// const data = {
-				// 	liveId: this.liveId
-				// }
-				receivePoints(this.liveId).then((res) => {
-					if (res.code == 200) {
-						console.log("用户领取看课积分", res);
-						//清除重试定时器
-						if (this.pointsRetryTimer) {
-							clearTimeout(this.pointsRetryTimer);
-							this.pointsRetryTimer = null;
-						}
-					}
-				}).catch((error) => {
-					console.log("用户领取积分失败error", error);
-					// 增加重试机制:最多重试3次
-					if (retryCount < 3) {
-						const delay = (retryCount + 1) * 2000; // 递增延迟: 2s, 4s, 6s
-						console.log(`领取积分失败,${delay}ms后进行第${retryCount + 1}次重试`);
-						if (this.pointsRetryTimer) {
-							clearTimeout(this.pointsRetryTimer);
-						}
-						this.pointsRetryTimer = setTimeout(() => {
-							this.receivePoints(retryCount + 1);
-						}, delay);
-					}
-				});
-			},
-			// 开始观看时长统计
-			// startWatchDurationTracking() {
-			// 	if (this.watchStartTime > 0) {
-			// 		console.log('观看时长统计已启动,跳过')
-			// 		return
-			// 	}
-			// 	this.watchStartTime = Date.now()
-			// 	this.isPageVisible = true
-			// 	console.log('开始观看时长统计', new Date(this.watchStartTime).toLocaleString())
-			// 	this.initPageVisibilityListener()
-			// },
-			// getCurrentWatchDuration() {
-			// 	if (this.watchStartTime === 0) {
-			// 		return this.accumulatedWatchDuration
-			// 	}
-			// 	if (this.isPageVisible) {
-			// 		const currentDuration = Math.floor((Date.now() - this.watchStartTime) / 1000)
-			// 		return this.accumulatedWatchDuration + currentDuration
-			// 	}
-			// 	return this.accumulatedWatchDuration
-			// },
-			// pauseWatchDurationTracking() {
-			// 	if (!this.isPageVisible || this.watchStartTime === 0) {
-			// 		return
-			// 	}
-			// 	const currentSessionDuration = Math.floor((Date.now() - this.watchStartTime) / 1000)
-			// 	this.accumulatedWatchDuration += currentSessionDuration
-			// 	this.lastPauseTime = Date.now()
-			// 	this.isPageVisible = false
-			// 	console.log(`暂停观看统计: 本次=${currentSessionDuration}秒, 累计=${this.accumulatedWatchDuration}秒`)
-			// },
-			// resumeWatchDurationTracking() {
-			// 	if (this.isPageVisible) {
-			// 		return
-			// 	}
-			// 	this.watchStartTime = Date.now()
-			// 	this.isPageVisible = true
-			// 	const pauseDuration = this.lastPauseTime > 0 ? Math.floor((Date.now() - this.lastPauseTime) / 1000) : 0
-			// 	console.log(`恢复观看统计: 暂停了${pauseDuration}秒, 当前累计=${this.accumulatedWatchDuration}秒`)
-			// },
-			// stopWatchDurationTracking() {
-			// 	if (this.isPageVisible && this.watchStartTime > 0) {
-			// 		const currentSessionDuration = Math.floor((Date.now() - this.watchStartTime) / 1000)
-			// 		this.accumulatedWatchDuration += currentSessionDuration
-			// 	}
-			// 	console.log(`停止观看统计: 总时长=${this.accumulatedWatchDuration}秒`)
-			// 	this.watchStartTime = 0
-			// 	this.isPageVisible = true
-			// 	this.lastPauseTime = 0
-			// 	this.removePageVisibilityListener()
-			// },
-			// initPageVisibilityListener() {
-			// 	uni.onAppShow(() => {
-			// 		console.log('小程序回到前台')
-			// 		this.resumeWatchDurationTracking()
-			// 	})
-			// 	uni.onAppHide(() => {
-			// 		console.log('小程序切换到后台')
-			// 		this.pauseWatchDurationTracking()
-			// 	})
-			// },
-			removePageVisibilityListener() {},
-			calculateLiveTimeDiff(timeStr) {
-				if (!timeStr) {
-					return 0
-				}
-				const now = Date.now()
-				const safeTimeStr = String(timeStr).replace(/-/g, '/')
-				const liveStartTime = Date.parse(safeTimeStr)
-				const diffInSeconds = Math.floor((now - liveStartTime) / 1000)
-				return diffInSeconds
-			},
-			calculateLiveEndTime(startTime, duration) {
-				if (!startTime) return ''
-				const safeStartTime = String(startTime).replace(/-/g, '/')
-				const startDate = new Date(safeStartTime)
-				if (isNaN(startDate.getTime())) return ''
-				const endTimeMs = startDate.getTime() + (Number(duration) * 1000)
-				const endDate = new Date(endTimeMs)
-				const year = endDate.getFullYear()
-				const month = this.padZero(endDate.getMonth() + 1)
-				const day = this.padZero(endDate.getDate())
-				const hours = this.padZero(endDate.getHours())
-				const minutes = this.padZero(endDate.getMinutes())
-				const seconds = this.padZero(endDate.getSeconds())
-				return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
-			},
-			startCountdown() {
-				this.isCountdownActive = true
-				this.countdownTimer = setInterval(() => {
-					this.updateCountdown()
-				}, 1000)
-			},
-			updateCountdown() {
-				if (!this.liveItem) {
-					return;
-				}
-				// console.log("开始倒计时", this.liveItem.duration, this.completionRate,this.watchDuration)
-				this.completionTime = this.liveItem.duration * this.completionRate * 0.01;
-				// 已达成观看时间
-				if (this.watchDuration > this.completionTime) {
-					if (this.countdownTimer) {
-						clearInterval(this.countdownTimer);
-						this.countdownTimer = null;
-						this.isPreview = true;
-						return;
-					}
-				}
-				// 倒计时已结束
-				if (this.pointsRemainingTime < 0) {
-					this.stopCountdown();
-					return;
-				}
-				this.showPoints = false;
-				this.diffLiveStartTime = this.calculateLiveTimeDiff(this.liveItem.startTime);
-				this.diffLiveEndTime = this.calculateLiveTimeDiff(this.liveItem.startTime) - this.liveItem.duration;
-				if (!this.liveItem.finishTime) {
-					this.liveItem.finishTime = this.calculateLiveEndTime(this.liveItem.startTime, this.liveItem.duration);
-				}
-				// 预告状态
-				if (this.diffLiveStartTime < 0) {
-					this.isPreview = true;
-					return;
-				}
-				// 直播已开始
-				if (this.diffLiveStartTime >= 0) {
-					// 计算总观看时长
-					this.totalWatchTime = this.watchDuration + Math.floor((Date.now() - this.liveBeginWatchTime) / 1000);
-					// 积分领取满足条件
-					if (this.totalWatchTime >= this.completionTime) {
-						if (this.countdownTimer) {
-							clearInterval(this.countdownTimer);
-							this.countdownTimer = null;
-							this.onCountdownComplete();
-							return;
-						}
-					}
-					this.isPreview = false;
-					// 直播中或回放状态都计算剩余时间
-					console.log("这个时间怎么这么多", this.completionTime, this.totalWatchTime)
-					this.pointsRemainingTime = Math.max(0, this.completionTime - this.totalWatchTime);
-				}
-				// 更新显示
-				this.updateCountdownDisplay();
-			},
-			stopCountdown() {
-				if (this.countdownTimer) {
-					clearInterval(this.countdownTimer)
-					this.countdownTimer = null
-				}
-				this.isCountdownActive = false
-				this.updateWatchDuration()
-			},
-			onCountdownComplete() {
-				console.log('倒计时完成!')
-				this.stopCountdown()
-				this.pointsRemainingTime = -1
-				this.triggerWatchComplete()
-				setTimeout(() => {
-					this.showToast = true
-					setTimeout(() => {
-						this.showToast = false
-					}, 5000)
-				}, 1000)
-			},
-			async triggerWatchComplete() {
-				if (!this.userInfo?.userId || !this.liveId) return
-				try {
-					console.log('用户已完成观看')
-					uni.removeStorageSync(this.watchProgressKey)
-				} catch (error) {
-					console.error('触发观看完成事件失败:', error)
-				}
-			},
-			padZero(num) {
-				return num < 10 ? `0${num}` : num.toString()
-			},
-			formatCountdown(seconds) {
-				const totalSeconds = Math.max(0, Math.floor(Number(seconds) || 0))
-				const hours = Math.floor(totalSeconds / 3600)
-				const remainingAfterHours = totalSeconds % 3600
-				const minutes = Math.floor(remainingAfterHours / 60)
-				const secs = remainingAfterHours % 60
-				return {
-					hours: this.padZero(hours),
-					minutes: this.padZero(minutes),
-					seconds: this.padZero(secs),
-					total: totalSeconds
-				}
-			},
-			getCountdownPercentage() {
-				if (!this.getRemainingTime) {
-					console.log('进度条计算:liveItem.duration无效', this.liveItem?.duration)
-					return 0
-				}
-				if (this.hasReachedTarget || this.pointsRemainingTime <= 0) {
-					return 100
-				}
-				const watchedTime = this.videoDuration - this.pointsRemainingTime
-				if (watchedTime <= 0) {
-					return 0
-				}
-				const percentage = (watchedTime / this.videoDuration) * 100
-				return Math.min(100, Math.max(0, percentage))
-			},
-			updateCountdownDisplay() {
-				this.$forceUpdate()
-			},
-			initWatchTime() {
-				const userId = this.userInfo?.userId || 'anonymous'
-				this.watchTimeStorageKey = `watchTime_${userId}_${this.liveId}`
-				try {
-					const storedTime = uni.getStorageSync(this.watchTimeStorageKey)
-					this.totalWatchTime = storedTime ? parseInt(storedTime) : 0
-					console.log(`加载累计观看时间: ${this.totalWatchTime}秒`)
-				} catch (error) {
-					console.error('加载观看时间失败:', error)
-					this.totalWatchTime = 0
-				}
-			},
-			saveWatchTime() {
-				if (!this.watchTimeStorageKey) return
-				try {
-					uni.setStorageSync(this.watchTimeStorageKey, this.totalWatchTime)
-					console.log(`保存观看时间: ${this.totalWatchTime}秒`)
-				} catch (error) {
-					console.error('保存观看时间失败:', error)
-				}
-			},
-			formatWatchTime(seconds) {
-				const hours = Math.floor(seconds / 3600)
-				const minutes = Math.floor((seconds % 3600) / 60)
-				const secs = seconds % 60
-				return {
-					hours: this.padZero(hours),
-					minutes: this.padZero(minutes),
-					seconds: this.padZero(secs),
-					total: seconds
-				}
-			},
-			handleFullscreenChange(isFullscreen) {
-				console.log('收到子组件全屏状态:', isFullscreen)
-				this.isFullscreen = isFullscreen
-
-				if (isFullscreen) {
-					this.shopping = false
-					this.isShowGift = false
-					this.isMore = false
-					this.showViewerList = false
-					this.isShowLotteryPop = false
-					this.winning = false
-					this.isFocus = false
-				}
-
-				this.$nextTick(() => {
-					this.$forceUpdate()
-				})
-			},
-			onInputFocus(value) {
-				this.isFocus = true
-				console.log('输入框聚焦:', value)
-			},
-			onInputBlur(value) {
-				this.isFocus = false
-				console.log('输入框失焦:', value)
-			},
-			onSendMessage(message) {
-				console.log('发送消息:', message)
-				this.sendMsg()
-			},
-			onInputChange(value) {
-				this.value = value
-			},
-			handleLiveStart() {
-				console.log('直播开始')
-				this.getliving(this.liveId)
-			},
-			handleSearchInput(keyword) {
-				this.inputInfo = keyword
-				clearTimeout(this.searchTimer)
-				this.searchTimer = setTimeout(() => {
-					this.queryCollect()
-				}, 500)
-			},
-			handleVideoError(error) {
-				console.error('视频播放错误:', error)
-			},
-			handleLiveStateChange(state) {
-				console.log('直播状态变化:', state)
-			},
-			handleNavigateToOrder() {
-				this.navgetTo('/pages_shopping/live/order')
-			},
-			handleShowMore() {
-				this.isMore = true
-				this.shopping = false
-			},
-			handleFillAddress(data) {
-				const {
-					productId,
-					recordId,
-					liveId
-				} = data
-				this.winning = false
-				this.navgetTo(
-					`/pages_shopping/live/confirmCreateOrder?type=win&productId=${productId}&liveId=${liveId}&recordId=${recordId}`
-				)
-			},
-			handleLotteryClose() {
-				this.isShowLotteryPop = false
-			},
-			handleLotteryClaim() {
-				this.onClaim()
-			},
-			handleGoShop(goodsData) {
-				this.goShop(goodsData.productId, goodsData.goodsId)
-			},
-			handleCloseGoods() {
-				this.isShowGoods = false
-			},
-			formatNumber(num) {
-				if (typeof num !== 'number') {
-					num = Number(num) || 0
-				}
-				if (num < 10000) {
-					return num.toString()
-				}
-				const wan = num / 10000
-				if (wan < 10) {
-					const rounded = Math.round(wan * 100) / 100
-					return rounded.toFixed(2).replace(/\.?0+$/, '') + 'w'
-				} else if (wan < 10000) {
-					const rounded = Math.round(wan * 10) / 10
-					return rounded.toFixed(1).replace(/\.0$/, '') + 'w'
-				} else {
-					const yi = wan / 10000
-					const rounded = Math.round(yi * 100) / 100
-					return rounded.toFixed(2).replace(/\.?0+$/, '') + '亿'
-				}
-			},
-			resetAllStates() {
-				this.liveUserCalled = false
-				this.talklist = []
-				this.liveViewersData = []
-				this.liveViewers = []
-				this.products = []
-				this.liveItem = []
-				this.isSocketOpen = false
-				this.isConnecting = false
-				this.isManualClose = true
-				this.reconnectCount = 0
-				this.heartBeatRetryCount = 0
-				this.lastHeartBeatTime = 0
-				this.adaptiveHeartBeatInterval = this.heartBeatInterval
-				this.isNetworkAvailable = true
-				this.networkType = 'unknown'
-				this.connectionStartTime = 0
-				this.connectionLatency = 0
-				this.messageCount = 0
-				this.errorCount = 0
-				this.lastPerformanceCheck = 0
-			},
-			getWebSocketPerformanceStats() {
-				const now = Date.now()
-				const uptime = this.connectionStartTime > 0 ? now - this.connectionStartTime : 0
-				return {
-					connectionLatency: this.connectionLatency,
-					uptime: uptime,
-					messageCount: this.messageCount,
-					errorCount: this.errorCount,
-					errorRate: this.messageCount > 0 ? (this.errorCount / this.messageCount * 100).toFixed(2) : 0,
-					messagesPerSecond: uptime > 0 ? (this.messageCount / (uptime / 1000)).toFixed(2) : 0,
-					networkType: this.networkType,
-					isConnected: this.isSocketAvailable(),
-					reconnectCount: this.reconnectCount
-				}
-			},
-			performanceCheck() {
-				const now = Date.now()
-				if (now - this.lastPerformanceCheck > 300000) {
-					const stats = this.getWebSocketPerformanceStats()
-					console.log('WebSocket性能统计:', stats)
-					this.lastPerformanceCheck = now
-
-					if (stats.errorRate > 10) {
-						console.warn(`WebSocket错误率过高: ${stats.errorRate}%`)
-					}
-
-					if (stats.connectionLatency > 5000) {
-						console.warn(`WebSocket连接延迟过高: ${stats.connectionLatency}ms`)
-					}
-				}
-			},
-			startVideoCacheCleanup() {
-				if (this.videoCleanupTimer) {
-					clearInterval(this.videoCleanupTimer)
-				}
-
-				this.videoCleanupTimer = setInterval(() => {
-					this.cleanupVideoCache()
-				}, 30000)
-			},
-			cleanupVideoCache() {
-				if (!this.liveItem || !this.liveId) return
-
-				if (this.liveItem.liveType === 2 && this.liveItem.videoUrl) {
-					this.reloadVideoPlayer()
-				}
-			},
-			reloadVideoPlayer() {
-				const videoId = `myVideo_${this.liveId}`
-				const videoContext = uni.createVideoContext(videoId, this)
-
-				if (videoContext) {
-					const currentTime = this.videoCurrentTime
-					videoContext.pause()
-					setTimeout(() => {
-						this.$set(this.liveItem, 'videoUrl', this.liveItem.videoUrl + '&t=' + Date.now())
-						setTimeout(() => {
-							if (videoContext.seek) {
-								videoContext.seek(currentTime)
-							}
-							videoContext.play()
-						}, 500)
-					}, 100)
-				}
-			},
-			startMemoryMonitoring() {
-				if (this.memoryMonitorTimer) {
-					clearInterval(this.memoryMonitorTimer)
-				}
-				this.memoryMonitorTimer = setInterval(() => {
-					this.checkMemoryUsage()
-				}, 15000)
-			},
-			checkMemoryUsage() {
-				try {
-					const timerCount = this.getActiveTimerCount()
-					if (timerCount > 10) {
-						console.warn(`检测到过多定时器: ${timerCount}个,可能存在内存泄漏`)
-						this.cleanupUnusedTimers()
-					}
-
-					if (this.messageQueue && this.messageQueue.length > 100) {
-						console.warn(`消息队列过长: ${this.messageQueue.length}条,清理旧消息`)
-						this.messageQueue = this.messageQueue.slice(-50)
-					}
-
-					if (this.userRandomColors && Object.keys(this.userRandomColors).length > 500) {
-						console.warn('用户颜色缓存过大,清理部分缓存')
-						const keys = Object.keys(this.userRandomColors)
-						const keysToRemove = keys.slice(0, keys.length - 200)
-						keysToRemove.forEach(key => delete this.userRandomColors[key])
-					}
-
-					if (Date.now() - this.lastPerformanceCheck > 60000) {
-						this.triggerGarbageCollection()
-						this.lastPerformanceCheck = Date.now()
-					}
-				} catch (error) {
-					console.error('内存检查失败:', error)
-				}
-			},
-			forceMemoryCleanup() {
-				console.log('执行强制内存清理')
-				this.cleanupVideoPlayer()
-				this.clearBigData()
-				this.triggerGarbageCollection()
-			},
-			cleanupVideoPlayer() {
-				const videoId = `myVideo_${this.liveId}`
-				const videoContext = uni.createVideoContext(videoId, this)
-
-				if (videoContext) {
-					videoContext.stop()
-					setTimeout(() => {
-						this.$set(this.liveItem, 'videoUrl', '')
-						setTimeout(() => {
-							this.$set(this.liveItem, 'videoUrl', this.getFreshVideoUrl())
-							if (this.$refs.liveVideo && this.$refs.liveVideo.playVideo) {
-								this.$refs.liveVideo.playVideo()
-							}
-						}, 500)
-					}, 100)
-				}
-			},
-			getFreshVideoUrl() {
-				if (!this.liveItem.originalVideoUrl) {
-					this.liveItem.originalVideoUrl = this.liveItem.videoUrl
-				}
-
-				const separator = this.liveItem.originalVideoUrl.includes('?') ? '&' : '?'
-				return this.liveItem.originalVideoUrl + separator + 't=' + Date.now()
-			},
-			clearBigData() {
-				if (this.talklist.length > 50) {
-					this.talklist = this.talklist.slice(-50)
-				}
-				if (this.liveViewersData.length > 100) {
-					this.liveViewersData = this.liveViewersData.slice(-100)
-				}
-				if (this.liveViewers.length > 100) {
-					this.liveViewers = this.liveViewers.slice(-100)
-				}
-				if (this.products.length > 50) {
-					this.products = this.products.slice(0, 50)
-				}
-				if (typeof gc === 'function') {
-					gc()
-				}
-			},
-			triggerGarbageCollection() {
-				if (wx && wx.triggerGC) {
-					wx.triggerGC()
-				}
-			},
-			forceScrollToBottom() {
-				console.log('执行强制滚动到底部')
-				this.scrollTop = 999999
-
-				this.$nextTick(() => {
-					if (this.talklist && this.talklist.length > 0) {
-						const lastMessage = this.talklist[this.talklist.length - 1]
-						const targetId = `list_${lastMessage.uniqueId || (this.talklist.length - 1)}`
-						console.log(
-							`尝试滚动到元素: ${targetId}, 当前消息数量: ${this.talklist.length}, 最后消息ID: ${lastMessage.uniqueId}`
-						)
-						this.scrollIntoView = targetId
-
-						setTimeout(() => {
-							this.scrollIntoView = ''
-						}, 200)
-					}
-					setTimeout(() => {
-						this.scrollTop = 999999
-						console.log('延迟设置scrollTop为999999')
-					}, 100)
-
-					setTimeout(() => {
-						this.nativeScrollToBottom()
-					}, 300)
-				})
-			},
-			simpleScrollToBottom() {
-				const now = Date.now()
-
-				if (now - this.lastScrollTime < this.scrollDebounceDelay) {
-					console.log('滚动防抖:忽略频繁调用')
-					return
-				}
-
-				this.lastScrollTime = now
-				console.log('执行可靠滚动到底部')
-
-				if (this.scrollTimer) {
-					clearTimeout(this.scrollTimer)
-					this.scrollTimer = null
-				}
-
-				this.scrollTop = 999999999
-				console.log('方案1: 设置scrollTop为999999999')
-
-				if (this.talklist.length > 0) {
-					const lastMessage = this.talklist[this.talklist.length - 1]
-					if (lastMessage && lastMessage.uniqueId) {
-						this.scrollIntoView = `msg-${lastMessage.uniqueId}`
-						console.log(`方案2: 设置scrollIntoView为msg-${lastMessage.uniqueId}`)
-					}
-				}
-
-				this.scrollTimer = setTimeout(() => {
-					this.scrollTop = 999999999
-					console.log('方案3: 延迟设置scrollTop为999999999')
-					this.scrollTimer = null
-				}, 50)
-			},
-			forceScrollToBottomOnSend() {
-				console.log('执行强制滚动到底部(发送消息专用)')
-
-				if (this.scrollTimer) {
-					clearTimeout(this.scrollTimer)
-					this.scrollTimer = null
-				}
-
-				this.lastScrollTime = Date.now()
-				this.scrollIntoView = ''
-
-				if (this.talklist.length > 0) {
-					const lastMessage = this.talklist[this.talklist.length - 1]
-					if (lastMessage && lastMessage.uniqueId) {
-						this.scrollIntoView = `list_${lastMessage.uniqueId}`
-					}
-				}
-
-				const targetScrollTop = Date.now()
-				this.scrollTop = targetScrollTop
-				this.nativeScrollToBottom()
-
-				this.$nextTick(() => {
-					this.scrollIntoView = ''
-					this.scrollTop = targetScrollTop + 1
-					setTimeout(() => {
-						this.nativeScrollToBottom()
-					}, 50)
-				})
-
-				this.scrollTimer = setTimeout(() => {
-					this.checkAndForceScroll(targetScrollTop)
-					this.scrollTimer = null
-				}, 200)
-			},
-			checkAndForceScroll(targetScrollTop) {
-				if (this.talklist.length > 0) {
-					const lastMessage = this.talklist[this.talklist.length - 1]
-					if (lastMessage && lastMessage.uniqueId) {
-						this.scrollIntoView = `list_${lastMessage.uniqueId}`
-					}
-				}
-				this.scrollTop = Date.now() + Math.random() * 1000
-				this.nativeScrollToBottom()
-
-				setTimeout(() => {
-					this.nativeScrollToBottom()
-				}, 100)
-			},
-			nativeScrollToBottom() {
-				try {
-					const query = uni.createSelectorQuery().in(this)
-					query.select('#msgScroll').node((res) => {
-						if (res && res.node) {
-							console.log('找到msgScroll节点,执行原生滚动')
-							const scrollHeight = res.node.scrollHeight
-							res.node.scrollTop = scrollHeight
-
-							setTimeout(() => {
-								res.node.scrollTop = scrollHeight + 100
-							}, 50)
-						}
-					}).exec()
-				} catch (error) {
-					console.error('原生滚动失败:', error)
-				}
-			},
-			onScroll(e) {
-				this.currentScrollTop = e.detail.scrollTop
-			},
-			stopMemoryMonitor() {
-				if (this.memoryMonitorTimer) {
-					clearInterval(this.memoryMonitorTimer)
-					this.memoryMonitorTimer = null
-				}
-			},
-			getActiveTimerCount() {
-				const timers = [
-					'trafficTimer', 'pingTimeoutTimer', 'heartBeatTimer', 'liveViewDataTimer',
-					'reconnectTimer', 'scrollTimer', 'searchTimer', 'purchasePromptTimer',
-					'welcomeTimer', 'redTimer', 'liveStartTimer', 'lotteryTimer', 'noticeTimer',
-					'memoryMonitorTimer', 'networkStatusTimer', 'networkRetryTimer'
-				];
-				return timers.filter(timer => this[timer] !== null).length
-			},
-			cleanupUnusedTimers() {
-				const timers = [
-					'trafficTimer', 'pingTimeoutTimer', 'heartBeatTimer', 'liveViewDataTimer',
-					'reconnectTimer', 'scrollTimer', 'searchTimer', 'purchasePromptTimer',
-					'welcomeTimer', 'redTimer', 'liveStartTimer', 'lotteryTimer',
-					'networkStatusTimer', 'networkRetryTimer'
-				];
-				timers.forEach(timerName => {
-					if (this[timerName] && typeof this[timerName] === 'number') {
-						if (timerName.includes('Interval')) {
-							clearInterval(this[timerName])
-						} else {
-							clearTimeout(this[timerName])
-						}
-						this[timerName] = null
-						console.log(`清理了可能泄漏的定时器: ${timerName}`)
-					}
-				})
-			},
-			clearAllTimersEnhanced() {
-				this.clearAllTimers()
-
-				if (this.networkRetryTimer) {
-					clearTimeout(this.networkRetryTimer)
-					this.networkRetryTimer = null
-				}
-
-				this.stopMemoryMonitor()
-				this.userRandomColors = Object.create(null)
-				this.shownEntryUsers.clear()
-				this.messageCount = 0
-				this.errorCount = 0
-				this.connectionLatency = 0
-				this.lastPerformanceCheck = 0
-
-				console.log('增强清理完成:所有定时器和缓存已清理')
-			},
-			goMiniProgram() {
-				uni.showToast({
-					title: '系统升级中,兑换请联系伴学助手!',
-					icon: 'none'
-				})
-			},
-			preventDoubleClick(e) {
-				e.preventDefault();
-				e.stopPropagation();
-				return false
-			},
-			clearAllTimers() {
-				const timers = [
-					'noticeTimer',
-					'scrollTimer',
-					'liveViewDataTimer',
-					'redTimer',
-					'liveStartTimer',
-					'lotteryTimer',
-					'welcomeTimer',
-					'trafficInterval',
-					'lookTimer',
-					'trafficTimer',
-					'intervalId',
-					'reconnectTimer',
-					'searchTimer',
-					'purchasePromptTimer',
-					'heartBeatTimer',
-					'pingTimeoutTimer'
-				]
-
-				timers.forEach((timer) => {
-					if (this[timer]) {
-						if (timer.includes('Interval') || timer.includes('Timer')) {
-							clearInterval(this[timer])
-						} else {
-							clearTimeout(this[timer])
-						}
-						this[timer] = null
-					}
-				})
-
-				this.stayTime = 0
-				this.startTime = 0
-				this.totalTraffic = 0
-				this.scrollPending = false
-				this.reconnectCount = 0
-				this.heartBeatRetryCount = 0
-			},
-			scrollToBottom() {
-				const now = Date.now()
-				if (now - this.lastScrollTime < this.scrollDebounceDelay) {
-					console.log('滚动防抖:忽略频繁调用')
-					return
-				}
-				this.lastScrollTime = now
-				if (this.scrollTimer) {
-					clearTimeout(this.scrollTimer)
-					this.scrollTimer = null
-				}
-				this.scrollTop = 999999999
-			},
-			startMemoryMonitor() {
-				if (this.memoryMonitorTimer) {
-					clearInterval(this.memoryMonitorTimer)
-				}
-				this.memoryMonitorTimer = setInterval(() => {
-					this.checkAndCleanMemory()
-				}, 5 * 60 * 1000);
-			},
-			checkAndCleanMemory() {
-				try {
-					if (this.talklist && this.talklist.length > 25) {
-						const keepCount = 20
-						this.talklist.splice(0, this.talklist.length - keepCount)
-					}
-
-					if (this.userRandomColors && Object.keys(this.userRandomColors).length > 50) {
-						const entries = Object.entries(this.userRandomColors)
-						const keepEntries = entries.slice(-50)
-						this.userRandomColors = Object.fromEntries(keepEntries)
-					}
-
-					if (this.shownEntryUsers && this.shownEntryUsers.size > 100) {
-						const array = Array.from(this.shownEntryUsers)
-						this.shownEntryUsers.clear()
-						array.slice(-100).forEach((id) => this.shownEntryUsers.add(id))
-					}
-
-					console.log('内存清理完成')
-				} catch (error) {
-					console.error('内存清理失败:', error)
-				}
-			},
-			async resumePageActivity() {
-				if (this.liveItem) {
-					await this.getliving(this.liveId)
-					this.startTimeTimer(this.liveItem)
-				}
-				if (!this.isSocketAvailable()) {
-					this.initSocket()
-				}
-			},
-			getUserRandomColor(userId) {
-				if (!userId) {
-					return '#8978e2'
-				}
-				if (this.userRandomColors[userId]) {
-					return this.userRandomColors[userId]
-				}
-				const color = this.generateStableColor(userId)
-				this.userRandomColors[userId] = color
-				this.saveUserColorsToStorage()
-				return color
-			},
-			generateStableColor(userId) {
-				let seed = 0
-				for (let i = 0; i < userId.length; i++) {
-					seed = (seed * 31 + userId.charCodeAt(i)) % 1000000
-				}
-				const colorPool = [
-					'#FF6B6B',
-					'#4ECDC4',
-					'#45B7D1',
-					'#96CEB4',
-					'#FFEAA7',
-					'#DDA0DD',
-					'#98D8C8',
-					'#F7DC6F',
-					'#BB8FCE',
-					'#85C1E9',
-					'#F8C471',
-					'#82E0AA',
-					'#F1948A',
-					'#85C1E9',
-					'#D7BDE2'
-				]
-				return colorPool[seed % colorPool.length]
-			},
-			saveUserColorsToStorage() {
-				try {
-					uni.setStorageSync('userRandomColors', this.userRandomColors)
-				} catch (e) {
-					console.warn('保存用户颜色缓存失败:', e)
-				}
-			},
-			loadUserColorsFromStorage() {
-				try {
-					const cached = uni.getStorageSync('userRandomColors')
-					if (cached) {
-						this.userRandomColors = cached
-					}
-				} catch (e) {
-					console.warn('加载用户颜色缓存失败:', e)
-				}
-			},
-			getNicknameInitial(nickName) {
-				if (!nickName || typeof nickName !== 'string') return '未'
-				if (/^[\u4e00-\u9fa5]/.test(nickName[0])) {
-					return nickName[0]
-				}
-				return nickName[0].toUpperCase()
-			},
-			async getUserInfo() {
-				await getUserInfo().then((res) => {
-						if (res.code == 200) {
-							this.userData = res.user
-						} else {
-							uni.showToast({
-								icon: 'none',
-								title: '请求失败'
-							})
-						}
-					},
-					(rej) => {}
-				)
-			},
-			handleAgreement() {
-				const templateId = this.templateId
-				if (this.hasSubscribed) return;
-				uni.requestSubscribeMessage({
-					tmplIds: [templateId],
-					success: (res) => {
-						if (res[templateId] === 'accept') {
-							uni.showToast({
-								title: '订阅成功,开播将提醒您',
-								icon: 'success',
-								duration: 2500 // 成功提示延长到2.5秒
-							})
-							this.hasSubscribed = true;
-							uni.setStorageSync('subscribe_status_' + this.liveId, true);
-							this.callSendMessageApi()
-						} else if (res[templateId] === 'reject') {
-							uni.showToast({
-								title: '您已拒绝订阅,将无法收到提醒',
-								icon: 'none',
-								duration: 2500 // 成功提示延长到2.5秒
-							})
-						} else if (res[templateId] === 'ban') {
-							uni.showToast({
-								title: '您已关闭所有订阅权限,请在设置中开启',
-								icon: 'none',
-								duration: 2500 // 成功提示延长到2.5秒
-							})
-						}
-					},
-					fail: (err) => {
-						console.error('订阅消息失败', err)
-						uni.showToast({
-							title: '订阅失败,请重试',
-							icon: 'none',
-							duration: 2500 // 成功提示延长到2.5秒
-						})
-					}
-				})
-			},
-			async callSendMessageApi() {
-				if (!this.userData.userId) return
-				const templateData = {
-					liveId: this.liveId,
-					userId: this.userData.userId,
-					templateId: this.templateId || '',
-					maOpenId: this.userData.maOpenId || '',
-					appid: this.appid || '',
-					data: {
-						thing6: this.liveItem.liveName,
-						date7: this.liveItem.startTime
-					}
-				}
-				subNotifyLive(templateData).then(
-					(res) => {
-						if (res.code == 200) {
-							this.isAgreement = true
-							uni.setStorageSync('isAgreement', true)
-						} else {
-							uni.showToast({
-								title: res.msg,
-								icon: 'none'
-							})
-						}
-					},
-					(rej) => {}
-				)
-			},
-			sendHeartBeat() {
-				if (!this.isSocketAvailable() || !this.isNetworkAvailable) {
-					console.warn('网络不可用或Socket连接异常,跳过心跳发送')
-					return
-				}
-
-				this.lastHeartBeatTime = Date.now()
-
-				try {
-					const heartBeatMsg = JSON.stringify({
-						cmd: 'heartbeat',
-						msg: 'ping',
-						userId: this.userData.userId || '',
-						liveId: this.liveId,
-						timestamp: this.lastHeartBeatTime,
-						networkType: this.networkType
-					})
-
-					this.socket.send({
-						data: heartBeatMsg,
-						success: () => {
-							this.heartBeatRetryCount = 0
-							this.adjustHeartBeatInterval(true)
-							this.startPingTimeout()
-						},
-						fail: (err) => {
-							console.error('心跳包发送失败:', err)
-							this.heartBeatRetryCount++
-							this.adjustHeartBeatInterval(false)
-
-							const retryDelay = this.getRetryDelay()
-
-							if (this.heartBeatRetryCount < this.maxHeartBeatRetries) {
-								setTimeout(() => this.sendHeartBeat(), retryDelay)
-							} else {
-								this.heartBeatRetryCount = 0
-								this.handleReconnect()
-							}
-						}
-					})
-				} catch (err) {
-					console.error('心跳发送异常:', err)
-					this.heartBeatRetryCount++
-
-					const retryDelay = this.getRetryDelay()
-					if (this.heartBeatRetryCount < this.maxHeartBeatRetries) {
-						setTimeout(() => this.sendHeartBeat(), retryDelay)
-					} else {
-						this.heartBeatRetryCount = 0
-						this.handleReconnect()
-					}
-				}
-			},
-			getRetryDelay() {
-				const baseDelay = 2000
-				const retryMultiplier = Math.pow(1.5, this.heartBeatRetryCount)
-
-				let networkMultiplier = 1
-				switch (this.networkType) {
-					case '2g':
-						networkMultiplier = 3
-						break
-					case '3g':
-						networkMultiplier = 2
-						break
-					case '4g':
-					case '5g':
-						networkMultiplier = 1
-						break
-					case 'wifi':
-						networkMultiplier = 0.8
-						break
-					default:
-						networkMultiplier = 1.5
-				}
-
-				return Math.min(baseDelay * retryMultiplier * networkMultiplier, 10000)
-			},
-			adjustHeartBeatInterval(isSuccess) {
-				if (isSuccess) {
-					this.adaptiveHeartBeatInterval = Math.min(this.adaptiveHeartBeatInterval * 1.1, 30000)
-				} else {
-					this.adaptiveHeartBeatInterval = Math.max(this.adaptiveHeartBeatInterval * 0.9, 10000)
-				}
-			},
-			startPingTimeout() {
-				if (this.pingTimeoutTimer) {
-					clearTimeout(this.pingTimeoutTimer)
-					this.pingTimeoutTimer = null
-				}
-
-				this.pingTimeoutTimer = setTimeout(() => {
-					console.warn('心跳超时,触发重连')
-					this.pingTimeoutTimer = null
-					this.heartBeatRetryCount++
-					if (this.heartBeatRetryCount < this.maxHeartBeatRetries) {
-						console.log(`心跳超时,尝试重发 (${this.heartBeatRetryCount}/${this.maxHeartBeatRetries})`)
-						setTimeout(() => this.sendHeartBeat(), 1000)
-					} else {
-						console.log('心跳重试次数用尽,触发重连')
-						this.heartBeatRetryCount = 0
-						this.handleReconnect()
-					}
-				}, this.pingTimeout)
-			},
-			stopHeartBeat() {
-				if (this.heartBeatTimer) {
-					clearInterval(this.heartBeatTimer)
-					this.heartBeatTimer = null
-				}
-				if (this.pingTimeoutTimer) {
-					clearTimeout(this.pingTimeoutTimer)
-					this.pingTimeoutTimer = null
-				}
-			},
-			isSocketAvailable() {
-				return this.socket && this.isSocketOpen && this.socket.readyState === 1
-			},
-			handleReconnect() {
-				if (this.isManualClose) {
-					console.log('手动关闭连接,不进行重连')
-					return
-				}
-
-				if (this.reconnectTimer) {
-					console.log('重连已在进行中,跳过重复重连')
-					return
-				}
-
-				this.stopHeartBeat()
-
-				if (!this.isNetworkAvailable) {
-					console.warn('网络不可用,延迟重连')
-					this.reconnectTimer = setTimeout(() => {
-						this.reconnectTimer = null
-						this.handleReconnect()
-					}, 5000)
-					return
-				}
-
-				if (this.reconnectCount < this.maxReconnectAttempts) {
-					this.reconnectCount++
-
-					const baseDelay = 1000
-					const exponentialDelay = baseDelay * Math.pow(2, this.reconnectCount - 1)
-					const jitter = Math.random() * 1000
-					const totalDelay = Math.min(exponentialDelay + jitter, 30000)
-
-					console.log(`第${this.reconnectCount}次重连,延迟${Math.round(totalDelay)}ms,网络类型:${this.networkType}`)
-
-					this.reconnectTimer = setTimeout(() => {
-						this.reconnectTimer = null
-						if (this.isNetworkAvailable && !this.isManualClose && !this.isSocketAvailable()) {
-							console.log('开始执行重连...')
-							this.initSocket()
-						} else if (this.isSocketAvailable()) {
-							console.log('连接已恢复,取消重连')
-							this.reconnectCount = 0
-						} else {
-							console.warn('重连时网络不可用或已手动关闭')
-							this.handleReconnect()
-						}
-					}, totalDelay)
-				} else {
-					console.log(`已达最大重连次数(${this.maxReconnectAttempts}),停止重连`)
-					this.showReconnectFailedMessage()
-				}
-			},
-			showReconnectFailedMessage() {
-				uni.showToast({
-					title: '网络连接异常,请检查网络后重新进入',
-					icon: 'none',
-					duration: 3000
-				})
-			},
-			handleConnectionError(errorType, error) {
-				console.error(`WebSocket ${errorType}:`, error)
-
-				if (errorType === '连接请求失败') {
-					if (!this.isNetworkAvailable) {
-						console.warn('网络不可用,等待网络恢复后重连')
-						return
-					}
-				}
-
-				this.handleReconnect()
-			},
-			resetReconnectState() {
-				this.reconnectCount = 0
-				this.heartBeatRetryCount = 0
-
-				if (this.reconnectTimer) {
-					clearTimeout(this.reconnectTimer)
-					this.reconnectTimer = null
-				}
-
-				this.adaptiveHeartBeatInterval = this.heartBeatInterval
-			},
-			initNetworkStatusListener() {
-				uni.getNetworkType({
-					success: (res) => {
-						this.networkType = res.networkType
-						this.isNetworkAvailable = res.networkType !== 'none'
-						console.log('当前网络类型:', res.networkType)
-					}
-				})
-
-				uni.onNetworkStatusChange((res) => {
-					const oldNetworkType = this.networkType
-					const oldNetworkAvailable = this.isNetworkAvailable
-
-					this.networkType = res.networkType
-					this.isNetworkAvailable = res.isConnected
-
-					console.log(`网络状态变化: ${oldNetworkType} -> ${res.networkType}, 连接状态: ${res.isConnected}`)
-
-					if (!oldNetworkAvailable && res.isConnected) {
-						console.log('网络恢复,尝试重连WebSocket')
-						this.resetReconnectState()
-						setTimeout(() => {
-							if (!this.isSocketAvailable()) {
-								this.initSocket()
-							}
-						}, 1000)
-					}
-
-					if (oldNetworkType !== res.networkType && res.isConnected) {
-						this.adjustHeartBeatForNetworkType(res.networkType)
-					}
-
-					if (!res.isConnected) {
-						console.warn('网络断开,停止心跳')
-						this.stopHeartBeat()
-					}
-				})
-			},
-			adjustHeartBeatForNetworkType(networkType) {
-				let newInterval = this.heartBeatInterval
-				switch (networkType) {
-					case '2g':
-						newInterval = 30000
-						break
-					case '3g':
-						newInterval = 20000
-						break
-					case '4g':
-					case '5g':
-						newInterval = 15000
-						break
-					case 'wifi':
-						newInterval = 10000
-						break
-					default:
-						newInterval = 15000
-				}
-
-				if (newInterval !== this.adaptiveHeartBeatInterval) {
-					this.adaptiveHeartBeatInterval = newInterval
-					console.log(`根据网络类型(${networkType})调整心跳间隔为${newInterval}ms`)
-
-					if (this.heartBeatTimer && this.isSocketAvailable()) {
-						this.startHeartBeat()
-					}
-				}
-			},
-			inputFocus() {
-				this.isFocus = true
-				this.isKeyboardShow = true
-			},
-			inputBlur() {
-				this.isFocus = false
-			},
-			onRed() {
-				if (!this.liveId) return
-				if (!this.redInfo?.redId) return
-				if (this.redTimer) {
-					clearInterval(this.redTimer)
-					this.redTimer = null
-				}
-				let data = {
-					liveId: this.liveId,
-					userId: this.userData.userId,
-					redId: this.redInfo.redId
-				}
-				liveRed(data).then(
-					(res) => {
-						this.isShowRed = false
-						this.redCard = res
-						this.isShowRedCard = true
-					},
-					(rej) => {}
-				)
-			},
-			onCoupon() {
-				if (!this.couponInfo.couponIssueId) return
-				let data = {
-					goodsId: this.couponInfo.goodsId,
-					couponIssueId: this.couponInfo.couponIssueId,
-					liveId: this.liveId
-				}
-				coupon(data).then((res) => {
-					this.isShowCoupon = false
-					if (res.code == 200) {
-						uni.showToast({
-							title: res.msg,
-							icon: 'none'
-						})
-					} else {
-						uni.showToast({
-							title: res.msg,
-							icon: 'none'
-						})
-					}
-				}).catch((rej) => {})
-			},
-			getMyLottery() {
-				this.winning = true
-				myLottery()
-					.then((res) => {
-						if (res.code == 200) {
-							this.prizeAll = res.data.list || {}
-						} else {}
-					})
-					.catch((rej) => {})
-			},
-			onLottery() {
-				if (!this.lotteryInfo) return
-
-				let data = {
-					lotteryId: this.lotteryInfo.lotteryId
-				}
-
-				liveLottery(data)
-					.then((res) => {
-						if (res.code == 200) {
-							const resData = res.data || {}
-							this.lotteryList = Array.isArray(resData) ? resData : []
-							this.lotteryProducts = Array.isArray(resData.products) ? resData.products : []
-
-							if (resData.duration) {
-								this.isShowLotteryPop = true
-							}
-						} else {
-							uni.showToast({
-								title: res.msg,
-								icon: 'none'
-							})
-							this.lotteryList = []
-							this.lotteryProducts = []
-						}
-					})
-					.catch((rej) => {
-						uni.showToast({
-							title: '获取抽奖信息失败',
-							icon: 'none'
-						})
-						this.lotteryList = []
-						this.lotteryProducts = []
-					})
-			},
-			onClaim() {
-				let data = {
-					liveId: this.liveId,
-					lotteryId: this.lotteryInfo.lotteryId
-				}
-				claim(data).then(
-					(res) => {
-						if (res.code == 200) {
-							uni.showToast({
-								title: res.msg,
-								icon: 'none'
-							})
-							this.isShowLotteryPop = false
-							this.havePrize = true
-							uni.setStorageSync('havePrize', this.havePrize)
-						} else {
-							uni.showToast({
-								title: res.msg,
-								icon: 'none'
-							})
-						}
-					},
-					(rej) => {}
-				)
-			},
-			confirm() {
-				this.isShowPrize = false
-				this.havePrize = false
-				uni.setStorageSync('havePrize', this.havePrize)
-			},
-			onGoodsCollect(item) {
-				if (!item || item.length === 0 || !item.goodsId) {
-					return
-				}
-				collectGoods(item.goodsId).then(
-					(res) => {
-						if (res.code == 200) {
-							uni.showToast({
-								title: res.msg,
-								icon: 'none'
-							})
-							item.isFavorite = !item.isFavorite
-						} else {
-							uni.showToast({
-								title: res.msg,
-								icon: 'none'
-							})
-						}
-					},
-					(rej) => {}
-				)
-			},
-			handleGoShopFromCart(item) {
-				this.goShop(item.productId, item.goodsId)
-			},
-			getliveOrder(item) {
-				if (!this.liveId) {
-					return
-				}
-				liveOrderUser(this.liveId).then(
-					(res) => {
-						if (res.code == 200) {
-							this.orderUser = res
-						} else {
-							console.log('获取正在购买用户失败')
-						}
-					},
-					(rej) => {}
-				)
-			},
-			onLiveStateChange(e, liveItem) {
-				const stateCode = e.detail.code
-				if (e.detail.code == -2301 || e.detail.code == -2302) {
-					if (this.$refs.liveVideo && this.$refs.liveVideo.playVideo) {
-						this.$refs.liveVideo.playVideo()
-					}
-				} else if (e.detail.code == 2004) {
-					this.calculateTimeDiff(this.liveItem)
-					this.startTrafficCalculation(this.bitrateLive)
-				}
-			},
-			onLiveError(e, liveItem) {
-				this.videoError(e, liveItem)
-				console.log('错误')
-			},
-			getCurrentActivities() {
-				if (!this.liveId) return
-				currentActivities(this.liveId).then(
-					(res) => {
-						if (res.code === 200) {
-							this.redInfo = (Array.isArray(res.red) ? res.red : [])[0] || {}
-							this.lotteryInfo = (Array.isArray(res.lottery) ? res.lottery : [])[0] || {}
-							this.goodsCard = res.goods || {}
-							this.notice = res.topMsg || {}
-							this.isShowGoods = this.goodsCard && this.goodsCard.status == 1
-							this.isShowRed = this.redInfo && this.redInfo.redStatus == 1
-							this.isShowLottery = this.lotteryInfo && this.lotteryInfo.lotteryStatus == 1
-							if (this.isShowRed) {
-								this.redTimer = setInterval(() => {
-									const redCountdown = this.handleTime(this.redInfo.updateTime, this.redInfo
-										.duration)
-									if (!redCountdown) {
-										this.isShowRed = false
-										clearInterval(this.redTimer)
-									}
-								}, 1000)
-							}
-							if (this.notice.msg) {
-								this.noticeTimer = setInterval(() => {
-									const noticeCountdown = this.handleTime(this.notice.endTime, 0)
-									console.log('出现1>>>', noticeCountdown)
-									if (!noticeCountdown) {
-										this.isShowNotice = false
-										clearInterval(this.noticeTimer)
-									} else {
-										this.isShowNotice = true
-									}
-								}, 1000)
-							}
-							if (this.isShowLottery) {
-								this.lotteryTimer = setInterval(() => {
-									this.countdown = this.handleTime(this.lotteryInfo.updateTime, this
-										.lotteryInfo.duration)
-								}, 1000)
-							}
-						} else {
-							uni.showToast({
-								title: res.msg,
-								icon: 'none'
-							})
-						}
-					},
-					(rej) => {}
-				)
-			},
-			calculateTimeDiff(item) {
-				if (!item.startTime) return
-				let timeStr = item.startTime
-
-				const time = new Date(timeStr.replace(/-/g, '/'))
-
-				if (isNaN(time.getTime())) {
-					return
-				}
-				const now = new Date()
-				let diffMs = Math.max(0, now.getTime() - time.getTime())
-				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)
-				this.diffTotalTime = `${hours}:${minutes}:${seconds}`
-			},
-			padZero(num) {
-				return num < 10 ? `0${num}` : num
-			},
-			startTimeTimer(item) {
-				if (!item) return
-				const totalTime = this.calculateTimeDiff(item)
-				item.timeTimer = setInterval(() => {
-					const totalTime = this.calculateTimeDiff(item)
-				}, 1000);
-			},
-			toggleViewerList() {  //加载直播间观众
-				const now = Date.now()
-				if (now - this.lastClickTime > this.clickDelay) {
-					this.showViewerList = !this.showViewerList
-					// if (this.showViewerList) {
-					// 	this.getliveUser(false);
-					// }
-					this.lastClickTime = now;
-				}
-			},
-			closeViewerList() {
-				this.showViewerList = false
-			},
-			openViewerList() {
-				// this.$nextTick(() => {
-				// 	this.calculateScrollHeight()
-				// })
-			},
-			calculateScrollHeight() {
-				// const query = uni.createSelectorQuery().in(this)
-				// query.select('.viewer-list-popup').boundingClientRect((data) => {
-				// 	if (data) {
-				// 		this.scrollHeight = data.height - 120
-				// 	}
-				// }).exec()
-			},
-			openViews() {
-				this.$nextTick(() => {
-					const query = uni.createSelectorQuery().in(this)
-					query.select('.view-box').boundingClientRect((data) => {
-							if (data) {
-								this.scrollHeight = data.height - 80
-							}
-						}).exec();
-				})
-			},
-			async handleViewerLoadMore(page) {
-				if (this.viewLoading) return;
-				this.viewPageNum = page.num;
-				await this.getliveUser(page.num > 1);
-			},
-			async getLiveMsg(liveItem) {
-				if (!liveItem || !this.liveId) {
-					console.error('getLiveMsg 错误:无效的 liveItem')
-					return
-				}
-				try {
-					const res = await liveMsg(this.liveId, 30, 1)
-					if (res.code == 200) {
-						const rows = Array.isArray(res.rows) ? res.rows : []
-						const reversedTalkList = [...rows].reverse()
-						this.talklist = Array.isArray(reversedTalkList) ? reversedTalkList : []
-						this.$nextTick(() => {
-							this.scrollToBottom()
-						})
-					} else {
-						this.talklist = []
-					}
-				} catch (error) {
-					this.talklist = []
-					console.error('获取聊天记录失败:', error)
-				}
-			},
-			generateRandomChineseName() {
-				const prefixes = [
-					'幸福', '快乐', '安康', '吉祥', '如意', '平安', '健康', '长寿', '福气', '美满',
-					'和谐', '团圆', '富贵', '荣华', '宁静', '淡泊', '知足', '常乐', '悠然', '自在',
-					'夕阳', '晚霞', '金秋', '银发', '老顽童', '开心', '笑口常开', '岁月静好', '云淡风轻', '海阔天空'
-				]
-
-				const suffixes = [
-					'老人', '大爷', '大妈', '爷爷', '奶奶', '伯伯', '阿姨', '前辈', '先生', '女士',
-					'长者', '翁', '婆', '哥', '姐', '友', '客', '迷', '粉丝', '达人',
-					'爱好者', '之家', '之人', '之心', '之情', '之乐', '之旅', '之梦', '之歌', '之韵'
-				]
-
-				const specialNames = [
-					'老有所乐', '知足常乐', '笑看人生', '云淡风轻', '岁月如歌', '夕阳红', '金色年华', '老当益壮',
-					'鹤发童颜', '老骥伏枥', '闲云野鹤', '淡泊明志', '宁静致远', '随遇而安', '顺其自然',
-					'老来俏', '开心果', '老宝贝', '不老松', '常青树'
-				]
-
-				if (Math.random() < 0.3) {
-					return specialNames[Math.floor(Math.random() * specialNames.length)]
-				} else {
-					const prefix = prefixes[Math.floor(Math.random() * prefixes.length)]
-					const suffix = suffixes[Math.floor(Math.random() * suffixes.length)]
-					return prefix + suffix
-				}
-			},
-			async getliveUser(isLoadMore = false) {
-				if (!isLoadMore) {
-					this.liveViewers = []
-				}
-				this.viewLoading = true;
-				try {
-					const res = await watchUserList(this.liveId, this.viewPageSize, this.viewPageNum, false);
-					console.log("qxj watchUserList res",res);
-					if (res.code === 200) {
-						const newRows = Array.isArray(res.rows) ? res.rows : []
-						
-						const newViewers = newRows.map((item) => ({
-								avatar: item.avatar || '',
-								userId: item.userId || '',
-								nickName: item.nickName || '未命名'
-						}));
-
-						let virtualData = [];
-						let virtualTotal = res.total > 20 ? 20 : res.total;
-						for (let i = 0; i < virtualTotal; i++) {
-							let data = {
-								avatar: '',
-								userId: '8565' + i,
-								nickName: this.generateRandomChineseName()
-							}
-							virtualData.push(data);
-						}
-						
-						if (!isLoadMore) {
-							this.liveViewersData = [...newViewers, ...virtualData];
-						}
-
-						// 过滤掉旧列表中的虚拟数据,保留真实用户
-						let currentRealViewers = isLoadMore ? this.liveViewers.filter(v => !String(v.userId).startsWith('8565')) : [];
-						
-						// 合并真实用户
-						let allRealViewers = [...currentRealViewers, ...newViewers];
-						
-						// 加上虚拟用户放在最后
-						this.liveViewers = [...allRealViewers, ...virtualData];
-						
-						let hasMore = newRows.length > 0;
-						if (this.liveViewers.length >= 100) {
-							hasMore = false;
-							this.lookAudsCount = this.liveUserTotal - 100;
-						} else {
-							this.lookAudsCount = 0;
-						}
-						
-						if (this.$refs.viewer) {
-							this.$refs.viewer.endSuccess(newRows.length, hasMore);
-						}
-					} else {
-						if (this.$refs.viewer) this.$refs.viewer.endErr();
-					}
-				} catch (error) {
-					console.error('获取观众列表失败:', error)
-					if (this.$refs.viewer) this.$refs.viewer.endErr();
-				} finally {
-					this.viewLoading = false
-				}
-			},
-			async getliveUserInit(isLoadMore = false) {
-				try {
-					const res = await watchUserList(this.liveId, this.viewPageSize, 1, false);
-					console.log("qxj watchUserList res",res);
-					if (res.code === 200) {
-						const userRows = Array.isArray(res.rows) ? res.rows : []
-						let array = userRows.map((item) => ({
-							avatar: item.avatar || '',
-							userId: item.userId || '',
-							nickName: item.nickName || '未命名'
-						}));
-						let virtualData = [];
-						let virtualTotal = res.total * 2 + 50;
-						//this.virtualTotal= virtualTotal;
-						this.liveUserTotal = virtualTotal;
-						// for (let i = 0; i < 5; i++) {
-						// 	let data = {
-						// 		avatar: '',
-						// 		userId: '8565' + i,
-						// 		nickName: this.generateRandomChineseName()
-						// 	}
-						// 	virtualData.push(data)
-						// }
-						this.liveTopViewersData = [...array];
-					
-					}
-				} catch (error) {
-					console.error('获取观众列表失败:', error)
-				} finally {
-				}
-			},
-			
-			showPurchaseMessage() {
-				if (this.purchasePromptTimer) {
-					clearTimeout(this.purchasePromptTimer)
-				}
-
-				this.showPurchasePrompt = true
-
-				this.purchasePromptTimer = setTimeout(() => {
-					this.showPurchasePrompt = false
-				}, 2000)
-			},
-			truncateString(str, maxLength) {
-				if (typeof str !== 'string' || str.length <= maxLength) {
-					return str
-				}
-				return str.slice(0, maxLength) + '...'
-			},
-			navgetTo(url) {
-				uni.navigateTo({
-					url: url
-				})
-			},
-			async getliving(liveId) {
-				if (!liveId) return
-				const param = {
-					id: liveId
-				}
-				try {
-					const res = await getlive(param)
-					if (res.code !== 200) {
-						uni.showToast({
-							title: res.msg,
-							icon: 'none'
-						})
-						return
-					}
-					this.liveItem = Object.assign({}, this.liveItem, res.data)
-					this.startTimeTimer(this.liveItem)
-					if (this.liveStartTimer) {
-						clearInterval(this.liveStartTimer)
-						this.liveStartTimer = null
-					}
-					if (res.data.status == 1) {
-						this.liveStartTimer = setInterval(async () => {
-							this.liveCountdown = this.handleTime(res.data.startTime, 0)
-							if (!this.liveCountdown) {
-								uni.removeStorageSync('isAgreement')
-								await this.getliving(this.liveId)
-								clearInterval(this.liveStartTimer)
-							}
-						}, 1000)
-						this.$set(this.liveItem, 'previewUrl', res.data.previewUrl)
-						this.$set(this.liveItem, 'livingUrl', '')
-						this.$set(this.liveItem, 'videoUrl', '')
-					} else if (res.data.status == 2) {
-						if (res.data.liveType == 1) {
-							let cTime = Math.floor(Math.random() * 10000) + 1
-							let livingUrl = res.data.flvHlsUrl + '&t=' + cTime
-							this.$set(this.liveItem, 'livingUrl', livingUrl)
-							this.$set(this.liveItem, 'videoUrl', '')
-						} else if (res.data.liveType === 2) {
-							this.$set(this.liveItem, 'videoUrl', res.data.videoUrl)
-							this.$set(this.liveItem, 'livingUrl', '')
-						}
-					} else if (res.data.status == 4 && res.data.liveType == 3) {
-						this.$set(this.liveItem, 'videoUrl', res.data.videoUrl)
-						this.$set(this.liveItem, 'livingUrl', '')
-					} else {
-						this.$set(this.liveItem, 'livingUrl', '')
-						this.$set(this.liveItem, 'videoUrl', '')
-					}
-					// if (this.liveItem.configJson) {
-					//    this.completionRate = JSON.parse(this.liveItem.configJson).completionRate * 0.01;
-					//  }
-					this.$set(this.liveItem, 'autoplay', res.data.liveType !== 0)
-					this.$set(this.liveItem, 'showType', res.data.showType)
-					this.storeId = res.storeId
-					this.diffLiveStartTime = this.calculateLiveTimeDiff(this.liveItem.startTime);
-					if (this.diffLiveStartTime < 0) { //预告
-						this.isPreview = true;
-						this.liveBeginWatchTime = Date.now();
-					} else {
-						if (!this.hasLiveEnd) { //没经历过直播结束
-							this.liveBeginWatchTime = Date.now();
-						}
-					}
-
-					console.log("是否调用积分列表", this.liveItem.completionPointsEnabled)
-					if (this.liveItem.completionPointsEnabled) {
-						console.log("是否调用积分列表")
-						this.getRemainingTime()
-					}
-					// 初始化累计观看时间
-					this.initWatchTime();
-					this.startLiveViewDataTimer()
-					if (this.$refs.liveVideo && this.$refs.liveVideo.playVideo) {
-						this.$refs.liveVideo.playVideo()
-					}
-				} catch (err) {
-					console.error('获取直播信息失败:', err)
-					uni.showToast({
-						title: '获取直播信息失败',
-						icon: 'none'
-					})
-				}
-			},
-			getPureDecimal(num, precision = 6) {
-				const decimalPart = Math.abs(num).toFixed(precision).split('.')[1]
-				return decimalPart?.replace(/0+$/, '') || ''
-			},
-			goBack() {
-				if (this.liveItem) {
-					if (this.$refs.liveVideo && this.$refs.liveVideo.pauseVideo) {
-						this.$refs.liveVideo.pauseVideo()
-					}
-				}
-				this.closeWebSocket(true)
-				const pages = getCurrentPages()
-				if (pages.length > 1) {
-					uni.navigateBack()
-				} else {
-					uni.reLaunch({
-						url: '/pages_course/livingList'
-					})
-				}
-			},
-			async onLike() {
-				if (!this.liveId) return
-				try {
-					const res = await liveDataLike(this.liveId)
-					if (res?.like) {
-						this.liveViewData.like++
-					} else {
-						uni.showToast({
-							title: res.msg,
-							icon: 'none'
-						})
-					}
-				} catch (error) {
-					console.error('点赞失败:', error)
-				}
-			},
-			getliveViewData() {
-				if (!this.liveId) return
-				getLiveViewData(this.liveId).then((res) => {
-					if (res.code == 200) {
-						this.liveViewData = res
-					}
-				}).catch((error) => {
-					console.error('获取直播间数据失败:', error)
-					this.liveViewData = {
-						like: 0,
-						watchCount: 0
-					}
-				})
-			},
-			startLiveViewDataTimer() {
-				if (this.liveViewDataTimer) {
-					clearInterval(this.liveViewDataTimer)
-					this.liveViewDataTimer = null
-				}
-				this.getliveViewData()
-				this.liveViewDataTimer = setInterval(() => {
-					if (this.liveId) {
-						this.getliveViewData()
-					}
-				}, 20000)
-			},
-			goShop(productId, goodsId) {
-				if (!this.liveId) return
-				uni.navigateTo({
-					url: '/pages_shopping/live/goods?productId=' + productId + '&liveId=' + this.liveId +
-						'&goodsId=' + goodsId + '&storeId=' + this.storeId
-				})
-			},
-			async queryCollect() {
-				this.loadingProducts = true
-				if (!this.liveId) return
-				if (this.inputInfo == null) this.inputInfo = ''
-				uni.showLoading({
-					title: '加载中'
-				})
-				try {
-					const res = await liveStore(this.liveId, this.inputInfo)
-					uni.hideLoading()
-					this.shopping = true
-					if (res.code === 200) {
-						this.products = Array.isArray(res.data) ? res.data : []
-					}
-				} catch (error) {
-					console.error('获取小黄车商品失败:', error)
-				} finally {
-					this.loadingProducts = false
-				}
-			},
-			initTime() {
-				const now = new Date()
-				this.timestamp = now.getTime()
-			},
-			showGift() {
-				this.isShowGift = true
-			},
-			clearChatInput() {
-				this.$refs.chatInput.clearInput()
-			},
-			openCart() {
-				this.queryCollect()
-			},
-			closeGift() {
-				this.isShowGift = false
-			},
-			closeShop() {
-				this.shopping = false
-			},
-			closeMore() {
-				this.isMore = false
-			},
-			closeWin() {
-				this.winning = false
-			},
-			closeWebSocket(isManual = true) {
-				if (!this.socket || !this.isSocketOpen) {
-					console.warn('WebSocket 任务不存在或未打开,无需关闭')
-					return
-				}
-
-				console.log(`WebSocket连接关闭 - ${isManual ? '手动' : '自动'}`)
-				this.isManualClose = isManual
-
-				this.cleanupAllResources()
-
-				try {
-					const socketToClose = this.socket
-					this.socket = null
-					this.isSocketOpen = false
-					this.isConnecting = false
-
-					socketToClose.close({
-						code: 1000,
-						reason: isManual ? '主动关闭' : '异常关闭'
-					})
-					console.log('WebSocket连接已发起关闭')
-				} catch (err) {
-					console.error('关闭WebSocket失败:', err)
-					this.socket = null
-					this.isSocketOpen = false
-					this.isConnecting = false
-				}
-			},
-			cleanupAllResources() {
-				this.stopHeartBeat()
-
-				if (this.pingTimeoutTimer) {
-					clearTimeout(this.pingTimeoutTimer)
-					this.pingTimeoutTimer = null
-				}
-
-				if (this.networkStatusTimer) {
-					clearTimeout(this.networkStatusTimer)
-					this.networkStatusTimer = null
-				}
-
-				this.resetReconnectState()
-
-				this.heartBeatRetryCount = 0
-				this.lastHeartBeatTime = 0
-				this.adaptiveHeartBeatInterval = this.heartBeatInterval
-			},
-			startHeartBeat() {
-				this.stopHeartBeat()
-				this.heartBeatTimer = setInterval(() => {
-					this.sendHeartBeat()
-				}, this.adaptiveHeartBeatInterval)
-			},
-			initSocket() {
-				if (this.isConnecting) {
-					console.log('WebSocket正在连接中,跳过重复连接')
-					return
-				}
-
-				if (!this.isNetworkAvailable) {
-					console.warn('网络不可用,延迟WebSocket连接')
-					if (!this.networkRetryTimer) {
-						this.networkRetryTimer = setTimeout(() => {
-							this.networkRetryTimer = null
-							this.initSocket()
-						}, 3000)
-					}
-					return
-				}
-
-				if (this.socket && this.socket.readyState === 1) {
-					console.log('WebSocket连接已存在且正常,无需重新连接')
-					this.reconnectCount = 0
-					return
-				}
-
-				if (this.socket && (this.socket.readyState === 0 || this.socket.readyState === 1)) {
-					console.log('关闭现有WebSocket连接,创建新连接')
-					this.closeWebSocket(false)
-					setTimeout(() => {
-						this.createWebSocketConnection()
-					}, 100)
-					return
-				}
-				this.createWebSocketConnection()
-			},
-			createWebSocketConnection() {
-				if (!this.liveId) {
-					console.error('缺失直播间ID,无法初始化WebSocket')
-					return
-				}
-				if (!this.userData || !this.userData.userId) {
-					console.error('用户信息缺失,无法初始化WebSocket')
-					return
-				}
-
-				this.isConnecting = true
-				this.isSocketOpen = false
-				this.connectionStartTime = Date.now()
-				this.resetReconnectState()
-
-				setTimeout(() => {
-					this.getliveUserInit(false)
-				}, 200)
-
-				const now = new Date()
-				this.timestamp = now.getTime()
-				const signature = CryptoJS.HmacSHA256(
-					`${this.liveId}${this.userData.userId}${this.userType}${this.timestamp}`, this.timestamp.toString()
-				).toString(CryptoJS.enc.Hex)
-
-				try {
-					const baseWsUrl = 'wss://im.fhhx.runtzh.com/ws/app/webSocket'
-					let wsUrl =
-						`${baseWsUrl}?userId=${this.userData.userId}&liveId=${this.liveId}&userType=${this.userType}&timestamp=${this.timestamp}&signature=${signature}`
-					if (this.qrFrom) {
-						wsUrl += this.qrFrom
-					}
-
-					console.log('qxj wsUrl', wsUrl)
-					const socketTask = uni.connectSocket({
-						url: wsUrl,
-						success: () => {
-							console.log('WebSocket连接请求发送成功')
-						},
-						fail: (err) => {
-							console.error('WebSocket连接请求失败:', err)
-							this.isConnecting = false
-							this.handleConnectionError('连接请求失败', err)
-						}
-					})
-
-					socketTask.onOpen((res) => {
-						console.log('WebSocket连接已打开')
-						this.socket = socketTask
-						this.isConnecting = false
-						this.isSocketOpen = true
-
-						if (this.connectionStartTime > 0) {
-							this.connectionLatency = Date.now() - this.connectionStartTime
-							console.log(`WebSocket连接延迟: ${this.connectionLatency}ms`)
-						}
-
-						this.reconnectCount = 0
-						this.resetReconnectState()
-						this.heartBeatRetryCount = 0
-						this.shownEntryUsers.clear()
-
-						if (this.reconnectCount === 0) {
-							console.log('WebSocket连接建立成功')
-						} else {
-							console.log(`WebSocket重连成功(第${this.reconnectCount}次尝试)`)
-						}
-						this.startHeartBeat()
-					})
-
-					socketTask.onMessage((res) => {
-						this.messageCount++
-						try {
-							const data = JSON.parse(res.data)
-							if (!!data.data && data.data.cmd === 'heartbeat') {
-								if (this.pingTimeoutTimer) {
-									clearTimeout(this.pingTimeoutTimer)
-									this.pingTimeoutTimer = null
-								}
-								this.heartBeatRetryCount = 0
-								this.adjustHeartBeatInterval(true)
-								return
-							}
-							this.handleSocketMessage(res)
-						} catch (err) {
-							console.error('消息解析异常:', err)
-							this.errorCount++
-						}
-					})
-
-					socketTask.onError((err) => {
-						console.error('WebSocket连接错误:', err)
-						this.errorCount++
-						this.isSocketOpen = false
-						this.isConnecting = false
-						this.stopHeartBeat()
-						this.handleConnectionError('连接错误', err)
-					})
-
-					socketTask.onClose((res) => {
-						console.log('WebSocket连接关闭:', res)
-						this.isSocketOpen = false
-						this.isConnecting = false
-						this.stopHeartBeat()
-
-						if (!this.isManualClose) {
-							if (res.code === 1000) {
-								console.log('WebSocket正常关闭,不进行重连')
-							} else {
-								console.warn(`WebSocket异常关闭 (code: ${res.code}, reason: ${res.reason})`)
-								this.handleReconnect()
-							}
-						} else {
-							console.log('WebSocket手动关闭,不进行重连')
-						}
-					})
-				} catch (e) {
-					console.error('创建WebSocket异常:', e)
-					this.handleReconnect()
-				}
-			},
-			handleTime(time, duration) {
-				let timeStamp
-
-				if (typeof time === 'number' && time > 0 && time < 9999999999999) {
-					timeStamp = time
-				} else if (typeof time === 'string' && time.trim() !== '') {
-					const match = time.match(/^(\w{3}) (\w{3}) (\d{1,2}) (\d{1,2}):(\d{2}):(\d{2}) CST (\d{4})$/)
-
-					if (match) {
-						const [, day, month, date, hours, minutes, seconds, year] = match
-
-						const monthMap = {
-							'Jan': 0,
-							'Feb': 1,
-							'Mar': 2,
-							'Apr': 3,
-							'May': 4,
-							'Jun': 5,
-							'Jul': 6,
-							'Aug': 7,
-							'Sep': 8,
-							'Oct': 9,
-							'Nov': 10,
-							'Dec': 11
-						}
-
-						const jsDate = new Date(
-							parseInt(year),
-							monthMap[month],
-							parseInt(date),
-							parseInt(hours),
-							parseInt(minutes),
-							parseInt(seconds)
-						)
-						timeStamp = jsDate.getTime()
-					} else {
-						const date = new Date(time)
-						if (!isNaN(date.getTime())) {
-							timeStamp = date.getTime()
-						} else {
-							console.error('无效的日期格式:', time)
-							return false
-						}
-					}
-				} else {
-					console.error('time参数必须是有效的时间戳(数字)或日期字符串')
-					return false
-				}
-
-				const targetTimestamp = timeStamp + duration * 60 * 1000
-				const currentTimestamp = Date.now()
-				const timeDiffMs = targetTimestamp - currentTimestamp
-
-				if (timeDiffMs <= 0) {
-					return false
-				}
-
-				const hours = Math.floor(timeDiffMs / (1000 * 60 * 60))
-				const minutes = Math.floor((timeDiffMs % (1000 * 60 * 60)) / (1000 * 60))
-				const seconds = Math.floor((timeDiffMs % (1000 * 60)) / 1000)
-
-				const formatNum = (num) => num.toString().padStart(2, '0')
-				return {
-					hours: formatNum(hours),
-					minutes: formatNum(minutes),
-					seconds: formatNum(seconds)
-				}
-			},
-			addToTalkList(message) {
-				const MAX_TALK_ITEMS = 30
-
-				if (!Array.isArray(this.talklist)) {
-					this.talklist = []
-				}
-
-				const wasAtLimit = this.talklist.length >= MAX_TALK_ITEMS
-				const isMyMessage = message.userId === this.userData.userId
-
-				try {
-					message.uniqueId = ++this.messageIdCounter
-
-					let msgdata = {}
-					try {
-						msgdata = JSON.parse(message.data)
-					} catch (e) {
-						console.warn('JSON解析失败:', e)
-						msgdata = {}
-					}
-
-					message.msgId = msgdata.msgId || Date.now()
-					this.talklist.push(message)
-				} catch (error) {
-					console.error('处理消息时出错:', error)
-				}
-
-				if (this.talklist.length > MAX_TALK_ITEMS) {
-					const removeCount = this.talklist.length - MAX_TALK_ITEMS
-					this.talklist.splice(0, removeCount)
-				}
-
-				this.$forceUpdate()
-
-				this.$nextTick(() => {
-					this.forceScrollToBottomOnSend()
-				})
-			},
-			async handleSocketMessage(message) {
-				try {
-					let data = JSON.parse(message.data)
-					const socketMessage = data.data
-					if (data.code == 200) {
-						const messageData = {
-							...socketMessage,
-							cmd: socketMessage.cmd || '',
-							ts: Date.now()
-						}
-						if (socketMessage.cmd == 'sendMsg') {
-							if (!this.isSocketAvailable()) {
-								uni.showToast({
-									title: '连接已断开,正在重试...',
-									icon: 'none'
-								})
-								this.handleReconnect()
-								return
-							}
-							this.addToTalkList(messageData)
-						} else if (socketMessage.cmd == 'red') {
-							const redData = socketMessage.data ? JSON.parse(socketMessage.data) : {}
-							this.redInfo = redData || {}
-							this.isShowRed = socketMessage.status === 1
-							if (this.isShowRed) {
-								this.redTimer = setInterval(() => {
-									const redCountdown = this.handleTime(this.redInfo.updateTime, this.redInfo
-										.duration)
-									if (!redCountdown) {
-										this.isShowRed = false
-										clearInterval(this.redTimer)
-									}
-								}, 1000)
-							}
-						} else if (socketMessage.cmd == 'goods') {
-							const goodsData = socketMessage.data ? JSON.parse(socketMessage.data) : {}
-							this.goodsCard = goodsData || {}
-							this.isShowGoods = socketMessage.status == 1
-						} else if (socketMessage.cmd == 'coupon') {
-							const couponData = socketMessage.data ? JSON.parse(socketMessage.data) : {}
-							this.couponInfo = couponData || {}
-							this.isShowCoupon = socketMessage.status === 1
-						} else if (socketMessage.cmd == 'likeDetail') {
-							this.liveViewData.like = socketMessage.data
-						} else if (socketMessage.cmd == 'lottery') {
-							const lotteryData = socketMessage.data ? JSON.parse(socketMessage.data) : {}
-							this.lotteryInfo = lotteryData || {}
-							this.isShowLottery = socketMessage.status === 1
-							if (socketMessage.status != 1) {
-								this.isShowLotteryPop = false
-							}
-							clearTimeout(this.lotteryTimer)
-							if (this.isShowLottery) {
-								this.lotteryTimer = setInterval(() => {
-									this.countdown = this.handleTime(this.lotteryInfo.updateTime, this
-										.lotteryInfo.duration)
-									if (!this.countdown) {
-										console.log('倒计时', this.countdown)
-										this.isShowLottery = false
-										this.isShowLotteryPop = false
-										clearInterval(this.lotteryTimer)
-									}
-								}, 1000)
-							} else {
-								this.isShowLottery = false
-							}
-						} else if (socketMessage.cmd == 'deleteMsg') {
-							const index = this.talklist.findIndex(item => item.msgId == socketMessage.msg)
-							if (index !== -1) {
-								this.talklist.splice(index, 1)
-							}
-						} else if (socketMessage.cmd == 'globalVisible') {} else if (socketMessage.cmd ==
-							'singleVisible') {} else if (socketMessage.cmd == 'entry') {
-							try {
-								//if (!this.liveUserCalled) {
-									await this.getliveUserInit(false)
-									this.liveUserCalled = true;
-								//}
-								const userIdToEntry = socketMessage.userId
-								const existingIndex = this.liveViewersData.findIndex((item) => item.userId ===
-userIdToEntry);
-								if (existingIndex === -1) {
-									const liveViewers = {
-										userId: socketMessage.userId,
-										nickName: socketMessage.nickName,
-										avatar: socketMessage.avatar
-									}
-									this.liveViewersData.push(liveViewers)
-									this.liveUserTotal++
-								}
-								
-								
-								const userData = JSON.parse(socketMessage.data || '{}')
-								const userId = userData.userId || socketMessage.userId
-								if (!userId) return
-								
-								if (!this.shownEntryUsers.has(userId)) {
-									this.inAndOut = socketMessage;
-									this.showWelcomeMessage = true;
-									this.shownEntryUsers.add(userId);
-									if (this.welcomeTimer) clearTimeout(this.welcomeTimer)
-									this.welcomeTimer = setTimeout(() => {
-										this.showWelcomeMessage = false
-									}, 3000)
-								}
-							} catch (err) {
-								console.error('解析entry用户数据失败:', err)
-							}
-						} else if (socketMessage.cmd == 'out') {
-							if (this.liveUserTotal > 0) {
-								const userIdToRemove = socketMessage.userId
-								const index = this.liveViewersData.findIndex((item) => item.userId === userIdToRemove)
-								if (index !== -1) {
-									this.liveViewersData.splice(index, 1)
-									this.liveUserTotal--
-								}
-							}
-							this.inAndOut = socketMessage
-							this.showWelcomeMessage = true
-
-							if (this.welcomeTimer) clearTimeout(this.welcomeTimer)
-							this.welcomeTimer = setTimeout(() => {
-								this.showWelcomeMessage = false
-							}, 3000)
-						} else if (socketMessage.cmd == 'sendTopMsg') {
-							clearInterval(this.noticeTimer)
-							console.log('公告消息>>>>', socketMessage)
-							const noticeData = socketMessage.data ? JSON.parse(socketMessage.data) : {}
-							this.notice = noticeData || {}
-							this.isShowNotice = true
-							if (this.isShowNotice) {
-								this.noticeTimer = setInterval(() => {
-									const noticeCountdown = this.handleTime(this.notice.endTime, 0)
-									if (!noticeCountdown) {
-										this.isShowNotice = false
-										clearInterval(this.noticeTimer)
-									}
-								}, 1000)
-							}
-						} else if (socketMessage.cmd == 'live_start' || socketMessage.cmd == 'live_end') {
-							if (this.liveStartTimer) {
-								clearInterval(this.liveStartTimer)
-								this.liveStartTimer = null
-							}
-							if (this.redTimer) {
-								clearInterval(this.redTimer)
-								this.redTimer = null
-							}
-							await this.getliving(this.liveId)
-						} else if (socketMessage.cmd == 'Integral') {
-							this.integral = {
-								msg: socketMessage.msg,
-								status: true
-							}
-						} else if (socketMessage.cmd == 'LotteryDetail') {
-							try {
-								this.prizeInfo = Array.isArray(JSON.parse(socketMessage.data || '[]')) ? JSON.parse(
-									socketMessage.data || '[]') : []
-							} catch (err) {
-								console.error('解析抽奖结果失败:', err)
-								this.prizeInfo = []
-							}
-							this.isShowPrize = true
-							this.isShowLottery = false
-							this.isShowLotteryPop = false
-						} else if (socketMessage.cmd == 'blockUser') {
-							uni.removeStorage({
-								key: 'AppToken',
-								success: () => {
-									uni.reLaunch({
-										url: '/pages/auth/login'
-									})
-								}
-							})
-						}
-					} else {
-						uni.showToast({
-							title: data.msg,
-							icon: 'none'
-						})
-					}
-				} catch (error) {
-					console.error('Socket消息处理失败:', error)
-				}
-			},
-			onBarrage(item) {
-				if (this.isSending) return
-				this.isSending = true
-				setTimeout(() => {
-					this.isSending = false
-				}, 800)
-				const text = (item || '').trim()
-				if (!text) {
-					uni.showToast({
-						title: '不能发送空消息',
-						icon: 'none'
-					})
-					return
-				}
-				if (!this.isSocketAvailable()) {
-					if (retries > 0) {
-						uni.showToast({
-							title: `连接不稳定,正在重试(${retries}次)...`,
-							icon: 'none'
-						})
-						setTimeout(() => this.sendMsg(retries - 1), 500)
-					} else {
-						uni.showToast({
-							title: '连接已断开,发送失败',
-							icon: 'none'
-						})
-					}
-					return
-				}
-				const liveId = this.liveId
-				const data = {
-					liveId,
-					userId: this.userData.userId,
-					userType: 0,
-					cmd: 'sendMsg',
-					msg: text,
-					nickName: this.userData.nickname || '未命名',
-					avatar: this.userData.avatar || '/static/images/avatar.png'
-				}
-				try {
-					this.socket.send({
-						data: JSON.stringify(data),
-						success: () => {
-							this.forceScrollToBottomOnSend()
-						},
-						fail: (err) => {
-							console.error('消息发送失败:', err)
-							if (retries > 0) {
-								uni.showToast({
-									title: `发送失败,正在重试(${retries}次)`,
-									icon: 'none'
-								})
-								setTimeout(() => this.sendMsg(retries - 1), 500)
-							} else {
-								uni.showToast({
-									title: '发送失败,请稍后再试',
-									icon: 'none'
-								})
-							}
-						}
-					})
-				} catch (err) {
-					console.error('发送消息异常:', err)
-					if (retries > 0) {
-						setTimeout(() => this.sendMsg(retries - 1), 500)
-					} else {
-						uni.showToast({
-							title: '发送失败,请稍后再试',
-							icon: 'none'
-						})
-					}
-				}
-			},
-			sendMsg(retries = 1) {
-				if (this.isSending) return
-				this.isSending = true
-				setTimeout(() => {
-					this.isSending = false
-				}, 800)
-				const text = (this.value || '').trim()
-				if (!text) {
-					uni.showToast({
-						title: '不能发送空消息',
-						icon: 'none'
-					})
-					return
-				}
-				if (!this.isSocketAvailable()) {
-					if (retries > 0) {
-						uni.showToast({
-							title: `连接不稳定,正在重试(${retries}次)...`,
-							icon: 'none'
-						})
-						setTimeout(() => this.sendMsg(retries - 1), 500)
-					} else {
-						uni.showToast({
-							title: '连接已断开,发送失败',
-							icon: 'none'
-						})
-						this.value = text
-					}
-					return
-				}
-				const liveId = this.liveId
-				this.value = ''
-				const data = {
-					liveId,
-					userId: this.userData.userId,
-					userType: 0,
-					cmd: 'sendMsg',
-					msg: text,
-					nickName: this.userData.nickname || '未命名',
-					avatar: this.userData.avatar || '/static/images/avatar.png'
-				}
-				try {
-					this.socket.send({
-						data: JSON.stringify(data),
-						success: () => {
-							this.value = ''
-							this.forceScrollToBottomOnSend()
-						},
-						fail: (err) => {
-							console.error('消息发送失败:', err)
-							if (retries > 0) {
-								uni.showToast({
-									title: `发送失败,正在重试(${retries}次)`,
-									icon: 'none'
-								})
-								setTimeout(() => this.sendMsg(retries - 1), 500)
-							} else {
-								uni.showToast({
-									title: '发送失败,请稍后再试',
-									icon: 'none'
-								})
-								this.value = text
-							}
-						}
-					})
-				} catch (err) {
-					console.error('发送消息异常:', err)
-					if (retries > 0) {
-						setTimeout(() => this.sendMsg(retries - 1), 500)
-					} else {
-						uni.showToast({
-							title: '发送失败,请稍后再试',
-							icon: 'none'
-						})
-						this.value = text
-					}
-				}
-			}
-		}
-	}
-</script>
-
-<style scoped lang="scss">
-	// 弹窗
-	.custom-toast {
-		position: fixed;
-		top: 50%;
-		left: 50%;
-		transform: translate(-50%, -50%);
-		z-index: 999999;
-	}
-
-	.toast-content {
-		background-color: rgba(0, 0, 0, 0.7);
-		color: white;
-		padding: 20rpx 40rpx;
-		border-radius: 16rpx;
-		max-width: 80vw;
-		text-align: center;
-		line-height: 1.5;
-		font-weight: 500;
-		font-size: 32rpx;
-	}
-
-	.swiper-wrapper {
-		position: relative;
-		width: 100%;
-		height: 100vh;
-		overflow: hidden;
-		background-color: #000000;
-
-		.live-bg {
-			position: absolute;
-			top: 0;
-			width: 100%;
-			height: 100%;
-		}
-
-		.container {
-			width: 100%;
-			height: 100%;
-			position: relative;
-			transition: opacity 0.3s ease;
-			transform: translateZ(0);
-			will-change: opacity;
-
-			&.fullscreen {
-
-				.content-top,
-				.side-group,
-				.chat-area-container,
-				.shop-popup,
-				.lottery-popup,
-				.more-popup,
-				.shop-card,
-				.gift-popup,
-				.coupon-pop,
-				.prize-popup,
-				.winning-popup,
-				.integral-popup,
-				.red-card-popup,
-				.viewer-popup {
-					display: none !important;
-					visibility: hidden !important;
-					opacity: 0 !important;
-					pointer-events: none !important;
-				}
-
-				.live-video {
-					position: fixed !important;
-					top: 0 !important;
-					left: 0 !important;
-					width: 100vw !important;
-					height: 100vh !important;
-					z-index: 99999 !important;
-					background: #000 !important;
-				}
-			}
-		}
-	}
-
-	.content {
-		position: relative;
-		z-index: 2;
-		height: 100%;
-		width: 100%;
-		top: 0;
-		left: 0;
-		display: flex;
-		flex-direction: column;
-		justify-content: space-between;
-		.progress-countdown {
-			margin-top: 24rpx;
-			z-index: 9000;
-			width: 180rpx;
-			display: flex;
-			flex-direction: column;
-			align-items: center;
-			background: rgba(0, 0, 0, 0.3);
-			border-radius: 16rpx;
-			padding: 16rpx;
-			flex-direction: column;
-		
-			&.progress-vertical {
-				top: 15%;
-				left: 24rpx;
-			}
-		
-			.title {
-				width: 148rpx;
-				height: 28rpx;
-			}
-		
-			.progress-bar-bg {
-				width: 148rpx;
-				height: 8rpx;
-				margin-top: 16rpx;
-				background: #ffffff;
-				border-radius: 6rpx;
-				overflow: hidden;
-				margin-bottom: 16rpx;
-		
-				.progress-bar-fill {
-					height: 100%;
-					background: #face15;
-					border-radius: 6rpx;
-					transition: width 1s linear;
-				}
-			}
-		
-			.progress-text {
-				color: #fff;
-				font-size: 20rpx;
-			}
-		}
-	}
-
-	.content-top {
-		width: 100%;
-		display: flex;
-		justify-content: space-between;
-		padding: 0 24rpx;
-		box-sizing: border-box;
-		position: fixed;
-		margin-top: 88rpx;
-		top: 0;
-		z-index: 5;
-		will-change: transform;
-
-		.x-f {
-			display: flex;
-			align-items: center;
-
-			.avatar-container {
-				padding: 6rpx 8rpx;
-				height: 64rpx;
-				background: rgba(0, 0, 0, 0.5);
-				border-radius: 32rpx;
-				display: flex;
-				align-items: center;
-			}
-		}
-
-		.end {
-			display: flex;
-			flex-direction: column;
-			align-items: flex-end;
-
-			.viewer-preview {
-				margin-top: 120rpx;
-				display: flex;
-				align-items: center;
-
-				.sum {
-					width: 80rpx;
-					height: 52rpx;
-					background: rgba(0, 0, 0, 0.5);
-					border-radius: 26rpx;
-					font-size: 30rpx;
-					color: #ffffff;
-					text-align: center;
-					line-height: 52rpx;
-				}
-			}
-
-			.complaint-box {
-				width: 140rpx;
-				margin-top: 20rpx;
-				display: flex;
-				align-items: center;
-				justify-content: center;
-				background: rgba(0, 0, 0, 0.3);
-				padding: 16rpx 0;
-				color: #fff;
-				border-radius: 28rpx;
-				z-index: 999;
-			}
-		}
-	}
-
-	
-
-	.side-group {
-		position: absolute;
-		top: 52%;
-		right: 24rpx;
-		z-index: 1000;
-		display: flex;
-		flex-direction: column;
-		align-items: center;
-		will-change: transform;
-
-		&.top2 {
-			top: 65%;
-		}
-
-		&.top3 {
-			top: 55%;
-		}
-
-		.side-item {
-			font-weight: 500;
-			font-size: 22rpx;
-			color: #ffffff;
-			margin-bottom: 26rpx;
-			text-align: center;
-
-			.button-reset {
-				background-color: transparent !important;
-				padding: 0 !important;
-				line-height: 1 !important;
-				margin: 0 !important;
-				width: auto !important;
-				font-weight: 500 !important;
-				border-radius: none !important;
-
-				&::after {
-					border: none !important;
-					padding: 0 !important;
-					margin: 0 !important;
-				}
-			}
-
-			.image {
-				width: 72rpx;
-				height: auto;
-			}
-
-			.txt {
-				font-size: 30rpx;
-				margin-top: 4rpx;
-			}
-		}
-	}
-
-	.chat-area-container {
-		position: fixed;
-		width: 100%;
-		bottom: 0;
-		z-index: 100;
-		transform: translateZ(0);
-		will-change: transform;
-		backface-visibility: hidden;
-
-		&.chat-area-focused {
-			transform: translateY(calc(-1 * var(--keyboard-height, 0rpx))) translateZ(0);
-			// z-index: 1000;
-		}
-	}
-
-	.chat-content {
-		height: 36vh;
-		overflow: hidden;
-		padding-left: 20rpx;
-		transform: translateZ(0);
-		will-change: height;
-		display: flex;
-		flex-direction: column;
-
-		&.chat-content-preview {
-			height: 20vh;
-		}
-
-		&.chat-content-focused {
-			height: 64rpx;
-		}
-	}
-
-	.shop-prompt {
-		width: auto;
-		display: inline-flex !important;
-		max-width: max-content;
-		padding: 6rpx 20rpx;
-		background: rgba(230, 154, 34, 0.7);
-		border-radius: 24rpx;
-		z-index: 9;
-		font-weight: 500;
-		color: #ffffff;
-		transition: opacity 0.3s ease;
-		margin-bottom: 20rpx;
-	}
-
-	.welcome-message {
-		width: 100%;
-		color: white;
-		border-radius: 20rpx;
-		z-index: 10;
-		transition: opacity 0.3s ease;
-	}
-
-	.notice-message {
-		max-width: 80%;
-		padding: 24rpx;
-		background: linear-gradient(135deg,
-				rgba(255, 220, 41, 0.8) 0%,
-				rgba(218, 187, 30, 0.4) 100%);
-		margin-bottom: 10rpx;
-		border-radius: 20rpx;
-		color: #ffffff;
-	}
-
-	.scrolly {
-		width: calc(100% - 20rpx);
-		-webkit-overflow-scrolling: touch;
-	}
-
-	.list {
-		width: 80%;
-		margin-bottom: 20rpx;
-		animation: simpleFade 0.2s;
-
-		.talk-list {
-			will-change: transform;
-			contain: layout style paint;
-			backface-visibility: hidden;
-			transform: translateZ(0);
-			max-width: 100%;
-			border-radius: 30rpx;
-			background: rgba(0, 0, 0, 0.3);
-			padding: 10rpx 30rpx;
-
-			.talk-item {
-				line-height: 1.4;
-				word-break: break-all;
-				word-wrap: break-word;
-				overflow-wrap: break-word;
-
-				.nickname {
-					color: #ffda73;
-				}
-
-				.message {
-					color: #ffffff;
-				}
-			}
-		}
-	}
-
-	.barrage {
-		background: rgba(0, 0, 0, 0.3);
-		padding: 12rpx 20rpx;
-		color: #fff;
-		margin: 30rpx 20rpx 0 20rpx;
-		border-radius: 30rpx;
-		white-space: nowrap;
-	}
-
-	.prize-card {
-		width: 504rpx;
-		padding: 40rpx 40rpx 30rpx;
-		box-sizing: border-box;
-		display: flex;
-		flex-direction: column;
-		border-radius: 20rpx;
-		align-items: center;
-		background: linear-gradient(180deg, #f7823f 0%, #ffd4be 27%, #ffffff 100%);
-		position: relative;
-
-		.nav-img {
-			width: 311rpx;
-			position: absolute;
-			top: -122rpx;
-			left: 50%;
-			transform: translateX(-50%);
-		}
-
-		.title {
-			color: #c32008;
-			font-size: 34rpx;
-			font-weight: 600;
-			margin: 20rpx 0 40rpx;
-		}
-
-		.prize-content {
-			width: 100%;
-			display: flex;
-			justify-content: space-between;
-			align-items: center;
-			font-size: 28rpx;
-			margin: 10rpx 0;
-
-			.txt {
-				font-weight: 600;
-			}
-		}
-
-		.tip {
-			font-size: 28rpx;
-			color: #414141;
-			margin: 40rpx 0;
-		}
-
-		.button {
-			width: 200rpx;
-			height: 70rpx;
-			line-height: 70rpx;
-			background: linear-gradient(180deg, #ff7c30 0%, #ff3a1e 100%);
-			border-radius: 28rpx;
-			font-weight: 500;
-			font-size: 32rpx;
-			color: #ffffff;
-			text-align: center;
-		}
-	}
-
-	.no-prize-card {
-		width: 504rpx;
-		padding: 40rpx 40rpx 30rpx;
-		box-sizing: border-box;
-		display: flex;
-		flex-direction: column;
-		border-radius: 20rpx;
-		align-items: center;
-		position: relative;
-
-		.img {
-			margin-top: 40rpx;
-			width: 300rpx;
-			height: 300rpx;
-		}
-
-		.tip {
-			font-size: 36rpx;
-			color: #414141;
-			margin: 40rpx 0;
-		}
-
-		.button {
-			width: 220rpx;
-			height: 80rpx;
-			line-height: 80rpx;
-			background: linear-gradient(180deg, #fdfbb8 0%, #b79243 100%);
-			border-radius: 28rpx;
-			font-weight: 500;
-			font-size: 32rpx;
-			color: #ffffff;
-			text-align: center;
-		}
-	}
-
-	.red-card {
-		width: 550rpx;
-		height: 636rpx;
-		position: relative;
-
-		.img {
-			position: absolute;
-			width: 100%;
-			height: 100%;
-		}
-
-		.red-content {
-			position: relative;
-			z-index: 5;
-			display: flex;
-			flex-direction: column;
-			align-items: center;
-
-			.title {
-				font-size: 36rpx;
-				color: #ff3a1e;
-				margin: 180rpx 0 90rpx;
-			}
-
-			.txt {
-				font-size: 28rpx;
-				color: #ffecc3;
-				margin: 80rpx 0 40rpx;
-			}
-
-			.button {
-				width: 392rpx;
-				height: 96rpx;
-				line-height: 96rpx;
-				background: linear-gradient(180deg, #fff4d5 0%, #ffe5b1 100%);
-				border-radius: 48rpx;
-				font-weight: 600;
-				font-size: 36rpx;
-				color: #c32008;
-				text-align: center;
-			}
-		}
-	}
-
-	.integral-box {
-		min-width: 400rpx;
-		max-width: 600rpx;
-		display: flex;
-		flex-direction: column;
-		align-items: center;
-		border-radius: 20rpx;
-		overflow: hidden;
-
-		.top {
-			width: 100%;
-			position: relative;
-
-			.title {
-				width: 100%;
-				font-weight: 600;
-				font-size: 40rpx;
-				color: #ffffff;
-				text-shadow: 0px 4rpx 8rpx rgba(255, 89, 2, 0.8);
-				position: absolute;
-				top: 50rpx;
-				text-align: center;
-			}
-
-			.photo {
-				width: 100%;
-			}
-		}
-
-		.item {
-			padding: 20rpx;
-
-			.title {
-				font-weight: 500;
-				font-size: 32rpx;
-				text-align: center;
-			}
-
-			.button {
-				font-size: 32rpx;
-				margin-top: 20rpx;
-				background: linear-gradient(270deg, #ff4702 0%, #fe6304 100%);
-				color: #fff;
-				text-align: center;
-				padding: 18rpx 60rpx;
-				border-radius: 10rpx;
-				font-weight: 500;
-			}
-		}
-	}
-
-	.coupon-pop {
-		position: fixed;
-		bottom: 140rpx;
-		right: 100rpx;
-		z-index: 5;
-		border-radius: 20rpx;
-		width: 320rpx;
-
-		.coupon-block {
-			width: 100%;
-			position: relative;
-
-			.bg {
-				height: 452rpx;
-				width: 100%;
-			}
-
-			.nav {
-				position: absolute;
-				height: 120rpx;
-				top: -120rpx;
-				left: 0;
-				width: 100%;
-				z-index: 6;
-			}
-
-			.close {
-				position: absolute;
-				right: 10rpx;
-				top: 10rpx;
-				z-index: 99;
-			}
-
-			.item {
-				width: 100%;
-				position: absolute;
-				top: 20rpx;
-				display: flex;
-				flex-direction: column;
-				align-items: center;
-				color: #fff;
-
-				.title {
-					font-weight: 500;
-					font-size: 30rpx;
-					margin: 16rpx 0 12rpx;
-				}
-
-				.price {
-					font-size: 40rpx;
-
-					.bold {
-						font-size: 56rpx;
-						font-weight: 600;
-					}
-				}
-
-				.txt {
-					font-weight: 500;
-					font-size: 30rpx;
-					margin: 5rpx 0;
-				}
-
-				.button {
-					background: linear-gradient(270deg, #fffce1 0%, #ffeaaf 100%);
-					color: #ff0004;
-					text-align: center;
-					padding: 16rpx 0;
-					border-radius: 40rpx;
-					font-weight: 500;
-					font-size: 30rpx;
-					width: 70%;
-					margin-top: 26rpx;
-				}
-			}
-		}
-	}
-
-	.more-block {
-		border-radius: 20rpx 0 0 20rpx;
-		padding: 70rpx 30rpx;
-		display: flex;
-		justify-content: space-between;
-
-		.item {
-			text-align: center;
-		}
-	}
-
-	.integral-popup {
-		min-width: 400rpx;
-		max-width: 600rpx;
-		display: flex;
-		flex-direction: column;
-		align-items: center;
-		border-radius: 20rpx;
-		overflow: hidden;
-
-		.integral-header {
-			width: 100%;
-			position: relative;
-
-			.integral-title {
-				width: 100%;
-				font-weight: 600;
-				font-size: 40rpx;
-				color: #ffffff;
-				text-shadow: 0px 4rpx 8rpx rgba(255, 89, 2, 0.8);
-				position: absolute;
-				top: 50rpx;
-				text-align: center;
-			}
-
-			.integral-background-image {
-				width: 100%;
-			}
-		}
-
-		.integral-content {
-			padding: 20rpx;
-
-			.integral-message {
-				font-weight: 500;
-				font-size: 32rpx;
-				text-align: center;
-			}
-
-			.integral-confirm-button {
-				font-size: 32rpx;
-				margin-top: 20rpx;
-				background: linear-gradient(270deg, #ff4702 0%, #fe6304 100%);
-				color: #fff;
-				text-align: center;
-				padding: 18rpx 60rpx;
-				border-radius: 10rpx;
-				font-weight: 500;
-			}
-		}
-	}
-
-	.gift {
-		padding: 32rpx 24rpx;
-		color: #ffffff;
-
-		.gift-top {
-			margin-bottom: 32rpx;
-			display: flex;
-			justify-content: space-between;
-			align-items: center;
-
-			.left {
-				font-weight: 600;
-				font-size: 28rpx;
-
-				.orange {
-					color: #f4a007;
-				}
-			}
-		}
-
-		.gift-block {
-			display: flex;
-			justify-content: space-between;
-			flex-wrap: wrap;
-
-			.item {
-				width: 162rpx;
-				height: 212rpx;
-				text-align: center;
-				margin-bottom: 20rpx;
-				border: 1rpx solid transparent;
-
-				.name {
-					font-size: 24rpx;
-					color: rgba(255, 255, 255, 0.8);
-					margin: 16rpx 0 12rpx;
-				}
-
-				.number {
-					font-size: 18rpx;
-					color: rgba(255, 255, 255, 0.4);
-				}
-
-				.button {
-					font-size: 24rpx;
-					width: 100%;
-					height: 56rpx;
-					line-height: 56rpx;
-					background: linear-gradient(270deg, #ff5701 0%, #ffb501 100%);
-				}
-			}
-
-			.active {
-				overflow: hidden;
-				background: #333333;
-				border-radius: 16rpx;
-				border: 1rpx solid rgba(255, 255, 255, 0.1);
-
-				.name {
-					margin: 4rpx 0 14rpx;
-				}
-			}
-		}
-	}
-
-	.view-box {
-		position: relative;
-		height: 40vh;
-		padding: 40rpx 0rpx;
-		box-sizing: border-box;
-		display: flex;
-		flex-direction: column;
-
-		.scroll-content {
-			flex: 1;
-			margin-top: 50rpx;
-			overflow-y: auto;
-			padding: 0 40rpx;
-		}
-
-		.bottom {
-			padding: 20rpx 40rpx;
-			position: absolute;
-			bottom: 0;
-			width: 100%;
-			box-shadow: 0rpx -4rpx 10rpx 0rpx rgba(195, 195, 195, 0.3);
-			background: #fff;
-		}
-	}
-
-	@keyframes simpleFade {
-		from {
-			opacity: 0;
-		}
-
-		to {
-			opacity: 1;
-		}
-	}
-
-	.skeleton-item {
-		display: flex;
-		padding: 20rpx;
-		background: #fff;
-		margin-bottom: 16rpx;
-		border-radius: 16rpx;
-	}
-
-	.skeleton-img {
-		width: 200rpx;
-		height: 200rpx;
-		background: #f0f0f0;
-		border-radius: 8rpx;
-		margin-right: 24rpx;
-		animation: pulse 1.5s ease-in-out infinite;
-	}
-
-	.skeleton-content {
-		flex: 1;
-	}
-
-	.skeleton-line {
-		height: 20rpx;
-		background: #f0f0f0;
-		margin-bottom: 16rpx;
-		border-radius: 4rpx;
-		animation: pulse 1.5s ease-in-out infinite;
-
-		&.short {
-			width: 60%;
-		}
-
-		&.medium {
-			width: 80%;
-		}
-
-		&.long {
-			width: 95%;
-		}
-	}
-
-	@keyframes pulse {
-		0% {
-			opacity: 1;
-		}
-
-		50% {
-			opacity: 0.5;
-		}
-
-		100% {
-			opacity: 1;
-		}
-	}
-
-	.text-white {
-		color: #ffffff;
-	}
-
-	.text-xs {
-		font-size: 18rpx;
-	}
-
-	.text-sm {
-		font-size: 24rpx;
-	}
-
-	.w52,
-	.w72 {
-		display: flex;
-		align-items: center;
-		justify-content: center;
-	}
-
-	.w52.h52.mr4 {
-		border-radius: 26rpx;
-	}
-
-	.x-f {
-		display: flex;
-		align-items: center;
-	}
-
-	.align-center {
-		display: flex;
-		align-items: center;
-	}
-
-	.justify-start {
-		display: flex;
-		justify-content: flex-start;
-	}
-
-	.flex-1 {
-		flex: 1;
-	}
-
-	.column {
-		flex-direction: column;
-	}
-
-	.colorf {
-		color: #ffffff;
-	}
-
-	.orange {
-		color: #f4a007;
-	}
-
-	::v-deep .u-icon--right {
-		justify-content: flex-end !important;
-	}
-</style>

+ 5 - 1
pages_course/living-new.vue

@@ -3200,7 +3200,11 @@
 						timeStamp = jsDate.getTime();
 					} else {
 						// 如果不是预期格式,回退到普通解析
-						const date = new Date(time);
+						let normalizedTime = time
+						if (normalizedTime.includes(' ')) {
+							normalizedTime = normalizedTime.replace(' ', 'T')
+						}
+						const date = new Date(normalizedTime);
 						if (!isNaN(date.getTime())) {
 							timeStamp = date.getTime();
 						} else {

+ 68 - 39
pages_course/living.vue

@@ -249,15 +249,16 @@
 						<image class="w48 h48" src="/static/images/order.png" />
 						<view style="text-align: center">芳华币</view>
 					</view>
+					<view class="item" @click="goOrder(), (isMore = false)">
+						<image class="w48 h48" src="/static/images/points.png" />
+						<view style="text-align: center">我的订单</view>
+					</view>
 					<view class="item"
 						@click="navgetTo('/pages_shopping/live/storeOrderRefundList?liveId=' + liveId), (isMore = false)">
 						<image class="w48 h48" src="/static/images/after_sales.png" />
 						<view style="text-align: center">售后订单</view>
 					</view>
-					<view class="item" @click="goMiniProgram(), (isMore = false)">
-						<image class="w48 h48" src="/static/images/points.png" />
-						<view style="text-align: center">兑换好礼</view>
-					</view>
+					
 					<view class="item" @click="getMyLottery(), (isMore = false), (winning = true)">
 						<image class="w48 h48" src="/static/images/health_sel.png" />
 						<view style="text-align: center">中奖记录</view>
@@ -702,7 +703,6 @@
 			})
 
 			this.initNetworkStatusListener();
-			this.getUserIntegralInfo();
 		},
 		onPullDownRefresh() {
 			this.getLiveMsg(this.liveItem);
@@ -756,11 +756,21 @@
 
 			if (isLiveLogin) {
 				if (this.liveId) {
-					await this.getliving(this.liveId)
-					this.getCurrentActivities()
-					this.getliveOrder()
-					this.initSocket()
+					const userInfo = uni.getStorageSync('userInfo');
+					if (userInfo) {
+						await this.getliving(this.liveId)
+						this.getCurrentActivities()
+						this.getliveOrder()
+						this.initSocket()
+					}
 				}
+				this.$nextTick(() => {
+				if (!this.userData.unionId) {
+					uni.navigateTo({
+						url: '/pages/auth/login'
+					})
+				}
+			})
 				this.hasInitialized = true
 				uni.removeStorageSync('isLiveLogin')
 			}
@@ -793,13 +803,7 @@
 				this.$refs.liveVideo.startTimer()
 			}
 
-			this.$nextTick(() => {
-				if (!this.userData.unionId) {
-					uni.navigateTo({
-						url: '/pages/auth/login'
-					})
-				}
-			})
+			
 			if (this.liveItem.completionPointsEnabled) {
 				setTimeout(() => {
 					this.startCountdown();
@@ -918,7 +922,7 @@
 		mounted() {
 			this.systemInfo = uni.getSystemInfoSync()
 			console.log('系统信息:', this.systemInfo.platform, this.systemInfo.model)
-			this.getCurrentActivities()
+			// this.getCurrentActivities()
 			this.getliveOrder()
 		},
 		watch: {
@@ -1048,7 +1052,10 @@
 				if (this.liveId) {
 					// 优先加载直播间信息(包含视频资源URL)
 					this.isOnload = true;
-					await this.getliving(this.liveId);
+					const userInfo = uni.getStorageSync('userInfo');
+					if (userInfo) {
+						await this.getliving(this.liveId);
+					}
 					Promise.all([
 						this.getLiveMsg(this.liveItem),
 						this.getliveViewData()
@@ -1059,6 +1066,8 @@
 					this.getCurrentActivities();
 					this.getliveOrder();
 					this.initSocket();
+			this.getUserIntegralInfo();
+
 				}
 			},
 			getUserIntegralInfo() {
@@ -1448,7 +1457,6 @@
 			},
 			getCountdownPercentage() {
 				if (!this.liveItem || !this.liveItem.duration) {
-					console.log('进度条计算:liveItem.duration无效', this.liveItem?.duration)
 					return 0
 				}
 				if (this.hasReachedTarget || this.pointsRemainingTime <= 0) {
@@ -1532,7 +1540,12 @@
 			},
 			handleLiveStart() {
 				console.log('直播开始')
-				this.getliving(this.liveId)
+				const userInfo = uni.getStorageSync('userInfo');
+			const isLiveLogin = uni.getStorageSync('isLiveLogin')
+
+				if (userInfo&&isLiveLogin) {
+					this.getliving(this.liveId)
+				}
 			},
 			handleSearchInput(keyword) {
 				this.inputInfo = keyword
@@ -1955,10 +1968,9 @@
 
 				console.log('增强清理完成:所有定时器和缓存已清理')
 			},
-			goMiniProgram() {
-				uni.showToast({
-					title: '系统升级中,兑换请联系伴学助手!',
-					icon: 'none'
+			goOrder() {
+				uni.navigateTo({
+					url: '/pages_shopping/live/order'
 				})
 			},
 			preventDoubleClick(e) {
@@ -2051,11 +2063,17 @@
 			},
 			async resumePageActivity() {
 				if (this.liveItem) {
-					await this.getliving(this.liveId)
+					const userInfo = uni.getStorageSync('userInfo');
+					if (userInfo) {
+						await this.getliving(this.liveId)
+					}
 					this.startTimeTimer(this.liveItem)
 				}
 				if (!this.isSocketAvailable()) {
-					this.initSocket()
+					const userInfo = uni.getStorageSync('userInfo');
+					if (userInfo) {
+						this.initSocket()
+					}
 				}
 			},
 			getUserRandomColor(userId) {
@@ -3038,10 +3056,13 @@
 						this.liveStartTimer = setInterval(async () => {
 							this.liveCountdown = this.handleTime(res.data.startTime, 0)
 							if (!this.liveCountdown) {
-								uni.removeStorageSync('isAgreement')
+							uni.removeStorageSync('isAgreement')
+							const userInfo = uni.getStorageSync('userInfo');
+							if (userInfo) {
 								await this.getliving(this.liveId)
-								clearInterval(this.liveStartTimer)
 							}
+							clearInterval(this.liveStartTimer)
+						}
 						}, 1000)
 						this.$set(this.liveItem, 'previewUrl', res.data.previewUrl)
 						this.$set(this.liveItem, 'livingUrl', '')
@@ -3456,7 +3477,11 @@
 						)
 						timeStamp = jsDate.getTime()
 					} else {
-						const date = new Date(time)
+						let normalizedTime = time
+						if (normalizedTime.includes(' ')) {
+							normalizedTime = normalizedTime.replace(' ', 'T')
+						}
+						const date = new Date(normalizedTime)
 						if (!isNaN(date.getTime())) {
 							timeStamp = date.getTime()
 						} else {
@@ -3666,16 +3691,19 @@
 								}, 1000)
 							}
 						} else if (socketMessage.cmd == 'live_start' || socketMessage.cmd == 'live_end') {
-							if (this.liveStartTimer) {
-								clearInterval(this.liveStartTimer)
-								this.liveStartTimer = null
-							}
-							if (this.redTimer) {
-								clearInterval(this.redTimer)
-								this.redTimer = null
-							}
-							await this.getliving(this.liveId)
-						} else if (socketMessage.cmd == 'Integral') {
+								if (this.liveStartTimer) {
+									clearInterval(this.liveStartTimer)
+									this.liveStartTimer = null
+								}
+								if (this.redTimer) {
+									clearInterval(this.redTimer)
+									this.redTimer = null
+								}
+								const userInfo = uni.getStorageSync('userInfo');
+								if (userInfo) {
+									await this.getliving(this.liveId)
+								}
+							} else if (socketMessage.cmd == 'Integral') {
 							this.integral = {
 								msg: socketMessage.msg,
 								status: true
@@ -4013,6 +4041,7 @@
 		top: 0;
 		z-index: 5;
 		will-change: transform;
+		color: #FFFFFF;
 
 		.x-f {
 			display: flex;

+ 1 - 1
pages_course/living1.vue

@@ -436,7 +436,7 @@
 			<u-popup :show="showadd" @close="close" @open="openViews" round="20rpx" bgColor="#ffffff" zIndex="10077">
 				<view class="view-box">
 					<view class="fs32" style="text-align: center">在线观众</view>
-					<scroll-view v-if="Array.isArray(liveViewers)" scroll-y class="scroll-content" :style="{ height: scrollHeight + 'px' }" @scrolltolower="handleScrollToLower">
+					<scroll-view v-if="Array.isArray(liveViewers)" enable-flex scroll-y class="scroll-content" :style="{ height: scrollHeight + 'px' }" @scrolltolower="handleScrollToLower">
 						<view class="fs28 x-f mb20 mt20" v-for="(item, index) in liveViewers || []" :key="index">
 							<view
 								:style="{

+ 5 - 1
pages_course/living3333.vue

@@ -3155,7 +3155,11 @@
 						)
 						timeStamp = jsDate.getTime()
 					} else {
-						const date = new Date(time)
+						let normalizedTime = time
+						if (normalizedTime.includes(' ')) {
+							normalizedTime = normalizedTime.replace(' ', 'T')
+						}
+						const date = new Date(normalizedTime)
 						if (!isNaN(date.getTime())) {
 							timeStamp = date.getTime()
 						} else {

+ 5 - 1
pages_course/living_1.vue

@@ -3155,7 +3155,11 @@
 						)
 						timeStamp = jsDate.getTime()
 					} else {
-						const date = new Date(time)
+						let normalizedTime = time
+						if (normalizedTime.includes(' ')) {
+							normalizedTime = normalizedTime.replace(' ', 'T')
+						}
+						const date = new Date(normalizedTime)
 						if (!isNaN(date.getTime())) {
 							timeStamp = date.getTime()
 						} else {

+ 1 - 1
pages_course/livingmy.vue

@@ -359,7 +359,7 @@
 			<u-popup :show="showadd" @close="close" @open="openViews" round="20rpx" bgColor="#ffffff" zIndex="10077">
 				<view class="view-box">
 					<view class="fs32" style="text-align: center">在线观众</view>
-					<scroll-view v-if="Array.isArray(liveViewers)" scroll-y class="scroll-content"
+					<scroll-view v-if="Array.isArray(liveViewers)" enable-flex scroll-y class="scroll-content"
 						:style="{ height: scrollHeight + 'px' }" @scrolltolower="handleScrollToLower">
 						<view class="fs28 x-f mb20 mt20" v-for="(item, index) in liveViewers || []" :key="index">
 							<view :style="{

+ 1 - 1
pages_course/livingold.vue

@@ -372,7 +372,7 @@
 			<u-popup :show="showadd" @close="close" @open="openViews" round='20rpx' bgColor='#ffffff' zIndex='10077'>
 				<view class="view-box">
 					<view class="fs32" style="text-align: center;">在线观众</view>
-					<scroll-view v-if="Array.isArray(liveViewers)" scroll-y class="scroll-content"
+					<scroll-view v-if="Array.isArray(liveViewers)" enable-flex scroll-y class="scroll-content"
 						:style="{height: scrollHeight + 'px'}" @scrolltolower="handleScrollToLower">
 						<view class="fs28 x-f mb20 mt20" v-for="(item,index) in (liveViewers||[])" :key="index">
 							<view

+ 1 - 1
pages_course/livingweek.vue

@@ -409,7 +409,7 @@
 			<u-popup :show="showadd" @close="close" @open="openViews" round="20rpx" bgColor="#ffffff" zIndex="10077">
 				<view class="view-box">
 					<view class="fs32" style="text-align: center">在线观众</view>
-					<scroll-view v-if="Array.isArray(liveViewers)" scroll-y class="scroll-content" :style="{ height: scrollHeight + 'px' }" @scrolltolower="handleScrollToLower">
+					<scroll-view v-if="Array.isArray(liveViewers)" enable-flex scroll-y class="scroll-content" :style="{ height: scrollHeight + 'px' }" @scrolltolower="handleScrollToLower">
 						<view class="fs28 x-f mb20 mt20" v-for="(item, index) in liveViewers || []" :key="index">
 							<view
 								:style="{

+ 5 - 1
pages_course/referenceliving.vue

@@ -5387,7 +5387,11 @@
 						timeStamp = jsDate.getTime();
 					} else {
 						// 如果不是预期格式,回退到普通解析
-						const date = new Date(time);
+						let normalizedTime = time
+						if (normalizedTime.includes(' ')) {
+							normalizedTime = normalizedTime.replace(' ', 'T')
+						}
+						const date = new Date(normalizedTime);
 						if (!isNaN(date.getTime())) {
 							timeStamp = date.getTime();
 						} else {

+ 26 - 2
pages_shopping/live/storeOrderDetail.vue

@@ -133,7 +133,7 @@
 								<view class="price-num">
 									<view class="price">
 										<text class="unit">¥</text>
-										<text class="num">{{product.price.toFixed(2)}}</text>
+										<text class="num">{{product.price.toFixed(2) ||'0.00'}}</text>
 									</view>
 									<!-- <view class="num">x{{item.num}}</view> -->
 								</view>
@@ -246,6 +246,10 @@
 		</view>
 		<!-- 按钮 -->
 		<view class="btn-box">
+			<view class="btn cancel">
+				<text>售后客服</text>
+				<button class="contact-btn" open-type="contact"></button>
+			</view>
 			<view class="btn cancel" v-if="order.status==1" @click="cancel()">取消订单</view>
 			<view class="btn pay" v-if="order.status==1" @click="pay()">立即付款</view>
 			<!-- <view class="btn cancel"  v-if="(order.status==0||order.status==1)&&order.isPrescribe==1&&prescribe==null"  @click="addPrescribe()">开处方</view> -->
@@ -308,7 +312,13 @@
 				return this.order.createTime;
 			},
 		},
-		methods: { // 日期格式化方法
+		methods: {
+			// toAfterSales(){
+			// 	uni.navigateTo({
+			// 		url: '/pages_shopping/live/afterSales?orderId=' + this.orderId
+			// 	})
+			// },
+			// 日期格式化方法
 			formatDate(date) {
 				const year = date.getFullYear();
 				const month = String(date.getMonth() + 1).padStart(2, '0');
@@ -882,6 +892,20 @@
 				background: #2BC7B9;
 				color: #FFFFFF;
 			}
+			// 客服button样式修复
+						.contact-btn {
+							position: absolute; // 绝对定位覆盖整个按钮区域
+							top: 0;
+							left: 0;
+							width: 100%;
+							height: 100%;
+							background: transparent; // 透明背景,不遮挡文字
+							border: none; // 去掉默认边框
+							padding: 0; // 去掉默认内边距
+							margin: 0; // 去掉默认外边距
+							opacity: 0; // 透明,只保留点击功能
+							z-index: 1; // 确保在文字上方,能接收到点击事件
+						}
 		}
 	}
 </style>

+ 11 - 1
pages_user/user/storeOrder.vue

@@ -147,8 +147,18 @@
 			uni.$on('refreshOrder', () => {
 				that.mescroll.resetUpScroll()
 			})
+			this.getDicts();
 		},
-		methods: {
+		methods: {getDicts: function() {
+				getDicts().then(
+					res => {
+						if (res.code == 200) {
+							uni.setStorageSync('dicts', JSON.stringify(res));
+						}
+					},
+					rej => {}
+				);
+			},
 			goSearch(e) {
 				this.searchKey=e.detail.value;
 				this.mescroll.resetUpScroll()

+ 1 - 1
pages_user/user/storeOrderDetail.vue

@@ -121,7 +121,7 @@
 								<view class="price-num">
 									<view class="price">
 										<text class="unit">¥</text>
-										<text class="num">{{JSON.parse(item.jsonInfo).price.toFixed(2)}}</text>
+										<text class="num">{{JSON.parse(item.jsonInfo).price.toFixed(2) ||'0.00'}}</text>
 									</view>
 									<view class="num">x{{JSON.parse(item.jsonInfo).num}}</view>
 								</view>

BIN
static/images/order.png


+ 1 - 1
uni_modules/uview-ui/components/u-transition/props.js

@@ -8,7 +8,7 @@ export default {
         // 使用的动画模式
         mode: {
             type: String,
-            default: uni.$u.props.transition.mode
+            default: uni.$u.props.transition.mode || 'fade'
         },
         // 动画的执行时间,单位ms
         duration: {

+ 266 - 267
utils/common.js

@@ -1,45 +1,45 @@
-import {checkLogin} from '@/api/user'
+import { checkLogin } from '@/api/user'
 import { getCourseDomain } from '@/api/common.js'
-import { getConfigByKey,checkCourseLogin } from '@/api/course.js'
+import { getConfigByKey, checkCourseLogin } from '@/api/course.js'
 import { checkCourseLoginLook } from '@/api/courseLook.js'
 import dayjs from 'dayjs'
 
 let TOKEN_KEYAuto = 'AppTokenmini_MYCourse'
 
-var isEmpty =function(obj) {
+var isEmpty = function (obj) {
 	if (typeof obj == "undefined" || obj == null || obj == "") {
 		return true;
 	} else {
 		return false;
 	}
 }
- 
-var checkToken= function() {
+
+var checkToken = function () {
 	var token = uni.getStorageSync('AppToken');
-	if (token==null||token==undefined||token=="" ) {
+	if (token == null || token == undefined || token == "") {
 		return false;
-	} 
+	}
 	return true;
 }
 
 
-var isLogin=  function() {
+var isLogin = function () {
 	return new Promise((resolve, reject) => {
 		checkLogin().then(
 			res => {
-				if(res.code==200){
+				if (res.code == 200) {
 					resolve(true);
-				}else{
+				} else {
 					resolve(false);
 				}
 			},
 			rej => { }
 		);
 	});
-	 
+
 }
 
-var  isLoginCourseAuto =  function() {
+var isLoginCourseAuto = function () {
 	return new Promise((resolve, reject) => {
 		// let token = uni.getStorageSync(TOKEN_KEYAuto);
 		// if (token==null||token==undefined||token=="" ) {
@@ -49,226 +49,225 @@ var  isLoginCourseAuto =  function() {
 		// }
 		checkCourseLogin().then(
 			res => {
-				if(res.code==200){
+				if (res.code == 200) {
 					resolve(true);
-				}else{
+				} else {
 					resolve(false);
 				}
 			},
 			rej => { }
 		);
-	}); 
+	});
 }
 //静默登录
-var checkLiveToken = function() {
+var checkLiveToken = function () {
 	var token = uni.getStorageSync('AppToken');
 	if (token == null || token == undefined || token == "") {
 		return false;
 	}
 	return true;
 }
-var loginOut= function() {
-	  uni.setStorageSync('AppToken',null);
-	  uni.setStorageSync('userInfo',null);
+var loginOut = function () {
+	uni.setStorageSync('AppToken', null);
+	uni.setStorageSync('userInfo', null);
 }
-var checkLoginState= function() {
+var checkLoginState = function () {
 	var token = uni.getStorageSync('AppToken');
-	if (token ) {
+	if (token) {
 		return true
 	} else {
 		return false
 	}
 }
 
-var getDictLabelName= function(key,dictValue) {
-	if(dictValue==null){
+var getDictLabelName = function (key, dictValue) {
+	if (dictValue == null) {
 		return "";
 	}
 	var dicts = uni.getStorageSync('dicts');
-	dicts=JSON.parse(dicts);
-	var dict=dicts[key]
-	var name="";
-	dict.forEach(function(item, index, array) {
-		 if(dictValue.toString()==item.dictValue.toString())
-		 {
-			 name=item.dictLabel
-		 }
+	dicts = JSON.parse(dicts);
+	var dict = dicts[key]
+	var name = "";
+	dict.forEach(function (item, index, array) {
+		if (dictValue.toString() == item.dictValue.toString()) {
+			name = item.dictLabel
+		}
 	});
 	return name;
 }
-var getDict= function(key) {
+var getDict = function (key) {
 	var dicts = uni.getStorageSync('dicts');
-	dicts=JSON.parse(dicts);
-	var dict=dicts[key]
+	dicts = JSON.parse(dicts);
+	var dict = dicts[key]
 	return dict;
 }
 
 
-var photosToArr= function(photoUrl) {
-	 var photos=[];
-	 if(photoUrl!=null&&photoUrl!=''){
-		 photos=photoUrl.split(',');
-	 }
-	 return photos
+var photosToArr = function (photoUrl) {
+	var photos = [];
+	if (photoUrl != null && photoUrl != '') {
+		photos = photoUrl.split(',');
+	}
+	return photos
 }
 
-var dateFormat=function dateFormat(fmt, date) {
-    let ret;
-    const opt = {
-        "Y+": date.getFullYear().toString(),        // 年
-        "m+": (date.getMonth() + 1).toString(),     // 月
-        "d+": date.getDate().toString(),            // 日
-        "H+": date.getHours().toString(),           // 时
-        "M+": date.getMinutes().toString(),         // 分
-        "S+": date.getSeconds().toString()          // 秒
-        // 有其他格式化字符需求可以继续添加,必须转化成字符串
-    };
-    for (let k in opt) {
-        ret = new RegExp("(" + k + ")").exec(fmt);
-        if (ret) {
-            fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
-        };
-    };
-    return fmt;
+var dateFormat = function dateFormat(fmt, date) {
+	let ret;
+	const opt = {
+		"Y+": date.getFullYear().toString(),        // 年
+		"m+": (date.getMonth() + 1).toString(),     // 月
+		"d+": date.getDate().toString(),            // 日
+		"H+": date.getHours().toString(),           // 时
+		"M+": date.getMinutes().toString(),         // 分
+		"S+": date.getSeconds().toString()          // 秒
+		// 有其他格式化字符需求可以继续添加,必须转化成字符串
+	};
+	for (let k in opt) {
+		ret = new RegExp("(" + k + ")").exec(fmt);
+		if (ret) {
+			fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
+		};
+	};
+	return fmt;
 }
 
 var getProvider = service => {
-  return new Promise((resolve, reject) => {
-    // 获取当前环境的服务商
-    uni.getProvider({
-      service: service || 'oauth',
-      success: function (res) {
-        // 此处可以排除h5
-        if (res.provider) {
-          resolve(res.provider[0])
-        }
-      },
-      fail() {
-        reject('获取环境服务商失败')
-      },
-    })
-  }).catch(error => {
-    console.log('167', error)
-  })
+	return new Promise((resolve, reject) => {
+		// 获取当前环境的服务商
+		uni.getProvider({
+			service: service || 'oauth',
+			success: function (res) {
+				// 此处可以排除h5
+				if (res.provider) {
+					resolve(res.provider[0])
+				}
+			},
+			fail() {
+				reject('获取环境服务商失败')
+			},
+		})
+	}).catch(error => {
+		console.log('167', error)
+	})
 }
- 
- var handleTree=function handleTree(data, id, parentId, rootId) {
- 	id = id || 'id'
- 	parentId = parentId || 'parentId'
- 	rootId = rootId || Math.min.apply(Math, data.map(item => { return item[parentId] })) || 0
- 	//对源数据深度克隆
- 	const cloneData = JSON.parse(JSON.stringify(data))
- 	//循环所有项
- 	const treeData = cloneData.filter(father => {
- 		let branchArr = cloneData.filter(child => {
- 			//返回每一项的子级数组
- 			return father[id] === child[parentId]
- 		});
- 		branchArr.length > 0 ? father.child = branchArr : '';
- 		//返回第一层
- 		return father[parentId] === rootId;
- 	});
- 	return treeData != '' ? treeData : data;
- }
-var parsePhone=function parsePhone(mobile) {
-    var str = mobile.substr(0,3)+"****"+mobile.substr(7);
-    return str;
+
+var handleTree = function handleTree(data, id, parentId, rootId) {
+	id = id || 'id'
+	parentId = parentId || 'parentId'
+	rootId = rootId || Math.min.apply(Math, data.map(item => { return item[parentId] })) || 0
+	//对源数据深度克隆
+	const cloneData = JSON.parse(JSON.stringify(data))
+	//循环所有项
+	const treeData = cloneData.filter(father => {
+		let branchArr = cloneData.filter(child => {
+			//返回每一项的子级数组
+			return father[id] === child[parentId]
+		});
+		branchArr.length > 0 ? father.child = branchArr : '';
+		//返回第一层
+		return father[parentId] === rootId;
+	});
+	return treeData != '' ? treeData : data;
 }
-var parseIdCard=function parseIdCard(idCard) {
-    var str = idCard.substr(0,4)+"****"+idCard.substr(8);
-    return str;
+var parsePhone = function parsePhone(mobile) {
+	var str = mobile.substr(0, 3) + "****" + mobile.substr(7);
+	return str;
 }
- 
+var parseIdCard = function parseIdCard(idCard) {
+	var str = idCard.substr(0, 4) + "****" + idCard.substr(8);
+	return str;
+}
+
 //格式为"1990-01-01"
-var getAge=function getAge(strBirthday){       
-    var returnAge,
-   		strBirthdayArr=strBirthday.split("-"),
-    	birthYear = strBirthdayArr[0],
-    	birthMonth = strBirthdayArr[1],
-    	birthDay = strBirthdayArr[2],  
-   	 	d = new Date(),
-    	nowYear = d.getFullYear(),
-    	nowMonth = d.getMonth() + 1,
-    	nowDay = d.getDate();   
-    if(nowYear == birthYear){
-        returnAge = 0;//同年 则为0周岁
-    }
-    else{
-        var ageDiff = nowYear - birthYear ; //年之差
-        if(ageDiff > 0){
-            if(nowMonth == birthMonth) {
-                var dayDiff = nowDay - birthDay;//日之差
-                if(dayDiff < 0) {
-                    returnAge = ageDiff - 1;
-                }else {
-                    returnAge = ageDiff;
-                }
-            }else {
-                var monthDiff = nowMonth - birthMonth;//月之差
-                if(monthDiff < 0) {
-                    returnAge = ageDiff - 1;
-                }
-                else {
-                    returnAge = ageDiff ;
-                }
-            }
-        }else {
-            returnAge = -1;//返回-1 表示出生日期输入错误 晚于今天
-        }
-    } 
-    return returnAge;//返回周岁年龄
+var getAge = function getAge(strBirthday) {
+	var returnAge,
+		strBirthdayArr = strBirthday.split("-"),
+		birthYear = strBirthdayArr[0],
+		birthMonth = strBirthdayArr[1],
+		birthDay = strBirthdayArr[2],
+		d = new Date(),
+		nowYear = d.getFullYear(),
+		nowMonth = d.getMonth() + 1,
+		nowDay = d.getDate();
+	if (nowYear == birthYear) {
+		returnAge = 0;//同年 则为0周岁
+	}
+	else {
+		var ageDiff = nowYear - birthYear; //年之差
+		if (ageDiff > 0) {
+			if (nowMonth == birthMonth) {
+				var dayDiff = nowDay - birthDay;//日之差
+				if (dayDiff < 0) {
+					returnAge = ageDiff - 1;
+				} else {
+					returnAge = ageDiff;
+				}
+			} else {
+				var monthDiff = nowMonth - birthMonth;//月之差
+				if (monthDiff < 0) {
+					returnAge = ageDiff - 1;
+				}
+				else {
+					returnAge = ageDiff;
+				}
+			}
+		} else {
+			returnAge = -1;//返回-1 表示出生日期输入错误 晚于今天
+		}
+	}
+	return returnAge;//返回周岁年龄
 }
 
-var clearHisSearch= function() {
- 	var searchList=[];
- 	uni.setStorageSync("hisSearch",JSON.stringify(searchList));
- }
- var getHisSearch= function() {
- 	var search = uni.getStorageSync('hisSearch');
- 	if(search!=null&&search!=undefined&&search!=""){
- 		var search=JSON.parse(search);
- 		return search;
- 	}
-	else{
-		var data=[];
+var clearHisSearch = function () {
+	var searchList = [];
+	uni.setStorageSync("hisSearch", JSON.stringify(searchList));
+}
+var getHisSearch = function () {
+	var search = uni.getStorageSync('hisSearch');
+	if (search != null && search != undefined && search != "") {
+		var search = JSON.parse(search);
+		return search;
+	}
+	else {
+		var data = [];
 		return data;
-	} 
- 	
- }
- var addHisSearch= function(searchVal) {
- 	var search = uni.getStorageSync('hisSearch');
-	var searchList=[];
-	if(search!=null&&search!=undefined&&search!=""){
-		searchList=JSON.parse(search);
-		
+	}
+
+}
+var addHisSearch = function (searchVal) {
+	var search = uni.getStorageSync('hisSearch');
+	var searchList = [];
+	if (search != null && search != undefined && search != "") {
+		searchList = JSON.parse(search);
+
 	}
 	searchList.push(searchVal);
 	//去复
 	const uniqueArr = [...new Set(searchList)];
-	uni.setStorageSync("hisSearch",JSON.stringify(uniqueArr));
- 	
- 	
- }
-
-
-
-var parseTime= function(num){//时间戳数据处理
-         let date = new Date(num*1000);
-        //时间戳为10位需*1000,时间戳为13位的话不需乘1000
-        let y = date.getFullYear();
-        let MM = date.getMonth() + 1;
-        MM = MM < 10 ? ('0' + MM) : MM;//月补0
-        let d = date.getDate();
-        d = d < 10 ? ('0' + d) : d;//天补0
-        let h = date.getHours();
-        h = h < 10 ? ('0' + h) : h;//小时补0
-        let m = date.getMinutes();
-        m = m < 10 ? ('0' + m) : m;//分钟补0
-        let s = date.getSeconds();
-        s = s < 10 ? ('0' + s) : s;//秒补0
-        return y + '-' + MM + '-' + d + ' ' + h + ':' + m+ ':' + s;
-
-}   
+	uni.setStorageSync("hisSearch", JSON.stringify(uniqueArr));
+
+
+}
+
+
+
+var parseTime = function (num) {//时间戳数据处理
+	let date = new Date(num * 1000);
+	//时间戳为10位需*1000,时间戳为13位的话不需乘1000
+	let y = date.getFullYear();
+	let MM = date.getMonth() + 1;
+	MM = MM < 10 ? ('0' + MM) : MM;//月补0
+	let d = date.getDate();
+	d = d < 10 ? ('0' + d) : d;//天补0
+	let h = date.getHours();
+	h = h < 10 ? ('0' + h) : h;//小时补0
+	let m = date.getMinutes();
+	m = m < 10 ? ('0' + m) : m;//分钟补0
+	let s = date.getSeconds();
+	s = s < 10 ? ('0' + s) : s;//秒补0
+	return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s;
+
+}
 // var setData= function(obj){
 // 	 let that = this;
 // 	 let keys = [];
@@ -289,7 +288,7 @@ var parseTime= function(num){//时间戳数据处理
 // 		 })
 // 	 });
 //  }
-var setData= function(obj){
+var setData = function (obj) {
 	let that = this;
 	const handleData = (tepData, tepKey, afterKey) => {
 		var tepData2 = tepData;
@@ -305,10 +304,10 @@ var setData= function(obj){
 		});
 		return tepData2;
 	};
-	const isFn = function(value) {
+	const isFn = function (value) {
 		return typeof value == 'function' || false;
 	};
-	Object.keys(obj).forEach(function(key) {
+	Object.keys(obj).forEach(function (key) {
 		let val = obj[key];
 		key = key.replace(/\]/g, '').replace(/\[/g, '.');
 		let front, after;
@@ -339,39 +338,39 @@ var setData= function(obj){
 	});
 
 }
- const urlToObj = function(url) {
-   let obj = {}
-   let str = url.slice(url.indexOf('?') + 1)
-   let arr = str.split('&')
-   for (let j = arr.length, i = 0; i < j; i++) {
-     let arr_temp = arr[i].split('=')
-     obj[arr_temp[0]] = arr_temp[1]
-   }
-   return obj
- }
- var checkCompanyUserLoginState= function() {
- 	var token = uni.getStorageSync('CompanyUserToken');
- 	if (token ) {
- 		return true
- 	} else {
- 		return false
- 	}
- }
- 
+const urlToObj = function (url) {
+	let obj = {}
+	let str = url.slice(url.indexOf('?') + 1)
+	let arr = str.split('&')
+	for (let j = arr.length, i = 0; i < j; i++) {
+		let arr_temp = arr[i].split('=')
+		obj[arr_temp[0]] = arr_temp[1]
+	}
+	return obj
+}
+var checkCompanyUserLoginState = function () {
+	var token = uni.getStorageSync('CompanyUserToken');
+	if (token) {
+		return true
+	} else {
+		return false
+	}
+}
+
 
 /**
  * 格式化时间
  * @param {Object} 时间字符串
  */
-var formatDate=function(dateStr) {
+var formatDate = function (dateStr) {
 
-	let date = dayjs(dateStr,'YYYY-MM-DD HH:mm:ss');
+	let date = dayjs(dateStr, 'YYYY-MM-DD HH:mm:ss');
 	let today = dayjs();
 
 	let formatStr = "";
 	if (date.year() != today.year()) {
 		formatDate = date.format('YYYY-MM-DD HH:mm');
-	} 
+	}
 	else if (date.month() === today.month()) {
 		switch (date.date() - today.date()) {
 			case 0:
@@ -387,41 +386,41 @@ var formatDate=function(dateStr) {
 				formatDate = date.format('MM-DD HH:mm');
 				break;
 		}
-	} 
+	}
 	else if (date.month() - today.month() === 0 && date.date() === 1) {
 		formatDate = date.format('明天 HH:mm');
-	} 
+	}
 	else {
 		formatDate = date.format('MM-DD HH:mm');
 	}
 	return formatDate;
 }
- /**
-  * 随机字符串
-  * 
-  */
- var generateRandomString=function(length){
-  let result = '';
-  const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
-  const charactersLength = characters.length;
-  
-  for (let i = 0; i < length; i++) {
-    result += characters.charAt(Math.floor(Math.random() * charactersLength));
-  }
-  return result;
+/**
+ * 随机字符串
+ * 
+ */
+var generateRandomString = function (length) {
+	let result = '';
+	const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+	const charactersLength = characters.length;
+
+	for (let i = 0; i < length; i++) {
+		result += characters.charAt(Math.floor(Math.random() * charactersLength));
+	}
+	return result;
 }
 
-var  getDomain =  function(data) {
+var getDomain = function (data) {
 	return new Promise((resolve, reject) => {
 		getCourseDomain(data).then(
 			res => {
-				if(res.code==200){
-					uni.setStorageSync('projectCode',data.projectCode)
-					uni.setStorageSync('addressUrl_'+data.projectCode,res.addressUrl)
-					uni.setStorageSync('requestImagesPath',res.imgpath)
-					uni.setStorageSync('sendType',res.sendType)
+				if (res.code == 200) {
+					uni.setStorageSync('projectCode', data.projectCode)
+					uni.setStorageSync('addressUrl_' + data.projectCode, res.addressUrl)
+					uni.setStorageSync('requestImagesPath', res.imgpath)
+					uni.setStorageSync('sendType', res.sendType)
 					resolve(res);
-				}else{
+				} else {
 					uni.showToast({
 						title: res.msg,
 						icon: 'error'
@@ -430,22 +429,22 @@ var  getDomain =  function(data) {
 			},
 			rej => { }
 		);
-	}); 
+	});
 }
-var  getConfigKey =  function() {
+var getConfigKey = function () {
 	return new Promise((resolve, reject) => {
-		getConfigByKey({key: 'course.config'}).then(res => {
+		getConfigByKey({ key: 'course.config' }).then(res => {
 			if (res.code == 200) {
 				let data = JSON.parse(res.data)
-				uni.setStorageSync('weixinOauth',data.userCourseAuthDomain)
+				uni.setStorageSync('weixinOauth', data.userCourseAuthDomain)
 				resolve(data.userCourseAuthDomain)
 			}
 		}).catch(error => {
 			reject(error)
 		});
-	}); 
+	});
 }
-var isLoginCourse=function(){
+var isLoginCourse = function () {
 	return new Promise((resolve, reject) => {
 		// let token = uni.getStorageSync('TOKEN_WEXIN');
 		// if (token==null||token==undefined||token=="" ) {
@@ -455,46 +454,46 @@ var isLoginCourse=function(){
 		// }
 		checkCourseLoginLook().then(
 			res => {
-				if(res.code==200){
+				if (res.code == 200) {
 					resolve(true);
-				}else{
+				} else {
 					resolve(false);
 				}
 			},
 			rej => { }
 		);
-	}); 
+	});
 }
 
 module.exports = {
-		formatDate:formatDate,
-        isEmpty : isEmpty,
-		checkLoginState : checkLoginState,
-		getDictLabelName:getDictLabelName,
-		photosToArr:photosToArr,
-		dateFormat:dateFormat,
-		getProvider:getProvider,
-		isLogin:isLogin,
-		checkToken:checkToken,
-		loginOut:loginOut,
-		handleTree:handleTree,
-		parsePhone:parsePhone,
-		getAge:getAge,
-		parseIdCard:parseIdCard,
-		getDict:getDict,
-		addHisSearch:addHisSearch,
-		clearHisSearch:clearHisSearch,
-		getHisSearch:getHisSearch,
-		parseTime:parseTime,
-		setData:setData,
-		urlToObj:urlToObj,
-		checkCompanyUserLoginState:checkCompanyUserLoginState,
-		isLoginCourseAuto:isLoginCourseAuto,
-		isLoginCourse:isLoginCourse,
-		generateRandomString:generateRandomString,
-		getDomain:getDomain,
-		getConfigKey: getConfigKey,
-		TOKEN_KEYAuto: TOKEN_KEYAuto,
+	formatDate: formatDate,
+	isEmpty: isEmpty,
+	checkLoginState: checkLoginState,
+	getDictLabelName: getDictLabelName,
+	photosToArr: photosToArr,
+	dateFormat: dateFormat,
+	getProvider: getProvider,
+	isLogin: isLogin,
+	checkToken: checkToken,
+	loginOut: loginOut,
+	handleTree: handleTree,
+	parsePhone: parsePhone,
+	getAge: getAge,
+	parseIdCard: parseIdCard,
+	getDict: getDict,
+	addHisSearch: addHisSearch,
+	clearHisSearch: clearHisSearch,
+	getHisSearch: getHisSearch,
+	parseTime: parseTime,
+	setData: setData,
+	urlToObj: urlToObj,
+	checkCompanyUserLoginState: checkCompanyUserLoginState,
+	isLoginCourseAuto: isLoginCourseAuto,
+	isLoginCourse: isLoginCourse,
+	generateRandomString: generateRandomString,
+	getDomain: getDomain,
+	getConfigKey: getConfigKey,
+	TOKEN_KEYAuto: TOKEN_KEYAuto,
 	checkLiveToken: checkLiveToken
 
 };