lex-xin 7 mēneši atpakaļ
vecāks
revīzija
53269d206c

+ 2 - 0
src/App.tsx

@@ -1,10 +1,12 @@
 import { defineComponent } from 'vue';
+import TheVip from './components/TheVip';
 export default defineComponent({
   name: 'app',
   setup() {
     return () => (
       <>
         <router-view></router-view>
+        <TheVip />
       </>
     );
   }

BIN
src/components/TheVip/icon-close.png


+ 51 - 0
src/components/TheVip/index.module.less

@@ -0,0 +1,51 @@
+
+.courseDialog {
+  padding: 20px !important;
+  max-width: 310px !important;
+  background: url('./top-bg.png') no-repeat top center #fff !important;
+  background-size: contain !important;
+  overflow: hidden;
+
+  .iconClose {
+    width: 18px;
+    height: 19px;
+    position: absolute;
+    top: 23px;
+    right: 20px;
+    z-index: 9;
+    background: url('./icon-close.png') no-repeat center;
+    background-size: contain;
+  }
+
+  .title {
+    position: relative;
+    font-size: 18px;
+    font-weight: 600;
+    color: #1A1A1A;
+    line-height: 25px;
+    text-align: center;
+  }
+
+  .content {
+    padding: 20px 0 25px;
+    font-size: 16px;
+    color: #666666;
+    line-height: 24px;
+    text-align: center;
+  }
+
+  .popupBtnGroup {
+    display: flex;
+    align-items: center;
+
+    &>button {
+      flex: 1;
+      font-weight: 400;
+      font-size: 16px !important;
+
+      &:last-child {
+        margin-left: 15px;
+      }
+    }
+  }
+}

+ 30 - 0
src/components/TheVip/index.tsx

@@ -0,0 +1,30 @@
+import { Button, Popup } from 'vant';
+import { defineComponent, reactive } from 'vue';
+import styles from './index.module.less';
+import { state } from '@/state';
+import { gotoMemberCenter } from '@/views/hook/useFee';
+
+export default defineComponent({
+  name: 'theVip',
+  setup() {
+    return () => (
+      <Popup v-model:show={state.vipShow} round class={styles.courseDialog}>
+        <i
+          class={styles.iconClose}
+          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>
+        </div>
+      </Popup>
+    );
+  }
+});

BIN
src/components/TheVip/top-bg.png


+ 10 - 0
src/state.ts

@@ -9,6 +9,9 @@ export const state = reactive({
     status: 'init' as status,
     data: {} as any
   },
+  vipShow: false, // 是否打开会员
+  buyVipId: '', // 购买会员编号
+  buyVipType: '' as '' | 'MUSIC' | 'COURSE',
   platformType: 'STUDENT' as 'STUDENT' | 'TEACHER' | 'SCHOOL',
   clientId: {
     STUDENT: 'jmedu-student',
@@ -29,6 +32,13 @@ export const state = reactive({
   choiseType: '', // 需要选择资源的类型
 });
 
+/** 购买会员提示 */
+export const handleShowVip = (buyVipId: string, buyVipType: '' | 'MUSIC' | 'COURSE') => {
+  state.vipShow = true;
+  state.buyVipId = buyVipId;
+  state.buyVipType = buyVipType;
+}
+
 // 预览上传到oss的地址
 export const getOssUploadUrl = (bucket: string) => {
   const tmpBucket = bucket || 'gyt';

BIN
src/views/courseList/image/icon-course-lock.png


BIN
src/views/courseList/image/top-bg.png


+ 9 - 3
src/views/courseList/index.module.less

@@ -14,6 +14,7 @@
     position: relative;
     width: 107px;
     min-height: 130px;
+    max-height: 135px;
     margin-right: 30px;
     border-radius: 2px;
     overflow: hidden;
@@ -265,6 +266,10 @@
 
 .courseDialog {
   padding: 20px;
+  max-width: 315px !important;
+  background: url('./image/top-bg.png') no-repeat top center #fff !important;
+  background-size: contain !important;
+  overflow: hidden;
 
   // :global {
   //   .van-popup__close-icon {
@@ -276,8 +281,8 @@
     width: 18px;
     height: 19px;
     position: absolute;
-    top: 24px;
-    right: 23px;
+    top: 23px;
+    right: 20px;
     z-index: 9;
     background: url('./image/icon-close.png') no-repeat center;
     background-size: contain;
@@ -287,7 +292,7 @@
     position: relative;
     font-size: 18px;
     font-weight: 600;
-    color: #131415;
+    color: #1A1A1A;
     line-height: 25px;
     text-align: center;
   }
@@ -297,6 +302,7 @@
     font-size: 16px;
     color: #666666;
     line-height: 24px;
+    text-align: center;
   }
 
   .popupBtnGroup {

+ 33 - 29
src/views/courseList/index.tsx

@@ -1,5 +1,5 @@
 import request from '@/helpers/request';
-import { state } from '@/state';
+import { handleShowVip, state } from '@/state';
 import {
   Button,
   Cell,
@@ -13,7 +13,8 @@ import {
   onMounted,
   reactive,
   onUnmounted,
-  TransitionGroup
+  TransitionGroup,
+  computed
 } from 'vue';
 import styles from './index.module.less';
 import { useRoute, useRouter } from 'vue-router';
@@ -25,13 +26,11 @@ import {
 // import iconLook from './image/look.svg'
 import iconCourse from './image/icon-course.png';
 import iconCachePoint from './image/icon-cache-point.png';
-// import iconCourseLock from './image/icon-course-lock.png';
+import iconCourseLock from './image/icon-course-lock.png';
 // import iconTip from './image/iconTip.png';
 import { browser } from '@/helpers/utils';
 import OEmpty from '@/components/o-empty';
-import { handleCheckVip, gotoMemberCenter, hasVip } from '../hook/useFee';
 import iconList from './image/icon-list.png';
-// import OSticky from '@/components/o-sticky';
 import OHeader from '@/components/o-header';
 import { useEventListener } from '@vant/use';
 import OLoading from '@/components/o-loading';
@@ -48,23 +47,32 @@ export default defineComponent({
       catchItem: {} as any,
       loading: true,
       detail: {
+        id: '',
         cover: '',
         name: '',
-        des: ''
+        des: '',
+        useStatus: '',
       },
       list: [] as any,
       isDownloading: false // 是否在下载资源
     });
 
+    /** 是否锁定 */
+    const isLock = computed(() => {
+      return  data.detail.useStatus === 'LOCK' && state.platformType === 'STUDENT' ? true : false;
+    })
+
     /** 获取课件详情 */
     const getDetail = async () => {
       const res: any = await request.get(
         `${state.platformApi}/lessonCourseware/getLessonCoursewareDetail/${route.query.id}`
       );
       if (res?.data) {
+        data.detail.id = res.data.id;
         data.detail.cover = res.data.coverImg;
         data.detail.name = res.data.name;
         data.detail.des = res.data.lessonTargetDesc;
+        data.detail.useStatus = res.data.useStatus;
       }
     };
     const getList = async () => {
@@ -78,7 +86,7 @@ export default defineComponent({
         if (Array.isArray(res?.data)) {
           data.list = res.data;
           res.data.forEach((item: any) => {
-            const { knowledgePointList, ...res } = item;
+            const { knowledgePointList } = item;
             const tempK = knowledgePointList || [];
             tempK.forEach((child: any) => {
               child.materialList = [
@@ -148,9 +156,10 @@ export default defineComponent({
         });
         return;
       }
-
-      const isVip = handleCheckVip();
-      if (!isVip) return;
+      if(isLock.value) {
+        handleShowVip(route.query.id as string, "COURSE")
+        return
+      }
 
       if (!item.hasCache) {
         // const hasFree = String(item.accessScope) === '0';
@@ -316,12 +325,6 @@ export default defineComponent({
               <div key="list" class={styles.periodList}>
                 <CellGroup inset>
                   {data.list.map((item: any) => {
-                    // const isLock =
-                    //   item.lockFlag ||
-                    //   ((route.query.code == 'select' ||
-                    //     state.platformType == 'STUDENT') &&
-                    //     !item.unlock);
-                    // const isSelect = route.query.code === 'select';
                     return (
                       <Cell
                         border
@@ -337,7 +340,7 @@ export default defineComponent({
                           icon: () => (
                             <div class={styles.periodItem}>
                               <div class={styles.periodItemModel}>
-                                <img src={iconCourse} />
+                                <img src={isLock.value ? iconCourseLock : iconCourse} />
                                 {item.hasCache ? (
                                   <img
                                     class={styles.iconCachePoint}
@@ -358,15 +361,18 @@ export default defineComponent({
                             <>
                               {item.knowledgePointList ? (
                                 <>
-                                  {item.hasCache ? (
-                                    <Button
+                                  { isLock.value ? <Button
                                       class={[
                                         styles.baseBtn,
                                         styles.look,
-                                        state.platformType === 'STUDENT' &&
-                                        !hasVip()
-                                          ? styles.disabled
-                                          : ''
+                                        styles.disable
+                                      ]}>
+                                      未解锁
+                                    </Button> : item.hasCache ? (
+                                    <Button
+                                      class={[
+                                        styles.baseBtn,
+                                        styles.look
                                       ]}>
                                       查看
                                     </Button>
@@ -375,10 +381,6 @@ export default defineComponent({
                                       class={[
                                         styles.baseBtn,
                                         styles.down,
-                                        state.platformType === 'STUDENT' &&
-                                        !hasVip()
-                                          ? styles.disabled
-                                          : '',
                                         item.downloadStatus == 1
                                           ? styles.downing
                                           : ''
@@ -406,10 +408,12 @@ export default defineComponent({
         {data.loading && <OLoading />}
         {!data.loading && !data.list.length && <OEmpty tips="暂无内容" />}
 
-        {state.platformType === 'STUDENT' && !hasVip() && (
+        {isLock.value && (
           <OSticky position="bottom">
             <div class={styles.btnGroup}>
-              <Button round block type="primary" onClick={gotoMemberCenter}>
+              <Button round block type="primary" onClick={() => {
+                handleShowVip(route.query.id as string, "COURSE")
+              }}>
                 开通会员即可查看所有课件
               </Button>
             </div>

+ 7 - 1
src/views/coursewarePlay/component/video-play.tsx

@@ -26,7 +26,7 @@ import {
 import TCPlayer from 'tcplayer.js';
 import 'tcplayer.js/dist/tcplayer.min.css';
 import { Slider } from 'vant';
-import { state } from '@/state';
+import { handleShowVip, state } from '@/state';
 
 // 秒转分
 export const getSecondRPM = (second: number, type?: string) => {
@@ -323,6 +323,12 @@ export default defineComponent({
     const gotoAccomany = (e: any) => {
       // 去云练习完整版
       e.stopPropagation();
+      // 判断是否需要购买
+      if(item.value.isLock) {
+        handleShowVip(item.value.materialMusicId, "MUSIC")
+        return
+      }
+
       const Authorization = sessionStorage.getItem('Authorization') || '';
       // const origin = /(localhost|192)/.test(location.host)
       //   ? 'https://test.gym.lexiaoya.cn'

+ 16 - 66
src/views/coursewarePlay/index.tsx

@@ -14,7 +14,7 @@ import iconBack from './image/back.svg';
 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 {
   listenerMessage,
@@ -38,7 +38,6 @@ import { Vue3Lottie } from 'vue3-lottie';
 import playLoadData from './datas/data.json';
 import { usePageVisibility } from '@vant/use';
 // import PlayRecordTime from './playRecordTime';
-import { handleCheckVip } from '../hook/useFee';
 import OGuide from '@/components/o-guide';
 import Tool, { ToolItem, ToolType } from './component/tool';
 import Pen from './component/tools/pen';
@@ -322,8 +321,12 @@ export default defineComponent({
                     materialRefs.length > 0
                       ? materialRefs[0].resourceIdStr
                       : null;
+                  const useStatus = materialRefs.length > 0
+                  ? materialRefs[0]?.extend?.useStatus : null
+                  const isLock = useStatus === 'LOCK' && state.platformType === "STUDENT" ? true : false
                   return {
                     ...item,
+                    isLock,
                     materialMusicId,
                     content: item.content,
                     knowledgePointId: [item.knowledgePointId],
@@ -343,8 +346,12 @@ export default defineComponent({
                       materialRefs.length > 0
                         ? materialRefs[0].resourceIdStr
                         : null;
+                    const useStatus = materialRefs.length > 0
+                    ? materialRefs[0]?.extend?.useStatus : null
+                    const isLock = useStatus === 'LOCK' && state.platformType === "STUDENT" ? true : false
                     return {
                       ...item,
+                      isLock,
                       materialMusicId,
                       content: item.content,
                       knowledgePointId: [n.id, item.knowledgePointId],
@@ -456,24 +463,7 @@ export default defineComponent({
     onMounted(async () => {
       await sysParamConfig();
       await getDetail();
-      const hasFree = String(data.detail?.accessScope) === '0';
-      if (!hasFree) {
-        if (state.platformType === 'STUDENT') {
-          const hasVip = handleCheckVip();
-          if (!hasVip) {
-            nextTick(() => {
-              postMessage({
-                api: 'courseLoading',
-                content: {
-                  show: false,
-                  type: 'fullscreen'
-                }
-              });
-            });
-            return;
-          }
-        }
-      }
+     
       // getCourseSchedule();
       window.addEventListener('message', iframeHandle);
 
@@ -1048,52 +1038,7 @@ export default defineComponent({
                       ? effects[effectIndex.value].next
                       : {}
                   }>
-                  {/* {m.type === 'VIDEO' && (
-                      <>
-                        <VideoPlay
-                          ref={(v: any) => (data.videoRefs[mIndex] = v)}
-                          item={m}
-                          isActive={activeEle}
-                          isEmtry={isEmtry}
-                          onPrepare={(val) => {
-                            m.isprepare = val
-                          }}
-                          onLoadedmetadata={(videoItem: any) => {
-                            m.videoEle = videoItem
-                          }}
-                          onTogglePlay={(paused: boolean) => {
-                            // console.log('播放切换', paused)
-                            if (!m.isprepare) {
-                              m.isprepare = true
-                            }
-                            m.autoPlay = false
-                            if (paused || popupData.open || popupData.guideOpen) {
-                              clearTimeout(activeData.timer)
-                            } else {
-                              setModelOpen()
-                            }
-                          }}
-                          onEnded={() => {
-                            const _index = popupData.activeIndex + 1
-                            if (_index < data.itemList.length) {
-                              handleSwipeChange(_index)
-                            }
-                          }}
-                          onReset={() => {
-                            if (!m.videoEle?.paused) {
-                              setModelOpen()
-                            }
-                          }}
-                        />
-                        <Transition name="van-fade">
-                          {!m.isprepare && (
-                            <div class={styles.loadWrap}>
-                              <Vue3Lottie animationData={playLoadData}></Vue3Lottie>
-                            </div>
-                          )}
-                        </Transition>
-                      </>
-                    )} */}
+                  
                   <Transition name="van-fade">
                     {m.typeCode === 'VIDEO' &&
                       data.animationState !== 'end' &&
@@ -1115,6 +1060,11 @@ export default defineComponent({
                           onClick={(e: any) => {
                             // 去云练习完整版
                             e.stopPropagation();
+                            if(m.isLock) {
+                              handleShowVip(m.materialMusicId, "MUSIC")
+                              return
+                            }
+
                             const Authorization =
                               sessionStorage.getItem('Authorization') || '';
                             const origin = /(localhost|192)/.test(location.host)

+ 5 - 8
src/views/exercise-after-class/index.tsx

@@ -23,7 +23,6 @@ import {
 // import { browser } from '@/helpers/utils';
 import { Vue3Lottie } from 'vue3-lottie';
 import playLoadData from '../coursewarePlay/datas/data.json';
-// import { handleCheckVip } from '../hook/useFee';
 import VideoClass from './video-class';
 import { usePageVisibility } from '@vant/use';
 import { useInterval, useIntervalFn } from '@vueuse/core';
@@ -163,12 +162,10 @@ export default defineComponent({
             autoplay: hasVip() ? true : false //自动播放
           };
         });
-        // console.log(data.trainings, 'trainings', hasVip());
         data.itemList = data.trainings.filter(
           (n: any) => n.id == route.query.materialId
         );
         data.videoData = data.itemList[0];
-        // console.log(data.videoData, '1212112', data.itemList);
         if (data.disableScreenRecordingFlag === '1') {
           // 检测是否录屏
           handleLimitScreenRecord();
@@ -442,11 +439,11 @@ export default defineComponent({
       data.visiableStatus = false;
     };
     const dialogCancel = () => {
-      try {
-        // data.trainings[data.itemIndex].currentTime = 0;
-      } catch (e) {
-        //
-      }
+      // try {
+      //   // data.trainings[data.itemIndex].currentTime = 0;
+      // } catch (e) {
+      //   //
+      // }
       data.visiableStatus = false;
     };
 

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

@@ -12,7 +12,7 @@ export const gotoMemberCenter = () => {
     pathname = '/mdaya/'
   }
   if (browserInfo.isApp) {
-    const url = window.location.origin + pathname + `#/member`;
+    const url = window.location.origin + pathname + `#/member?id=${state.buyVipId}&type=${state.buyVipType}`;
     postMessage({
       api: 'openWebView',
       content: {

+ 1 - 1
vite.config.ts

@@ -14,7 +14,7 @@ function resolve(dir: string) {
 }
 // https://vitejs.dev/config/
 // https://github.com/vitejs/vite/issues/1930 .env
-const proxyUrl = 'https://test.gym.lexiaoya.cn';
+const proxyUrl = 'https://dev.gym.lexiaoya.cn';
 export default defineConfig({
   base: './',
   plugins: [