Просмотр исходного кода

课程详情

Signed-off-by: 李妹妹 <1639016684@qq.com>
李妹妹 3 месяцев назад
Родитель
Сommit
c7b7751cd2

+ 1 - 1
components/Server.vue

@@ -50,7 +50,7 @@
 				} else {
 					// 默认位置:右侧80%高度
 					this.left = 750 - 150 - 20; // 屏幕宽度 - 容器宽度 - 右边距
-					this.top = this.px2rpx(this.screenHeight * 0.8 - 75); // 80%高度,居中偏移
+					this.top = this.px2rpx(this.screenHeight * 0.9 - 75); // 80%高度,居中偏移
 				}
 			},
 			

+ 1 - 1
components/likeProduct.vue

@@ -125,7 +125,7 @@
 		display: flex;
 		align-items: center;
 		justify-content: left;
-		padding: 30upx 0;
+		padding-bottom:24rpx;
 		image{
 			width: 37upx;
 			height: 37upx;

+ 12 - 4
pages.json

@@ -350,7 +350,15 @@
 										"enablePullDownRefresh": false
 										//"navigationStyle": "custom"
 									}
-								}
+								},
+							{
+									"path": "courseDetail",
+									"style": {
+											"navigationBarTitleText": "课程详情",
+											"enablePullDownRefresh": false,
+											"navigationStyle": "custom"
+										}
+									}
 				]
 		},
 		// {
@@ -1416,12 +1424,12 @@
 	"tabBar": {
 		"color": "#666666",
 		"selectedColor": "#FF233C",
-		// "custom": true, 
+		//"custom": true, 
 		"borderStyle": "white",
 		"backgroundColor": "#ffffff",
 		"height": "64px",
-		"fontSize": "12px",
-		"iconWidth": "18px",
+		"fontSize": "16px",
+		"iconWidth": "24px",
 		"spacing": "4px",
 		"list": [{
 				//"pagePath": "pages/home/newindex",

+ 2 - 2
pages/home/index.vue

@@ -219,8 +219,8 @@ export default {
 			uni.navigateTo({ url: '/pages_index/course' })
 		},
 		onCourseClick(course) {
-			uni.showToast({ title: course.name, icon: 'none' })
-			// 可跳转课程详情: uni.navigateTo({ url: '/pages_course/videovip?id=' + course.id })
+			//uni.showToast({ title: course.name, icon: 'none' })
+		uni.navigateTo({ url: '/pages_index/courseDetail'})
 		}
 	}
 }

+ 53 - 57
pages/user/index.vue

@@ -44,7 +44,7 @@
 							<view class="all-order" @click="showOrder('')">
 								<text class="text">全部订单</text>
 								<image
-									src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/arrow4.png"
+									src="@/static/images/right.png"
 									mode=""></image>
 							</view>
 						</view>
@@ -453,13 +453,13 @@
 					display: flex;
 
 					.head-img {
-						width: 120upx;
-						height: 120upx;
+						width: 150rpx;
+						height: 150rpx;
 						border-radius: 50%;
 						overflow: hidden;
-						margin-right: 30upx;
+						margin-right: 20upx;
 						border: 4upx solid #FFFFFF;
-						box-shadow: 0px 5px 15px 2px rgba(0, 0, 0, 0.1);
+						//box-shadow: 0px 5px 15px 2px rgba(0, 0, 0, 0.1);
 
 						image {
 							width: 100%;
@@ -468,23 +468,25 @@
 					}
 
 					.name-phone {
-						padding-top: 15upx;
-
+						//padding-top: 15upx;
+                        display: flex;
+						flex-direction: column;
+						align-items: start;
 						.name {
-							font-size: 40upx;
-							font-family: PingFang SC;
-							font-weight: bold;
-							color: #111111;
-							line-height: 1;
+							font-family: PingFangSC, PingFang SC;
+							font-weight: 600;
+							font-size: 40rpx;
+							color: rgba(0,0,0,0.85);
+							line-height: 56rpx;
 						}
 
 						.phone {
-							font-size: 28upx;
-							font-family: PingFang SC;
-							font-weight: 500;
-							color: #666666;
-							line-height: 1;
-							margin-top: 30upx;
+							margin-top: 20rpx;
+							font-family: PingFangSC, PingFang SC;
+							font-weight: 400;
+							font-size: 32rpx;
+							color: rgba(0,0,0,0.85);
+							line-height: 44rpx;
 						}
 					}
 				}
@@ -520,7 +522,7 @@
 			}
 
 			.my-order {
-				padding: 50upx 20upx 0;
+				padding: 40rpx 24rpx 0;
 
 				.inner {
 					box-sizing: border-box;
@@ -528,7 +530,7 @@
 					// height: 105upx;
 					background: #FFFFFF;
 					border-radius: 16upx;
-					padding: 30rpx 24rpx 10rpx;
+					padding: 30rpx 24rpx 0rpx;
 					display: flex;
 					flex-direction: column;
 					justify-content: space-between;
@@ -551,12 +553,12 @@
 							align-items: center;
 
 							.text {
-								font-size: 32rpx;
-								font-family: PingFang SC;
+								font-family: PingFangSC, PingFang SC;
 								font-weight: 400;
-								color: #999999;
-								line-height: 1;
-								margin-right: 8upx;
+								font-size: 32rpx;
+								color: rgba(0,0,0,0.65);
+								line-height: 44rpx;
+								margin-right: 12px;
 							}
 
 							image {
@@ -589,15 +591,15 @@
 							image {
 								width: 60rpx;
 								height: 60rpx;
-								margin-bottom: 18upx;
+								margin-bottom: 10rpx;
 							}
 
 							.text {
 								font-family: PingFangSC, PingFang SC;
 								font-weight: 400;
 								font-size: 36rpx;
-								color: #111111;
-								line-height: 1;
+								color: rgba(0,0,0,0.85);
+								line-height: 50rpx;
 							}
 						}
 					}
@@ -608,8 +610,8 @@
 	}
 
 	.content {
-		margin-top: 30upx;
-		padding: 0 20upx;
+		margin-top: 30rpx;
+		padding: 0 24rpx;
 		display: flex;
 		align-items: center;
 		justify-content: center;
@@ -631,19 +633,20 @@
 
 			.tools-list {
 				margin-top: 40rpx;
+				margin-bottom: 40rpx;
 				display: flex;
 				flex-wrap: wrap;
 				width: 100%;
-
+                box-sizing: border-box;
+                   gap: 40rpx 26rpx;
 				.item {
 					box-sizing: border-box;
-					width: 25%;
-					display: flex;
-					flex-direction: column;
-					align-items: center;
-					justify-content: center;
-					margin-bottom: 40rpx;
-					position: relative;
+					  width: calc((100% - 3*26rpx) / 4);  /* 就写 25%,什么都不用减 */
+					  display: flex;
+					  flex-direction: column;
+					  align-items: center;
+					  justify-content: center;
+					  position: relative;
 
 					image {
 						width: 50rpx;
@@ -653,8 +656,8 @@
 					.text {
 						font-family: PingFangSC, PingFang SC;
 						font-weight: 400;
-						font-size: 32rpx;
-						color: #111111;
+						font-size: 36rpx;
+						color: rgba(0,0,0,0.85);
 						line-height: 50rpx;
 						margin-top: 8rpx;
 					}
@@ -673,19 +676,6 @@
 		}
 	}
 
-	.log-out {
-		height: 80upx;
-		line-height: 80upx;
-		text-align: center;
-		font-family: PingFangSC, PingFang SC;
-		font-weight: 400;
-		font-size: 36rpx;
-		color: #666666;
-		background: #FFFFFF;
-		border-radius: 16upx;
-		margin-top: 20upx;
-	}
-
 	.sub-btn {
 		position: absolute;
 		width: 100%;
@@ -720,9 +710,15 @@
 	}
 
 	.log-out {
-		height: 100rpx;
-		line-height: 100rpx;
-		margin: 10px;
-		border-radius: 20rpx;
+		height: 110rpx;
+		line-height: 110rpx;
+		text-align: center;
+		font-family: PingFangSC, PingFang SC;
+		font-weight: 400;
+		font-size: 36rpx;
+		color: rgba(0,0,0,0.65);
+		background: #FFFFFF;
+		margin: 30rpx 24rpx 40rpx;
+		border-radius: 24rpx;
 	}
 </style>

+ 1185 - 0
pages_index/courseDetail.vue

@@ -0,0 +1,1185 @@
+<template>
+	<view class="page">
+		<view class="video-wrap">
+			<video
+				:key="activeIndex"
+				@timeupdate="onTimeUpdate"
+				@progress="progressChange"
+				@error="videoErrorCallback"
+				@play="getPlay"
+				@pause="getPause"
+				@ended="getEnded"
+				@fullscreenchange="fullscreenchange"
+				:title="courseInfo.title"
+				style="width: 100%;height: 420rpx;"
+				:poster="poster"
+				id="video-content-box"
+				controls
+				:autoplay="true"
+				:auto-pause-if-open-native="true"
+				:auto-pause-if-navigate="true"
+				:enable-progress-gesture="false"
+				:show-progress="true"
+				:picture-in-picture-mode="[]"
+				:show-background-playback-button="false"
+				:src="videoUrl"
+			>
+			<cover-view class="back-box" :style="{'top':statusBarHeight}" @click="goBack()">
+			   <cover-image src="@/static/images/return_black.png" style="width: 24px;height: 24px;"></cover-image>
+			</cover-view>
+			</video>
+		</view>
+
+		<scroll-view class="page-scroll" scroll-y>
+			<view class="content">
+				<view class="course-title">{{ courseInfo.title }}</view>
+				<view class="course-desc">{{ courseInfo.desc }}</view>
+				<view class="course-views">{{ courseInfo.views }}次播放</view>
+			</view>
+
+			<view class="section-head">
+				<view class="left">
+					<view class="dot"></view>
+					<text class="section-title">课程目录</text>
+				</view>
+				<text class="count" @click="showCatalog = true">共{{ catalogList.length }}节 &#8250;</text>
+			</view>
+
+			<scroll-view class="catalog-scroll" scroll-x>
+				<view class="catalog-row">
+					<view
+						v-for="(item, index) in catalogList"
+						:key="item.id"
+						class="catalog-item"
+						:class="{ active: activeIndex === index }"
+						@click="selectCourse(index)"
+					>
+						<view class="catalog-top">
+							<view class="catalog-index-wrap">
+								<text class="catalog-index">第{{ index + 1 }}讲</text>
+								<view class="catalog-active-dot" v-if="activeIndex === index"></view>
+							</view>
+							<text class="free-tag" v-if="item.free">限时免费</text>
+						</view>
+						<view class="catalog-name ellipsis2">{{ item.name }}</view>
+					</view>
+				</view>
+			</scroll-view>
+
+			<view class="comment-wrap">
+				<view class="comment-title">评论</view>
+				<view class="comment-item" v-for="item in comments" :key="item.id">
+					<image class="avatar" :src="item.avatar" mode="aspectFill"></image>
+					<view class="comment-main">
+						<view class="name">{{ item.name }}</view>
+						<view class="time">{{ item.time }}</view>
+						<view class="text">{{ item.content }}</view>
+					</view>
+				</view>
+			</view>
+			<view class="bottom-space"></view>
+		</scroll-view>
+		
+		<view class="answer-entry" @click="openAnswerPopup">
+			<image class="gift-icon" src="@/static/images/new/jpk.png" mode="aspectFit"></image>
+			<view class="answer-tip" :class="{ done: hasAward }">{{ answerEntryTip }}</view>
+			<view class="answer-btn">答题</view>
+		</view>
+
+		<view class="bottom-bar">
+			<view class="input">发表我的态度</view>
+			<view class="send-btn">发送</view>
+			<view class="share-btn" @click="handleShare">
+				<text class="share-icon">&#x2197;</text>
+				<text>分享</text>
+			</view>
+		</view>
+		
+		<view class="answer-mask" v-if="showAnswerPopup" @click="closeAnswerPopup">
+			<view class="answer-panel" @click.stop>
+				<view class="answer-head">
+					<view class="left">
+						<view class="dot"></view>
+						<text class="section-title">问答题</text>
+					</view>
+					<view class="close-btn" @click="closeAnswerPopup">&#10005;</view>
+				</view>
+				<view class="answer-divider"></view>
+				<view class="question-title">{{ answerQuestion.title }}</view>
+				<view
+					v-for="(option, index) in answerQuestion.options"
+					:key="option.value"
+					class="answer-option"
+					:class="{ active: selectedAnswer === option.value, disabled: !canAnswer }"
+					@click="selectAnswer(option.value)"
+				>
+					{{ option.label }}
+				</view>
+				<view
+					class="submit-btn"
+					:class="{ active: canAnswer && selectedAnswer, disabled: !canAnswer || !selectedAnswer }"
+					@click="submitAnswer"
+				>
+					{{ canAnswer ? "提交答案" : ("再观看" + answerCountdownText + "可答题") }}
+				</view>
+			</view>
+		</view>
+		
+		<view class="answer-result-mask" v-if="showAnswerResultPopup" @click="closeAnswerResultPopup">
+			<view class="answer-result-panel" @click.stop>
+				<view class="result-title">{{ resultConfig.title }}</view>
+				<view class="result-subtitle" v-if="answerResultType === 'success'">
+					获得<text class="result-score">{{ awardScore }}</text>积分,自动到账
+				</view>
+				<view class="result-subtitle" v-else>{{ resultConfig.subtitle }}</view>
+				<view class="result-chance">{{ resultConfig.chanceText }}</view>
+				<view class="result-primary-btn" v-if="resultConfig.showPrimary" @click="goToIntegralMall">
+					前往积分商城兑换
+				</view>
+				<view class="result-second-btn" @click="closeAnswerResultPopup">继续观看</view>
+			</view>
+			<view class="result-close" @click.stop="closeAnswerResultPopup">&#10005;</view>
+		</view>
+
+		<view class="share-mask" v-if="showSharePopup" @click="closeSharePopup">
+			<view class="share-panel" @click.stop>
+				<view class="share-card">
+					<view class="share-item" @click="onShareSelect('wechat')">
+						<view class="share-avatar wechat">&#xe607;</view>
+						<text class="share-text">分享给微信好友</text>
+					</view>
+					<view class="share-item" @click="onShareSelect('moments')">
+						<view class="share-avatar moments"></view>
+						<text class="share-text">分享到朋友圈</text>
+					</view>
+				</view>
+				<view class="cancel-btn" @click="closeSharePopup">取消</view>
+			</view>
+		</view>
+
+		<view class="popup-mask" v-if="showCatalog" @click="showCatalog = false">
+			<view class="popup-panel" @click.stop>
+				<view class="popup-head">
+					<view class="left">
+						<view class="dot"></view>
+						<text class="section-title">课程目录</text>
+					</view>
+					<view class="close-btn" @click="showCatalog = false">&#10005;</view>
+				</view>
+				<scroll-view class="popup-scroll" scroll-y>
+					<view
+						v-for="(item, index) in catalogList"
+						:key="item.id"
+						class="popup-item"
+						:class="{ active: activeIndex === index }"
+						@click="selectCourse(index)"
+					>
+						<view class="catalog-top">
+							<text class="catalog-index">第{{ index + 1 }}讲</text>
+							<text class="free-tag" v-if="item.free">限时免费</text>
+						</view>
+						<view class="popup-name">{{ item.name }}</view>
+					</view>
+				</scroll-view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	computed: {
+		poster() {
+			const item = this.catalogList[this.activeIndex];
+			return (item && item.poster) || this.courseInfo.cover;
+		},
+		canAnswer() {
+			return this.answerCountdown <= 0;
+		},
+		answerCountdownText() {
+			const second = this.answerCountdown < 0 ? 0 : this.answerCountdown;
+			const minuteNum = Math.floor(second / 60);
+			const secondNum = second % 60;
+			if (minuteNum > 0) {
+				return minuteNum + "分" + secondNum + "秒";
+			}
+			return secondNum + "秒";
+		},
+		answerEntryTip() {
+			if (this.hasAward) {
+				return "已得" + this.awardScore + "积分";
+			}
+			if (this.attemptsLeft <= 0) {
+				return "未答对 明天再来";
+			}
+			if (!this.canAnswer) {
+				return "再观看" + this.answerCountdownText + "可答题得奖励";
+			}
+			return "答题得奖励";
+		},
+		resultConfig() {
+			const configMap = {
+				success: {
+					title: "恭喜你,回答正确",
+					subtitle: "",
+					chanceText: "每节课拥有" + this.maxAttempts + "次答题机会",
+					showPrimary: true
+				},
+				fail: {
+					title: "很遗憾答错了",
+					subtitle: "请继续努力哦",
+					chanceText: "每节课拥有" + this.maxAttempts + "次答题机会",
+					showPrimary: false
+				},
+				exhausted: {
+					title: "今天答题次数已用完",
+					subtitle: "明天再来哦",
+					chanceText: "每节课拥有" + this.maxAttempts + "次答题机会",
+					showPrimary: false
+				}
+			};
+			return configMap[this.answerResultType];
+		}
+	},
+	data() {
+		return {
+			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
+			isShu: false,
+			isFull: false,
+			videoUrl: "http://bjzmkytcpv.ylrzcloud.com/course/202647/1775560007686.mp4",
+			videoContext: null,
+			playTime: 0,
+			videoDuration: 0,
+			bufferRate: 0,
+			errorCount: 0,
+			showCatalog: false,
+			showSharePopup: false,
+			showAnswerPopup: false,
+			showAnswerResultPopup: false,
+			activeIndex: 0,
+			answerTimer: null,
+			answerCountdown: 90,
+			selectedAnswer: "",
+			answerResultType: "success",
+			maxAttempts: 3,
+			attemptsLeft: 3,
+			correctAnswer: "C",
+			awardScore: 20,
+			hasAward: false,
+			answerQuestion: {
+				title: "1.《大美国医》药王级鹿茸粉单选特价供应货源还剩下不足多少盒?",
+				options: [
+					{ value: "A", label: "A.800 盒" },
+					{ value: "B", label: "B.1000 盒" },
+					{ value: "C", label: "C.1500 盒" },
+					{ value: "D", label: "D.5000 盒" }
+				]
+			},
+			courseInfo: {
+				title: "邹方斌讲《毛笔书法修心课》",
+				desc: "零基础名师教学零起步,邹方斌讲《毛笔书法修心课》在家也能轻松学书法。",
+				views: "4127946",
+				duration: "45:38",
+				cover: "https://picsum.photos/900/520"
+			},
+			catalogList: [
+				{ id: 1, name: "毛笔书法修心课》在家也能学", free: true },
+				{ id: 2, name: "毛笔书法修心课》在家也能轻松学", free: true },
+				{ id: 3, name: "毛笔书法修心课》在家也能轻松学", free: false },
+				{ id: 4, name: "书法艺术概论", free: true },
+				{ id: 5, name: "运笔的基础知识", free: true },
+				{ id: 6, name: "字形结构与章法", free: true }
+			],
+			comments: [
+				{
+					id: 1,
+					name: "app用户32781",
+					time: "今天08:38",
+					content: "讲的真好,循序渐进,让小白也很容易能入门学习!",
+					avatar: "https://picsum.photos/80/80?1"
+				},
+				{
+					id: 2,
+					name: "app用户32781",
+					time: "2026-02-10 12:37",
+					content: "讲的通俗易懂,很好!",
+					avatar: "https://picsum.photos/80/80?2"
+				},
+				{
+					id: 3,
+					name: "app用户32781",
+					time: "2026-02-10 12:37",
+					content: "赞赞赞,我要好好学!",
+					avatar: "https://picsum.photos/80/80?3"
+				}
+			]
+		};
+	},
+	onLoad() {
+		this.initLessonVideo();
+		this.startAnswerCountdown();
+	},
+	onReady() {
+		this.$nextTick(() => {
+			this.videoContext = uni.createVideoContext("video-content-box", this);
+			this.tryPlayVideo();
+		});
+	},
+	onUnload() {
+		this.clearAnswerTimer();
+	},
+	methods: {
+		/** 进入页或切课后尝试自动播放(部分端需与 autoplay 配合) */
+		tryPlayVideo() {
+			if (!this.videoContext) {
+				this.videoContext = uni.createVideoContext("video-content-box", this);
+			}
+			const ctx = this.videoContext;
+			if (!ctx || !ctx.play) {
+				return;
+			}
+			this.$nextTick(() => {
+				setTimeout(() => {
+					try {
+						ctx.play();
+					} catch (e) {
+						console.warn("tryPlayVideo", e);
+					}
+				}, 100);
+			});
+		},
+		initLessonVideo() {
+			const item = this.catalogList[this.activeIndex];
+		},
+		onTimeUpdate(e) {
+			const d = (e && e.detail) || {};
+			this.playTime = Math.floor(d.currentTime || 0);
+			if (d.duration) {
+				this.videoDuration = d.duration;
+			}
+		},
+		progressChange(e) {
+			const d = (e && e.detail) || {};
+			if (d.buffered != null) {
+				this.bufferRate = d.buffered;
+			}
+		},
+		videoErrorCallback(e) {
+			this.errorCount += 1;
+			console.error("courseDetail video error", e);
+			if (this.errorCount > 3) {
+				return;
+			}
+			uni.showToast({
+				title: "视频加载失败,请稍后重试",
+				icon: "none"
+			});
+		},
+		getPlay() {
+			this.errorCount = 0;
+		},
+		getPause() {},
+		getEnded() {
+			if (this.videoDuration) {
+				this.playTime = Math.floor(this.videoDuration);
+			}
+		},
+		fullscreenchange(e) {
+			const d = (e && e.detail) || {};
+			this.isFull = !!d.fullScreen;
+		},
+		startAnswerCountdown() {
+			this.clearAnswerTimer();
+			this.answerTimer = setInterval(() => {
+				if (this.answerCountdown <= 0) {
+					this.clearAnswerTimer();
+					return;
+				}
+				this.answerCountdown -= 1;
+			}, 1000);
+		},
+		clearAnswerTimer() {
+			if (this.answerTimer) {
+				clearInterval(this.answerTimer);
+				this.answerTimer = null;
+			}
+		},
+		openAnswerPopup() {
+			if (this.attemptsLeft <= 0) {
+				this.answerResultType = "exhausted";
+				this.showAnswerResultPopup = true;
+				return;
+			}
+			this.showAnswerPopup = true;
+		},
+		closeAnswerPopup() {
+			this.showAnswerPopup = false;
+		},
+		closeAnswerResultPopup() {
+			this.showAnswerResultPopup = false;
+		},
+		selectAnswer(value) {
+			if (!this.canAnswer) {
+				return;
+			}
+			this.selectedAnswer = value;
+		},
+		submitAnswer() {
+			if (!this.canAnswer || !this.selectedAnswer) {
+				return;
+			}
+			this.attemptsLeft -= 1;
+			this.showAnswerPopup = false;
+			if (this.selectedAnswer === this.correctAnswer) {
+				this.answerResultType = "success";
+				this.hasAward = true;
+			} else if (this.attemptsLeft <= 0) {
+				this.answerResultType = "exhausted";
+			} else {
+				this.answerResultType = "fail";
+			}
+			this.showAnswerResultPopup = true;
+			this.selectedAnswer = "";
+		},
+		goToIntegralMall() {
+			this.showAnswerResultPopup = false;
+			uni.navigateTo({
+				url: "/pages_user/user/integralGoodsList"
+			});
+		},
+		goBack() {
+			uni.navigateBack({
+				delta: 1,
+				fail: () => {
+					uni.switchTab({
+						url: "/pages/home/index"
+					});
+				}
+			});
+		},
+		selectCourse(index) {
+			this.activeIndex = index;
+			this.showCatalog = false;
+			this.initLessonVideo();
+			this.$nextTick(() => {
+				this.videoContext = uni.createVideoContext("video-content-box", this);
+				this.tryPlayVideo();
+			});
+		},
+		handleShare() {
+			this.showSharePopup = true;
+		},
+		closeSharePopup() {
+			this.showSharePopup = false;
+		},
+		onShareSelect(type) {
+			this.showSharePopup = false;
+			const shareText = type === "wechat" ? "微信好友" : "朋友圈";
+			uni.showToast({
+				title: "分享至" + shareText + "待接入",
+				icon: "none"
+			});
+		}
+	}
+};
+</script>
+
+<style scoped lang="scss">
+.page {
+	background: #f6f6f6;
+	height: 100vh;
+}
+.back-box{
+	position: fixed;
+	left:12px;
+	z-index:9999
+}
+.page-scroll {
+	height: calc(100vh - 118rpx);
+	padding-top: 420rpx;
+	box-sizing: border-box;
+}
+
+.video-wrap {
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	z-index: 20;
+	width: 100%;
+	height: 420rpx;
+}
+
+.video-cover {
+	width: 100%;
+	height: 100%;
+}
+
+.video-mask {
+	position: absolute;
+	inset: 0;
+	background: rgba(0, 0, 0, 0.2);
+}
+
+.top-left {
+	position: absolute;
+	left: 24rpx;
+	top: 24rpx;
+	color: #fff;
+	font-size: 56rpx;
+	z-index: 2;
+}
+
+.top-right {
+	position: absolute;
+	right: 24rpx;
+	top: 24rpx;
+	display: flex;
+	gap: 12rpx;
+	z-index: 2;
+}
+
+.dot-btn {
+	min-width: 56rpx;
+	height: 56rpx;
+	padding: 0 18rpx;
+	border-radius: 28rpx;
+	background: rgba(0, 0, 0, 0.45);
+	color: #fff;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	font-size: 26rpx;
+}
+
+.video-control {
+	position: absolute;
+	bottom: 18rpx;
+	left: 24rpx;
+	right: 24rpx;
+	z-index: 2;
+	display: flex;
+	align-items: center;
+	color: #fff;
+	font-size: 24rpx;
+}
+
+.play-icon {
+	margin-right: 12rpx;
+	font-size: 28rpx;
+}
+
+.time-text {
+	min-width: 70rpx;
+}
+
+.progress-line {
+	flex: 1;
+	height: 4rpx;
+	margin: 0 14rpx;
+	background: rgba(255, 255, 255, 0.85);
+}
+
+.content {
+	background: #fff;
+	padding: 24rpx;
+}
+
+.course-title {
+	font-size: 42rpx;
+	font-weight: 600;
+	color: #222;
+	line-height: 58rpx;
+}
+
+.course-desc {
+	margin-top: 14rpx;
+	font-size: 32rpx;
+	color: #666;
+	line-height: 46rpx;
+}
+
+.course-views {
+	margin-top: 14rpx;
+	font-size: 34rpx;
+	color: #999;
+}
+
+.section-head {
+	margin-top: 14rpx;
+	padding: 18rpx 24rpx 14rpx;
+	background: #fff;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+}
+
+.left {
+	display: flex;
+	align-items: center;
+}
+
+.dot {
+	width: 20rpx;
+	height: 20rpx;
+	background: #f23b4d;
+	border-radius: 4rpx;
+	margin-right: 12rpx;
+}
+
+.section-title {
+	font-size: 38rpx;
+	font-weight: 600;
+	color: #222;
+}
+
+.count {
+	color: #9a9a9a;
+	font-size: 30rpx;
+}
+
+.catalog-scroll {
+	padding: 4rpx 24rpx 20rpx;
+	background: #fff;
+	white-space: nowrap;
+}
+
+.catalog-row {
+	display: inline-flex;
+	gap: 12rpx;
+}
+
+.catalog-item {
+	width: 280rpx;
+	min-height: 192rpx;
+	background: #FFF0F2;
+	border-radius: 20rpx;
+	background: #f2f3f6;
+	padding:24rpx;
+	box-sizing: border-box;
+	position: relative;
+}
+
+.catalog-item.active {
+	background: #ffeef1;
+	border-color: #ffd7de;
+}
+
+.catalog-top {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+}
+
+.catalog-index-wrap {
+	display: flex;
+	align-items: center;
+}
+
+.catalog-index {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 32rpx;
+	color: #FF233C;
+	line-height: 44rpx;
+}
+
+.catalog-active-dot {
+	width: 18rpx;
+	height: 18rpx;
+	margin-left: 8rpx;
+	border-radius: 50%;
+	background: #ff2b49;
+	position: relative;
+}
+
+.catalog-active-dot::after {
+	content: "";
+	position: absolute;
+	left: 5rpx;
+	top: 5rpx;
+	width: 8rpx;
+	height: 8rpx;
+	border-radius: 50%;
+	background: #fff;
+}
+
+.free-tag {
+	position: absolute;
+	right: 0;
+	top:0;
+	padding:2rpx 10rpx;
+	background: #ff2b49;
+	border-radius: 0rpx 20rpx 0rpx 20rpx;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 28rpx;
+	color: #FFFFFF;
+	line-height: 40rpx;
+}
+
+.catalog-name {
+	margin-top: 12rpx;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: rgba(0,0,0,0.65);
+	line-height: 44rpx;
+	white-space: normal;
+	word-break: break-all;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+}
+
+.comment-wrap {
+	margin-top: 14rpx;
+	background: #fff;
+	padding: 24rpx;
+}
+
+.comment-title {
+	font-size: 42rpx;
+	font-weight: 600;
+	color: #222;
+	margin-bottom: 16rpx;
+}
+
+.comment-item {
+	display: flex;
+	padding: 14rpx 0;
+}
+
+.avatar {
+	width: 72rpx;
+	height: 72rpx;
+	border-radius: 50%;
+	margin-right: 16rpx;
+}
+
+.comment-main {
+	flex: 1;
+}
+
+.name {
+	font-size: 36rpx;
+	color: #333;
+	font-weight: 600;
+}
+
+.time {
+	font-size: 30rpx;
+	color: #999;
+	margin-top: 2rpx;
+}
+
+.text {
+	font-size: 36rpx;
+	color: #333;
+	line-height: 48rpx;
+	margin-top: 8rpx;
+}
+
+.bottom-space {
+	height: 40rpx;
+}
+
+.answer-entry {
+	position: fixed;
+	right: 16rpx;
+	bottom: 210rpx;
+	z-index: 28;
+	width: 146rpx;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+}
+
+.gift-icon {
+	width: 128rpx;
+	height: 78rpx;
+	margin-bottom: -4rpx;
+}
+
+.answer-tip {
+	width: 146rpx;
+	background: #ffe08b;
+	border: 2rpx solid #f5cd62;
+	border-radius: 14rpx;
+	font-size: 34rpx;
+	line-height: 42rpx;
+	padding: 6rpx 10rpx;
+	color: #ff2b49;
+	text-align: center;
+	box-sizing: border-box;
+}
+
+.answer-tip.done {
+	border-color: #f2be3f;
+	color: #c53533;
+}
+
+.answer-btn {
+	margin-top: 8rpx;
+	width: 116rpx;
+	height: 62rpx;
+	border-radius: 32rpx;
+	background: #ff3b57;
+	color: #fff;
+	font-size: 38rpx;
+	font-weight: 600;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.bottom-bar {
+	position: fixed;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	height: 118rpx;
+	background: #fff;
+	border-top: 1rpx solid #eee;
+	display: flex;
+	align-items: center;
+	padding: 0 18rpx;
+	box-sizing: border-box;
+}
+
+.input {
+	flex: 1;
+	height: 70rpx;
+	background: #f3f3f3;
+	border-radius: 35rpx;
+	padding: 0 24rpx;
+	color: #bbb;
+	font-size: 30rpx;
+	display: flex;
+	align-items: center;
+}
+
+.send-btn {
+	margin-left: 14rpx;
+	width: 146rpx;
+	height: 70rpx;
+	background: #ff3b57;
+	border-radius: 35rpx;
+	color: #fff;
+	font-size: 34rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.share-btn {
+	width: 88rpx;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	font-size: 24rpx;
+	color: #222;
+}
+
+.share-icon {
+	color: #ff3b57;
+	font-size: 36rpx;
+	line-height: 1;
+}
+
+.share-mask {
+	position: fixed;
+	inset: 0;
+	background: rgba(0, 0, 0, 0.45);
+	z-index: 120;
+	display: flex;
+	align-items: flex-end;
+}
+
+.share-panel {
+	width: 100%;
+	padding: 20rpx 20rpx 28rpx;
+	box-sizing: border-box;
+}
+
+.share-card {
+	background: #fff;
+	border-radius: 20rpx;
+	overflow: hidden;
+}
+
+.share-item {
+	height: 106rpx;
+	padding: 0 28rpx;
+	display: flex;
+	align-items: center;
+	background: #fff;
+}
+
+.share-item + .share-item {
+	border-top: 1rpx solid #f0f0f0;
+}
+
+.share-avatar {
+	width: 52rpx;
+	height: 52rpx;
+	border-radius: 50%;
+	margin-right: 18rpx;
+	flex-shrink: 0;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	font-size: 26rpx;
+	color: #fff;
+}
+
+.wechat {
+	background: #1fc48a;
+}
+
+.moments {
+	background: conic-gradient(#f8c11b 0deg, #65ca59 130deg, #48b4f8 250deg, #f8c11b 360deg);
+}
+
+.share-text {
+	font-size: 36rpx;
+	color: #333;
+}
+
+.cancel-btn {
+	margin-top: 14rpx;
+	height: 94rpx;
+	background: #fff;
+	border-radius: 47rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	color: #333;
+	font-size: 38rpx;
+}
+
+.answer-mask {
+	position: fixed;
+	inset: 0;
+	background: rgba(0, 0, 0, 0.45);
+	display: flex;
+	align-items: flex-end;
+	z-index: 130;
+}
+
+.answer-panel {
+	width: 100%;
+	background: #fff;
+	border-radius: 24rpx 24rpx 0 0;
+	padding: 20rpx 22rpx 30rpx;
+	box-sizing: border-box;
+}
+
+.answer-head {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+}
+
+.answer-divider {
+	margin-top: 16rpx;
+	height: 1rpx;
+	background: #ededed;
+}
+
+.question-title {
+	margin-top: 18rpx;
+	font-size: 46rpx;
+	font-weight: 600;
+	color: #222;
+	line-height: 60rpx;
+}
+
+.answer-option {
+	margin-top: 18rpx;
+	background: #f3f4f7;
+	border-radius: 16rpx;
+	padding: 22rpx 24rpx;
+	font-size: 42rpx;
+	color: #333;
+	line-height: 48rpx;
+}
+
+.answer-option.active {
+	background: #ffedf0;
+	color: #ff2b49;
+	font-weight: 600;
+}
+
+.answer-option.disabled {
+	color: #4a4a4a;
+}
+
+.submit-btn {
+	margin: 48rpx auto 0;
+	width: 690rpx;
+	max-width: 100%;
+	height: 88rpx;
+	border-radius: 44rpx;
+	background: #c3c4c8;
+	color: #fff;
+	font-size: 40rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.submit-btn.active {
+	background: #ff3b57;
+}
+
+.submit-btn.disabled {
+	background: #c3c4c8;
+}
+
+.answer-result-mask {
+	position: fixed;
+	inset: 0;
+	background: rgba(0, 0, 0, 0.45);
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	z-index: 135;
+}
+
+.answer-result-panel {
+	width: 660rpx;
+	background: #fff;
+	border-radius: 28rpx;
+	padding: 34rpx 34rpx 26rpx;
+	box-sizing: border-box;
+	text-align: center;
+}
+
+.result-title {
+	font-size: 52rpx;
+	font-weight: 600;
+	color: #111;
+	line-height: 72rpx;
+}
+
+.result-subtitle {
+	margin-top: 24rpx;
+	font-size: 46rpx;
+	color: #333;
+	line-height: 62rpx;
+}
+
+.result-score {
+	color: #ff2b49;
+	font-size: 56rpx;
+	font-weight: 600;
+}
+
+.result-chance {
+	margin-top: 18rpx;
+	font-size: 38rpx;
+	color: #666;
+	line-height: 52rpx;
+}
+
+.result-primary-btn {
+	margin-top: 28rpx;
+	height: 84rpx;
+	border-radius: 42rpx;
+	background: #ff3b57;
+	color: #fff;
+	font-size: 40rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.result-second-btn {
+	margin-top: 22rpx;
+	height: 84rpx;
+	border-radius: 42rpx;
+	border: 2rpx solid #ff3b57;
+	color: #ff3b57;
+	font-size: 40rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.result-close {
+	margin-top: 16rpx;
+	width: 56rpx;
+	height: 56rpx;
+	border-radius: 50%;
+	border: 2rpx solid #fff;
+	color: #fff;
+	font-size: 34rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.popup-mask {
+	position: fixed;
+	inset: 0;
+	background: rgba(0, 0, 0, 0.45);
+	display: flex;
+	align-items: flex-end;
+	z-index: 99;
+}
+
+.popup-panel {
+	width: 100%;
+	height: 66vh;
+	background: #fff;
+	border-radius: 28rpx 28rpx 0 0;
+	padding: 24rpx;
+	box-sizing: border-box;
+}
+
+.popup-head {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+}
+
+.close-btn {
+	width: 54rpx;
+	height: 54rpx;
+	border-radius: 50%;
+	background: #f3f3f3;
+	color: #999;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	font-size: 28rpx;
+}
+
+.popup-scroll {
+	height: calc(66vh - 90rpx);
+	margin-top: 16rpx;
+}
+
+.popup-item {
+	background: #f5f5f5;
+	border-radius: 16rpx;
+	padding: 16rpx;
+	margin-bottom: 14rpx;
+}
+
+.popup-item.active {
+	background: #ffeef1;
+}
+
+.popup-name {
+	margin-top: 8rpx;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: rgba(0,0,0,0.65);
+	line-height: 44rpx;
+}
+</style>

+ 57 - 4
pages_user/user/integralGoodsList.vue

@@ -24,6 +24,12 @@
 							<image src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/exchange.png"></image>
 							兑换订单</view>
 					</view>
+					<view class="search-cont">
+						<view class="inner">
+							<image class="icon-search" src="@/static/images/icon-search.png" mode=""></image>
+							<input type="text" @confirm="goSearch"   :value="keyWord" placeholder="搜索商品" placeholder-style="font-size:28rpx;color:#BBBBBB;font-family: PingFang SC;" />
+						</view>
+					</view>
 				</view>
 				<!-- <view class="navbox">
 					<view class="navbox-item" @click="goCart()">
@@ -56,14 +62,14 @@
 					 :current="tabIndex"
 					 :scrollable="true"
 					 :list="tabs"  
-					 lineColor="#FF233C"
+					 lineColor="#F4F6F7"
 					 inactiveStyle="font-size: 40rpx;color: #222"
 					 activeStyle="font-size: 40rpx;font-weight:bold;color: #FF233C;"
 					@change="tabChange">
 					</u-tabs>
 				</view>
 			</view>
-			<mescroll-body :top="top+20+'px'" bottom="0"  ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption">
+			<mescroll-body top="710rpx" bottom="0"  ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption">
 			<view class="integral-box"  >
 				<view class="item"  @click="navTo('/pages_user/user/integralGoodsDetails?goodsId='+item.goodsId)" v-for="(item,index) in dataList">
 					<view class="top">
@@ -107,6 +113,7 @@
 			 	use:true,
 				auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback)
 			},
+			keyWord:'',
 			upOption: {
 				onScroll:false,
 				use: true, // 是否启用上拉加载; 默认true
@@ -122,7 +129,7 @@
 				}
 			},
 			dataList: [],
-			top: 156,
+			top: 0,
 			cartNum: 0,
 			statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
 			menuButtonLeft:0,
@@ -158,6 +165,10 @@
 			//console.log("------")
 		   uni.navigateBack();
 		},
+		goSearch(e) {
+			this.keyWord=e.detail.value;
+			this.mescroll.resetUpScroll();
+		},
 		getMenuButton(){
 			const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
 			this.menuButtonLeft = menuButtonInfo.left
@@ -291,7 +302,8 @@
 			var that = this;
 			var data = {
 				pageNum: page.num,
-				pageSize: page.size
+				pageSize: page.size,
+				keyword:this.keyWord
 			};
 			if(this.typeOptions&&this.typeOptions.length>0) {
 				this.type = this.tabIndex == 0 ? null : this.typeOptions[this.tabIndex-1].dictValue;
@@ -349,6 +361,7 @@
 		left: 0;
 		z-index: 9;
 	}
+	
 	.header-nav {
 		height: 88rpx;
 		display: flex;
@@ -426,6 +439,46 @@
 		z-index: 99;
 	}
 }
+.search-cont{
+	    width: 100%;
+		padding: 24rpx 0rpx 20rpx;
+		background-color: #F4F6F7;
+		display:flex;
+		align-items: center;
+		justify-content: space-between;
+		.inner{
+			box-sizing: border-box;
+			width: 100%;
+			height:76rpx;
+			background: #FFFFFF;
+			border-radius: 38rpx;
+			display: flex;
+			align-items: center;
+			//padding: 0 20rpx;
+			.icon-search{
+				width: 44rpx;
+				height: 44rpx;
+				margin-right: 12rpx;
+			}
+			input{
+				height:76rpx;
+				line-height: 76rpx;
+				font-size: 32rpx;
+				flex: 1;
+			}
+			
+		}
+		.icon-search{
+			margin-left: 20rpx;
+			width: 44rpx;
+			height: 44rpx;
+			image{
+				width: 44rpx;
+				height: 44rpx;
+			}
+			
+		}
+	}
 .content{
 	height: 100%;
 	.cont-box{

BIN
static/images/icon-search.png


BIN
static/images/right.png