From bf50dc43351d1a9781a84faf775913e813ea6ecb Mon Sep 17 00:00:00 2001
From: Jacob <hlnie@tohours.com>
Date: 星期二, 20 十月 2026 12:53:42 +0800
Subject: [PATCH] Merge branch 'dev' into sit

---
 pages/zone/index.vue |  190 +++++++++++++++++++++++++++++++++++++----------
 1 files changed, 150 insertions(+), 40 deletions(-)

diff --git a/pages/zone/index.vue b/pages/zone/index.vue
index 0ce7a0d..c264c79 100644
--- a/pages/zone/index.vue
+++ b/pages/zone/index.vue
@@ -14,16 +14,38 @@
 		<view :style="{ height: marTop + 'px' }"></view>
 		<yueyangZone ref=yueyangZoneRef v-if="isYueyangZone" :zoneInfo="info" :careBeanRate="careBeanRate"
 			style="position: relative;z-index: 2;" @goLottery="goLottery" :relationKey="relationKey"></yueyangZone>
+		<view v-if="isYueyangZone" class="detail-btn" @click="goDetail">
+			<text>娑堣�楁槑缁�</text>
+		</view>
 		<view v-else>
 			<view class="expireTime" v-if="expireTime && expireTime.length">
 				<text>涓撳尯灏嗗湪</text>
-				<text v-for="(val, index) in expireTime" :key="index">
-					<text class="num">{{ val }}</text>{{ expireTimeUnit[index] }}
+				<text v-for="(item, index) in expireTime" :key="index">
+					<text class="num"><text v-for="(char, ci) in item.digits" :key="ci"
+							class="digit">{{ char }}</text></text>{{ item.unit }}
 				</text>
 				<text>{{ startOrEnd }}</text>
 			</view>
 			<view class="head_img">
 				<image :src="info.image"></image>
+			</view>
+			<view v-if="info.zoneType == 8 && info.info" class="rich-content">
+				<rich-text :nodes="info.info"></rich-text>
+			</view>
+			<view v-if="info.zoneType == 8 && info.uploadVideo" class="video-wrap">
+				<view v-show="!videoControls" style="width:100%;height:750rpx">
+					<video id="zoneVideo" :src='info.uploadVideo' objectFit="contain" controls
+						style="width:100%;height:100%" show-center-play-btn="true" show-mute-btn="true" muted="true"
+						show-fullscreen-btn="true" auto-pause-if-navigate :custom-cache="false"
+						:enable-progress-gesture="true" show-progress="false"
+						:poster="info.uploadVideoImg || info.image" @pause="zoneVideoPause"></video>
+				</view>
+				<view class="video-poster" v-show="videoControls">
+					<image class="image" :src="info.uploadVideoImg || info.image"></image>
+				</view>
+				<view class="video-stop" v-show="videoControls" @tap="bindZoneVideoPlay">
+					<image class="image" src="https://ossacmall.bluedeer.com.cn/app/static/images/stop.png"></image>
+				</view>
 			</view>
 			<view class="tag-wrap-container" :style="'top:' + (marTop) + 'px;'" v-if="info.zoneType == 7">
 				<view class="tag-wrap">
@@ -67,9 +89,8 @@
 					</view>
 				</view>
 			</view>
-			<view @click="goLottery" class="lottery_banner" v-if="info && info.isLottery">
-				<image class="lottery_bannerImg"
-					src="https://ossacmall.bluedeer.com.cn/app/static/images/zone_lotteryBanner.gif" mode="widthFix">
+			<view @click="goLottery" class="lottery_banner" v-if="info && info.isLottery && info.lotteryBanner">
+				<image class="lottery_bannerImg" :src="info.lotteryBanner" mode="widthFix">
 				</image>
 			</view>
 			<view class="tag-img-container" v-if="info.zoneType == 7">
@@ -586,7 +607,7 @@
 			showMenu: false,
 			selectedMenuArr: [],
 			expireTime: [],
-			expireTimeUnit: [],
+			countdownToken: 0,
 			isPageShow: false,
 			loginBackFn: null,
 			errText: '',
@@ -596,6 +617,8 @@
 			isYueyangZone: false,
 			isOpen: false, // 榛樿鏀惰捣锛宖alse鏀惰捣/true灞曞紑
 			currentIndex: -1, // 榛樿閫変腑绗竴涓�愬叏閮ㄣ��
+			videoControls: true, // 涓撳尯娲诲姩瑙嗛鏄惁鏄剧ず娴锋姤+鎾斁鎸夐挳
+			zoneVideoContext: '', // 娲诲姩瑙嗛鎾斁涓婁笅鏂�
 			partitionList: [],
 			partitionProject: {},
 			tagList: [],
@@ -835,6 +858,17 @@
 		}
 	},
 	methods: {
+		/**
+		 * 涓撳尯娲诲姩瑙嗛锛氱偣鍑绘捣鎶ユ挱鏀炬寜閽悗鎾斁
+		 */
+		bindZoneVideoPlay() {
+			if (!this.zoneVideoContext) {
+				this.zoneVideoContext = uni.createVideoContext('zoneVideo', this);
+			}
+			this.$set(this, 'videoControls', false);
+			this.zoneVideoContext.play();
+		},
+		zoneVideoPause() { },
 		handleCouponRule() {
 			this.$refs.personalAndShareCouponRuleRef.show(this.info.ruleContentText)
 		},
@@ -1195,6 +1229,11 @@
 				// that.myCareBean = res2.data.totalCareBeans;
 			});
 		},
+		goDetail() {
+			uni.navigateTo({
+				url: '/pages/consumption/index?zoneId=' + this.info.id
+			})
+		},
 		goLottery() {
 			let that = this;
 			var data = {
@@ -1288,6 +1327,9 @@
 			})
 		},
 		validAlert(data) {
+			// 姣忔閲嶆柊璁$畻鍓嶄綔搴熸棫鐨勫�掕鏃堕摼锛岄伩鍏嶅鏉″畾鏃跺櫒鍚屾椂鍒锋柊瀵艰嚧鏁板瓧璺冲姩
+			this.countdownToken++
+			const token = this.countdownToken
 			const {
 				startTime,
 				expireTime
@@ -1306,17 +1348,17 @@
 					let minutes = startTimetamp.getMinutes()
 					minutes = minutes < 10 ? '0' + minutes : minutes;
 
-					this.countdownTimer(startTime.split('-').join('/'), 'start')
+					this.countdownTimer(startTime.split('-').join('/'), 'start', token)
 					this.startOrEnd = "鍚庡紑鍚�"
 					return
-				}
-			}
-			if (expireTime) {
-				const expireTimetamp = new Date(expireTime.split('-').join('/')).getTime();
-				if (expireTimetamp < nowTimestamp) {
+					}
+					}
+					if (expireTime) {
+					const expireTimetamp = new Date(expireTime.split('-').join('/')).getTime();
+					if (expireTimetamp < nowTimestamp) {
 					return
-				}
-				this.countdownTimer(expireTime.split('-').join('/'), 'end')
+					}
+					this.countdownTimer(expireTime.split('-').join('/'), 'end', token)
 				this.startOrEnd = "鍚庣粨鏉�"
 			}
 		},
@@ -1445,6 +1487,7 @@
 			console.log('涓撳尯璇︽儏鍏ュ弬锛氾細', params)
 			getZoneDetail(that.id, params).then(res => {
 				that.info = res.data;
+				//that.info.zoneType=8;
 				that.updateZoneShareMenu();
 				if (res.data.zoneType == 6) {
 					that.setYueyangZone()
@@ -1454,7 +1497,7 @@
 						that.homeTop = that.getHomeTop(0.4)
 					}
 					that.expireTime = [];
-					that.expireTimeUnit = [];
+					that.countdownToken++;
 					that.where.page = 1;
 					that.getGoodList()
 					that.validAlert(res.data)
@@ -1480,8 +1523,9 @@
 				}
 			});
 		},
-		countdownTimer(expireTime, type) {
+		countdownTimer(expireTime, type, token) {
 			if (!expireTime) return
+			if (token !== undefined && token !== this.countdownToken) return
 			let that = this;
 			// 缁撴潫鏃堕棿鐨勬椂闂存埑锛堥渶浼犲叆涓�涓湁鏁堢殑鏃ユ湡瀵硅薄鎴栨椂闂存埑锛�
 			const endTimestamp = new Date(expireTime).getTime();
@@ -1493,56 +1537,56 @@
 			if (type == 'end') {
 				if (diff <= 0) {
 					this.expireTime = []
-					this.expireTimeUnit = []
 					return
 				} else { }
 			} else if (type == 'start') {
 				if (diff <= 0) {
 					this.expireTime = []
-					this.expireTimeUnit = []
 					const expireTime2 = that.info.expireTime
 					if (expireTime2) {
 						const expireTimetamp = new Date(expireTime2.split('-').join('/')).getTime();
 						if (expireTimetamp < nowTimestamp) {
 							return
 						}
-						this.countdownTimer(expireTime2.split('-').join('/'), 'end')
+						this.countdownTimer(expireTime2.split('-').join('/'), 'end', token)
 						this.startOrEnd = "鍚庣粨鏉�"
 					}
 					return
 				}
 			}
+			const pad = num => (num < 10 ? '0' + num : String(num))
 			const res = []
-			const unit = []
 			const days = Math.floor(diff / (1000 * 60 * 60 * 24))
 			diff %= (1000 * 60 * 60 * 24)
-			if (days > 0) {
-				res.push(days);
-				unit.push('鏃�')
-			}
 			// 杞崲涓哄皬鏃躲�佸垎閽熴�佺
 			const hours = Math.floor(diff / (1000 * 60 * 60));
 			diff %= (1000 * 60 * 60); // 鍓╀綑姣鏁�
-			if (hours > 0) {
-				res.push(hours < 10 ? '0' + hours : hours);
-				unit.push('鏃�')
-			}
 			const minutes = Math.floor(diff / (1000 * 60));
-			if (minutes > 0) {
-				res.push(minutes < 10 ? '0' + minutes : minutes);
-				unit.push('鍒�')
-			}
 			diff %= (1000 * 60); // 鍓╀綑姣鏁�
 			const seconds = Math.floor(diff / 1000);
-			if (seconds > 0) {
-				res.push(seconds < 10 ? '0' + seconds : seconds);
-				unit.push('绉�')
+			// 澶╂暟涓� 0 鏃朵笉灞曠ず锛屾椂/鍒�/绉掑缁堝睍绀猴紙琛� 0锛夛紝淇濊瘉鍊掕鏃堕暱搴︾ǔ瀹�
+			if (days > 0) {
+				res.push({
+					digits: pad(days).split(''),
+					unit: '鏃�'
+				})
 			}
+			res.push({
+				digits: pad(hours).split(''),
+				unit: '鏃�'
+			})
+			res.push({
+				digits: pad(minutes).split(''),
+				unit: '鍒�'
+			})
+			res.push({
+				digits: pad(seconds).split(''),
+				unit: '绉�'
+			})
 			this.expireTime = res
-			this.expireTimeUnit = unit
 			if (this.isPageShow) {
 				setTimeout(() => {
-					that.countdownTimer(expireTime, type)
+					that.countdownTimer(expireTime, type, token)
 				}, 1000)
 			}
 		},
@@ -1629,13 +1673,11 @@
 .lottery_banner {
 	margin: 15rpx auto;
 	width: 690rpx;
-	height: 120rpx;
 	text-align: center;
 }
 
 .lottery_bannerImg {
 	width: 690rpx;
-	height: 120rpx;
 }
 
 .tag-wrap-container {
@@ -1836,6 +1878,21 @@
 	transform: translate(0, -50%);
 }
 
+.detail-btn {
+	border: 2rpx solid #fff;
+	border-top-left-radius: 20rpx;
+	border-bottom-left-radius: 20rpx;
+	padding: 10rpx;
+	background-color: #daf2b2;
+	color: #1e984f;
+	width: 50rpx;
+	position: fixed;
+	top: 200rpx;
+	right: 0rpx;
+	line-height: 1rem;
+	z-index: 99;
+}
+
 .head_img {
 	width: 750rpx;
 	height: 422rpx;
@@ -1844,6 +1901,48 @@
 		width: 750rpx;
 		height: 422rpx;
 	}
+}
+
+.rich-content {
+	padding: 24rpx 30rpx;
+	background-color: #fff;
+}
+
+.video-wrap {
+	position: relative;
+	width: 100%;
+	height: 750rpx;
+	background-color: #000;
+}
+
+.video-wrap .video-poster {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 750rpx;
+	z-index: 9;
+}
+
+.video-wrap .video-poster .image {
+	width: 100%;
+	height: 100%;
+}
+
+.video-wrap .video-stop {
+	position: absolute;
+	top: 50%;
+	left: 50%;
+	width: 136rpx;
+	height: 136rpx;
+	margin-top: -68rpx;
+	margin-left: -68rpx;
+	z-index: 9;
+}
+
+.video-wrap .video-stop .image {
+	width: 100%;
+	height: 100%;
 }
 
 .toolbarList {
@@ -2062,11 +2161,22 @@
 	padding: 15rpx;
 	padding-left: 30rpx;
 	color: #979797;
+	font-size: 26rpx;
 
 	.num {
+		display: inline-block;
 		color: #000000;
 		background: #FFE20E;
-		padding: 0 10rpx;
+		padding: 0 6rpx;
+		margin: 0 4rpx;
+		vertical-align: middle;
+	}
+
+	/* 姣忎釜鏁板瓧鍥哄畾瀹藉害锛岄伩鍏嶅�掕鏃惰烦鍔ㄦ椂瀹藉害蹇介暱蹇界煭 */
+	.digit {
+		display: inline-block;
+		width: 19rpx;
+		text-align: center;
 	}
 }
 </style>
\ No newline at end of file

--
Gitblit v1.4.0