Bladeren bron

feat: 添加数学启蒙模块,优化多处细节

1. 新增math页面与首页数学入口组件
2. 全局替换img标签为image标签适配uni-app
3. 重构lock组件逻辑,新增会员解锁弹窗
4. 优化多个页面的权限判断逻辑
5. 调整部分页面样式与布局
408249787@qq.com 1 week geleden
bovenliggende
commit
cf6f80b03d

+ 2 - 2
README.md

@@ -99,11 +99,11 @@ PassThrough 是一种用于访问组件内部 DOM 结构的 API,它允许开
 <table>
   <tr>
     <td align="center">
-      <img src="https://unix.cool-js.com/qrcode-h5.png" width="200px" /><br/>
+      <image mode="aspectFill" src="https://unix.cool-js.com/qrcode-h5.png" width="200px" /><br/>
       H5 预览
     </td>
     <td align="center">
-      <img src="https://unix.cool-js.com/qrcode-apk.png" width="200px" /><br/>
+      <image mode="aspectFill" src="https://unix.cool-js.com/qrcode-apk.png" width="200px" /><br/>
       APP 下载
     </td>
   </tr>

+ 97 - 13
components/loading.uvue

@@ -1,18 +1,102 @@
-<script setup lang='ts'>
+<style scoped>
+  .loader3 {
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    align-items: center;
+    height: 40px;
+  }
+
+  .bars {
+    width: 10px;
+    height: 20px;
+    margin: 0 2px;
+    border-radius: 4px;
+    animation: loader3 3s ease-in-out infinite;
+  }
+
+  .bar1 {
+    background-color: #4285F4;
+    animation-delay: -0.8s;
+  }
+
+  .bar2 {
+    background-color: #4285F4;
+    animation-delay: -0.7s;
+  }
+
+  .bar3 {
+    background-color: #4285F4;
+    animation-delay: -0.6s;
+  }
+
+  .bar4 {
+    background-color: #4285F4;
+    animation-delay: -0.5s;
+  }
+
+  .bar5 {
+    background-color: #4285F4;
+    animation-delay: -0.4s;
+  }
+
+  .bar6 {
+    background-color: #4285F4;
+    animation-delay: -0.3s;
+  }
+
+  .bar7 {
+    background-color: #4285F4;
+    animation-delay: -0.2s;
+  }
+
+  .bar8 {
+    background-color: #4285F4;
+    animation-delay: -0.1s;
+  }
+
+  .bar9 {
+    background-color: #4285F4;
+    animation-delay: 0s;
+  }
+
+  .bar10 {
+    background-color: #4285F4;
+    animation-delay: 0.1s;
+  }
+
+  @keyframes loader3 {
+    0% {
+      transform: scale(1);
+    }
+
+    20% {
+      transform: scale(1, 2.32);
+    }
+
+    40% {
+      transform: scale(1);
+    }
+  }
+  .loading-image {
+    @apply w-full h-full fixed bg-[#000118] top-0 left-0 flex items-center justify-center;
+    z-index: 10000;
+  }
+</style>
 
-</script>
 <template>
   <view class="loading-image">
-    <image src="https://oss.xiaoxiongcode.com/static/home/loading.gif" />
+     <div class="loader3">
+    <div class="bars bar1"></div>
+    <div class="bars bar2"></div>
+    <div class="bars bar3"></div>
+    <div class="bars bar4"></div>
+    <div class="bars bar5"></div>
+    <div class="bars bar6"></div>
+    <div class="bars bar7"></div>
+    <div class="bars bar8"></div>
+    <div class="bars bar9"></div>
+    <div class="bars bar10"></div>
+  </div>
   </view>
 </template>
-<style lang="scss" scoped>
-.loading-image {
-  @apply w-full h-full fixed bg-[#000118] top-0 left-0 flex items-center justify-center;
-  z-index: 10000;
-
-  image {
-    @apply object-cover w-[70vw];
-  }
-}
-</style>

+ 32 - 21
components/lock.uvue

@@ -1,5 +1,8 @@
 <script setup lang='ts'>
+import { type PropType } from 'vue'
+import { dict } from '@/.cool/store'
 import { wechatPay, wechatPayRequest, wechatPayQuery, wechatPayCancel } from '@/services/user'
+import { user } from '@/.cool'
 import { ref } from 'vue'
 const emit = defineEmits(['close'])
 const props = defineProps({
@@ -7,31 +10,33 @@ const props = defineProps({
     type: Object,
     default: () => ({})
   },
-  isPay: {
-    type: Boolean,
-    default: false
+  type: {
+    type: String as PropType<'vip' | 'course'>,
+    default: 'vip'
   },
-  platFormLock: {
+  finish: {
     type: Boolean,
     default: true
-  },
-  payFlag: {
-    type: Boolean,
-    default: false
   }
 })
 const visible = ref(false)
+const visible2 = ref(false)
+const visible3 = ref(false)
 function handleOpen() {
-  if (!props.isPay) {
+  console.log(1)
+  if (!props.finish) {
+    visible2.value = true
     return
   }
-  console.log(2)
-  if (!props.payFlag && !props.record.trialPlay) {
+switch (props.type) {
+  case 'course':
     visible.value = true
-  }
-  else {
-    visible2.value = true
-  }
+    break;
+  case 'vip':
+    visible3.value = true
+    break;
+}
+
 }
 async function getPayStatus(outTradeNo: string) {
   const res = await wechatPayQuery({
@@ -39,16 +44,16 @@ async function getPayStatus(outTradeNo: string) {
   })
   if (res.code !== 1000) {
     getPayStatus(outTradeNo)
-  }else{
-    emit('close',true)
+  } else {
+    emit('close', true)
+    await user.get()
   }
 }
 
 const handlePay = async () => {
-
   try {
     const { prepayId, outTradeNo } = await wechatPay({
-      subjectId: props.record.subjectId,
+      subjectId: props.type === 'course' ? props.record.subjectId : dict.getValueByLabelMapByType('index_subject_id')['物理'],
     })
     const { signature, timestamp, nonceStr } = await wechatPayRequest({
       prepayId, outTradeNo
@@ -82,7 +87,7 @@ const handlePay = async () => {
               title: "订单已取消",
               icon: 'success'
             });
-            emit('close',false)
+            emit('close', false)
           }
         })
       }
@@ -95,7 +100,6 @@ const handlePay = async () => {
   }
 
 }
-const visible2 = ref(false)
 
 </script>
 <template>
@@ -114,6 +118,13 @@ const visible2 = ref(false)
       <cl-button class="mt-4" size="large" type="warn" block @tap="visible2 = false"> 返回 </cl-button>
     </view>
   </cl-popup>
+  <cl-popup v-model="visible3" showClose :size="400" :show-header="false" direction="center">
+    <view class="p-[40px] ">
+      <cl-text class="text-center" color="#000" :size="20"> 小朋友,快叫爸爸妈妈帮忙成为会员,解锁更多精彩内容吧! </cl-text>
+      <cl-text class="text-center" color="#666" :size="14"> 购买物理AI课后自动成为会员</cl-text>
+      <cl-button class="mt-4" size="large" type="warn" block @tap="handlePay"> 前往购课 </cl-button>
+    </view>
+  </cl-popup>
 </template>
 <style lang="scss" scoped>
 .bg1 {

+ 7 - 0
pages.json

@@ -63,6 +63,13 @@
 				"disableScroll": true
 			}
 		},
+			{
+			"path": "pages/math/index",
+			"style": {
+				"navigationStyle": "custom",
+				"disableScroll": true
+			}
+		},
 		{
 			"path": "pages/english/index",
 			"style": {

+ 1 - 1
pages/catalog/detail.uvue

@@ -214,7 +214,7 @@ onUnmounted(() => {
         :show-casting-button="false" autoplay @controlstoggle="handleControlsToggle" @ended="handleEnded">
       </video>
       <view v-else class="w-full h-full ">
-        <img src="https://oss.xiaoxiongcode.com/static/home/assert_1.gif" alt="" class="w-full h-full object-cover" />
+        <image mode="aspectFill" src="https://oss.xiaoxiongcode.com/static/home/assert_1.gif" alt="" class="w-full h-full object-cover" />
         <!-- 顶部提示文字 -->
         <view class="absolute text-[20px] top-[20vh] w-full flex flex-row items-center justify-center">
           <!-- <cl-icon name="notification-3-fill" color="#FCE762" :size="40"></cl-icon> -->

+ 3 - 3
pages/catalog/index.uvue

@@ -110,7 +110,7 @@ function handleClose(val: boolean) {
   <Loading v-show="isLoading" />
   <cl-page v-show="!isLoading">
     <Back />
-    <img src="https://oss.xiaoxiongcode.com/static/home/2.png" alt="" class="w-full h-full object-cover" />
+    <image mode="aspectFill" src="https://oss.xiaoxiongcode.com/static/home/2.png" alt="" class="w-full h-full object-cover" />
     <!-- 精灵图动画 -->
     <cl-image src="https://oss.xiaoxiongcode.com/static/home/3.gif" mode="heightFix"
       class="!absolute bottom-0 left-0 !w-[44vh] !h-[55vh] z-[1]" />
@@ -140,8 +140,8 @@ function handleClose(val: boolean) {
             <Progress :num="6" size="12px"
               :percentage="course.courseUserProgress ? course.courseUserProgress?.status == 1 ? 6 : course.courseUserProgress?.assistantProgress : 0" />
           </view>
-          <Lock v-if="(!course.trialPlay && !record.payFlag) || !course.platFormLock" :record="course" isPay
-            :platFormLock="course.platFormLock" :payFlag="record.payFlag" @close="handleClose" />
+          <Lock v-if="(!course.trialPlay && !record.payFlag) || !course.platFormLock" :record="course" type="course"
+            :finish="course.platFormLock"  @close="handleClose" />
         </view>
       </scroll-view>
     </view>

+ 6 - 3
pages/chinese/index.uvue

@@ -1,5 +1,6 @@
 <script lang="ts" setup>
-import { ref, onMounted } from 'vue'
+import { user } from '@/.cool'
+import { ref, onMounted, computed } from 'vue'
 import { fetchSubjectConfigInfo } from '@/services/subject/info'
 import type { SubjectCatalogResult } from '@/services/subject/catalog'
 import Progress from '../catalog/components/progress.uvue'
@@ -21,6 +22,8 @@ async function getDataList() {
   dataList.value = res.catalogList || []
   catalog.value = res?.catalogList?.[0]
 }
+const userInfo = computed(() => user.info.value?.userInfo)
+
 onMounted(async () => {
   try {
     await getDataList()
@@ -55,7 +58,7 @@ function handleDetail(item: SubjectCatalogResult) {
   <Loading v-show="isLoading" />
   <cl-page v-show="!isLoading">
     <Back />
-    <img src="https://oss.xiaoxiongcode.com/static/语文/图层 4.png" alt="" class="w-full h-full object-cover" />
+    <image mode="aspectFill" src="https://oss.xiaoxiongcode.com/static/语文/图层 4.png" alt="" class="w-full h-full object-cover" />
     <!-- 精灵图动画 -->
     <cl-image src="https://oss.xiaoxiongcode.com/static/home/3.gif" mode="heightFix"
       class="!absolute bottom-0 left-0 !w-[44vh] !h-[55vh] z-[1]" />
@@ -82,7 +85,7 @@ function handleDetail(item: SubjectCatalogResult) {
           <!-- <view>
             <Progress :progress="30" />
           </view> -->
-          <Lock v-if="!course.trialPlay && !record.payFlag" :record="course" :payFlag="record.payFlag" />
+          <Lock v-if="userInfo?.memberLevel === 'default'" :record="course" type="vip"/>
         </view>
       </scroll-view>
     </view>

+ 5 - 3
pages/english/index.uvue

@@ -1,5 +1,6 @@
 <script lang="ts" setup>
-import { ref, onMounted } from 'vue'
+import { user } from '@/.cool'
+import { ref, onMounted, computed } from 'vue'
 import { fetchSubjectConfigInfo } from '@/services/subject/info'
 import type { SubjectCatalogResult } from '@/services/subject/catalog'
 import Progress from '../catalog/components/progress.uvue'
@@ -13,6 +14,7 @@ const visible = ref<boolean>(false)
 const dataList = ref<SubjectCatalogResult[]>([])
 const catalog = ref<SubjectCatalogResult>()
 const record = ref<any>()
+const userInfo = computed(() => user.info.value?.userInfo)
 async function getDataList() {
   const res = await fetchSubjectConfigInfo({ id: router.query().id })
   record.value = res
@@ -53,7 +55,7 @@ function handleDetail(item: SubjectCatalogResult) {
   <Loading v-show="isLoading" />
   <cl-page v-show="!isLoading">
     <Back />
-    <img src="https://oss.xiaoxiongcode.com/static/英语/图层 6.png" alt="" class="w-full h-full object-cover" />
+    <image mode="aspectFill" src="https://oss.xiaoxiongcode.com/static/英语/图层 6.png" alt="" class="w-full h-full object-cover" />
 
     <!-- 精灵图动画 -->
     <!-- <cl-image src="https://oss.xiaoxiongcode.com/static/home/3.gif" mode="heightFix"
@@ -81,7 +83,7 @@ function handleDetail(item: SubjectCatalogResult) {
           <!-- <view>
             <Progress :progress="30" />
           </view> -->
-          <Lock v-if="!course.trialPlay && !record.payFlag" :record="course" :payFlag="record.payFlag" />
+           <Lock v-if="userInfo?.memberLevel === 'default'" :record="course" type="vip"/>
         </view>
       </scroll-view>
     </view>

+ 5 - 3
pages/game/index.uvue

@@ -1,5 +1,6 @@
 <script lang="ts" setup>
-import { ref, onMounted } from 'vue'
+import { user } from '@/.cool'
+import { ref, onMounted, computed } from 'vue'
 import { fetchSubjectConfigInfo } from '@/services/subject/info'
 import type { SubjectCatalogResult } from '@/services/subject/catalog'
 import Progress from '../catalog/components/progress.uvue'
@@ -10,6 +11,7 @@ import { config } from '@/config'
 import { router } from "@/.cool";
 import { dict } from '@/.cool/store'
 const isLoading = ref(true)
+const userInfo = computed(() => user.info.value?.userInfo)
 const visible = ref<boolean>(false)
 const dataList = ref<SubjectCatalogResult[]>([])
 const catalog = ref<SubjectCatalogResult>()
@@ -55,7 +57,7 @@ function handleDetail(item: SubjectCatalogResult) {
   <Loading v-show="isLoading" />
   <cl-page v-show="!isLoading">
     <Back />
-    <img src="https://oss.xiaoxiongcode.com/static/语文/图层 4.png" alt="" class="w-full h-full object-cover" />
+    <image mode="aspectFill" src="https://oss.xiaoxiongcode.com/static/语文/图层 4.png" alt="" class="w-full h-full object-cover" />
     <!-- 精灵图动画 -->
     <cl-image src="https://oss.xiaoxiongcode.com/static/home/3.gif" mode="heightFix"
       class="!absolute bottom-0 left-0 !w-[44vh] !h-[55vh] z-[1]" />
@@ -82,7 +84,7 @@ function handleDetail(item: SubjectCatalogResult) {
           <!-- <view>
             <Progress :progress="30" />
           </view> -->
-          <Lock v-if="!course.trialPlay && !record.payFlag" :record="course" :payFlag="record.payFlag" />
+          <Lock v-if="userInfo?.memberLevel === 'default'" :record="course" type="vip"/>
         </view>
       </scroll-view>
     </view>

+ 99 - 0
pages/index/components/math.uvue

@@ -0,0 +1,99 @@
+<script setup lang='ts'>
+import { ref } from 'vue'
+import { router } from '@/.cool'
+import { user } from '@/.cool'
+
+function handleView(url) {
+  router.push({ path: url })
+}
+</script>
+<template>
+  <!-- <view class="bottom">
+    <view class=" progress">
+      <view class="text-[26px] font-bold">学习进度</view>
+      <view class=" w-full flex flex-row items-center justify-center gap-2">
+
+        <cl-progress class="flex-1" color="linear-gradient(0deg, #1FA5F5 37%, #A2D8FF 100%)"
+          :value="user.info.value?.studyCourseNum" :show-text="false" :strokeWidth="16"
+          :pt="{ outer: { className: '!rounded-full' }, inner: { className: '!rounded-full' } }"></cl-progress>
+
+        <view class="text-[12px] w-[100px] rounded-full text-black font-bold text-center check
+               to-pink-500 h-[20px] ">
+          今日打卡
+        </view>
+
+      </view>
+    </view>
+    <view class="flex-1 flex flex-col items-center justify-between gap-2 bg1 py-3">
+      <cl-image src="https://oss.xiaoxiongcode.com/static/home/17.png" mode="widthFix" width="40%" height="auto" />
+      <text class="text-[14px]">趣味虚拟实验</text>
+    </view>
+    <view class="flex-1 flex flex-col items-center justify-between gap-1 bg2 py-3"
+      @tap="handleView('/pages/card/index')">
+      <cl-image src="https://oss.xiaoxiongcode.com/static/home/19.png" mode="widthFix" width="70%" height="auto" />
+      <text class="text-[14px]">我的收获</text>
+    </view>
+    <view class="flex-1 flex flex-col items-center justify-between gap-1 bg3 py-3">
+      <cl-image src="https://oss.xiaoxiongcode.com/static/home/18.png" mode="widthFix" width="35%" height="auto" />
+      <text class="text-[14px]">学习报告</text>
+    </view>
+  </view> -->
+  <view class="content" @tap="handleView('/pages/math/index')">
+    <cl-image src="https://oss.xiaoxiongcode.com/static/home/play.png" mode="heightFix" height="100%" width="auto" />
+    <view class="flex-1 flex flex-col items-center justify-center gap-2 ft">
+      <view class="text-[10vh] font-bold">
+        数学启蒙
+      </view>
+      <!-- <view class="h-[15vh]">
+        <cl-image src="https://oss.xiaoxiongcode.com/static/home/play.png" mode="heightFix" height="100%"
+          width="auto" />
+      </view> -->
+    </view>
+  </view>
+</template>
+<style lang="scss" scoped>
+.bottom {
+  @apply absolute bottom-[1vh] left-1/2 w-full max-w-[800px] rounded-[20px] px-10 py-1 flex flex-row items-center justify-between gap-5;
+  transform: translateX(-50%);
+
+  .progress {
+    @apply w-[400px] h-[80px] rounded-[40px] flex justify-center gap-2 px-[30px] gap-3;
+    background: linear-gradient(0deg, #AAE3FF 0%, #DFF4FD 100%);
+    width: 40%;
+  }
+
+  .check {
+    background: linear-gradient(0deg, #FBD00E 0%, #FBEC92 100%);
+    line-height: 20px;
+  }
+}
+
+.bg1 {
+  background: linear-gradient(0deg, #7597FA 0%, #C1DAFF 100%);
+  border-radius: 28px;
+  height: 80px;
+}
+
+.bg2 {
+  background: linear-gradient(0deg, #3CD3DE 0%, #ADFBFF 100%);
+  border-radius: 28px;
+  height: 80px;
+}
+
+.bg3 {
+  background: linear-gradient(0deg, #FFCE4A 0%, #FFEC88 100%);
+  border-radius: 28px;
+  height: 80px;
+}
+
+.ft {
+  font-family: eryazhaocaimao;
+  text-shadow: 0 0 10px rgba(255, 255, 255, 0.8), 0 0 20px rgba(255, 255, 255, 0.6), 0 0 30px rgba(255, 255, 255, 0.4), 0 0 40px rgba(62, 166, 238, 0.8);
+}
+
+.content {
+  @apply absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-white w-[120vh] border-[3px] border-[#fff] border-solid rounded-[30px] px-10 py-4 h-[40vh] flex flex-row items-center justify-between gap-4;
+  background: linear-gradient(0deg, #C7F0FE 0%, #30B9FF 100%);
+
+}
+</style>

+ 2 - 2
pages/index/home copy.uvue

@@ -7,10 +7,10 @@ function handlePage(url) {
 </script>
 <template>
 	<cl-page>
-		<img src="https://oss.xiaoxiongcode.com/static/home/11.jpg" alt="" class="w-full h-full object-cover" />
+		<image mode="aspectFill" src="https://oss.xiaoxiongcode.com/static/home/11.jpg" alt="" class="w-full h-full object-cover" />
 		<view class="content">
 			<view class="relative w-[25vw] " @tap="handlePage('/pages/catalog/index')">
-				<img src="https://oss.xiaoxiongcode.com/static/home/13.png" alt="" class="w-full object-cover" />
+				<image mode="aspectFill" src="https://oss.xiaoxiongcode.com/static/home/13.png" alt="" class="w-full object-cover" />
 				<view class="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center text-white pb-3">
 					<view class="text-2xl font-bold">全部课程</view>
 					<view class="text-[11px] px-2 py-1 rounded-full bg-[#55B58A] text-white font-bold mt-2">点击这里查看上过课程</view>

+ 9 - 5
pages/index/home.uvue

@@ -9,6 +9,7 @@ import English from './components/english.uvue'
 import Mix from './components/mix.uvue'
 import Game from './components/game.uvue'
 import Exchange from './components/exchange.uvue'
+import MathModal from './components/math.uvue'
 
 const menuList = computed(() => {
 	return [
@@ -31,6 +32,7 @@ const icons = {
 	game: "https://oss.xiaoxiongcode.com/static/home/娱乐.png",
 	exchange: "https://oss.xiaoxiongcode.com/static/home/图层 5.png",
 	user: "https://oss.xiaoxiongcode.com/static/home/个人中心.png",
+	math: "https://oss.xiaoxiongcode.com/static/home/math.png",
 }
 const selected = ref<string>('physics')
 function handlePage(val: any) {
@@ -53,7 +55,7 @@ const visible = ref(false)
 </script>
 <template>
 	<cl-page :backTop="false">
-		<img src="https://oss.xiaoxiongcode.com/static/home/111.png" alt=""
+		<image src="https://oss.xiaoxiongcode.com/static/home/111.png" mode="aspectFill" alt=""
 			class="w-full h-full object-cover absolute top-0 left-0" />
 		<view class="menus w-[90vw]">
 			<image src="https://oss.xiaoxiongcode.com/static/home/643.png"
@@ -62,15 +64,16 @@ const visible = ref(false)
 				<view v-for="item in menuList" :key="item.code"
 					class="flex flex-col items-center p-1 px-4 justify-center gap-1  transition-all duration-300"
 					@tap="handlePage(item)" :class="{ 'selected': item.code === selected }">
-					<image :src="icons[item.code]" mode="aspectFill"  class="w-[4vw] h-[4vw]"></image>
-					<text  class="text-[1.5vw] text-[#1E1E1E]">{{ item.label }}</text>
+					<image :src="icons[item.code]" mode="aspectFill" class="w-[4vw] h-[4vw]"></image>
+					<text class="text-[1.5vw] text-[#1E1E1E]">{{ item.label }}</text>
 				</view>
 				<view class="flex flex-col items-center p-1 px-4 justify-center gap-1  transition-all duration-300"
 					@tap="visible = true">
-					<view class="bg-[#09ba07] p-[1vw] rounded-[2vw] w-[4vw] h-[4vw] flex items-center justify-center" @tap="visible = true">
+					<view class="bg-[#09ba07] p-[1vw] rounded-[2vw] w-[4vw] h-[4vw] flex items-center justify-center"
+						@tap="visible = true">
 						<image src="https://oss.xiaoxiongcode.com/static/个人中心/微信.png" class="w-full h-full"></image>
 					</view>
-					<text  class="text-[1.5vw] text-[#1E1E1E]">添加老师</text>
+					<text class="text-[1.5vw] text-[#1E1E1E]">添加老师</text>
 				</view>
 			</view>
 		</view>
@@ -96,6 +99,7 @@ const visible = ref(false)
 		<Mix v-else-if="selected === 'mix'" />
 		<Game v-else-if="selected === 'game'" />
 		<Exchange v-else-if="selected === 'exchange'" />
+		<MathModal v-else-if="selected === 'math'" />
 	</cl-page>
 </template>
 <style lang="scss" scoped>

+ 186 - 0
pages/math/index.uvue

@@ -0,0 +1,186 @@
+<script lang="ts" setup>
+import { user } from '@/.cool'
+import { ref, onMounted, computed } from 'vue' 
+import { fetchSubjectConfigInfo } from '@/services/subject/info'
+import type { SubjectCatalogResult } from '@/services/subject/catalog'
+import Progress from '../catalog/components/progress.uvue'
+import Back from '@/components/back.uvue'
+import Lock from '@/components/lock.uvue'
+import Loading from '@/components/loading.uvue'
+import { config } from '@/config'
+import { router } from "@/.cool";
+import { dict } from '@/.cool/store'
+const isLoading = ref(true)
+const visible = ref<boolean>(false)
+const dataList = ref<SubjectCatalogResult[]>([])
+const catalog = ref<SubjectCatalogResult>()
+const record = ref<any>()
+
+async function getDataList() {
+  const id = dict.getValueByLabelMapByType('index_subject_id')['数学']
+  const res = await fetchSubjectConfigInfo({ id })
+  record.value = res
+  dataList.value = res.catalogList || []
+  catalog.value = res?.catalogList?.[0]
+}
+onMounted(async () => {
+  try {
+    await getDataList()
+    isLoading.value = false
+  } catch (err) {
+    console.log(err);
+    isLoading.value = false
+  }
+})
+function handleSelect(item: SubjectCatalogResult) {
+  catalog.value = item
+  visible.value = false
+}
+function handleDetail(item: SubjectCatalogResult) {
+  if (!item.payFlag && !item.trialPlay) {
+    uni.showToast({
+      title: '请先购买',
+      icon: 'none'
+    })
+    return
+  }
+  router.push({
+    path: "/pages/english/detail",
+    query: {
+      id: item.id,
+    }
+  });
+}
+const userInfo = computed(() => user.info.value?.userInfo)
+</script>
+
+<template>
+  <Loading v-show="isLoading" />
+  <cl-page v-show="!isLoading">
+    <Back />
+    <image mode="aspectFill" src="https://oss.xiaoxiongcode.com/static/home/math-bg.png" alt="" class="w-full h-full object-cover" />
+    <!-- 精灵图动画 -->
+    <cl-image src="https://oss.xiaoxiongcode.com/static/home/3.gif" mode="heightFix"
+      class="!absolute bottom-0 left-0 !w-[44vh] !h-[55vh] z-[1]" />
+    <view>
+
+    </view>
+    <!-- 顶部右侧光标签 -->
+    <view class="light-tag" @tap="visible = true">
+      <image class="light-icon" v-if="catalog?.fileList?.[0]?.url" :src="config.baseUrl + catalog?.fileList?.[0]?.url">
+      </image>
+      <text class="light-text">{{ catalog?.name }}</text>
+      <cl-icon name="arrow-left-right-line" color="primary"></cl-icon>
+    </view>
+    <view class="boxs">
+      <scroll-view class="scroll-view_H" direction="horizontal" :show-scrollbar="false">
+        <view class="scroll-view-item_H bg-[white]" v-for="course in catalog?.courseList || []" :key="course.id"
+          @tap="handleDetail(course)">
+          <cl-image :src="config.baseUrl + course?.fileList?.[0]?.url" mode="heightFix"
+            class="!w-full !h-[26vh] mb-[2px] rounded-xl"></cl-image>
+          <text class="text-[16px] font-bold">{{
+            course.mainTitle }}</text>
+          <text class="text-[14px] text-[#666]">{{
+            course.assistantTitle }}</text>
+          <!-- <view>
+            <Progress :progress="30" />
+          </view> -->
+          <Lock v-if="userInfo?.memberLevel === 'default'" :record="course" type="vip"/>
+        </view>
+      </scroll-view>
+    </view>
+    <!-- <view class="footer">
+      <view>
+        <cl-image src="https://oss.xiaoxiongcode.com/static/home/4.png" mode="heightFix"
+          class=" !h-[40px] mb-[2px] rounded-xl"></cl-image>
+        <text class="text-[14px] text-white font-bold text-stroke-custom">虚拟实验</text>
+      </view>
+      <view>
+        <cl-image src="https://oss.xiaoxiongcode.com/static/home/5.png" mode="heightFix"
+          class=" !h-[40px] mb-[2px] rounded-xl"></cl-image>
+        <text class="text-[14px] text-white font-bold text-stroke-custom">我的收获</text>
+      </view>
+      <view>
+        <cl-image src="https://oss.xiaoxiongcode.com/static/home/6.png" mode="heightFix"
+          class=" !h-[40px] mb-[2px] rounded-xl"></cl-image>
+        <text class="text-[14px] text-white font-bold text-stroke-custom">学习报告</text>
+      </view>
+    </view> -->
+    <cl-popup v-model="visible" :show-header="false" direction="center" :size="600">
+      <view class="p-4">
+        <cl-row :gutter="0">
+          <cl-col :span="6" v-for="item in dataList || []" :key="item.id" :pt="{
+            className: '!p-2'
+          }" @tap="handleSelect(item)">
+            <view class="select-item" :class="{ selected: item.id === catalog?.id }">
+              <image :src="config.baseUrl + item?.fileList?.[0]?.url" class="w-[30rpx] h-[30rpx] mb-[2px]"></image>
+              <text>{{ item.name }}</text>
+            </view>
+          </cl-col>
+        </cl-row>
+      </view>
+    </cl-popup>
+  </cl-page>
+</template>
+
+
+
+<style lang="scss" scoped>
+.boxs {
+  @apply w-[100vw] h-[50vh] absolute top-1/2 left-[50vh] z-[1];
+  transform: translateY(-50%);
+}
+
+.scroll-view_H {
+  width: 100%;
+  height: 100%;
+  flex-direction: row;
+}
+
+.scroll-view-item_H {
+  @apply w-[40vh] h-[50vh] mr-[20px] rounded-2xl border-[5px] border-[#1D4BD9] border-solid border-b-[10px] p-1 flex items-center justify-between pb-[20px];
+}
+
+.light-tag {
+  @apply absolute top-3 left-1/2 z-[1] flex flex-row items-center bg-white px-3 py-2 font-bold rounded-full shadow-md;
+  transform: translateX(-50%);
+
+  .light-icon {
+    width: 20px;
+    height: 20px;
+    margin-right: 3px;
+  }
+
+  .light-text {
+    font-size: 16px;
+    min-width: 100px;
+    padding-right: 5px;
+  }
+}
+
+.select-item {
+  @apply flex items-center justify-center rounded-xl border-[3px] border-[#1D4BD9] border-solid border-b-[5px] px-4 py-2 font-bold;
+}
+
+.selected {
+  @apply border-green-500;
+}
+
+.footer {
+  @apply absolute bottom-2 right-5 z-[1] flex flex-row items-center justify-center gap-4;
+}
+
+.text-stroke-custom {
+  color: white;
+  text-shadow:
+    /* 左上角投影 */
+    -1px -1px 0 #1D4BD9,
+    /* 右上角投影 */
+    1px -1px 0 #1D4BD9,
+    /* 左下角投影 */
+    -1px 1px 0 #1D4BD9,
+    /* 右下角投影 */
+    1px 1px 0 #1D4BD9;
+
+}
+</style>

+ 7 - 10
pages/mix/index.uvue

@@ -1,5 +1,6 @@
 <script lang="ts" setup>
-import { ref, onMounted } from 'vue'
+import { user } from '@/.cool'
+import { ref, onMounted, computed } from 'vue'
 import { fetchSubjectConfigInfo } from '@/services/subject/info'
 import type { SubjectCatalogResult } from '@/services/subject/catalog'
 import Progress from '../catalog/components/progress.uvue'
@@ -13,6 +14,7 @@ const visible = ref<boolean>(false)
 const dataList = ref<SubjectCatalogResult[]>([])
 const catalog = ref<SubjectCatalogResult>()
 const record = ref<any>()
+const userInfo = computed(() => user.info.value?.userInfo)
 async function getDataList() {
   const res = await fetchSubjectConfigInfo({ id: router.query().id })
   record.value = res
@@ -33,13 +35,7 @@ function handleSelect(item: SubjectCatalogResult) {
   visible.value = false
 }
 function handleDetail(item: SubjectCatalogResult) {
-  if (!item.payFlag && !item.trialPlay) {
-    uni.showToast({
-      title: '请先购买',
-      icon: 'none'
-    })
-    return
-  }
+
   router.push({
     path: "/pages/english/detail",
     query: {
@@ -53,7 +49,7 @@ function handleDetail(item: SubjectCatalogResult) {
   <Loading v-show="isLoading" />
   <cl-page v-show="!isLoading">
     <Back />
-    <img src="https://oss.xiaoxiongcode.com/static/语文/图层 4.png" alt="" class="w-full h-full object-cover" />
+    <image mode="aspectFill" src="https://oss.xiaoxiongcode.com/static/语文/图层 4.png" alt="" class="w-full h-full object-cover" />
 
     <!-- 精灵图动画 -->
     <!-- <cl-image src="https://oss.xiaoxiongcode.com/static/home/3.gif" mode="heightFix"
@@ -81,7 +77,8 @@ function handleDetail(item: SubjectCatalogResult) {
           <!-- <view>
             <Progress :progress="30" />
           </view> -->
-          <Lock v-if="!course.trialPlay && !record.payFlag" :record="course" :payFlag="record.payFlag" />
+           <Lock v-if="userInfo?.memberLevel === 'default'" :record="course" type="vip"/>
+
         </view>
       </scroll-view>
     </view>

+ 5 - 3
pages/test/index.uvue

@@ -1,5 +1,6 @@
 <script lang="ts" setup>
-import { ref, onMounted } from 'vue'
+import { user } from '@/.cool'
+import { ref, onMounted, computed } from 'vue'
 import { fetchSubjectAppInfo } from '@/services/subject/info'
 import { querySubjectCourseTest } from '@/services/subject/test'
 import type { SubjectCatalogResult } from '@/services/subject/catalog'
@@ -10,6 +11,7 @@ import Loading from '@/components/loading.uvue'
 import { config } from '@/config'
 import { dict } from '@/.cool/store'
 import { router } from "@/.cool";
+const userInfo = computed(() => user.info.value?.userInfo)
 
 const isLoading = ref(true)
 const visible = ref<boolean>(false)
@@ -78,7 +80,7 @@ async function onScroll(e: any) {
   <Loading v-show="isLoading" />
   <cl-page v-show="!isLoading">
     <Back />
-    <img src="https://oss.xiaoxiongcode.com/static/home/2.png" alt="" class="w-full h-full object-cover" />
+    <image mode="aspectFill" src="https://oss.xiaoxiongcode.com/static/home/2.png" alt="" class="w-full h-full object-cover" />
     <!-- 顶部右侧光标签 -->
     <view class="light-tag" @tap="visible = true">
       <image class="light-icon" v-if="catalog?.fileList?.[0]?.url" :src="config.baseUrl + catalog?.fileList?.[0]?.url">
@@ -95,7 +97,7 @@ async function onScroll(e: any) {
             class="!w-full !h-[28vh] mb-[10px] rounded-xl"></cl-image>
           <text class="text-[4vh] font-bold">{{
             test.name }}</text>
-          <Lock v-if="test.lockFlag" :record="test" />
+          <Lock v-if="userInfo?.memberLevel === 'default'" :record="test" type="vip"/>
         </view>
       </scroll-view>
     </view>

+ 2 - 3
pages/user/components/conversion.uvue

@@ -14,11 +14,10 @@ onMounted(() => {
 <template>
   <view class=" bg-[#fff] shadow rounded-xl mt-[20px] text-[#00A9FF] ">
     <scroll-view direction="vertical" :show-scrollbar="false" class="sidebar">
-      <view class="w-full grid grid-cols-2 gap-4" v-if="recordList.length > 0">
+      <view class="w-full grid grid-cols-2 gap-4 py-2" v-if="recordList.length > 0">
         <view v-for="item in recordList" :key="item" class="box flex flex-row  items-center gap-2">
           <view class="h-full">
-            <cl-image src="https://oss.xiaoxiongcode.com/static/个人中心/图层 13.png" mode="heightFix" height="100%"
-              width="auto"></cl-image>
+            <image src="https://oss.xiaoxiongcode.com/static/个人中心/图层 13.png" mode="heightFix" class=" h-full" />
           </view>
           <view class="flex flex-col justify-around h-full">
             <view class="text-[16px] font-bold text-[#FC500F]">

+ 2 - 2
pages/user/components/user.uvue

@@ -60,7 +60,7 @@ const avatar = ref('')
     <cl-row :gutter="20" class="w-full">
       <cl-col :span="8">
         <view class="w-full h-full bg-[#00A9FF] rounded-3xl  shadow">
-          <scroll-view direction="vertical" :show-scrollbar="false" class="sidebar2">
+          <scroll-view direction="vertical" :show-scrollbar="false" class="sidebar2 pt-2">
             <view class=" flex justify-end items-center mh">
               <view class="w-[88px] h-[88px] border border-[#fff] border-solid border-[4px] rounded-full z-[1]">
                 <cl-avatar :size="80"
@@ -68,7 +68,7 @@ const avatar = ref('')
                   rounded></cl-avatar>
               </view>
               <view
-                class="bg-[#FDF6E9]  rounded-3xl p-[10px] w-full mt-[-30px] pt-[30px] px-[20px] text-black flex flex-col justify-between ">
+                class="bg-[#FDF6E9] flex-1 rounded-3xl p-[10px] w-full mt-[-30px] pt-[30px] px-[20px] text-black flex flex-col justify-between ">
                 <view>
                   <view class="py-1 text-[14px]">
                     用户账号:{{ userInfo.username }}

+ 1 - 1
pages/user/info.uvue

@@ -12,7 +12,7 @@ const active = ref<'user' | 'conversion' | 'set'>('user')
 <template>
   <cl-page>
     <Back />
-    <img src="https://oss.xiaoxiongcode.com/static/个人中心/bg.png" alt="" class="w-full h-full object-cover">
+    <image mode="aspectFill" src="https://oss.xiaoxiongcode.com/static/个人中心/bg.png" alt="" class="w-full h-full object-cover" />
     <view class="content">
       <view class="flex flex-row justify-between items-center">
         <view