Преглед изворни кода

Merge remote-tracking branch 'origin/2025鹅状元数学' into 2025鹅状元数学

wangxy пре 1 месец
родитељ
комит
f399737ffe
31 измењених фајлова са 414 додато и 417 уклоњено
  1. 23 11
      common/styles/global/components.scss
  2. 46 29
      common/styles/global/pages.scss
  3. 1 1
      components/custom-tabbar/custom-tabbar.vue
  4. 3 3
      components/dialog/nichengDialog.vue
  5. 1 1
      components/dialog/tipBigDialog.vue
  6. 1 1
      components/dialog/tipDialog.vue
  7. 3 3
      components/dialog/tipMiddleDialog.vue
  8. 3 3
      components/dialog/tipSmallDialog.vue
  9. 1 1
      components/question/danxuan.vue
  10. 1 1
      components/question/panduan.vue
  11. 1 1
      components/question/tiankong.vue
  12. 299 335
      pages/chanpinneirong/index.vue
  13. 31 27
      pages/xinshuxue/unitTest.vue
  14. BIN
      static/images/common/close-icon.png
  15. BIN
      static/images/common/ezy-common-bottom-bj.png
  16. BIN
      static/images/common/ezy-common-center-bj.png
  17. BIN
      static/images/common/ezy-common-top-bj.png
  18. BIN
      static/images/common/h-jt-icon.png
  19. BIN
      static/images/common/tip-big-bj.png
  20. BIN
      static/images/common/tip-cancel-btn.png
  21. BIN
      static/images/common/tip-confirm-btn.png
  22. BIN
      static/images/common/tip-middle-bj.png
  23. BIN
      static/images/common/tip-small-bj.png
  24. BIN
      static/images/exam/shiti-btn-blue-bj.png
  25. BIN
      static/images/exam/shiti-btn-orange-bj.png
  26. BIN
      static/images/exam/shiti-jj-btn.png
  27. BIN
      static/images/exam/shiti-title.png
  28. BIN
      static/images/my/my-page-bj.png
  29. BIN
      static/images/my/my-tel-bj.png
  30. BIN
      static/images/my/my-tel-btn.png
  31. BIN
      static/images/my/tk-dialog-bj.png

+ 23 - 11
common/styles/global/components.scss

@@ -118,17 +118,24 @@ $titleBar-tabBar-page: calc(100vh - var(--status-bar-height));
 	width: 24rpx;height: 38rpx;content: '';display: block;margin: 12rpx auto;
 	background-image: url("@/static/images/common/navBar-return-btn.png");@include ezy-no-repeat-cover();
 }
-/***** 试题---题干 *****/
+/***** 试题 *****/
+// 标题
+.ezy-shiti-title{
+	width: 216rpx;height: 96rpx;line-height: 96rpx;text-align: center;color: #fff;font-size: 32rpx;
+	background-image: url("@/static/images/exam/shiti-title.png");@include ezy-no-repeat-cover();
+}
+
+// 题干
 .ezy-shiti-question{
 	margin: 24rpx 0 42rpx;font-size: 32rpx;color: #333;line-height: 1.6;padding: 0 10rpx;box-sizing: border-box;
 	text-align: justify;word-wrap: break-word;word-break: break-all;display: block;@include ezy-rich-text;
 }
+
 /***** 单选题 *****/
 .ezy-danxuan-box{
 	margin: 0 10rpx;
 	.danxuan-title{
 		width: 231rpx;height: 63rpx;
-		background-image: url("@/static/images/exam/danxuan-title.png");@include ezy-no-repeat-cover();
 	}
 	.danxuan-option-box{
 		width: 100%;line-height:96rpx;border-radius: 8px;margin-bottom: 20rpx;
@@ -179,6 +186,7 @@ $titleBar-tabBar-page: calc(100vh - var(--status-bar-height));
 }
 /***** 填空题 *****/
 .ezy-tiankong-box{
+	margin: 0 10rpx;
 	.tiankongn-title{
 		width: 231rpx;height: 63rpx;
 		background-image: url("@/static/images/exam/tiankong-title.png");@include ezy-no-repeat-cover;
@@ -230,14 +238,11 @@ $titleBar-tabBar-page: calc(100vh - var(--status-bar-height));
 
 /***** 试题白色的框 *****/
 .shiti-frame-box{
-	flex: 1;width: 92%;height: auto;background-color: rgba(255, 255, 255, 0.6);border-radius: 10px;
-	margin: 12rpx auto 32rpx;position: relative;padding: 10% 0 6%;box-sizing: border-box;display: flex;flex-direction: column;
-}
-.shiti-frame-box::before{
-	content: "";display: block;background-color: rgba(255, 255, 255, 0.6);border-radius: 0 0 10rpx 10rpx;
-	position: absolute;top: 20rpx;left: 20rpx;right: 20rpx;bottom: 30rpx;z-index: 1;
+	width: 95%;height: auto;background-color: #fff;box-shadow: 0 0rpx 4rpx rgba(100, 159, 241, 0.2);
+	flex: 1;position: relative;display: flex;flex-direction: column;
+	border-radius: 16rpx;box-sizing: border-box;padding:32rpx 24rpx 24rpx;margin: 20rpx 2.5% 36rpx;
 }
-	
+
 /***** 模拟标题栏 *****/
 .ezy-title-bar {
 	height: calc(44px + env(safe-area-inset-top));
@@ -261,9 +266,10 @@ $titleBar-tabBar-page: calc(100vh - var(--status-bar-height));
 	  background-image: url("@/static/images/common/dialog-login-img.png");
 	 }
 	.tip-btn-box{
-		width: 100%;display: flex;justify-content: space-between;
+		width: 100%;display: flex;justify-content: space-between;margin: 52rpx 0 0;
 		.not-confirm-btn,.confirm-btn{
-			width: 208rpx;height: 83rpx;@include ezy-no-repeat-cover;margin: 30rpx 32rpx 0;
+			width: 248rpx;height: 92rpx;line-height: 92rpx;
+			color: #fff;@include ezy-no-repeat-cover;
 		}
 		.not-confirm-btn{background-image: url("@/static/images/common/tip-cancel-btn.png");}
 		.confirm-btn{background-image: url("@/static/images/common/tip-confirm-btn.png");}
@@ -274,6 +280,12 @@ $titleBar-tabBar-page: calc(100vh - var(--status-bar-height));
 		width: 625rpx;height: 365rpx;padding: 42rpx 48rpx;
 		background-image: url("@/static/images/common/tip-small-bj.png");
 	}
+	.tip-btn-box{
+		margin: 0;
+		.not-confirm-btn,.confirm-btn{
+			width: 220rpx;height: 82rpx;line-height: 82rpx;margin: 30rpx 20rpx 0;
+		}
+	}
 }
 .tip-middle-dialog{
 	.tip-content-box{

+ 46 - 29
common/styles/global/pages.scss

@@ -108,7 +108,7 @@
 
 // 用户协议弹窗
 .agree-sections-dialog{
-	width: 700rpx;height: 490rpx;padding: 90rpx 0 42rpx;box-sizing: border-box;text-align: center;margin-bottom: 26%;
+	width: 700rpx;height: 490rpx;padding: 80rpx 0 42rpx;box-sizing: border-box;text-align: center;margin-bottom: 26%;
 	background-image: url("@/static/images/login/agree-dialog-bg.png");@include ezy-no-repeat-cover;
 	.agree-title{color:#111;font-size: 40rpx;}
 	.agree-tip{color:#666;font-size: 30rpx;margin-top: 46rpx;}
@@ -687,11 +687,22 @@
 
 // 考试页
 .ezy-exam-page{
-	width: 100%;height: 100vh;background-color: #0ab2f0;position: relative;
-	padding-top:var(--status-bar-height);display: flex;flex-direction: column;
-	@include ezy-no-repeat-cover(top);
+	width: 100%;height: 100vh;background-color: #f9f9fb;position: relative;
+	display: flex;flex-direction: column;
+	.exam-body{
+		z-index: 1;position: relative;flex: 1;display: flex;flex-direction: column;
+	}
+	.xx-jd-box{
+		width: 95%;background-color: #fff;box-shadow: 0 0rpx 4rpx rgba(100, 159, 241, 0.2);
+		border-radius: 16rpx;box-sizing: border-box;padding:36rpx 36rpx 42rpx;margin: 20rpx auto 0;
+		.xx-row{display: flex;justify-content: space-between;align-items: center;margin-bottom: 24rpx;}
+		.text-row{color: #5d5e61;}
+		.dq-jd-text{color: #5693f5;font-size: 52rpx;}
+		.dq-jd-line{margin: 0 6rpx;}
+	}
+	.exam-progress-box{border-radius: 20rpx;overflow: hidden;}
 	.ezy-exam-swiper{
-		width: 615rpx;flex: 1;z-index: 2;margin: 0 auto;
+		width: 100%;flex: 1;z-index: 2;margin: 0 auto;
 		uni-swiper-item{overflow: auto;}
 	}
 	.exam-submit-btn{
@@ -701,11 +712,19 @@
 	.tip-mask-box{
 		width: 100%;height: 100vh;position: relative;position: absolute;top: 0;left: 0;z-index: 3;
 	}
-	.exam-tip-box{
-		width: 750rpx;height: 355.77rpx;@include ezy-no-repeat-cover;
-		background-image: url("@/static/images/exam/exam-tip-bj.png");
-		color: #036f6f;font-size: 32rpx;z-index: 3;padding: 180rpx 0 0 100rpx;
-		position: absolute;left: 0;right: 0;bottom: var(--window-bottom);
+	.swiper-tip-box{
+		font-size: 30rpx;color: #5989e2;justify-content: center;margin-top: 20rpx;
+		display: flex;flex-direction: row;align-items: center;
+	}
+	.swiper-tip-box::before,.swiper-tip-box::after{
+		content: '';width: 12rpx;height: 26rpx;display: block;
+		background-image: url("@/static/images/common/h-jt-icon.png");@include ezy-no-repeat-cover;
+	}
+	.swiper-tip-box::before{transform: rotate(180deg);margin-right: 32rpx;}
+	.swiper-tip-box::after{margin-left: 32rpx;}
+	.shiti-jj-btn{
+		width: 630rpx;height: 88rpx;@include ezy-no-repeat-cover;margin: 10rpx auto;
+		background-image: url("@/static/images/exam/shiti-jj-btn.png");
 	}
 }
 
@@ -1073,48 +1092,49 @@
 
 // 绑定手机号弹窗
 .my-tel-dialog{
-	background-color: rgba(255, 255, 255, 0.6);
+	background-color: rgba(0,0,0, 0.76);
 	position: fixed;display: flex;flex-direction: column;top: 0;left: 0;bottom:0;right: 0;
-	justify-content: center;align-items: center;
+	justify-content: center;align-items: center;z-index: 3;
 	.tel-close{width: 50rpx;height: 50rpx;@include ezy-no-repeat-cover;position: absolute;right: 30rpx;top: 30rpx;
 	background-image: url("@/static/images/common/close-icon.png");}
 	.my-tel-content{
-		width: 625rpx;height: 740rpx;box-sizing: border-box;padding: 100rpx 62rpx;
+		width: 625rpx;height: 740rpx;box-sizing: border-box;padding: 100rpx 42rpx;
 		background-image: url("@/static/images/my/my-tel-bj.png");@include ezy-no-repeat-cover;position: relative;
 
 	}
-	.my-tel-title{font-size: 40rpx;color: #333;text-align:center;margin-bottom: 24rpx;}
+	.my-tel-title{font-size: 40rpx;color: #333;text-align:center;margin-bottom: 32rpx;}
 	.tel-row{border-bottom: 1px dashed #70cbf4;}
-	.yzm-row{padding-top: 32rpx;}
+	.yzm-row{padding-top: 36rpx;}
 	/***** 输入手机号页面*****/
 	.my-input-box{
-		width:500rpx;height: 88rpx;box-sizing: border-box;
-		display: flex;align-items: center;
-		background-image: url("@/static/images/my/my-tel-input.png");@include ezy-no-repeat-cover;
-		.my-input {font-size: 32rpx;padding: 0 22rpx;box-sizing: border-box;color: #fff;flex: 1;}
-		.uni-input-placeholder {font-size: 25rpx;color: #ffffffd9;}
+		width:540rpx;height: 88rpx;line-height: 88rpx;box-sizing: border-box;
+		display: flex;align-items: center;border: 1rpx solid #e3e3e3;border-radius: 16rpx;
+		@include ezy-no-repeat-cover;
+		.my-input {font-size: 32rpx;padding: 0 22rpx;box-sizing: border-box;color: #666;flex: 1;}
+		.uni-input-placeholder {font-size: 32rpx;color: #ccc;}
 		.close-btn{width: 36rpx;height: 36rpx;margin-right: 30rpx;@include ezy-no-repeat-cover;
 		background-image: url("@/static/images/login/login-close-icon.png");flex-shrink: 0;}
 	}
 
-	.get-yzm-btn{color: #3b73bf;margin:24rpx 0 36rpx;font-size: 25rpx;}
+	.get-yzm-btn{color: #3b73bf;margin:46rpx 0 32rpx;font-size: 32rpx;}
 	.get-yzm-disabled{color: #666;}
 
 	.yzm-tip{color: #3b73bf;margin:0 0 24rpx;font-size: 25rpx;}
 
 	.my-bind-btn{
-		width:500rpx;height: 88rpx;text-align: center;line-height: 88rpx;color: #fff;margin-top: 24rpx;
+		width:540rpx;height: 92rpx;text-align: center;line-height: 92rpx;color: #fff;margin-top: 36rpx;
 		background-image: url("@/static/images/my/my-tel-btn.png");@include ezy-no-repeat-cover;
 	}
 }
 
 // 兑换码
 .duihuan-dialog{
+	.tip-content-box{padding: 42rpx 42rpx;}
 	.duihuan-input{
-		width:465rpx;height: 82rpx;box-sizing: border-box;padding: 0 18rpx;
-		display: flex;align-items: center;margin: 0 auto;
-		background-image: url("@/static/images/my/my-tel-input.png");@include ezy-no-repeat-cover;
-		.uni-input-placeholder {font-size: 25rpx;color: #ffffffd9;}
+		width:540rpx;height: 88rpx;line-height: 88rpx;box-sizing: border-box;
+		display: flex;align-items: center;margin: 0 auto;color: #666;
+		border: 1rpx solid #e3e3e3;border-radius: 16rpx;font-size: 32rpx;
+		.uni-input-placeholder {font-size: 32rpx;color: #ccc;}
 	}
 }
 
@@ -1853,9 +1873,6 @@
 			position: absolute;bottom: 12rpx;right: 12rpx;
 			
 		}
-		.item-play-btn:active{
-			transform: rotate(180deg);
-		}
 		.item-play-btn::before{
 			content: '';width: 46rpx;height: 48rpx;display: block;
 			background-image: url("@/static/images/xuanke/xbb-item-jt.png");@include ezy-no-repeat-cover;

+ 1 - 1
components/custom-tabbar/custom-tabbar.vue

@@ -52,7 +52,7 @@
 					{
 						iconPath: 'static/images/tabbar/unselect/wode-sj.png',
 						activePath: 'static/images/tabbar/select/wode-sj.png',
-						path: `/pages/my/index`
+						path: `/pages/chanpinMy/my`
 					},
 				],
 				currentTab: 0,

+ 3 - 3
components/dialog/nichengDialog.vue

@@ -1,14 +1,14 @@
 <!-- 小弹窗 一行文字 -->
 <template>
 	<uni-popup ref="tipSmallPopup" :animation="false" :is-mask-click="false"
-	 mask-background-color="rgba(255, 255, 255, 0.6);">
+	 mask-background-color="rgba(0,0,0, 0.76);">
 	 <view class="ezy-tip-dialog tip-small-dialog duihuan-dialog">
 		<view class="tip-content-box">
 			<view class="tip-title">{{title}}</view>
 				<input class="duihuan-input" type="text" focus v-model="nichengValue" placeholder="请输入昵称" />
 				<view class="tip-btn-box">
-					<view class="not-confirm-btn" @click="handleClose"></view>
-					<view class="confirm-btn" @click="confirmBtn"></view>
+					<view class="not-confirm-btn" @click="handleClose">取消</view>
+					<view class="confirm-btn" @click="confirmBtn">确认</view>
 				</view>
 		</view>
 	 </view>

+ 1 - 1
components/dialog/tipBigDialog.vue

@@ -1,7 +1,7 @@
 <!-- 大弹窗 三~四行文字 -->
 <template>
  <uni-popup ref="tipBigPopup" :animation="false" :is-mask-click="false"
-  mask-background-color="rgba(255, 255, 255, 0.6);">
+  mask-background-color="rgba(0,0,0, 0.76);">
   <view class="ezy-tip-dialog tip-big-dialog">
   <view class="tip-content-box">
    <view class="tip-title">{{title}}</view>

+ 1 - 1
components/dialog/tipDialog.vue

@@ -1,6 +1,6 @@
 <template>
 	<uni-popup ref="tipPopup" :animation="false" :is-mask-click="false"
-	 mask-background-color="rgba(0, 0, 0, 0.4)">
+	 mask-background-color="rgba(0,0,0, 0.76);">
 	 <view class="phone-tip-dialog">
 			<view class="common-body-box">
 				<view class="tip-title">{{title}}</view>

+ 3 - 3
components/dialog/tipMiddleDialog.vue

@@ -1,14 +1,14 @@
 <!-- 中弹窗 二行文字 -->
 <template>
 	<uni-popup ref="tipMiddlePopup" :animation="false" :is-mask-click="false"
-	 mask-background-color="rgba(255, 255, 255, 0.6);">
+	 mask-background-color="rgba(0,0,0, 0.76);">
 	 <view class="ezy-tip-dialog tip-middle-dialog">
 		<view class="tip-content-box">
 			<view class="tip-title">{{title}}</view>
 			<view class="tip-content">{{content}}</view>
 			<view class="tip-btn-box">
-				<view class="not-confirm-btn" @click="handleClose"></view>
-				<view class="confirm-btn" @click="confirmBtn"></view>
+				<view class="not-confirm-btn" @click="handleClose">取消</view>
+				<view class="confirm-btn" @click="confirmBtn">确认</view>
 			</view>
 		</view>
 	 </view>

+ 3 - 3
components/dialog/tipSmallDialog.vue

@@ -1,14 +1,14 @@
 <!-- 小弹窗 一行文字 -->
 <template>
 	<uni-popup ref="tipSmallPopup" :animation="false" :is-mask-click="false"
-	 mask-background-color="rgba(255, 255, 255, 0.6);">
+	 mask-background-color="rgba(0,0,0, 0.76);">
 	 <view class="ezy-tip-dialog tip-small-dialog">
 		<view class="tip-content-box">
 			<view class="tip-title">{{title}}</view>
 			<view class="tip-content">{{content}}</view>
 			<view class="tip-btn-box">
-				<view class="not-confirm-btn" @click="handleClose"></view>
-				<view class="confirm-btn" @click="confirmBtn"></view>
+				<view class="not-confirm-btn" @click="handleClose">取消</view>
+				<view class="confirm-btn" @click="confirmBtn">确认</view>
 			</view>
 		</view>
 	 </view>

+ 1 - 1
components/question/danxuan.vue

@@ -1,7 +1,7 @@
 <template>
 	<view v-if="question" class="ezy-danxuan-box">
 		<!-- 标题区域 -->
-		<view class="danxuan-title"></view>
+		<view class="ezy-shiti-title">单选题</view>
 		<!-- 题干区域 -->
 		<rich-text :nodes="data.name" class="ezy-shiti-question"></rich-text>
 		<!-- 选项区域 -->

+ 1 - 1
components/question/panduan.vue

@@ -1,7 +1,7 @@
 <template>
 	<view class="ezy-panduan-box">
 		<!-- 标题区域 -->
-		<view class="panduan-title"></view>
+		<view class="ezy-shiti-title">判断题</view>
 		<!-- 题干区域 -->
 		<rich-text :nodes="question.name" class="ezy-shiti-question"></rich-text>
 		<!-- 选项区域 -->

+ 1 - 1
components/question/tiankong.vue

@@ -1,7 +1,7 @@
 <template>
 	<view class="ezy-tiankong-box">
 		<!-- 标题区域 -->
-		<view class="tiankongn-title"></view>
+		<view class="ezy-shiti-title">填空题</view>
 		<!-- 显示填空后的文本 -->
 		<view class="ezy-shiti-question" v-html="formattedText" :question="question" :myflag="myflag"
 			:change:myflag="TK.updateFlag" :change:question="TK.watchQuestionChange"></view>

+ 299 - 335
pages/chanpinneirong/index.vue

@@ -1,243 +1,257 @@
 <template>
 	<view class="container">
-		<view @click="aaaa">asdfasdfdasfads</view>
-		<view class="icon-title-navBar-box">
-			<view class="nav-bar-icon" @click="handleBack"></view>
-			<view class="nav-bar-title">学习</view>
+		<!-- 当前单元标题(吸顶效果) -->
+		<view class="sticky-title" v-if="currentUnitName">
+			 {{ showStickyTitle ? currentUnitName : "学习" }}
 		</view>
-		<!-- z-paging 列表 -->
-		<z-paging ref="paging" @scroll="onScroll" @query="loadData" :refresher-enabled="false"
-			:loading-more-enabled="false" :auto="false" :fixed="false" :hide-empty-view="true">
 
+		<!-- 返回顶部按钮 -->
+		<view class="back-top" v-if="showBackTop" @click="scrollToTop">
+			<text>↑</text>
+		</view>
+
+		<scroll-view scroll-y class="scroll-view" :scroll-top="scrollTop" @scroll="onScroll">
+			<view class="subject-info" v-if="subjectDetail">
+				<text class="course-name">{{ subjectDetail.chanpinName }}</text>
+				<text class="course-name">等级:{{ subjectDetail.dengjiName }}</text>
+				<text class="course-name">版本:{{ subjectDetail.dengjiName }}</text>
+				<text class="course-name">单元:{{ subjectDetail.curDanyuanName }}</text>
+				<progress :percent="20" class="exam-progress-box" stroke-width="10" backgroundColor="#3c7dfd"
+					activeColor="#ffd11c" />
+				<text class="course-name">继续学习</text>
+			</view>
 			<!-- 单元列表 -->
-			<view v-for="(danyuan, danyuanIndex) in danyuanList" :key="danyuan.danyuanId"
-				:id="'danyuan-' + danyuanIndex" class="danyuan-item">
-				<!-- 当前学科信息 -->
-				<view class="subject-info" v-if="subjectDetail">
-					<text class="course-name">{{ subjectDetail.chanpinName }}</text>
-					<text class="course-name">等级:{{ subjectDetail.dengjiName }}</text>
-					<text class="course-name">版本:{{ subjectDetail.dengjiName }}</text>
-					<text class="course-name">单元:{{ subjectDetail.curDanyuanName }}</text>
-					<text class="course-name">课程:{{ subjectDetail.chanpinName }}</text>
-				</view>
+			<view v-for="(unit, index) in danyuanList" :key="unit.danyuanId" :id="'unit-' + index" class="unit-item">
 				<!-- 单元标题 -->
-				<view class="danyuan-header">
-					<text class="danyuan-title">{{ danyuan.danyuanName }}</text>
-					<text class="danyuan-intro">{{ danyuan.danyuanIntro }}</text>
+				<view class="unit-title">
+					<text class="unit-name">{{ unit.danyuanName }}</text>
+					<text class="unit-intro">{{ unit.danyuanIntro }}</text>
 				</view>
-
+				<text class="unit-name">{{ unit.danyuanName }}</text>
 				<!-- 节列表 -->
-				<view v-if="danyuan.jieList && danyuan.jieList.length > 0">
-					<view v-for="jie in danyuan.jieList" :key="jie.jieId" class="jie-item">
-						<text class="jie-name">{{ jie.number }}. {{ jie.jieName }}</text>
-						<text class="jie-desc">{{ jie.jieIntro }}</text>
+				<view v-for="section in unit.jieList" :key="section.jieId" class="section-item">
+					<view class="status" :class="section.wanchengFlag === 1 ? 'completed' : 'uncompleted'">
+						{{ section.wanchengFlag === 1 ? '已完成' : '未开始' }}
+					</view>
+					<view class="section-left">
+						<image class="section-cover" :src="section.cover" mode="aspectFill"></image>
+						<view class="section-info">
+							<text class="section-name">{{ section.jieName }}</text>
+							<text class="section-desc">{{ section.jieIntro }}</text>
+						</view>
+					</view>
+					<view class="section-right">
+						<text class="section-number">第{{ section.number }}节</text>
+						<text>播放按钮</text>
 					</view>
-				</view>
-
-				<!-- 无课程内容提示 -->
-				<view v-else class="empty-jie">
-					<text class="empty-text">暂无课程内容</text>
 				</view>
 			</view>
-		</z-paging>
 
-		<!-- 回到顶部按钮 -->
-		<view v-if="showBackToTop" class="back-to-top" @click="scrollToTop">
-			<text class="back-to-top-icon">↑</text>
-			<text class="back-to-top-text">顶部</text>
-		</view>
-
-		<!-- 当前单元提示 -->
-		<view v-if="currentUnitName" class="current-unit-tip">
-			<text>{{ currentUnitName }}</text>
-		</view>
-	
-		<CustomTabBar :currentTabNumber="0"></CustomTabBar>
-		
+			<!-- 底部占位 -->
+			<view style="height: 100px; text-align: center;">查看更多内容</view>
+		</scroll-view>
+		<CustomTabBar :currentTabNumber="1"></CustomTabBar>
 	</view>
 </template>
 
 <script>
+	import CustomTabBar from '@/components/custom-tabbar/custom-tabbar.vue';
 	import {
 		shuxueChanpinBanben
 	} from "@/api/chanpinneirong.js"
-	import CustomTabBar from '@/components/custom-tabbar/custom-tabbar.vue';
 	export default {
 		data() {
 			return {
-				activeSubjectId: 2,
-
-				// 学科详情数据
+				danyuanList: [],
+				currentUnitName: "",
 				subjectDetail: null,
+				showBackTop: false,
+				scrollTop: 0,
+				pageCacheKey: 'learn_page_scroll_cache',
+				hasRestoredScroll: false,
+				showStickyTitle: false
+			}
+		},
+		components: {
+			CustomTabBar
+		},
+		onShow() {
 
-				// 单元列表
-				danyuanList: [],
+			console.log('学习页面显示,尝试恢复滚动位置')
+			// 如果没有恢复过,从缓存恢复
+			if (!this.hasRestoredScroll) {
+				this.restoreScrollPosition()
+			}
+		},
 
-				// 当前单元名称
-				currentUnitName: '',
+		// 新增:页面隐藏时保存滚动位置
+		onHide() {
 
-				// 单元位置信息
-				unitPositions: [],
+			console.log('学习页面隐藏,保存滚动位置')
+			this.saveScrollPosition()
+		},
 
-				// 新增:是否显示回到顶部按钮
-				showBackToTop: false,
+		onLoad() {
 
-				// 新增:显示回到顶部按钮的阈值(滚动多少距离后显示)
-				backToTopThreshold: 500
-			}
+			this.loadDataFromApi()
 		},
-		components: {
-			CustomTabBar
-		},
-		mounted() {
-			//初始化加载数据
-			this.$nextTick(() => {
-			//	this.$refs.paging.reload()
-			})
+
+		onReady() {
+
+			// 页面渲染完成后执行
+			setTimeout(() => {
+				this.getUnitPositions();
+			}, 300);
 		},
 
 		methods: {
-			aaaa(){
-				this.$refs.paging.reload()
-			},
-			handleBack() {
 
-			},
-			// z-paging 加载数据
-			async loadData() {
-				// 目前只处理数学学科
-				if (this.activeSubjectId !== 2) {
-					this.$refs.paging.complete([])
-					return
+
+			loadDataFromApi() {
+				const req = {
+					banbenId: 7
 				}
+				shuxueChanpinBanben(req).then(res => {
+					this.subjectDetail = res.data
+					this.danyuanList = res.data.danyuanList || []
+					// 初始化当前单元
+					if (this.danyuanList.length > 0) {
+						this.currentUnitName = this.danyuanList[0].danyuanName
+					}
+				})
+			},
 
-				try {
-					// 调用数学API
-					const req = {
-						banbenId: 7
+			// 保存滚动位置到缓存
+			saveScrollPosition() {
+				if (this.scrollTop > 0) {
+					const scrollData = {
+						scrollTop: this.scrollTop,
+						currentUnit: this.currentUnitName,
+						timestamp: Date.now()
 					}
-					const res = await shuxueChanpinBanben(req)
+					uni.setStorageSync(this.pageCacheKey, scrollData)
+					console.log('保存滚动位置到缓存:', scrollData.scrollTop, '当前单元:', scrollData.currentUnit)
+				}
+			},
 
-					if (res.code === 0 && res.data) {
-						// 直接使用后端返回的数据
-						this.subjectDetail = res.data
-						this.danyuanList = res.data.danyuanList || []
+			// 从缓存恢复滚动位置
+			restoreScrollPosition() {
+				try {
+					const saved = uni.getStorageSync(this.pageCacheKey)
+					if (saved && saved.scrollTop > 0) {
+						this.showStickyTitle = true
+						// 延迟执行滚动
+						setTimeout(() => {
+							this.scrollTop = saved.scrollTop
+
+							// 恢复当前单元名称
+							if (saved.currentUnit) {
+								this.currentUnitName = saved.currentUnit
+							}
 
-						// 告诉z-paging加载完成
-						this.$refs.paging.complete(this.danyuanList)
+							this.hasRestoredScroll = true
 
-						// 计算单元位置
-						this.$nextTick(() => {
-							this.calculateUnitPositions()
-						})
+							// 再次延迟确保滚动生效
+							// setTimeout(() => {
+							// 	this.scrollTop = saved.scrollTop + 0.01
+							// }, 50)
+						}, 100)
+					} else {
+						this.showStickyTitle = false
 					}
-				} catch (error) {
-					console.error('加载失败:', error)
-					this.$refs.paging.complete(false)
+				} catch (e) {
+					console.error('读取缓存失败:', e)
 				}
 			},
-			// 计算单元位置
-			calculateUnitPositions() {
-				if (!this.danyuanList || this.danyuanList.length === 0) return
-				// 清空位置信息
-				this.unitPositions = []
-				// 使用 $nextTick 确保DOM已更新
-				this.$nextTick(() => {
-					// 稍微延迟确保渲染完成
-					setTimeout(() => {
-						const query = uni.createSelectorQuery().in(this)
-
-						// 一次性查询所有单元
-						const selectors = this.danyuanList.map((_, index) => {
-							return query.select(`#danyuan-${index}`).boundingClientRect()
-						})
-						// 执行查询
-						query.exec((results) => {
-							if (results && results.length === this.danyuanList.length) {
-								results.forEach((rect, index) => {
-									if (rect) {
-										// 保存相对位置(注意:这是相对于屏幕的位置)
-										this.$set(this.unitPositions, index, {
-											top: rect.top,
-											height: rect.height,
-											name: this.danyuanList[index]
-												.danyuanName
-										})
-									}
-								})
-								console.log('单元位置计算完成:', this.unitPositions)
-							}
-						})
-					}, 100)
-				})
+
+			// 获取每个单元的位置信息
+			getUnitPositions() {
+				const query = uni.createSelectorQuery().in(this);
+
+				this.danyuanList.forEach((unit, index) => {
+					query.select('#unit-' + index).boundingClientRect();
+				});
+
+				query.exec((res) => {
+					console.log('单元位置信息:', res);
+				});
 			},
-			// 滚动事件 - 修改后版本
-			onScroll(e) {
-				const scrollTop = e.detail.scrollTop
-				console.log('滚动位置:', scrollTop)
 
-				// 新增:控制回到顶部按钮的显示/隐藏
-				this.showBackToTop = scrollTop > this.backToTopThreshold
+			// 滚动事件处理
+			onScroll(e) {
+				const scrollTop = e.detail.scrollTop;
 
-				// 查找当前滚动到的单元
-				let currentUnitName = ''
+				// 更新滚动位置
+				this.scrollTop = scrollTop;
 
-				for (let i = this.unitPositions.length - 1; i >= 0; i--) {
-					const position = this.unitPositions[i]
-					if (position && scrollTop >= position.top - 50) {
-						currentUnitName = position.name
-						break
-					}
+				// 实时保存到缓存
+				const saveData = {
+					scrollTop: scrollTop,
+					currentUnit: this.currentUnitName,
+					timestamp: Date.now()
 				}
+				uni.setStorageSync(this.pageCacheKey, saveData)
 
-				// 更新当前单元提示
-				if (currentUnitName && currentUnitName !== this.currentUnitName) {
-					this.currentUnitName = currentUnitName
-					console.log('切换到单元:', currentUnitName)
-				}
+				// 显示/隐藏返回顶部按钮
+				this.showBackTop = scrollTop > 400;
+
+				// 监听滚动,更新当前显示的单元
+				this.updateCurrentUnit(scrollTop);
 			},
 
-			// 新增:回到顶部方法
-			scrollToTop() {
-				console.log('执行回到顶部')
-
-				// 方法1: 使用z-paging的scrollToTop方法(最简单)
-				if (this.$refs.paging) {
-					this.$refs.paging.scrollToTop({
-						animated: true,
-						duration: 300
-					})
-				}
+			// 更新当前显示的单元
+			updateCurrentUnit(scrollTop) {
 
-				// 方法2: 对于H5环境,额外滚动整个页面
-				// #ifdef H5
-				setTimeout(() => {
-					window.scrollTo({
-						top: 0,
-						behavior: 'smooth'
-					})
-				}, 100)
-				// #endif
-
-				// 方法3: 对于App环境,使用uni的pageScrollTo
-				// #ifdef APP-PLUS
-				uni.pageScrollTo({
-					scrollTop: 0,
-					duration: 300
-				})
-				// #endif
+				const query = uni.createSelectorQuery().in(this);
 
-				// 隐藏回到顶部按钮
-				this.showBackToTop = false
+				for (let i = 0; i < this.danyuanList.length; i++) {
+					query.select('#unit-' + i).boundingClientRect();
+				}
+				query.exec((res) => {
+					// 添加一个偏移量,让切换更平滑
+					const offset = 80;
+					for (let i = 0; i < res.length; i++) {
+						const rect = res[i];
+						if (rect) {
+							// 计算单元在页面中的实际位置(考虑滚动)
+							const unitTop = rect.top + scrollTop;
+							if (scrollTop + offset >= unitTop) {
+								if (i == res.length - 1 || scrollTop + offset < (res[i + 1].top + scrollTop)) {
+									// 每次滚动都设置吸顶标题显示状态
+									this.showStickyTitle = i >= 1
+
+									if (this.currentUnitName !== this.danyuanList[i].danyuanName) {
+										this.currentUnitName = this.danyuanList[i].danyuanName;
+
+										// 单元变化时立即保存
+										const saveData = {
+											scrollTop: this.scrollTop,
+											currentUnit: this.currentUnitName,
+											timestamp: Date.now()
+										}
+										uni.setStorageSync(this.pageCacheKey, saveData)
+									}
+									break;
+								}
+							}
+						}
+					}
+				});
+			},
 
-				// 可选:显示提示
-				uni.showToast({
-					title: '回到顶部',
-					icon: 'none',
-					duration: 800
-				})
+			// 返回顶部
+			scrollToTop() {
+				// 清除缓存
+				uni.removeStorageSync(this.pageCacheKey)
+				this.hasRestoredScroll = false
+				this.showStickyTitle = false
+				// 回到顶部
+				this.scrollTop = this.scrollTop + 1; // 先改变值触发重新渲染
+				this.$nextTick(() => {
+					this.scrollTop = 0;
+					this.currentUnitName = this.danyuanList[0].danyuanName;
+				});
 			}
-
 		}
 	}
 </script>
@@ -245,204 +259,154 @@
 <style scoped>
 	.container {
 		height: 100vh;
-		background-color: #f8f9fa;
+		background-color: #f5f5f5;
 	}
 
-	/* 学科标签页 */
-	.subject-tabs {
-		background-color: white;
-		padding: 20rpx 0;
-		border-bottom: 1rpx solid #eee;
-	}
-
-	.tabs-scroll {
-		white-space: nowrap;
-		height: 80rpx;
-	}
-
-	.tabs-content {
-		display: inline-flex;
-		padding: 0 30rpx;
+	/* 吸顶标题 */
+	.sticky-title {
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		z-index: 100;
+		background-color: #1890ff;
+		color: white;
+		padding: 12px 16px;
+		font-size: 16px;
+		font-weight: bold;
+		text-align: center;
+		box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
 	}
 
-	.tab-item {
-		padding: 0 40rpx;
-		height: 60rpx;
+	/* 返回顶部按钮 */
+	.back-top {
+		position: fixed;
+		right: 16px;
+		bottom: 100px;
+		z-index: 99;
+		width: 44px;
+		height: 44px;
+		background-color: #1890ff;
+		border-radius: 50%;
 		display: flex;
 		align-items: center;
 		justify-content: center;
+		color: white;
+		font-size: 20px;
+		box-shadow: 0 2px 8px rgba(24, 144, 255, 0.4);
 	}
 
-	.tab-text {
-		font-size: 32rpx;
-		color: #666;
-		position: relative;
-		padding: 10rpx 0;
-	}
-
-	.tab-item.active .tab-text {
-		color: #4a6fe3;
-		font-weight: bold;
-	}
-
-	.tab-item.active .tab-text::after {
-		content: '';
-		position: absolute;
-		bottom: 0;
-		left: 0;
-		right: 0;
-		height: 4rpx;
-		background-color: #4a6fe3;
-		border-radius: 2rpx;
-	}
-
-	/* 学科信息 */
-	.subject-info {
-		padding: 30rpx;
-		background-color: white;
-		margin-bottom: 20rpx;
-	}
-
-	.course-name {
-		display: block;
-		font-size: 36rpx;
-		font-weight: bold;
-		color: #333;
-		margin-bottom: 10rpx;
+	.back-top:active {
+		background-color: #096dd9;
+		transform: scale(0.95);
 	}
 
-	.current-info {
-		display: block;
-		font-size: 28rpx;
-		color: #666;
+	/* 滚动区域 */
+	.scroll-view {
+		height: 100%;
+		padding-top: 50px;
+		/* 给吸顶标题留出空间 */
+		box-sizing: border-box;
 	}
 
 	/* 单元样式 */
-	.danyuan-item {
-		background-color: white;
-		margin: 20rpx;
-		border-radius: 16rpx;
+	.unit-item {
+		margin: 12px;
+		background: white;
+		border-radius: 8px;
 		overflow: hidden;
-		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
-		margin-bottom: 30rpx;
+		box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
 	}
 
-	.danyuan-header {
-		background: #4a6fe3;
-		padding: 30rpx;
+	.unit-title {
+		padding: 16px;
+		background: linear-gradient(135deg, #1890ff, #36cfc9);
 		color: white;
 	}
 
-	.danyuan-title {
-		display: block;
-		font-size: 32rpx;
+	.unit-name {
+		font-size: 18px;
 		font-weight: bold;
-		margin-bottom: 10rpx;
+		display: block;
+		margin-bottom: 4px;
 	}
 
-	.danyuan-intro {
-		font-size: 28rpx;
+	.unit-intro {
+		font-size: 14px;
 		opacity: 0.9;
 	}
 
 	/* 节样式 */
-	.jie-item {
-		padding: 24rpx 30rpx;
-		border-bottom: 1rpx solid #f0f0f0;
+	.section-item {
+		padding: 12px 16px;
+		border-bottom: 1px solid #f0f0f0;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
 	}
 
-	.jie-item:last-child {
+	.section-item:last-child {
 		border-bottom: none;
 	}
 
-	.jie-name {
-		display: block;
-		font-size: 30rpx;
-		font-weight: 500;
-		color: #333;
-		margin-bottom: 8rpx;
+	.section-left {
+		display: flex;
+		align-items: center;
+		flex: 1;
 	}
 
-	.jie-desc {
-		display: block;
-		font-size: 26rpx;
-		color: #666;
+	.section-cover {
+		width: 60px;
+		height: 60px;
+		border-radius: 6px;
+		margin-right: 12px;
 	}
 
-	/* 空课程提示 */
-	.empty-jie {
-		padding: 40rpx;
-		text-align: center;
+	.section-info {
+		flex: 1;
 	}
 
-	.empty-text {
-		font-size: 28rpx;
-		color: #999;
+	.section-name {
+		font-size: 16px;
+		color: #333;
+		display: block;
+		margin-bottom: 4px;
+		font-weight: 500;
 	}
 
-	/* 新增:回到顶部按钮样式 */
-	.back-to-top {
-		position: fixed;
-		bottom: 120rpx;
-		right: 30rpx;
-		width: 100rpx;
-		height: 100rpx;
-		background-color: rgba(74, 111, 227, 0.9);
-		border-radius: 50%;
-		display: flex;
-		flex-direction: column;
-		align-items: center;
-		justify-content: center;
-		z-index: 999;
-		box-shadow: 0 4rpx 20rpx rgba(74, 111, 227, 0.3);
-		transition: all 0.3s ease;
+	.section-desc {
+		font-size: 13px;
+		color: #666;
 	}
 
-	.back-to-top:active {
-		transform: scale(0.95);
-		background-color: rgba(74, 111, 227, 1);
+	.section-right {
+		display: flex;
+		flex-direction: column;
+		align-items: flex-end;
+		margin-left: 12px;
 	}
 
-	.back-to-top-icon {
-		font-size: 40rpx;
-		color: white;
-		font-weight: bold;
+	.section-number {
+		font-size: 12px;
+		color: #999;
+		margin-bottom: 4px;
 	}
 
-	.back-to-top-text {
-		font-size: 22rpx;
-		color: white;
-		margin-top: 4rpx;
+	.status {
+		font-size: 12px;
+		padding: 2px 8px;
+		border-radius: 10px;
 	}
 
-	/* 当前单元提示 */
-	.current-unit-tip {
-		position: fixed;
-		top: 200rpx;
-		left: 50%;
-		transform: translateX(-50%);
-		background-color: rgba(74, 111, 227, 0.9);
-		color: white;
-		padding: 20rpx 40rpx;
-		border-radius: 50rpx;
-		font-size: 28rpx;
-		z-index: 1000;
-		box-shadow: 0 4rpx 20rpx rgba(74, 111, 227, 0.3);
-		animation: fadeInOut 3s ease-in-out;
+	.status.completed {
+		background-color: #f6ffed;
+		color: #52c41a;
+		border: 1px solid #b7eb8f;
 	}
 
-	@keyframes fadeInOut {
-
-		0%,
-		100% {
-			opacity: 0;
-			transform: translateX(-50%) translateY(-20rpx);
-		}
-
-		10%,
-		90% {
-			opacity: 1;
-			transform: translateX(-50%) translateY(0);
-		}
+	.status.uncompleted {
+		background-color: #fff7e6;
+		color: #fa8c16;
+		border: 1px solid #ffd591;
 	}
 </style>

+ 31 - 27
pages/xinshuxue/unitTest.vue

@@ -1,41 +1,45 @@
 <template>
 	<view class="ezy-exam-page">
-
 		<view class="icon-title-navBar-box">
 			<view @click="handleBack" class="nav-bar-icon"></view>
 			<text class="nav-bar-title">单元测试</text>
 		</view>
 
-		<view>
-			<view>
-				<view>当前学习进度</view>
-				<view>{{data.current+1}}/{{data.total}}</view>
+		<view class="exam-body">
+			<view class="xx-jd-box">
+				<view class="xx-row">
+					<view>当前学习进度</view>
+					<view class="text-row">
+						<text class="dq-jd-text">{{data.current+1}}</text>
+						<text class="dq-jd-line">/</text>{{data.total}}</view>
+				</view>
+				<progress :percent="(data.current+1)/data.total * 100" class="exam-progress-box"
+				stroke-width="10" backgroundColor="#3c7dfd" activeColor="#ffd11c"/>
+			</view>
+		
+
+			<view class="shiti-frame-box">
+				<w-swiper :list="data.list" :current="data.current" class="ezy-exam-swiper" @change="onSwiperChange">
+					<template v-slot:default="{item}">
+						<view class="body" v-if="item.mta_show">
+							<danxuan :question="item" v-if="item.type == '1'"></danxuan>
+							<panduan :question="item" v-if="item.type == '2'"></panduan>
+							<tiankong :question="item" v-if="item.type == '3'" :placeholders="item.placeholders"></tiankong>
+							<!-- 交卷按钮 -->
+							<view class="shiti-jj-btn" v-if="item.stId == data.list[data.total-1].stId"
+								@click="handleSubmit"></view>
+						</view>
+					</template>
+				</w-swiper>
+				<!--  左右滑动提示  -->
+				<view class="swiper-tip-box">
+					左右滑动查看更多题目
+				</view>
 			</view>
-			<progress :percent="data.current/data.total * 100" :border-radius="30" stroke-width="10" />
-		</view>
-
-		<view class="shiti-frame-box">
-			<w-swiper :list="data.list" :current="data.current" class="ezy-exam-swiper" @change="onSwiperChange">
-				<template v-slot:default="{item}">
-					<view class="body" v-if="item.mta_show">
-						<danxuan :question="item" v-if="item.type == '1'"></danxuan>
-						<panduan :question="item" v-if="item.type == '2'"></panduan>
-						<tiankong :question="item" v-if="item.type == '3'" :placeholders="item.placeholders"></tiankong>
-						<button type="primary" v-if="item.stId == data.list[data.total-1].stId"
-							@click="handleSubmit">交卷</button>
-					</view>
-				</template>
-			</w-swiper>
 		</view>
 
 
-
-		<!--  左右滑动提示  -->
-		<view>
-			<view>
-				< <text>左右滑动查看更多题目 1</text>>
-			</view>
-		</view>
+		
 
 		<!-- 填空 -->
 		<FillItem :value="result" ref="popupRef" @blur="onBlur"></FillItem>

BIN
static/images/common/close-icon.png


BIN
static/images/common/ezy-common-bottom-bj.png


BIN
static/images/common/ezy-common-center-bj.png


BIN
static/images/common/ezy-common-top-bj.png


BIN
static/images/common/h-jt-icon.png


BIN
static/images/common/tip-big-bj.png


BIN
static/images/common/tip-cancel-btn.png


BIN
static/images/common/tip-confirm-btn.png


BIN
static/images/common/tip-middle-bj.png


BIN
static/images/common/tip-small-bj.png


BIN
static/images/exam/shiti-btn-blue-bj.png


BIN
static/images/exam/shiti-btn-orange-bj.png


BIN
static/images/exam/shiti-jj-btn.png


BIN
static/images/exam/shiti-title.png


BIN
static/images/my/my-page-bj.png


BIN
static/images/my/my-tel-bj.png


BIN
static/images/my/my-tel-btn.png


BIN
static/images/my/tk-dialog-bj.png