Explorar o código

fix: 对接联调首页搜索页面(课程搜索)

wenxingxing hai 2 días
pai
achega
095afcd974
Modificáronse 3 ficheiros con 540 adicións e 522 borrados
  1. 5 0
      pages/index/course.vue
  2. 530 522
      pages/index/homePageSearch.vue
  3. 5 0
      pages/index/video.vue

+ 5 - 0
pages/index/course.vue

@@ -259,7 +259,12 @@ export default {
 				cateType: 1,
 				yxxTag: 0
 			};
+			uni.showLoading({
+				title: "加载中...",
+				mask: true,
+			})
 			const res = await courseTypeDataApi(params);
+			uni.hideLoading()
 			if (res.code === 200) {
 				this.categories = [...this.categories, ...res.data.list];
 			}

+ 530 - 522
pages/index/homePageSearch.vue

@@ -9,21 +9,13 @@
 					</image>
 					<input type="text" @confirm="goSearch" v-model="keywordValue" placeholder="请输入关键字搜索内容"
 						placeholder-style="font-size:28rpx;color:#BBBBBB;font-family: PingFang SC;" />
-					<u-icon v-if="keywordValue !=''" name="close-circle" color="#00000073" size="20"
+					<u-icon v-if="keywordValue != ''" name="close-circle" color="#00000073" size="20"
 						@tap="deleteKeywordMethods"></u-icon>
 				</view>
 				<view class="searchBtnViewClass" @tap="goSearch">搜索</view>
-				<!-- <view class="icon-search">
-					<image @click="showChange(2)" v-if="true"
-						src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/search1.png" mode="">
-					</image>
-					<image @click="showChange(1)" v-else
-						src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/search2.png" mode="">
-					</image>
-				</view> -->
 			</view>
-			<view class="nav-row">
-				<view class="nav-all" :class="{ active: activeId === 'all'}" @tap.stop="onSelectAll">
+			<view v-if="false" class="nav-row">
+				<view class="nav-all" :class="{ active: activeId === 'all' }" @tap.stop="onSelectAll">
 					<text>全部</text>
 				</view>
 				<scroll-view scroll-x class="nav-scroll" :show-scrollbar="false">
@@ -31,68 +23,70 @@
 						<view v-for="(item, index) in navList" :key="index"
 							:class="['nav-item', { active: item.id === activeId }]"
 							@tap.stop="onSelectByIndex(item.id)">
-							<text>{{ item.categoryName}}</text>
+							<text>{{ item.categoryName }}</text>
 						</view>
 					</view>
 				</scroll-view>
 			</view>
 		</view>
-		<!-- 最近学习 内容 -->
-		<scroll-view scroll-y class="scroll-wrap" :show-scrollbar="false">
-			<!-- 有学习记录:按日期分组列表 -->
-			<template v-if="courseList.length > 0">
-				<view class="course-grid">
+		<scroll-view scroll-y class="scroll-wrap" :show-scrollbar="false" :scroll-top="scrollTop"
+			@scrolltolower="isSearch ? getPageSearchCoursesData() : getPageRecommendCoursesData()">
+			<!-- 没有搜索词-推荐课程 -->
+			<template v-if="!isSearch">
+				<view style="height: 300rpx;width: 100%;"> </view>
+				<view class="recommend-section">
+					<text class="recommend-title">大家都在学习</text>
+					<view v-if="recommendList.length > 0" class="course-grid" style="padding: 0;">
+						<view v-for="(course, idx) in recommendList" :key="idx" class="course-card"
+							@click="onCourseClick(course)">
+							<view class="card-cover">
+								<image :src="course.imgUrl || '/static/logo.jpg'" mode="aspectFill" class="cover-img">
+								</image>
+							</view>
+							<view class="card-footer">
+								<text class="card-title">{{ course.courseName }}</text>
+								<view class="x-end" style="justify-content: space-between;">
+									<view class="course-meta">
+										<image src="@/static/images/new/renshu.png"></image>
+										<text class="meta-count">{{ course.watchUserCount }}</text>
+									</view>
+									<view class="btn-watch" @click.stop="onCourseClick(course)">立即观看</view>
+								</view>
+							</view>
+						</view>
+					</view>
+					<view v-else class="empty-state">
+						<image class="empty-icon" src="@/static/images/new/nodata.png"></image>
+						<text class="empty-text">暂无课程</text>
+					</view>
+				</view>
+
+			</template>
+			<!-- 搜索后的课程列表 内容 -->
+			<template v-else>
+				<view v-if="courseList.length > 0" class="course-grid">
 					<view v-for="(course, idx) in courseList" :key="idx" class="course-card"
 						@click="onCourseClick(course)">
 						<view class="card-cover">
-							<image :src="course.cover || '/static/logo.jpg'" mode="aspectFill" class="cover-img">
+							<image :src="course.imgUrl || '/static/logo.jpg'" mode="aspectFill" class="cover-img">
 							</image>
 						</view>
 						<view class="course-info">
-							<text class="card-title">{{ course.title }}</text>
+							<text class="card-title">{{ course.courseName }}</text>
 							<view class="x-end" style="justify-content: space-between;">
 								<view class="course-meta">
 									<image src="@/static/images/new/renshu.png"></image>
-									<text class="meta-count">{{ course.views }}</text>
+									<text class="meta-count">{{ course.watchUserCount }}</text>
 								</view>
 								<view class="btn-watch" @click.stop="onCourseClick(course)">立即观看</view>
 							</view>
 						</view>
-
 					</view>
 				</view>
-			</template>
-
-			<!-- 无学习记录:空态 + 为您精选 -->
-			<template v-else>
-				<view class="empty-state">
-					<!-- <view class="empty-icon"></view> -->
+				<view v-if="isSearch && courseList.length == 0" class="empty-state">
 					<image class="empty-icon" src="@/static/images/new/nodata.png"></image>
 					<text class="empty-text">没有搜索任何内容,换个词试试</text>
 				</view>
-				<view v-if="recommendList.length>0" class="recommend-section">
-					<text class="recommend-title">大家都在学习</text>
-					<view class="course-grid" style="padding: 0;">
-						<view v-for="(course, idx) in recommendList" :key="idx" class="course-card"
-							@click="onCourseClick(course)">
-							<view class="card-cover">
-								<image :src="course.cover || '/static/logo.jpg'" mode="aspectFill" class="cover-img">
-								</image>
-							</view>
-
-							<view class="card-footer">
-								<text class="card-title">{{ course.title }}</text>
-								<view class="x-end" style="justify-content: space-between;">
-									<view class="course-meta">
-										<image src="@/static/images/new/renshu.png"></image>
-										<text class="meta-count">{{ course.views }}</text>
-									</view>
-									<view class="btn-watch" @click.stop="onCourseClick(course)">立即观看</view>
-								</view>
-							</view>
-						</view>
-					</view>
-				</view>
 			</template>
 			<view class="bottom-placeholder"></view>
 		</scroll-view>
@@ -100,508 +94,522 @@
 </template>
 
 <script>
-	export default {
-		data() {
-			return {
-				keywordValue: '',
-				statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
-				activeId: 'all',
-				categoryExpand: true,
-				categoryIndex: 0,
-				categories: ['全部', '歌唱艺术', '太极养生', '防骗指南', '手机摄影', '棋牌益智', '用药指导', '膳食营养', '慢病管理'],
-				courseList: [{
-						title: '刘金的《0基础金曲演唱速练课》',
-						views: '9239',
-						cover: ''
-					},
-					{
-						title: '邹方斌讲《毛笔书法修心课》',
-						views: '10.8w',
-						cover: ''
-					},
-					{
-						title: '张斌《元气八段锦》系列课',
-						views: '2.5w',
-						cover: ''
-					},
-					{
-						title: '翔哥精讲摄影课—手机微距拍摄技巧...',
-						views: '100w+',
-						cover: ''
-					},
-					{
-						title: '道家智慧 入门21讲',
-						views: '1.2w',
-						cover: ''
-					},
-					{
-						title: '入门进阶必修 瑜伽呼吸全精讲',
-						views: '3.6w',
-						cover: ''
-					}
-				],
-				recentList: [{
-						date: '2026-02-08',
-						list: [{
-								title: '歌唱家刘金的《0基础金曲演唱速练课》',
-								progress: 87,
-								cover: ''
-							},
-							{
-								title: '资深编辑邹方斌讲《毛笔书法修心课》',
-								progress: 56,
-								cover: ''
-							}
-						]
-					},
-					{
-						date: '2026-02-01',
-						list: [{
-							title: '张斌《元气八段锦》系列课',
-							progress: 56,
-							cover: ''
-						}]
-					}
-				],
-				navList: [{
-						id: 37,
-						categoryName: "健康食品"
-					},
-					{
-						id: 35,
-						categoryName: "绿色有机"
-					},
-					{
-						id: 36,
-						categoryName: "膳食营养"
-					},
-					{
-						id: 33,
-						categoryName: "太极养生"
-					}
-				],
-				recommendList: [{
-						title: '刘金的《0基础金曲演唱速练课》',
-						views: '9239',
-						cover: ''
-					},
-					{
-						title: '邹方斌讲《毛笔书法修心课》',
-						views: '10.8w',
-						cover: ''
-					},
-					{
-						title: '张斌《元气八段锦》系列课',
-						views: '2.5w',
-						cover: ''
-					},
-					{
-						title: '翔哥精讲摄影课-手机微距拍摄技巧...',
-						views: '100w+',
-						cover: ''
-					}
-				]
-			}
-		},
-		onLoad() {
-			// 若无最近学习,可置空 recentList 显示空态
-			// this.recentList = [];
-		},
-		methods: {
-			deleteKeywordMethods() {
-				this.keywordValue = ''
-				this.goSearch()
+import {
+	courseListDataApi
+} from '@/api/home'
+export default {
+	data() {
+		return {
+			keywordValue: '',
+			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
+			activeId: 'all',
+			courseList: [],
+			isSearch: false,
+			scrollTop: 0,
+			searchPage: {
+				pageNum: 1,
+				pageSize: 10,
+				total: 0,
+			},
+			navList: [{
+				id: 37,
+				categoryName: "健康食品"
 			},
-			goSearch() {},
-			onSelectAll() {
-				this.activeId = 'all'
+			{
+				id: 35,
+				categoryName: "绿色有机"
 			},
-			onCourseClick(course) {
-				uni.showToast({
-					title: course.title || '立即观看',
-					icon: 'none'
-				})
-				// uni.navigateTo({ url: '/pages_course/videovip?id=' + (course.id || '') })
+			{
+				id: 36,
+				categoryName: "膳食营养"
 			},
-			onSelectByIndex(id) {
-				this.activeId = id
+			{
+				id: 33,
+				categoryName: "太极养生"
 			}
+			],
+			recommendList: [],
+			recommendPage: {
+				pageNum: 1,
+				pageSize: 10,
+				total: 0,
+			},
 		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	/* 图片箭头旋转类(展开时向上) */
-	.rotate-arrow {
-		transform: rotate(180deg);
-	}
-
-	.container {
-		min-height: 100vh;
-		background: #F5F5F5;
-		display: flex;
-		flex-direction: column;
-	}
-
-	/* 顶部 Tab */
-	.top-nav {
-		display: flex;
-		flex-direction: column;
-		background: #fff;
-		/* border-bottom: 1rpx solid #f0f0f0; */
-	}
-
-	.search-cont {
-		padding: 24rpx 24rpx 40rpx;
-		background-color: #FFFFFF;
-		display: flex;
-		align-items: center;
-		justify-content: space-between;
-
-		.inner {
-			box-sizing: border-box;
-			width: calc(100vw - 135rpx);
-			height: 72rpx;
-			background: #F7F7F7;
-			border-radius: 38rpx;
-			display: flex;
-			align-items: center;
-			padding: 0 20rpx;
-
-			.icon-search {
-				width: 28upx;
-				height: 28upx;
-				margin-right: 20upx;
+	},
+	onLoad() {
+		this.getRecommendData()
+	},
+	methods: {
+		deleteKeywordMethods() {
+			this.keywordValue = ''
+			this.isSearch = false
+			this.courseList = []
+			this.scrollTop = 0
+		},
+		goSearch() {
+			if (this.keywordValue == '') {
+				this.isSearch = false
+				this.searchPage.pageNum = 1;
+				this.searchPage.total = 0;
+				this.courseList = [];
+			} else {
+				this.resetSearchDataList()
 			}
+		},
+		onSelectAll() {
+			this.activeId = 'all'
+		},
+		onCourseClick(course) {
+			uni.navigateTo({
+				url: `/pages/course/info?courseId=${course.courseId}`
+			})
+		},
+		onSelectByIndex(id) {
+			this.activeId = id
+		},
 
-			input {
-				height: 65rpx;
-				line-height: 65rpx;
-				flex: 1;
-				font-size: 32rpx;
-				padding-right: 15rpx;
+		// 搜索课程列表
+		async searchCourseList() {
+			let params = {
+				pageNum: this.searchPage.pageNum,
+				pageSize: this.searchPage.pageSize,
+				keyword: this.keywordValue,
+			};
+			uni.showLoading({
+				title: "加载中...",
+				mask: true,
+			})
+			const res = await courseListDataApi(params);
+			this.isSearch = true
+			uni.hideLoading()
+			if (res.code === 200 && res.data.list.length > 0) {
+				this.searchPage.total = res.data.total;
+				this.courseList = [...this.courseList, ...res.data.list];
 			}
+		},
 
-		}
-
-		.searchBtnViewClass {
-			font-weight: 400;
-			font-size: 36rpx;
-			color: #222222;
-		}
-
-		.icon-search {
-			margin-left: 10upx;
-			width: 40upx;
-			height: 40upx;
-
-			image {
-				width: 40upx;
-				height: 40upx;
+		// 分页获取搜索课程列表
+		getPageSearchCoursesData() {
+			if (this.searchPage.total <= this.courseList.length) {
+				return;
 			}
+			this.searchPage.pageNum++;
+			this.searchCourseList();
+		},
 
-		}
-	}
-
-	.nav-row {
-		display: flex;
-		align-items: center;
-		padding: 0 24rpx 24rpx;
-		gap: 30rpx;
-	}
-
-	.nav-all {
-		flex-shrink: 0;
-		font-family: PingFangSC, PingFang SC;
-		font-weight: 400;
-		font-size: 40rpx;
-		color: rgba(0, 0, 0, 0.85);
-		line-height: 56rpx;
-	}
-
-	.nav-all.active {
-		color: #FF233C;
-		font-weight: 600;
-	}
-
-	.nav-scroll {
-		flex: 1;
-	}
-
-	.nav-inner {
-		display: inline-flex;
-		padding: 0;
-		gap: 30rpx;
-	}
-
-	.nav-item {
-		flex-shrink: 0;
-		font-family: PingFangSC, PingFang SC;
-		font-weight: 400;
-		font-size: 40rpx;
-		color: rgba(0, 0, 0, 0.85);
-		line-height: 56rpx;
-	}
-
-	.nav-item.active {
-		color: #FF233C;
-		font-weight: 600;
-	}
-
-	/* 滚动区 */
-	.scroll-wrap {
-		flex: 1;
-		height: 0;
-	}
-
-	/* 课程网格 */
-	.course-grid {
-		display: flex;
-		flex-wrap: wrap;
-		padding: 24rpx;
-		gap: 24rpx 20rpx;
-		flex-direction: column;
-	}
+		// 搜索课程列表重置方法
+		resetSearchDataList() {
+			this.searchPage.pageNum = 1;
+			this.searchPage.total = 0;
+			this.courseList = [];
+			this.scrollTop = 0;
+			this.searchCourseList();
+		},
 
-	.course-card {
-		display: flex;
-		background: #fff;
-		border-radius: 20rpx;
-		overflow: hidden;
-		padding: 20rpx;
-	}
+		// 获取推荐课程列表
+		async getRecommendData() {
+			let params = {
+				pageNum: this.recommendPage.pageNum,
+				pageSize: this.recommendPage.pageSize,
+			};
+			const res = await courseListDataApi(params);
+			if (res.code === 200 && res.data.list.length > 0) {
+				this.recommendPage.total = res.data.total;
+				this.recommendList = [...this.recommendList, ...res.data.list];
+			}
+		},
 
-	.course-tag {
-		position: absolute;
-		left: 0;
-		bottom: 0;
-		right: 0;
-		padding: 8rpx 12rpx;
-		background: linear-gradient(transparent, rgba(0, 0, 0, 0.6));
-		font-size: 22rpx;
-		color: #fff;
-	}
+		// 分页获取推荐课程列表
+		getPageRecommendCoursesData() {
+			if (this.recommendPage.total <= this.recommendList.length) {
+				return;
+			}
+			this.recommendPage.pageNum++;
+			this.getRecommendData();
+		},
 
-	.course-info {
-		flex: 1;
-		padding-left: 24rpx;
-		/* padding: 20rpx 24rpx; */
-		display: flex;
-		flex-direction: column;
-		justify-content: space-between;
-		min-width: 0;
+		// 推荐课程列表重置方法
+		resetRecommendDataList() {
+			this.recommendPage.pageNum = 1;
+			this.recommendPage.total = 0;
+			this.recommendList = [];
+			this.getRecommendData();
+		},
 	}
+}
+</script>
 
-	.course-meta {
+<style lang="scss" scoped>
+/* 图片箭头旋转类(展开时向上) */
+.rotate-arrow {
+	transform: rotate(180deg);
+}
+
+.container {
+	// min-height: 100vh;
+	background: #F5F5F5;
+	display: flex;
+	flex-direction: column;
+}
+
+/* 顶部 Tab */
+.top-nav {
+	display: flex;
+	flex-direction: column;
+	background: #fff;
+}
+
+.search-cont {
+	padding: 24rpx 24rpx 20rpx;
+	background-color: #FFFFFF;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+
+	.inner {
+		box-sizing: border-box;
+		width: calc(100vw - 135rpx);
+		height: 72rpx;
+		background: #F7F7F7;
+		border-radius: 38rpx;
 		display: flex;
 		align-items: center;
+		padding: 0 20rpx;
 
-		image {
-			width: 30rpx;
-			height: 30rpx;
+		.icon-search {
+			width: 28upx;
+			height: 28upx;
+			margin-right: 20upx;
 		}
 
-	}
-
-	.meta-icon {
-		font-size: 24rpx;
-		margin-right: 6rpx;
-		color: #999;
-	}
-
-	.meta-count {
-		margin-left: 10rpx;
-		font-family: PingFangSC, PingFang SC;
-		font-weight: 400;
-		font-size: 32rpx;
-		color: #666666;
-	}
-
-	.card-cover {
-		position: relative;
-		width: 296rpx;
-		height: 222rpx;
-		border-radius: 20rpx;
-		overflow: hidden;
-		flex-shrink: 0;
-	}
-
-	.cover-img {
-		width: 100%;
-		height: 100%;
-		background: #BB6D6D;
-	}
-
-	.card-title {
-		font-family: PingFangSC, PingFang SC;
-		font-weight: 600;
-		font-size: 36rpx;
-		color: #222222;
-		line-height: 50rpx;
-		text-align: justify;
-		overflow: hidden;
-		text-overflow: ellipsis;
-		display: -webkit-box;
-		-webkit-line-clamp: 2;
-		-webkit-box-orient: vertical;
-	}
+		input {
+			height: 65rpx;
+			line-height: 65rpx;
+			flex: 1;
+			font-size: 32rpx;
+			padding-right: 15rpx;
+		}
 
-	.card-footer {
-		flex: 1;
-		padding-left: 24rpx;
-		/* padding: 20rpx 24rpx; */
-		display: flex;
-		flex-direction: column;
-		justify-content: space-between;
-		min-width: 0;
 	}
 
-	.card-views {
-		font-family: PingFangSC, PingFang SC;
+	.searchBtnViewClass {
 		font-weight: 400;
-		font-size: 32rpx;
-		color: #666666;
-		line-height: 44rpx;
-	}
-
-	.btn-watch {
-		width: 168rpx;
-		height: 64rpx;
-		line-height: 64rpx;
-		text-align: center;
-		background: linear-gradient(135deg, #FF5267 0%, #FF233C 100%);
-		border-radius: 32rpx;
-		font-family: PingFangSC, PingFang SC;
-		font-weight: 600;
-		font-size: 32rpx;
-		color: #FFFFFF;
-	}
-
-	/* 最近学习 - 按日期分组 */
-	.recent-group {
-		padding: 24rpx 24rpx 0;
-	}
-
-	.group-date {
-		display: flex;
-		align-items: center;
-		margin-bottom: 24rpx;
-	}
-
-	.date-icon {
-		width: 32rpx;
-		height: 32rpx;
-		margin-right: 8rpx;
-	}
-
-	.date-text {
-		font-family: PingFangSC, PingFang SC;
-		font-weight: 600;
-		font-size: 40rpx;
-		line-height: 56rpx;
-		color: #222222;
-	}
-
-	.recent-card {
-		display: flex;
-		background: #fff;
-		border-radius: 20rpx;
-		overflow: hidden;
-		padding: 20rpx;
-		margin-bottom: 24rpx;
-	}
-
-	.recent-card:last-child {
-		margin-bottom: 0;
-	}
-
-	.recent-thumb {
-		position: relative;
-		width: 296rpx;
-		height: 222rpx;
-		border-radius: 20rpx;
-		overflow: hidden;
-		flex-shrink: 0;
-	}
-
-	.thumb-img {
-		width: 100%;
-		height: 100%;
-		background: #BB6D6D;
-	}
-
-	.recent-info {
-		flex: 1;
-		padding-left: 24rpx;
-		/* padding: 20rpx 24rpx; */
-		display: flex;
-		flex-direction: column;
-		justify-content: space-between;
-		min-width: 0;
-	}
-
-	.recent-title {
-		font-family: PingFangSC, PingFang SC;
-		font-weight: 600;
 		font-size: 36rpx;
 		color: #222222;
-		line-height: 50rpx;
-		text-align: justify;
-		overflow: hidden;
-		text-overflow: ellipsis;
-		display: -webkit-box;
-		-webkit-line-clamp: 2;
-		-webkit-box-orient: vertical;
-	}
-
-	.recent-progress {
-		font-family: PingFangSC, PingFang SC;
-		font-weight: 400;
-		font-size: 32rpx;
-		color: rgba(0, 0, 0, 0.65);
-		line-height: 44rpx;
-	}
-
-	/* 空态 */
-	.empty-state {
-		display: flex;
-		flex-direction: column;
-		align-items: center;
-		justify-content: center;
-		padding: 80rpx 0 48rpx;
-		/* background: linear-gradient(180deg, #fff5f5 0%, #fff 100%); */
-	}
-
-	.empty-icon {
-		width: 310rpx;
-		height: 260rpx;
-		margin-bottom: 30rpx;
 	}
 
-	.empty-text {
-		font-family: PingFangSC, PingFang SC;
-		font-weight: 400;
-		font-size: 36rpx;
-		color: rgba(0, 0, 0, 0.25);
-		line-height: 50rpx;
-	}
+	.icon-search {
+		margin-left: 10upx;
+		width: 40upx;
+		height: 40upx;
 
-	/* 为您精选 */
-	.recommend-section {
-		padding: 0 24rpx 32rpx;
-	}
-
-	.recommend-title {
-		display: block;
-		font-family: PingFangSC, PingFang SC;
-		font-weight: 600;
-		font-size: 40rpx;
-		color: #222222;
-		line-height: 56rpx;
-		padding-bottom: 24rpx;
-	}
+		image {
+			width: 40upx;
+			height: 40upx;
+		}
 
-	.bottom-placeholder {
-		height: 120rpx;
 	}
+}
+
+.nav-row {
+	display: flex;
+	align-items: center;
+	padding: 0 24rpx 24rpx;
+	gap: 30rpx;
+}
+
+.nav-all {
+	flex-shrink: 0;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 40rpx;
+	color: rgba(0, 0, 0, 0.85);
+	line-height: 56rpx;
+}
+
+.nav-all.active {
+	color: #FF233C;
+	font-weight: 600;
+}
+
+.nav-scroll {
+	flex: 1;
+}
+
+.nav-inner {
+	display: inline-flex;
+	padding: 0;
+	gap: 30rpx;
+}
+
+.nav-item {
+	flex-shrink: 0;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 40rpx;
+	color: rgba(0, 0, 0, 0.85);
+	line-height: 56rpx;
+}
+
+.nav-item.active {
+	color: #FF233C;
+	font-weight: 600;
+}
+
+/* 滚动区 */
+.scroll-wrap {
+	flex: 1;
+	height: 0;
+}
+
+/* 课程网格 */
+.course-grid {
+	display: flex;
+	flex-wrap: wrap;
+	padding: 24rpx;
+	gap: 24rpx 20rpx;
+	flex-direction: column;
+}
+
+.course-card {
+	display: flex;
+	background: #fff;
+	border-radius: 20rpx;
+	overflow: hidden;
+	padding: 20rpx;
+}
+
+.course-tag {
+	position: absolute;
+	left: 0;
+	bottom: 0;
+	right: 0;
+	padding: 8rpx 12rpx;
+	background: linear-gradient(transparent, rgba(0, 0, 0, 0.6));
+	font-size: 22rpx;
+	color: #fff;
+}
+
+.course-info {
+	flex: 1;
+	padding-left: 24rpx;
+	/* padding: 20rpx 24rpx; */
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	min-width: 0;
+}
+
+.course-meta {
+	display: flex;
+	align-items: center;
+
+	image {
+		width: 30rpx;
+		height: 30rpx;
+	}
+
+}
+
+.meta-icon {
+	font-size: 24rpx;
+	margin-right: 6rpx;
+	color: #999;
+}
+
+.meta-count {
+	margin-left: 10rpx;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: #666666;
+}
+
+.card-cover {
+	position: relative;
+	width: 296rpx;
+	height: 222rpx;
+	border-radius: 20rpx;
+	overflow: hidden;
+	flex-shrink: 0;
+}
+
+.cover-img {
+	width: 100%;
+	height: 100%;
+	background: #BB6D6D;
+}
+
+.card-title {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 36rpx;
+	color: #222222;
+	line-height: 50rpx;
+	text-align: justify;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+}
+
+.card-footer {
+	flex: 1;
+	padding-left: 24rpx;
+	/* padding: 20rpx 24rpx; */
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	min-width: 0;
+}
+
+.card-views {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: #666666;
+	line-height: 44rpx;
+}
+
+.btn-watch {
+	width: 168rpx;
+	height: 64rpx;
+	line-height: 60rpx;
+	text-align: center;
+	background: linear-gradient(135deg, #FF5267 0%, #FF233C 100%);
+	border-radius: 32rpx;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 32rpx;
+	color: #FFFFFF;
+}
+
+/* 最近学习 - 按日期分组 */
+.recent-group {
+	padding: 24rpx 24rpx 0;
+}
+
+.group-date {
+	display: flex;
+	align-items: center;
+	margin-bottom: 24rpx;
+}
+
+.date-icon {
+	width: 32rpx;
+	height: 32rpx;
+	margin-right: 8rpx;
+}
+
+.date-text {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 40rpx;
+	line-height: 56rpx;
+	color: #222222;
+}
+
+.recent-card {
+	display: flex;
+	background: #fff;
+	border-radius: 20rpx;
+	overflow: hidden;
+	padding: 20rpx;
+	margin-bottom: 24rpx;
+}
+
+.recent-card:last-child {
+	margin-bottom: 0;
+}
+
+.recent-thumb {
+	position: relative;
+	width: 296rpx;
+	height: 222rpx;
+	border-radius: 20rpx;
+	overflow: hidden;
+	flex-shrink: 0;
+}
+
+.thumb-img {
+	width: 100%;
+	height: 100%;
+	background: #BB6D6D;
+}
+
+.recent-info {
+	flex: 1;
+	padding-left: 24rpx;
+	/* padding: 20rpx 24rpx; */
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	min-width: 0;
+}
+
+.recent-title {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 36rpx;
+	color: #222222;
+	line-height: 50rpx;
+	text-align: justify;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+}
+
+.recent-progress {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: rgba(0, 0, 0, 0.65);
+	line-height: 44rpx;
+}
+
+/* 空态 */
+.empty-state {
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+	padding: 80rpx 0 48rpx;
+	/* background: linear-gradient(180deg, #fff5f5 0%, #fff 100%); */
+}
+
+.empty-icon {
+	width: 310rpx;
+	height: 260rpx;
+	margin-bottom: 30rpx;
+}
+
+.empty-text {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 36rpx;
+	color: rgba(0, 0, 0, 0.25);
+	line-height: 50rpx;
+}
+
+/* 为您精选 */
+.recommend-section {
+	padding: 0 24rpx 32rpx;
+}
+
+.recommend-title {
+	display: block;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 40rpx;
+	color: #222222;
+	line-height: 56rpx;
+	padding-bottom: 24rpx;
+}
+
+.bottom-placeholder {
+	height: 120rpx;
+}
 </style>

+ 5 - 0
pages/index/video.vue

@@ -256,7 +256,12 @@ export default {
 				cateType: 1,
 				yxxTag: 1
 			};
+			uni.showLoading({
+				title: "加载中...",
+				mask: true,
+			})
 			const res = await courseTypeDataApi(params);
+			uni.hideLoading()
 			if (res.code === 200) {
 				this.categories = [...this.categories, ...res.data.list];
 			}