yuhongqi 2 nedēļas atpakaļ
vecāks
revīzija
b502a39f9f

+ 6 - 0
api/cacheLiving.js

@@ -32,6 +32,8 @@ const api = {
 	liveOrderUser: (liveId) => `/app/cacheLive/liveOrder/liveOrderUser/${liveId}`,
 	liveMsg: (liveId, pageSize, pageNum) =>
 		`/app/cacheLive/liveMsg/list/?liveId=${liveId}&pageSize=${pageSize}&pageNum=${pageNum}`,
+	myLiveMsg: (liveId, pageSize, pageNum) =>
+		`/app/cacheLive/liveMsg/myList?liveId=${liveId}&pageSize=${pageSize}&pageNum=${pageNum}`,
 	liveLottery: '/app/cacheLive/liveLottery/detail',
 	myLottery: '/app/cacheLive/liveLottery/myLottery',
 	completionRecords: (liveId) => `/app/cacheLive/completion/records?liveId=${liveId}`,
@@ -67,6 +69,10 @@ export function liveMsg(liveId, pageSize, pageNum, data = {}) {
 	return request(api.liveMsg(liveId, pageSize, pageNum), data, 'GET', 'application/json;charset=UTF-8')
 }
 
+export function myLiveMsg(liveId, pageSize, pageNum, data = {}) {
+	return request(api.myLiveMsg(liveId, pageSize, pageNum), data, 'GET', 'application/json;charset=UTF-8')
+}
+
 export function liveLottery(data) {
 	return request(api.liveLottery, data, 'POST', 'application/json;charset=UTF-8')
 }

+ 26 - 10
api/order.js

@@ -5,8 +5,10 @@ const api = {
 	liveOrderList: '/app/live/liveOrder/getMyStoreOrderList', // 订单列表
 	// liveOrderList: '/app/live/liveOrder/list', // 订单列表
 	createliveOrder: '/app/live/liveOrder/create', // 创建订单
+	createliveOrderOpt: '/app/live/liveOrderOpt/create', // 创建订单(优化版)
+	payLiveOrderOpt: '/app/live/liveOrderOpt/pay', // 支付(优化版)
 	createReward: '/app/live/liveOrder/createReward', // 创建中奖订单
-	
+
 	updateConfirm: (orderId, type) => `/app/live/liveOrder/updateConfirm/${orderId}/${type} `, // 取消/支付订单确认
 	updateLiveOrder: '/app/live/liveOrder/update', // 取消/支付订单
 	liveOrderKey: '/app/live/liveOrder/confirm', // 生成订单key
@@ -15,7 +17,7 @@ const api = {
 	editAddress: '/app/address/editAddress', // 编辑地址
 	delAddress: '/app/address/delAddress', // 删除地址
 	getCitys: '/app/common/getCitys', // 获取省市区
-	parseAddress: '/app/address/parseAddress', //地址解析 
+	parseAddress: '/app/address/parseAddress', //地址解析
 	getAddressById: '/app/address/getAddressById', //
 
 	queryLiveCartList: '/live/liveCart/list', //查询购物车列表
@@ -39,11 +41,12 @@ const api = {
 	liveOrder: (orderId) => `/app/live/liveOrder/info/${orderId}`, // 订单详情
 	getMyStoreOrderById: (orderId) => `/app/live/liveOrder/info/${orderId}`,
 	computed: '/app/live/liveOrder/computed', // 查询创建订单信息
+	computeCache: '/app/live/liveOrder/computeCache', // 查询创建订单信息
 	computedReward: '/app/live/liveOrder/computedReward', // 中奖填地址=>查询创建中奖订单信息
-	
-	// finishOrder: '/app/live/liveOrder/finishOrder', 
+
+	// finishOrder: '/app/live/liveOrder/finishOrder',
 	// cancelOrder: '/app/live/liveOrder/cancelOrder',
-	
+
 
 }
 
@@ -55,6 +58,16 @@ export function createliveOrder(data) {
 	return request(api.createliveOrder, data, 'POST', 'application/json;charset=UTF-8')
 }
 
+// 创建订单(优化版)
+export function createliveOrderOpt(data) {
+	return request(api.createliveOrderOpt, data, 'POST', 'application/json;charset=UTF-8')
+}
+
+// 支付(优化版)
+export function payLiveOrderOpt(data) {
+	return request(api.payLiveOrderOpt, data, 'POST', 'application/json;charset=UTF-8')
+}
+
 // 创建中奖订单
 export function createReward(data) {
 	return request(api.createReward, data, 'POST', 'application/json;charset=UTF-8')
@@ -101,18 +114,18 @@ export function delAddress(data) {
 	return request(api.delAddress, data, 'POST', 'application/json;charset=UTF-8')
 }
 
-//获取省市区 
+//获取省市区
 export function getCitys(data) {
 	return request(api.getCitys, data, 'GET', 'application/json;charset=UTF-8')
 }
 
 
-//地址解析 
+//地址解析
 export function parseAddress(data) {
 	return request(api.parseAddress, data, 'POST', 'application/json;charset=UTF-8')
 }
 
-// 
+//
 export function getAddressById(data) {
 	return request(api.getAddressById, data, 'GET', 'application/json;charset=UTF-8')
 }
@@ -213,6 +226,9 @@ export function getMyStoreOrderById(orderId, data = {}) {
 export function computed(data ) {
 	return request(api.computed, data, 'POST', 'application/json;charset=UTF-8');
 }
+export function computeCache(data ) {
+	return request(api.computeCache, data, 'POST', 'application/json;charset=UTF-8');
+}
 // 中奖填地址=>查询中奖创建订单信息
 export function computedReward(data ) {
 	return request(api.computedReward, data, 'POST', 'application/json;charset=UTF-8');
@@ -229,8 +245,8 @@ export function computedReward(data ) {
  export function getExpress(data) {
  	 return request('/app/live/liveOrder/getExpress',data,'POST','application/json;charset=UTF-8');
  }
- 
+
  // 抽奖中奖接口
  export function payConfirmReward(data) {
  	 return request('/app/live/liveOrder/payConfirmReward',data,'POST','application/json;charset=UTF-8');
- }
+ }

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 314 - 238
pages_course/living.vue


+ 13 - 21
pages_course/living/components/LiveChatPanel.vue

@@ -119,8 +119,7 @@
 </template>
 
 <script>
-import { liveMsg } from '@/api/cacheLiving.js'
-import { appendTalkMessage, removeTalkMessageByMsgId } from '../services/liveMessageService.js'
+import { appendTalkMessage, removeTalkMessageByMsgId, loadHistoryMessages } from '../services/liveMessageService.js'
 
 export default {
 	name: 'LiveChatPanel',
@@ -258,31 +257,24 @@ export default {
 			return rows.filter(item => String(item.userId) === currentUserId)
 		},
 
-		async loadHistory(liveItem) {
+		async loadHistory(liveItem, refresh = false) {
 			const item = liveItem || this.liveItem
 			if (!item || !this.liveId) {
 				console.error('loadHistory 错误:无效的 liveItem')
 				return
 			}
 			try {
-				const res = await liveMsg(this.liveId, 30, 1)
-				if (res.code == 200) {
-					let rows = Array.isArray(res.rows) ? res.rows : []
-					rows = this.filterTalklistByUserId(rows)
-					// 接口按时间倒序,展示需正序:旧在上、新在下
-					rows = [...rows].reverse()
-					rows.forEach((row) => {
-						if (!row.uniqueId) {
-							row.uniqueId = ++this.messageIdCounter
-						}
-					})
-					this.talklist = rows
-					this.$nextTick(() => {
-						this.scrollToBottom(true)
-					})
-				} else {
-					this.talklist = []
-				}
+				let rows = await loadHistoryMessages(this.liveId, 30, 1, refresh)
+				rows = this.filterTalklistByUserId(rows)
+				rows.forEach((row) => {
+					if (!row.uniqueId) {
+						row.uniqueId = ++this.messageIdCounter
+					}
+				})
+				this.talklist = rows
+				this.$nextTick(() => {
+					this.scrollToBottom(true)
+				})
 			} catch (error) {
 				this.talklist = []
 				console.error('获取聊天记录失败:', error)

+ 7 - 2
pages_course/living/services/liveMessageService.js

@@ -1,10 +1,15 @@
 import { liveMsg } from '@/api/cacheLiving.js'
+import { oncePerSession } from './liveRequestGuard.js'
 
 const MAX_TALK_ITEMS = 30
 
 /** 拉取历史聊天记录 */
-export async function loadHistoryMessages(liveId, pageSize = 30, pageNum = 1) {
-	const res = await liveMsg(liveId, pageSize, pageNum)
+export async function loadHistoryMessages(liveId, pageSize = 30, pageNum = 1, refresh = false) {
+	const res = await oncePerSession(
+		`live:msg:${liveId}:${pageSize}:${pageNum}`,
+		() => liveMsg(liveId, pageSize, pageNum),
+		{ refresh }
+	)
 	if (res.code !== 200) {
 		return []
 	}

+ 53 - 0
pages_course/living/services/liveRequestGuard.js

@@ -0,0 +1,53 @@
+const inflightRequests = new Map()
+const sessionCache = new Map()
+
+/**
+ * 同一 key 在请求进行中只发起一次(并发去重)
+ */
+export function dedupeRequest(key, factory) {
+	if (inflightRequests.has(key)) {
+		return inflightRequests.get(key)
+	}
+	const promise = Promise.resolve()
+		.then(factory)
+		.finally(() => {
+			inflightRequests.delete(key)
+		})
+	inflightRequests.set(key, promise)
+	return promise
+}
+
+/**
+ * 同一会话内同一 key 只请求一次(完成后也不会再发,除非 refresh)
+ */
+export function oncePerSession(key, factory, { refresh = false } = {}) {
+	if (refresh) {
+		clearDedupeKey(key)
+	}
+	if (sessionCache.has(key)) {
+		return sessionCache.get(key)
+	}
+	const promise = dedupeRequest(key, factory).catch((err) => {
+		sessionCache.delete(key)
+		throw err
+	})
+	sessionCache.set(key, promise)
+	return promise
+}
+
+export function clearDedupeKey(key) {
+	inflightRequests.delete(key)
+	sessionCache.delete(key)
+}
+
+export function clearSessionByPrefix(prefix) {
+	const keys = new Set([
+		...sessionCache.keys(),
+		...inflightRequests.keys()
+	])
+	keys.forEach((key) => {
+		if (key.startsWith(prefix)) {
+			clearDedupeKey(key)
+		}
+	})
+}

+ 36 - 7
pages_course/living/services/liveRoomService.js

@@ -1,18 +1,47 @@
-import { getlive, getLiveViewData, currentActivities } from '@/api/cacheLiving.js'
+import {
+	getlive,
+	getLiveViewData,
+	currentActivities,
+	remainingTime,
+	completionRecords
+} from '@/api/cacheLiving.js'
+import { oncePerSession, clearSessionByPrefix } from './liveRequestGuard.js'
 
 /** 加载直播间详情 */
-export function fetchLiveRoom(liveId) {
-	return getlive({ id: liveId })
+export function fetchLiveRoom(liveId, refresh = false) {
+	return oncePerSession(`live:room:${liveId}`, () => getlive({ id: liveId }), { refresh })
 }
 
 /** 点赞/观看/在线人数 */
-export function fetchLiveViewData(liveId) {
-	return getLiveViewData(liveId)
+export function fetchLiveViewData(liveId, refresh = false) {
+	return oncePerSession(`live:view:${liveId}`, () => getLiveViewData(liveId), { refresh })
 }
 
 /** 红包/抽奖/商品卡/公告快照 */
-export function fetchCurrentActivities(liveId) {
-	return currentActivities(liveId)
+export function fetchCurrentActivities(liveId, refresh = false) {
+	return oncePerSession(`live:activities:${liveId}`, () => currentActivities(liveId), { refresh })
+}
+
+/** 完课积分剩余时长 */
+export function fetchRemainingTime(liveId, refresh = false) {
+	return oncePerSession(`live:remaining:${liveId}`, () => remainingTime({ liveId }), { refresh })
+}
+
+/** 用户积分领取记录 */
+export function fetchCompletionRecords(liveId, refresh = false) {
+	return oncePerSession(`live:completion:${liveId}`, () => completionRecords({ liveId }), { refresh })
+}
+
+/** 下拉刷新等场景清除该直播间缓存 */
+export function clearLiveRoomRequestCache(liveId) {
+	if (!liveId) return
+	clearSessionByPrefix(`live:room:${liveId}`)
+	clearSessionByPrefix(`live:view:${liveId}`)
+	clearSessionByPrefix(`live:activities:${liveId}`)
+	clearSessionByPrefix(`live:remaining:${liveId}`)
+	clearSessionByPrefix(`live:completion:${liveId}`)
+	clearSessionByPrefix(`live:orderUser:${liveId}`)
+	clearSessionByPrefix(`live:msg:${liveId}:`)
 }
 
 /** 解析 live 接口返回,写入 liveItem 常用字段 */

+ 6 - 4
pages_course/living/services/liveShopService.js

@@ -1,14 +1,16 @@
 import { liveStore, liveOrderUser } from '@/api/cacheLiving.js'
 import { checkPurchaseLimit } from '@/api/product'
+import { oncePerSession } from './liveRequestGuard.js'
 
 /** 小黄车商品列表(点击购物车后再请求) */
-export function fetchLiveStore(liveId, keyword = '') {
-	return liveStore(liveId, keyword || '')
+export function fetchLiveStore(liveId, keyword = '', refresh = false) {
+	const kw = keyword || ''
+	return oncePerSession(`live:store:${liveId}:${kw}`, () => liveStore(liveId, kw), { refresh })
 }
 
 /** 正在购买用户 */
-export function fetchLiveOrderUser(liveId) {
-	return liveOrderUser(liveId)
+export function fetchLiveOrderUser(liveId, refresh = false) {
+	return oncePerSession(`live:orderUser:${liveId}`, () => liveOrderUser(liveId), { refresh })
 }
 
 /** 跳转商品前限购校验 */

+ 11 - 0
pages_course/living/services/liveUserService.js

@@ -0,0 +1,11 @@
+import { getUserInfo } from '@/api/cacheLiving.js'
+import { oncePerSession, clearDedupeKey } from './liveRequestGuard.js'
+
+/** 用户信息(会话内只请求一次) */
+export function fetchLiveUserInfo(refresh = false) {
+	return oncePerSession('app:userInfo', () => getUserInfo(), { refresh })
+}
+
+export function clearLiveUserInfoCache() {
+	clearDedupeKey('app:userInfo')
+}

+ 3 - 12
pages_course/livingList.vue

@@ -92,18 +92,9 @@
 				});
 			},
 			goLive(item) {
-				if(item.liveId == 2016){
-					uni.navigateTo({
-						//url: `./living?liveId=1195`
-						url: `./livingnew?liveId=${item.liveId}`
-					});
-				}else {
-					uni.navigateTo({
-						//url: `./living?liveId=1195`
-						url: `./living?liveId=${item.liveId}`
-					});
-				}
-
+				uni.navigateTo({
+					url: `./livingnew?liveId=${item.liveId}`
+				});
 			}
 		}
 	}

+ 142 - 108
pages_course/livingnew.vue

@@ -207,7 +207,15 @@
 	import LiveViewerBar from '@/pages_course/living/components/LiveViewerBar.vue';
 	import LiveSideActions from '@/pages_course/living/components/LiveSideActions.vue';
 	import { fetchLiveOrderUser } from '@/pages_course/living/services/liveShopService.js';
-	import { fetchLiveViewData } from '@/pages_course/living/services/liveRoomService.js';
+	import { fetchLiveUserInfo } from '@/pages_course/living/services/liveUserService.js';
+	import {
+		fetchLiveRoom,
+		fetchLiveViewData,
+		fetchCurrentActivities,
+		fetchRemainingTime,
+		fetchCompletionRecords,
+		clearLiveRoomRequestCache
+	} from '@/pages_course/living/services/liveRoomService.js';
 	import { createLiveSocket } from '@/pages_course/living/services/liveSocket.js';
 	import { parseWsEnvelope, parseJsonField, parseNumericField, isSuccessEnvelope } from '@/pages_course/living/services/liveSocketProtocol.js';
 	import {
@@ -218,20 +226,15 @@
 		liveRed,
 		liveDataLike,
 		collectGoods,
-		currentActivities,
-		getlive,
 		subNotifyLive,
 		internetTraffic,
 		liveInternetTraffic,
 		loginByMp,
-		getUserInfo,
 		getIsAddKf,
 		liveWatchUser,
 		submitLiveQuiz,
-		completionRecords,
 		completionReceive,
 		completionUnreceived,
-		remainingTime,
 		updateWatchDuration,
 		receivePoints,
 		integrallogs
@@ -347,6 +350,13 @@
 				isLoadingLiveInfo: false, // 是否正在加载课程间信息
 				isLoadingVideo: false, // 是否正在加载视频资源
 				hasCheckedLogin: false, // 是否已检查登录状态
+				initPromise: null, // 登录后初始化 Promise,防止重复
+				p1DataLoaded: false,
+				secondaryDataLoaded: false,
+				chatHistoryLoaded: false,
+				isFirstShow: true,
+				isFetchingUserInfo: false,
+				lastTrafficSubmitAt: 0,
 
 				liveViewersData: [],
 				liveUserCalled: false,
@@ -512,11 +522,16 @@
 			this.initNetworkStatusListener();
 		},
 		async onPullDownRefresh() {
-			// 下拉刷新时,重新加载数据
 			if (this.liveId) {
+				clearLiveRoomRequestCache(this.liveId);
 				this.isLoadingLiveInfo = false;
-				await this.getliving(this.liveId);
-				await this.loadChatHistory();
+				this.chatHistoryLoaded = false;
+				this.secondaryDataLoaded = false;
+				this.p1DataLoaded = false;
+				await this.getliving(this.liveId, { refresh: true });
+				await this.loadChatHistory(true);
+				this.modules.p1 = true;
+				this.loadP1Data(true);
 			}
 			setTimeout(() => {
 				uni.stopPullDownRefresh();
@@ -583,8 +598,11 @@
 				uni.removeStorageSync('scene');
 			}
 
-			// 恢复播放和连接
-			await this.resumePageActivity();
+			// 恢复播放和连接(首次 onShow 跳过,避免与 onLoad 重复拉取)
+			if (!this.isFirstShow) {
+				await this.resumePageActivity();
+			}
+			this.isFirstShow = false;
 
 			// 恢复观看时长统计(如果之前已经开始统计)
 			if (this.watchStartTime > 0 || this.accumulatedWatchDuration > 0) {
@@ -607,23 +625,10 @@
 
 			// 启动内存监控,定期清理
 			this.startMemoryMonitor();
-			if (this.trafficTimer) {
-				clearInterval(this.trafficTimer);
-				this.trafficTimer = null;
-				this.startTime = 0;
-				this.totalTraffic = 0;
-			}
-			// 重置视频加载状态和流量计算开始时间
-			this.videoLoaded = false;
-			this.trafficStartTime = 0;
-			// 清除等待定时器
-			if (this.waitingTimer) {
-				clearTimeout(this.waitingTimer);
-				this.waitingTimer = null;
+			// 不在 onShow 重置流量统计,避免重复上报 getLiveInternetTraffic
+			if (!this.lookTimer) {
+				this.startTimer();
 			}
-			this.waitingStartTime = 0;
-			this.lastVideoUpdateTime = 0;
-			this.startTimer();
 			this.$nextTick(() => {
 				console.log(444, this.userInfo);
 				if (!this.userInfo || !this.userInfo.nickname) {
@@ -964,24 +969,43 @@
 		},
 		methods: {
 			// 查询当前用户当前课程间领取积分的剩余时长
-			getRemainingTime() {
+			getRemainingTime(refresh = false) {
 				if (!this.liveId) return;
-				const data = {
-					liveId: this.liveId
-				}
-				remainingTime(data).then((res) => {
+				fetchRemainingTime(this.liveId, refresh).then((res) => {
 					if (res.code == 200) {
-						//this.pointsRemainingTime = res.data.remainingTime;
 						this.hasReceived = res.data.hasReceived;
 						this.videoDuration = res.data.videoDuration;
-						this.watchDuration = res.data.watchDuration; //停留时长
-						//this.completionRate= res.data.completionRate*0.01;//完课比例
+						this.watchDuration = res.data.watchDuration;
 						console.log("查询当前用户当前课程间领取积分的剩余时长", res)
 					}
-				}).catch((error) => {
-
-				});
-
+				}).catch(() => {});
+			},
+			loadSecondaryLiveData(refresh = false) {
+				if (!refresh && this.secondaryDataLoaded) {
+					return;
+				}
+				if (!this.liveId) {
+					return;
+				}
+				this.secondaryDataLoaded = true;
+				this.loadCompletionRecords(refresh);
+				if (this.liveItem.completionPointsEnabled) {
+					this.getRemainingTime(refresh);
+				}
+			},
+			loadCompletionRecords(refresh = false) {
+				if (!this.liveId) return;
+				fetchCompletionRecords(this.liveId, refresh).then((res) => {
+					if (res.code == 200) {
+						const targetData = res.data.find(item => item.liveId == this.liveId);
+						if (targetData) {
+							this.receiveStatus = true;
+						} else {
+							this.receiveStatus = false;
+						}
+						console.log("查询用户积分领取记录", res)
+					}
+				}).catch(() => {});
 			},
 
 			// 更新用户的看课时长 (传入课程间id和看课时长)
@@ -1790,17 +1814,26 @@
 				this.user.nickname = e.detail.value
 			},
 			async haveLogin() {
+				if (this.initPromise) {
+					return this.initPromise;
+				}
+				this.initPromise = this._doHaveLogin();
+				try {
+					return await this.initPromise;
+				} catch (err) {
+					this.initPromise = null;
+					throw err;
+				}
+			},
+			async _doHaveLogin() {
 				if (this.isOnload) {
 					return;
 				}
-				this.userInfo = uni.getStorageSync('userInfo');
-				if (this.userInfo) {
-					await this.getUserInfo();
-				}
+				this.isOnload = true;
+				await this.getUserInfo();
 				if (!this.liveId) {
 					return;
 				}
-				this.isOnload = true;
 				await this.getliving(this.liveId);
 				await this.$nextTick();
 				await Promise.all([
@@ -1813,20 +1846,33 @@
 				this.scheduleDeferredModules();
 			},
 			scheduleDeferredModules() {
+				if (this.p1DataLoaded) {
+					return;
+				}
 				setTimeout(() => {
+					if (this.p1DataLoaded) {
+						return;
+					}
 					this.modules.p1 = true;
 					this.loadP1Data();
 				}, 1500);
 			},
-			loadP1Data() {
-				this.getliveViewData();
-				this.loadLiveOrderUser();
+			loadP1Data(refresh = false) {
+				if (!refresh && this.p1DataLoaded) {
+					return;
+				}
+				if (!this.liveId) {
+					return;
+				}
+				this.p1DataLoaded = true;
+				this.getliveViewData(refresh);
+				this.loadLiveOrderUser(refresh);
 				this.modules.p2Activity = true;
-				this.getCurrentActivities();
+				this.applyCurrentActivities(refresh);
 			},
-			loadLiveOrderUser() {
+			loadLiveOrderUser(refresh = false) {
 				if (!this.liveId) return;
-				fetchLiveOrderUser(this.liveId).then(res => {
+				fetchLiveOrderUser(this.liveId, refresh).then(res => {
 					if (res.code === 200) {
 						this.orderUser = res;
 					}
@@ -1940,9 +1986,13 @@
 				this.isKeyboardShow = false;
 				this.restoreGoodsCardAfterKeyboard();
 			},
-			async loadChatHistory() {
+			async loadChatHistory(refresh = false) {
+				if (!refresh && this.chatHistoryLoaded) {
+					return;
+				}
 				if (this.$refs.chat && this.$refs.chat.loadHistory) {
-					await this.$refs.chat.loadHistory(this.liveItem);
+					await this.$refs.chat.loadHistory(this.liveItem, refresh);
+					this.chatHistoryLoaded = true;
 				}
 			},
 			onShopBuy({ productId, goodsId }) {
@@ -2551,6 +2601,11 @@
 				if (!this.liveId || !this.userInfo || !this.userInfo.userId) {
 					return;
 				}
+				const now = Date.now();
+				if (now - this.lastTrafficSubmitAt < 8000) {
+					return;
+				}
+				this.lastTrafficSubmitAt = now;
 
 				// 计算当前观看时长对应的流量
 				const totalDuration = this.liveItem.videoDuration || this.liveItem.duration || 0;
@@ -2660,29 +2715,33 @@
 			},
 			// 恢复页面活动
 			async resumePageActivity() {
-				if (this.liveItem) {
-					await this.getliving(this.liveId);
-					this.startTimeTimer(this.liveItem);
+				if (!this.liveId || !this.isOnload) {
+					if (!this.isSocketAvailable()) {
+						this.initSocket();
+					}
+					return;
 				}
+				await this.getliving(this.liveId, { skipSecondary: true });
+				this.startTimeTimer(this.liveItem);
 				if (!this.isSocketAvailable()) {
 					this.initSocket();
 				}
 			},
-			async getUserInfo() {
-				await getUserInfo().then(
-					(res) => {
-						if (res.code == 200) {
-							this.userInfo = res.user;
-							this.isNow = dayjs(this.userInfo.updateTime).isSame(dayjs(), 'day')
-						} else {
-							uni.showToast({
-								icon: 'none',
-								title: '请求失败'
-							});
-						}
-					},
-					(rej) => {}
-				);
+			async getUserInfo(refresh = false) {
+				try {
+					const res = await fetchLiveUserInfo(refresh);
+					if (res.code == 200) {
+						this.userInfo = res.user;
+						this.isNow = dayjs(this.userInfo.updateTime).isSame(dayjs(), 'day');
+					} else {
+						uni.showToast({
+							icon: 'none',
+							title: '请求失败'
+						});
+					}
+				} catch (e) {
+					console.error('getUserInfo failed', e);
+				}
 			},
 
 			//订阅消息
@@ -3217,9 +3276,9 @@
 				console.log('错误');
 			},
 			//  红包 卡片 抽奖
-			getCurrentActivities() {
+			applyCurrentActivities(refresh = false) {
 				if (!this.liveId) return;
-				currentActivities(this.liveId).then(
+				fetchCurrentActivities(this.liveId, refresh).then(
 					(res) => {
 						if (res.code === 200) {
 							// 提取数据(默认空数组/对象避免报错)
@@ -3487,45 +3546,22 @@
 					url: url
 				});
 			},
-			// 查询用户积分领取记录
+			// 查询用户积分领取记录(供外部刷新时调用)
 			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 = true;
-						} else {
-							console.log('未找到liveId为', this.liveId, '的数据');
-							this.receiveStatus = false; // 或其他默认值
-						}
-						console.log("查询用户积分领取记录", res)
-					}
-				}).catch((error) => {
-
-				});
+				this.loadCompletionRecords();
 			},
 
 			// 修改获取课程信息方法
-			async getliving(liveId) {
+			async getliving(liveId, options = {}) {
+				const { skipSecondary = false, refresh = false } = options;
 				if (!liveId) return;
-				// 防止重复请求
 				if (this.isLoadingLiveInfo) {
 					console.log('正在加载课程间信息,跳过重复请求');
 					return;
 				}
 				this.isLoadingLiveInfo = true;
-				const param = {
-					id: liveId
-				};
 				try {
-					const res = await getlive(param);
-					this.isLoadingLiveInfo = false;
+					const res = await fetchLiveRoom(liveId, refresh);
 					if (res.code !== 200) {
 						uni.showToast({
 							title: res.msg,
@@ -3605,8 +3641,8 @@
 						this.completionRate = JSON.parse(this.liveItem.configJson).completionRate * 0.01
 					}
 					console.log("查询当前用户当前课程间领取积分的剩余时长", this.liveId)
-					if (this.liveItem.completionPointsEnabled) {
-						this.getRemainingTime(); //查询当前用户当前课程间领取积分的剩余时长
+					if (!skipSecondary) {
+						this.loadSecondaryLiveData(refresh);
 					}
 					this.$set(this.liveItem, 'autoplay', res.data.liveType !== 0);
 					this.$set(this.liveItem, 'showType', res.data.showType);
@@ -3626,8 +3662,6 @@
 							this.liveBeginWatchTime = this.getServerTimeNow();
 						}
 					}
-					this.getliveViewData();
-					this.completionRecords();
 					// 初始化观看时间统计
 					this.initWatchTime();
 					const diff = this.calculateLiveTimeDiff(this.liveItem.serviceStartTime, true)
@@ -3649,12 +3683,13 @@
 						}
 					});
 				} catch (err) {
-					this.isLoadingLiveInfo = false;
 					console.error('获取课程信息失败:', err);
 					uni.showToast({
 						title: '获取课程信息失败',
 						icon: 'none'
 					});
+				} finally {
+					this.isLoadingLiveInfo = false;
 				}
 			},
 			getPureDecimal(num, precision = 6) {
@@ -3763,11 +3798,10 @@
 			},
 
 			//课程间点赞、关注、在线人数数据
-			getliveViewData() {
+			getliveViewData(refresh = false) {
 				if (!this.liveId) return;
 
-				// 使用 Promise 包装,支持 await
-				return fetchLiveViewData(this.liveId).then((res) => {
+				return fetchLiveViewData(this.liveId, refresh).then((res) => {
 					if (res.code == 200) {
 						// 强制响应式更新,确保数据实时显示
 						this.liveViewData = res;

+ 112 - 126
pages_shopping/live/confirmCreateOrder.vue

@@ -139,10 +139,11 @@
 
 <script>
 	import {
-		createliveOrder, // 创建订单
+		createliveOrderOpt, // 创建订单(优化版)
 		createReward, // 创建中奖订单
 		userAddr, // 获取用户收货地址
 		computed,
+    computeCache,
 		computedReward,
 		liveOrderKey, // 生成订单key
 	} from "@/api/order.js"
@@ -180,6 +181,7 @@
 				confirmParam: [],
 				type: '',
 				isFirstLoad: true,
+				pageInitializing: false,
 				recordId: '',
 				productValueSelect: ''
 			}
@@ -196,8 +198,9 @@
 			this.isFirstLoad = true;
 			this.recordId = options.recordId || '';
 			this.productValueSelect = options.productValueSelect || ''
+			uni.$on('updateAddress', this.handleAddressUpdate);
 			if (options.type == 'win') {
-				this.getKey()
+				this._keyPromise = this.getKey()
 			}
 		},
 		computed: {
@@ -211,89 +214,84 @@
 			}
 		},
 		onShow() {
-			// 页面返回时重置提交状态,避免无法再次提交
 			this.submittingOrder = false;
-			this.openCoupon()
-			if (this.type == 'win') {
-				this.computedRewardOrder()
-			} else {
-				this.computedOrder()
+			if (this.isFirstLoad && !this.pageInitializing) {
+				this.initOrderPage();
 			}
-			if (!this.cityId) {
-				this.getUserAddr()
-			}
-			// this.getUserAddr()
-			uni.$on('updateAddress', (e) => {
-				this.address = e;
-				this.addressId = e.addressId;
-				this.cityId = e.cityId;
-				console.log("地址", e.cityId)
-			});
-		},
-		mounted() {
-			// uni.$on('updateAddress', (e) => {
-			// 	this.address = e;
-			// 	this.addressId = e.addressId;
-			// });
 		},
 		onUnload() {
 			uni.$off('updateAddress', this.handleAddressUpdate);
 		},
-		beforeDestroy() {
-			uni.$off('updateAddress');
-		},
 		methods: {
+			// 进入页面:优惠券 → 地址 → 计算(只算一次)
+			async initOrderPage() {
+				if (this.pageInitializing) {
+					return;
+				}
+				this.pageInitializing = true;
+				try {
+					if (this.type === 'win' && this._keyPromise) {
+						await this._keyPromise;
+					}
+					await this.loadCoupons();
+					this.autoSelectMaxCoupon();
+					await this.loadUserAddr();
+					await this.computeOrderPrice();
+				} catch (e) {
+					console.error('初始化订单页失败:', e);
+				} finally {
+					this.isFirstLoad = false;
+					this.pageInitializing = false;
+				}
+			},
 			handleAddressUpdate(item) {
 				console.log('接收到地址数据:', item);
 				this.cityId = item.cityId;
 				this.address = item;
 				this.addressId = item.addressId;
+				this.computeOrderPrice();
+			},
+			loadUserAddr() {
+				return userAddr().then(res => {
+					if (res.code == 200) {
+						console.log("用户收货地址>>>>", res.data)
+						if (res.data && !this.address) {
+							this.address = res.data;
+						}
+						if (res.data && res.data.cityIds) {
+							this.cityId = res.data.cityIds;
+						}
+					} else {
+						uni.showToast({
+							title: res.msg,
+							icon: 'none'
+						});
+					}
+				});
+			},
+			computeOrderPrice() {
 				if (this.type == 'win') {
-					this.computedRewardOrder()
-				} else {
-					this.computedOrder()
+					return this.computedRewardOrder();
 				}
+				return this.computedOrder();
 			},
-			// 获取用户收货地址
+			// 获取用户收货地址(兼容旧调用)
 			getUserAddr() {
-				userAddr().then(res => {
-						if (res.code == 200) {
-							console.log("用户收货地址>>>>", res.data)
-							if (res.data && !this.address) {
-								this.address = res.data;
-							}
-							if (res.data && res.data.cityIds) {
-								this.cityId = res.data.cityIds;
-							}
-							if (this.type == 'win') {
-								this.computedRewardOrder()
-							} else {
-								this.computedOrder()
-							}
-						} else {
-							uni.showToast({
-								title: res.msg,
-								icon: 'none'
-							});
-						}
-					},
-					rej => {}
-				);
+				return this.loadUserAddr().then(() => this.computeOrderPrice());
 			},
 			// 获得key
 			getKey() {
-				liveOrderKey().then(res => {
-						if (res.code == 200) {
-							this.orderKey = res.orderKey
-						} else {
-							uni.showToast({
-								title: res.msg,
-								icon: 'none'
-							});
-						}
-					},
-					rej => {}
-				);
+				return liveOrderKey().then(res => {
+					if (res.code == 200) {
+						this.orderKey = res.orderKey
+					} else {
+						uni.showToast({
+							title: res.msg,
+							icon: 'none'
+						});
+						return Promise.reject(new Error(res.msg));
+					}
+				});
 			},
 			// 查询创建订单信息
 			computedOrder() {
@@ -306,19 +304,18 @@
 					attrValueId: this.productValueSelect
 				}
 
-				computed(data).then(res => {
-						if (res.code == 200) {
-							console.log("查询创建订单信息>>>>", res.data)
-							this.orderData = res.data
-						} else {
-							uni.showToast({
-								title: res.msg,
-								icon: 'none'
-							});
-						}
-					},
-					rej => {}
-				);
+				return computeCache(data).then(res => {
+					if (res.code == 200) {
+						console.log("查询创建订单信息>>>>", res.data)
+						this.orderData = res.data
+					} else {
+						uni.showToast({
+							title: res.msg,
+							icon: 'none'
+						});
+						return Promise.reject(new Error(res.msg));
+					}
+				});
 			},
 			// 查询中奖创建订单信息
 			computedRewardOrder() {
@@ -329,19 +326,18 @@
 					totalNum: 1,
 					remark: this.orderData.remark || ''
 				}
-				computedReward(data).then(res => {
-						if (res.code == 200) {
-							console.log("查询创建订单信息>>>>", res.data)
-							this.orderData = res.data || {}
-						} else {
-							uni.showToast({
-								title: res.msg,
-								icon: 'none'
-							});
-						}
-					},
-					rej => {}
-				);
+				return computedReward(data).then(res => {
+					if (res.code == 200) {
+						console.log("查询创建订单信息>>>>", res.data)
+						this.orderData = res.data || {}
+					} else {
+						uni.showToast({
+							title: res.msg,
+							icon: 'none'
+						});
+						return Promise.reject(new Error(res.msg));
+					}
+				});
 			},
 
 
@@ -365,10 +361,14 @@
 					appId: wx.getAccountInfoSync().miniProgram.appId
 				}
 
-				return createliveOrder(data).then(res => {
+				return createliveOrderOpt(data).then(res => {
 					if (res.code == 200) {
-						this.orderList = res.order;
-						return res.order;
+						const order = res.order || {};
+						if (order.id && !order.orderId) {
+							order.orderId = order.id;
+						}
+						this.orderList = order;
+						return order;
 					} else {
 						uni.showToast({
 							title: res.msg,
@@ -414,20 +414,16 @@
 				this.couponText = "-¥" + (item.couponPrice || 0).toFixed(2);
 				this.couponUserId = item.id;
 				this.couponVisible = false;
-				if (this.type == 'win') {
-					this.computedRewardOrder()
-				} else {
-					this.computedOrder()
-				}
-
+				this.computeOrderPrice();
 			},
-			// 自动选择最大优惠券
+			// 自动选择最大优惠券(不触发计算,由 initOrderPage 统一计算)
 			autoSelectMaxCoupon() {
-				if (this.couponsList.length === 0 || !this.isFirstLoad) {
+				if (this.couponsList.length === 0) {
 					return;
 				}
+				const totalPrice = this.orderData.totalPrice || 0;
 				const availableCoupons = this.couponsList.filter(item =>
-					item.status === 0 && item.useMinPrice <= (this.orderData.totalPrice || 0)
+					item.status === 0 && (totalPrice <= 0 || item.useMinPrice <= totalPrice)
 				);
 				if (availableCoupons.length === 0) {
 					return;
@@ -436,34 +432,24 @@
 				const maxCoupon = availableCoupons[0];
 				this.couponText = "-¥" + (maxCoupon.couponPrice || 0).toFixed(2);
 				this.couponUserId = maxCoupon.id;
-
 				console.log('自动选择最大优惠券:', maxCoupon);
-				this.isFirstLoad = false;
-				// 重新计算订单价格
-				if (this.type == 'win') {
-					this.computedRewardOrder()
-				} else {
-					this.computedOrder()
-				}
 			},
-			openCoupon() {
-				console.log("点了优惠券列表")
+			loadCoupons() {
 				if (!this.liveId || !this.goodsId) {
 					console.log('缺少必要参数,跳过优惠券请求');
-					return;
+					return Promise.resolve();
 				}
 				const data = {
 					liveId: this.liveId,
 					goodsId: this.goodsId
 				};
-				curCoupon(data).then(res => {
+				return curCoupon(data).then(res => {
 					this.couponsList = res.data || [];
-					if (this.isFirstLoad) {
-						setTimeout(() => {
-							this.autoSelectMaxCoupon();
-						}, 100);
-					}
-				})
+				});
+			},
+			openCoupon() {
+				console.log("点了优惠券列表")
+				this.loadCoupons();
 			},
 			openAddress() {
 				uni.navigateTo({
@@ -480,10 +466,10 @@
 					});
 					return;
 				}
-				
+
 				// 立即标记提交中,防止快速重复点击
 				this.submittingOrder = true;
-				
+
 				try {
 					// 参数校验
 					if (this.orderKey == null) {
@@ -502,7 +488,7 @@
 						});
 						return;
 					}
-					
+
 					// 创建订单
 					let orderList;
 					if (this.type == "win") {
@@ -512,7 +498,7 @@
 					}
 					console.log("orderList>>", orderList)
 					const orderListStr = encodeURIComponent(JSON.stringify(orderList));
-					
+
 					// 跳转到支付页面
 					uni.redirectTo({
 						url: `/pages_shopping/live/paymentOrder?orderList=${orderListStr}&couponUserId=${this.couponUserId}&type=${this.type}&liveId=${this.liveId}`,

+ 4 - 7
pages_shopping/live/paymentOrder.vue

@@ -61,7 +61,7 @@
 				</view>
 				<view class="item">
 					<text class="label">优惠券</text>
-					<text class="text">-¥{{order ? (Number(order.discountMoney) || 0).toFixed(2) : "0.00"}} </text>
+					<text class="text">-¥{{order ? (Number(order.discountMoney || order.couponPrice) || 0).toFixed(2) : "0.00"}} </text>
 				</view>
 			</view>
 
@@ -77,15 +77,12 @@
 		clearPayType
 	} from '@/api/storeOrder'
 	import dayjs from 'dayjs';
-	import {
-		weChatPayment
-	} from '@/api/pay_new'
 	import {
 		zfbPayment,
-		// weChatPayment
 	} from '@/api/pay'
 	import {
 		payConfirmReward,
+		payLiveOrderOpt,
 	} from '@/api/order'
 	
 	export default {
@@ -196,7 +193,7 @@
 				}
 				
 				var data = {
-					orderId: this.order.id,
+					orderId: this.order.id || this.order.orderId,
 					payType: 1,
 					appId: wx.getAccountInfoSync().miniProgram.appId
 				};
@@ -204,7 +201,7 @@
 				this.payParams = data
 				var that = this;
 				uni.showLoading();
-				weChatPayment(data).then(
+				payLiveOrderOpt(data).then(
 					res => {
 						if (res.code == 501) {
 							that.isPaying = false; // 重置支付状态

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels