lex-xin 5 months ago
parent
commit
5f010b020e

+ 17 - 6
src/components/TheVip/index.tsx

@@ -3,24 +3,35 @@ import { defineComponent } from 'vue';
 import styles from './index.module.less';
 import { state } from '@/state';
 import { gotoMemberCenter } from '@/views/hook/useFee';
+import {
+  postMessage
+} from '@/helpers/native-message';
 
 export default defineComponent({
   name: 'theVip',
   setup() {
     return () => (
-      <Popup v-model:show={state.vipShow} round class={styles.courseDialog}>
-        <i
+      <Popup v-model:show={state.vipShow} round class={styles.courseDialog} closeOnClickOverlay={false}>
+        {state.vipFrom !== "exercise" && <i
           class={styles.iconClose}
-          onClick={() => (state.vipShow = false)}></i>
+          onClick={() => (state.vipShow = false)}></i>}
         <div class={styles.title}>温馨提示</div>
 
         <div class={styles.content}>
-          开通管乐AI学练宝,解锁更多课件,享受全新学习体验!
+          该课件暂未解锁,解锁更多课件,享受全新学习体验!
         </div>
 
         <div class={styles.popupBtnGroup}>
-          <Button round onClick={() => state.vipShow = false}>取消</Button>
-          <Button round type="primary" onClick={gotoMemberCenter}>
+          <Button round onClick={() => {
+            state.vipShow = false
+            if(state.vipFrom === "exercise") {
+              postMessage({ api: 'back' });
+            }
+          }}>取消</Button>
+          <Button round type="primary" onClick={() => {
+            gotoMemberCenter()
+            state.vipShow = false
+          }}>
             去开通
           </Button>
         </div>

+ 4 - 2
src/state.ts

@@ -11,7 +11,8 @@ export const state = reactive({
   },
   vipShow: false, // 是否打开会员
   buyVipId: '', // 购买会员编号
-  buyVipType: '' as '' | 'MUSIC' | 'COURSE',
+  buyVipType: '' as '' | 'MUSIC' | 'LESSON',
+  vipFrom: '' as 'exercise' | '', // 来源
   platformType: 'STUDENT' as 'STUDENT' | 'TEACHER' | 'SCHOOL',
   clientId: {
     STUDENT: 'jmedu-student',
@@ -33,10 +34,11 @@ export const state = reactive({
 });
 
 /** 购买会员提示 */
-export const handleShowVip = (buyVipId: string, buyVipType: '' | 'MUSIC' | 'COURSE') => {
+export const handleShowVip = (buyVipId: string, buyVipType: '' | 'MUSIC' | 'LESSON', vipFrom = '' as 'exercise' | '') => {
   state.vipShow = true;
   state.buyVipId = buyVipId;
   state.buyVipType = buyVipType;
+  state.vipFrom = vipFrom
 }
 
 // 预览上传到oss的地址

BIN
src/views/choose-homework/music-list/icons/icon-free.png


BIN
src/views/choose-homework/music-list/icons/icon-lock.png


+ 6 - 2
src/views/choose-homework/music-list/index.module.less

@@ -285,8 +285,12 @@
   display: flex;
   align-items: center;
   margin-left: 15PX;
-  img{
-    width: 40PX;
+  &.FREE img {
+    width: 38Px;
+    margin-top: -2PX;
+  }
+  &.LOCK img {
+    width: 49Px;
     margin-top: -2PX;
   }
 }

+ 9 - 5
src/views/choose-homework/music-list/index.tsx

@@ -22,7 +22,9 @@ import request from '@/helpers/request';
 import { state as baseState } from '@/state';
 import state, { getInitState, appState } from '../pageState';
 import ChoosePartName from './modals/choosePartName';
-import VipIcon from './icons/vip.png';
+// import VipIcon from './icons/vip.png';
+import iconFree from './icons/icon-free.png'
+import iconLock from './icons/icon-lock.png'
 import iconSearch from './icons/icon_search.png';
 import styles from './index.module.less';
 import MusicIcon from './icons/music.png';
@@ -561,9 +563,11 @@ export default defineComponent({
                       icon: () => (
                         <div class={styles['icon-status']}>
                           <Icon class={styles.iconMusic} name={MusicIcon} />
-                          {item.rankIds ? (
-                            <div class={styles.icon}>
-                              <img src={VipIcon} />
+                          {/* 学生端 学校端 */}
+                          {['FREE', 'LOCK'].includes(item.useStatus) && (baseState.platformType === "STUDENT") ? (
+                            <div class={[styles.icon, styles[item.useStatus]]}>
+                              {item.useStatus === 'FREE' ? <img src={iconFree} /> : ''}
+                              {item.useStatus === 'LOCK' ? <img src={iconLock} /> : ''}
                             </div>
                           ) : null}
                         </div>
@@ -574,7 +578,7 @@ export default defineComponent({
                           color="#444"
                           style={{
                             paddingLeft:
-                              (item.rankIds ? '4PX' : '15PX') + '!important'
+                              (['FREE', 'LOCK'].includes(item.useStatus) && (baseState.platformType === "STUDENT") ? '4PX' : '15PX') + '!important'
                           }}
                           text={item.name}
                           key="notactive"

+ 16 - 4
src/views/courseList/index.tsx

@@ -14,7 +14,8 @@ import {
   reactive,
   onUnmounted,
   TransitionGroup,
-  computed
+  computed,
+  watch
 } from 'vue';
 import styles from './index.module.less';
 import { useRoute, useRouter } from 'vue-router';
@@ -32,7 +33,7 @@ import { browser } from '@/helpers/utils';
 import OEmpty from '@/components/o-empty';
 import iconList from './image/icon-list.png';
 import OHeader from '@/components/o-header';
-import { useEventListener } from '@vant/use';
+import { useEventListener, usePageVisibility } from '@vant/use';
 import OLoading from '@/components/o-loading';
 import OSticky from '@/components/o-sticky';
 export default defineComponent({
@@ -41,6 +42,7 @@ export default defineComponent({
     const route = useRoute();
     const router = useRouter();
     const browserInfo = browser();
+    const pageVisibility = usePageVisibility();
     const data = reactive({
       titleOpacity: 0,
       catchStatus: false,
@@ -59,9 +61,19 @@ export default defineComponent({
 
     /** 是否锁定 */
     const isLock = computed(() => {
-      return  data.detail.useStatus === 'LOCK' && state.platformType === 'STUDENT' ? true : false;
+      return  (data.detail.useStatus === 'LOCK' && state.platformType === 'STUDENT') ? true : false;
     })
 
+    /** 页面显示和隐藏 */
+    watch(
+      () => pageVisibility.value,
+      value => {
+        if(value === "visible") {
+          getDetail()
+        }
+      }
+    );
+
     /** 获取课件详情 */
     const getDetail = async () => {
       const res: any = await request.get(
@@ -157,7 +169,7 @@ export default defineComponent({
         return;
       }
       if(isLock.value) {
-        handleShowVip(route.query.id as string, "COURSE")
+        handleShowVip(route.query.id as string, "LESSON")
         return
       }
 

+ 27 - 22
src/views/coursewarePlay/index.tsx

@@ -57,6 +57,9 @@ export default defineComponent({
         if (value == 'hidden') {
           handleStop();
         }
+        if (value === "visible") {
+          // getDetail('visiable')
+        }
       }
     );
     /** 设置播放容器 16:9 */
@@ -216,7 +219,7 @@ export default defineComponent({
       }
       return list;
     };
-    const getItemList = async () => {
+    const getItemList = async (type?: string) => {
       const list: any = [];
 
       for (let i = 0; i < data.knowledgePointList.length; i++) {
@@ -241,26 +244,28 @@ export default defineComponent({
       }
 
       // console.log(list, 'list')
-
-      let _firstIndex = list.findIndex(
-        (n: any) =>
-          n.knowledgePointMaterialRelationId == route.query.kId ||
-          n.materialId == route.query.kId
-      );
-      _firstIndex = _firstIndex > -1 ? _firstIndex : 0;
-      const item = list[_firstIndex];
-
-      // console.log(_firstIndex, '_firstIndex', route.query.kId, 'route.query.kId', item)
-      // 是否自动播放
-      if (activeData.isAutoPlay) {
-        item.autoPlay = true;
+      if(!type) {
+        let _firstIndex = list.findIndex(
+          (n: any) =>
+            n.knowledgePointMaterialRelationId == route.query.kId ||
+            n.materialId == route.query.kId
+        );
+        _firstIndex = _firstIndex > -1 ? _firstIndex : 0;
+        const item = list[_firstIndex];
+  
+        // console.log(_firstIndex, '_firstIndex', route.query.kId, 'route.query.kId', item)
+        // 是否自动播放
+        if (activeData.isAutoPlay) {
+          item.autoPlay = true;
+        }
+        popupData.activeIndex = _firstIndex;
+        popupData.playIndex = _firstIndex;
+        popupData.tabName = item.tabName;
+        popupData.tabActive = item.knowledgePointId;
+        popupData.itemActive = item.id;
+        popupData.itemName = item.name;
       }
-      popupData.activeIndex = _firstIndex;
-      popupData.playIndex = _firstIndex;
-      popupData.tabName = item.tabName;
-      popupData.tabActive = item.knowledgePointId;
-      popupData.itemActive = item.id;
-      popupData.itemName = item.name;
+      
       nextTick(() => {
         data.itemList = list;
         checkedAnimation(popupData.activeIndex);
@@ -281,7 +286,7 @@ export default defineComponent({
         }, 500);
       });
     };
-    const getDetail = async () => {
+    const getDetail = async (type = "") => {
       try {
         const res: any = await request.get(
           state.platformApi +
@@ -365,7 +370,7 @@ export default defineComponent({
               return n;
             }
           );
-          getItemList();
+          getItemList(type);
         }
       } catch (error) {
         console.log(error);

+ 40 - 18
src/views/exercise-after-class/index.tsx

@@ -12,7 +12,7 @@ import {
 import styles from './index.module.less';
 import 'plyr/dist/plyr.css';
 import request from '@/helpers/request';
-import { state } from '@/state';
+import { handleShowVip, state } from '@/state';
 import { useRoute } from 'vue-router';
 import iconBack from '../coursewarePlay/image/back.svg';
 import {
@@ -20,13 +20,11 @@ import {
   postMessage,
   promisefiyPostMessage
 } from '@/helpers/native-message';
-// import { browser } from '@/helpers/utils';
 import { Vue3Lottie } from 'vue3-lottie';
 import playLoadData from '../coursewarePlay/datas/data.json';
 import VideoClass from './video-class';
 import { usePageVisibility } from '@vant/use';
 import { useInterval, useIntervalFn } from '@vueuse/core';
-import { handleCheckVip, hasVip } from '../hook/useFee';
 
 // const materialType = {
 //   视频: 'VIDEO',
@@ -103,7 +101,7 @@ export default defineComponent({
       item: null as any
     });
     // 获取课后练习记录
-    const getTrainingRecord = async () => {
+    const getTrainingRecord = async (materialId?: any) => {
       try {
         // ?${query.courseScheduleId}?userId=${state.user?.data?.id}
         const res: any = await request.post(
@@ -131,7 +129,7 @@ export default defineComponent({
             if (item.times > item.trainingTimes) {
               data.isPlayAll = false;
             }
-            if (item.id + '' == route.query.materialId) {
+            if (item.id + '' == (materialId || route.query.materialId)) {
               popupData.tabName = item.musicScoreName;
             }
           });
@@ -142,7 +140,7 @@ export default defineComponent({
       }
       return [];
     };
-    const setRecord = async (trainings: any[]) => {
+    const setRecord = async (trainings: any[], materialId?: any) => {
       if (Array.isArray(trainings)) {
         data.trainings = trainings.map((n: any) => {
           // const materialRefs = n.materialRefs ? n.materialRefs : [];
@@ -157,13 +155,13 @@ export default defineComponent({
             loop: false,
             videoEle: null,
             timer: null,
-            muted: hasVip() ? false : true, // 静音
+            muted: n.useStatus === "LOCK" ? false : true, // 静音
             // muted: true,
-            autoplay: hasVip() ? true : false //自动播放
+            autoplay: n.useStatus === "LOCK" ? true : false //自动播放
           };
         });
         data.itemList = data.trainings.filter(
-          (n: any) => n.id == route.query.materialId
+          (n: any) => n.id == materialId || route.query.materialId
         );
         data.videoData = data.itemList[0];
         if (data.disableScreenRecordingFlag === '1') {
@@ -201,7 +199,7 @@ export default defineComponent({
       }
     };
 
-    // 获取支付渠道
+    // 获取是否录屏
     const sysParamConfig = async () => {
       try {
         const res = await request.get(
@@ -284,13 +282,12 @@ export default defineComponent({
       await sysParamConfig();
       const trainings = await getTrainingRecord();
       // 初始化状态
-      // console.log(trainings, 'trainings');
+      
       setRecord(trainings);
-      // 是否为会员
+      // 是否解锁
       if (state.platformType === 'STUDENT') {
-        data.isMember = handleCheckVip();
-        // console.log(data.isMember, 'isMember');
-        if (!data.isMember) {
+        if(data.videoData.useStatus === "LOCK") {
+          handleShowVip(data.videoData.lessonCoursewareId, "LESSON", "exercise")
           nextTick(() => {
             postMessage({
               api: 'courseLoading',
@@ -418,7 +415,6 @@ export default defineComponent({
         data.visiableConfirmText = isLastIndex ? '完成' : '下一题';
         data.visiableStatus = true;
         data.itemIndex = itemIndex;
-        console.log(itemIndex, 'index');
         data.isLastIndex = isLastIndex;
       }
     };
@@ -431,7 +427,11 @@ export default defineComponent({
         }
         data.itemList = [nextItem];
         data.videoData = nextItem;
-        handleExerciseCompleted();
+        if(data.videoData.useStatus === "UNLOCK") {
+          handleShowVip(data.videoData.lessonCoursewareId, "LESSON", "exercise")
+        } else {
+          handleExerciseCompleted();
+        }
       } else {
         postMessage({ api: 'goBack' });
       }
@@ -447,6 +447,28 @@ export default defineComponent({
       data.visiableStatus = false;
     };
 
+    const reloadPage = async () => {
+      if(state.vipShow) return
+      const trainings = await getTrainingRecord(data.videoData.lessonCoursewareId);
+      setRecord(trainings, data.videoData.lessonCoursewareId);
+      // 是否解锁
+      if (state.platformType === 'STUDENT') {
+        if(data.videoData.useStatus === "LOCK") {
+          handleShowVip(data.videoData.lessonCoursewareId, "LESSON", "exercise")
+          nextTick(() => {
+            postMessage({
+              api: 'courseLoading',
+              content: {
+                show: false,
+                type: 'fullscreen'
+              }
+            });
+          });
+          return;
+        }
+      }
+    }
+
     watch(pageVisibility, (value: any) => {
       handleStopVideo();
       if (value == 'visible') {
@@ -462,6 +484,7 @@ export default defineComponent({
             // console.log(234);
           }
         );
+        reloadPage()
       }
     });
 
@@ -513,7 +536,6 @@ export default defineComponent({
                         clearTimeout(activeData.timer);
                         activeData.model = true;
                         videoIntervalRef.pause();
-                        console.log('11111');
                       }}
                       onEnded={() => addTrainingRecord()}
                       onChangeModal={(status: boolean) => {

+ 0 - 1
src/views/hook/useFee.ts

@@ -5,7 +5,6 @@ import dayjs from 'dayjs';
 import { showDialog } from 'vant';
 
 export const gotoMemberCenter = () => {
-  postMessage({ api: 'back' });
   const browserInfo = browser();
   let pathname = '/'
   if (/gym.lexiaoya.cn/.test(location.origin) || /test.gym.lexiaoya.cn/.test(location.origin)) {