Browse Source

Merge branch 'hqyDev' of http://git.dayaedu.com/liushengqiang/classroom-app into online

黄琪勇 2 months ago
parent
commit
f3dd2e0393

+ 84 - 68
src/helpers/utils.ts

@@ -18,6 +18,22 @@ export function vaildMusicScoreUrl() {
   return returnUrl;
 }
 
+export function vaildPPTUrl() {
+  const url: string = window.location.hostname;
+  let returnUrl = '';
+
+  if (/test/.test(url)) {
+    returnUrl = 'https://test.kt.colexiu.com/classroom-ppt';
+  } else if (/dev/.test(url)) {
+    returnUrl = 'https://dev.kt.colexiu.com/classroom-ppt';
+  } else if (/localhost/.test(url)) {
+    returnUrl = 'http://localhost:9527';
+  } else {
+    returnUrl = 'https://mec.colexiu.com/classroom-ppt';
+  }
+  return returnUrl;
+}
+
 export const browser = () => {
   // https://blog.csdn.net/qq_19309473/article/details/124138954
   const u = navigator.userAgent;
@@ -48,7 +64,7 @@ export const browser = () => {
     }
     return IsIPad;
   }
-  //  || navigator?.userAgent?.includes("UAWEIVRD-W09") 
+  //  || navigator?.userAgent?.includes("UAWEIVRD-W09")
 
   return {
     trident: u.indexOf('Trident') > -1, //IE内核
@@ -261,23 +277,23 @@ const instruments: any = {
   'Electric Grand Piano': '电钢琴',
   'Rhodes Piano': '柔和的电钢琴',
   'Chorused Piano': '加合唱效果的电钢琴',
-  'Harpsichord': '羽管键琴',
-  'Clavichord': '科拉维科特琴',
-  'Celesta': '钢片琴',
-  'Glockenspiel': '钢片琴',
+  Harpsichord: '羽管键琴',
+  Clavichord: '科拉维科特琴',
+  Celesta: '钢片琴',
+  Glockenspiel: '钢片琴',
   'Music box': '八音盒',
-  'Vibraphone': '颤音琴',
-  'Marimba': '马林巴',
-  'Xylophone': '木琴',
+  Vibraphone: '颤音琴',
+  Marimba: '马林巴',
+  Xylophone: '木琴',
   'Tubular Bells': '管钟',
-  'Dulcimer': '大扬琴',
+  Dulcimer: '大扬琴',
   'Hammond Organ': '击杆风琴',
   'Percussive Organ': '打击式风琴',
   'Rock Organ': '摇滚风琴',
   'Church Organ': '教堂风琴',
   'Reed Organ': '簧管风琴',
-  'Accordian': '手风琴',
-  'Harmonica': '口琴',
+  Accordian: '手风琴',
+  Harmonica: '口琴',
   'Tango Accordian': '探戈手风琴',
   'Acoustic Guitar': '钢弦吉他',
   'Electric Guitar': '闷音电吉他',
@@ -289,23 +305,23 @@ const instruments: any = {
   'Fretless Bass': '无品贝司',
   'Slap Bass': '掌击',
   'Synth Bass': '电子合成',
-  'Violin': '小提琴',
-  'Viola': '中提琴',
-  'Cello': '大提琴',
-  'Contrabass': '低音大提琴',
+  Violin: '小提琴',
+  Viola: '中提琴',
+  Cello: '大提琴',
+  Contrabass: '低音大提琴',
   'Tremolo Strings': '弦乐群颤音音色',
   'Pizzicato Strings': '弦乐群拨弦音色',
   'Orchestral Harp': '竖琴',
-  'Timpani': '定音鼓',
+  Timpani: '定音鼓',
   'String Ensemble': '弦乐合奏音色',
   'Synth Strings': '合成弦乐合奏音色',
   'Choir Aahs': '人声合唱',
   'Voice Oohs': '人声',
   'Synth Voice': '合成人声',
   'Orchestra Hit': '管弦乐敲击齐奏',
-  'Trumpet': '小号',
-  'Trombone': '长号',
-  'Tuba': '大号',
+  Trumpet: '小号',
+  Trombone: '长号',
+  Tuba: '大号',
   'Muted Trumpet': '加弱音器小号',
   'French Horn': '法国号',
   'Brass Section': '铜管组',
@@ -314,36 +330,36 @@ const instruments: any = {
   'Alto Sax': '中音萨克斯管',
   'Tenor Sax': '次中音萨克斯管',
   'Baritone Sax': '低音萨克斯管',
-  'Oboe': '双簧管',
+  Oboe: '双簧管',
   'English Horn': '英国管',
-  'Bassoon': '巴松',
+  Bassoon: '巴松',
   'Soprano Saxophone': '高音萨克斯管',
   'Alto Saxophone': '中音萨克斯管',
   'Tenor Saxophone': '次中音萨克斯管',
   'Baritone Saxophone': '低音萨克斯管',
-  'Piccolo': '短笛',
-  'Flute': '长笛',
-  'Recorder': '竖笛',
+  Piccolo: '短笛',
+  Flute: '长笛',
+  Recorder: '竖笛',
   'Soprano Recorder': '高音竖笛',
   'Pan Flute': '排箫',
   'Bottle Blow': '瓶木管',
-  'Whistle': '口哨声',
-  'Ocarina': '陶笛',
-  'Lead': '合成主音',
+  Whistle: '口哨声',
+  Ocarina: '陶笛',
+  Lead: '合成主音',
   'Lead lead': '合成主音',
   'Pad age': '合成音色',
-  'Pad': '合成音色',
-  'FX': '合成效果  科幻',
-  'Sitar': '西塔尔',
-  'Banjo': '班卓琴',
-  'Shamisen': '三昧线',
-  'Koto': '十三弦筝',
-  'Kalimba': '卡林巴',
-  'Bagpipe': '风笛',
-  'Fiddle': '民族提琴',
-  'Shanai': '山奈',
+  Pad: '合成音色',
+  FX: '合成效果  科幻',
+  Sitar: '西塔尔',
+  Banjo: '班卓琴',
+  Shamisen: '三昧线',
+  Koto: '十三弦筝',
+  Kalimba: '卡林巴',
+  Bagpipe: '风笛',
+  Fiddle: '民族提琴',
+  Shanai: '山奈',
   'Tinkle Bell': '叮当铃',
-  'Agogos': '阿戈戈铃',
+  Agogos: '阿戈戈铃',
   'Steel Drums': '钢鼓',
   'Taiko Drum': '太鼓',
   'Melodic Toms': '嗵嗵鼓',
@@ -351,18 +367,18 @@ const instruments: any = {
   'Reverse Cymbals': '反向镲',
   'Agogo Bells': '阿戈戈铃',
   'Taiko Drums': '太鼓',
-  'Bongos': '邦戈鼓',
+  Bongos: '邦戈鼓',
   'Bongo Bell': '邦戈铃',
-  'Congas': '康加鼓',
-  'Guiro': '刮壶',
+  Congas: '康加鼓',
+  Guiro: '刮壶',
   'Guitar Fret Noise': '吉他换把杂音',
   'Breath Noise': '呼吸声',
-  'Seashore': '海浪声',
+  Seashore: '海浪声',
   'Bird Tweet': '鸟鸣',
   'Telephone Ring': '电话铃',
-  'Helicopter': '直升机',
-  'Applause': '鼓掌声',
-  'Gunshot': '枪声',
+  Helicopter: '直升机',
+  Applause: '鼓掌声',
+  Gunshot: '枪声',
   'Acoustic Bass Drum': '大鼓',
   'Bass Drum': '大鼓',
   'Side Drum': '小鼓鼓边',
@@ -382,9 +398,9 @@ const instruments: any = {
   'Ride Cymbals': '叮叮镲',
   'Chinese Cymbals': '中国镲',
   'Ride Bell': '圆铃',
-  'Tambourine': '铃鼓',
+  Tambourine: '铃鼓',
   'Splash Cymbal': '溅音镲',
-  'Cowbell': '牛铃',
+  Cowbell: '牛铃',
   'Crash Cymbal': '强音钹',
   'Vibra-Slap': '颤音器',
   'Ride Cymbal': '打点钹',
@@ -397,68 +413,68 @@ const instruments: any = {
   'Low Timbale': '低音天巴鼓',
   'High Agogo': '高音阿戈戈铃',
   'Low Agogo': '低音阿戈戈铃',
-  'Cabasa': '卡巴萨',
-  'Maracas': '沙锤',
+  Cabasa: '卡巴萨',
+  Maracas: '沙锤',
   'Short Whistle': '短口哨',
   'Long Whistle': '长口哨',
   'Short Guiro': '短刮壶',
   'Long Guiro': '长刮壶',
-  'Claves': '响棒',
+  Claves: '响棒',
   'Hi Wood Block': '高音木鱼',
   'Low Wood Block': '低音木鱼',
   'Mute Triangle': '弱音三角铁',
   'Open Triangle': '强音三角铁',
   'Drum Set': '架子鼓',
   'Hulusi flute': '葫芦丝',
-  'Melodica': '口风琴',
+  Melodica: '口风琴',
   'Snare Drum': '小军鼓',
   'Horn in F': '圆号',
-  'Triangle': '三角铁',
-  'Vibrato': '颤音琴',
+  Triangle: '三角铁',
+  Vibrato: '颤音琴',
   'Suspend Cymbals': '吊镲',
   'Suspended Cymbals': '吊镲',
   'Tom-Toms': '嗵嗵鼓',
-  'Bell': '铃铛',
-  'Bells': '铃铛',
+  Bell: '铃铛',
+  Bells: '铃铛',
   'Alto Clarinet': '中音单簧管',
   'Bass Clarinet': '低音单簧管',
-  'Clarinet': '单簧管',
-  'Cornet': '短号',
-  'Euphonium': '上低音号',
+  Clarinet: '单簧管',
+  Cornet: '短号',
+  Euphonium: '上低音号',
   'crash cymbals': '对镲',
-  'Castanets': '响板',
-  'Shaker': '沙锤',
+  Castanets: '响板',
+  Shaker: '沙锤',
   'Mark tree': '音树',
-  'Chimes': '管钟',
+  Chimes: '管钟',
   'Mark Tree': '音树',
   'Tom-toms': '嗵嗵鼓',
   'Hi-Hat': '踩镲',
   'Sleigh Bells': '雪橇铃',
-  'Flexatone': '弹音器',
+  Flexatone: '弹音器',
   'Brake drum': '闸鼓',
-  'Gong': '锣',
+  Gong: '锣',
   'concert tom': '音乐会嗵嗵鼓',
   'brake drum': '车轮鼓',
   'finger cymbal': '指钹',
   'ride cymbal': '叮叮镲',
   'Concert Toms': '音乐会嗵嗵鼓',
-  'Vibraslap': '弹音器',
+  Vibraslap: '弹音器',
   'Wood Blocks': '木鱼',
   'Temple Blocks': '木鱼',
   'Wood Block': '木鱼',
   'Field Drum': '军鼓',
   'Quad-Toms': '筒鼓',
-  'Quads': '筒鼓',
+  Quads: '筒鼓',
   'Drums set': '架子鼓',
   'High Bongo': '邦戈',
-  'Timbales': '天巴鼓',
+  Timbales: '天巴鼓',
   'rain stick': '雨棒',
   'String Bass': '弦乐低音',
   'Floor Tom': '侧嗵鼓',
   'Brake Drum': '闸鼓',
   'Tam-tam': '大锣',
-  'Cymbal': '镲',
-  'Cymbals': '镲',
+  Cymbal: '镲',
+  Cymbals: '镲'
 };
 
 /** 获取分轨名称 */

+ 63 - 0
src/views/courseware-play/component/PptList/index.tsx

@@ -0,0 +1,63 @@
+import { defineComponent, ref, onMounted, onUnmounted } from 'vue';
+import styles from './pptList.module.less';
+import { vaildPPTUrl } from '@/helpers/utils';
+import { storage } from '@/helpers/storage';
+import { ACCESS_TOKEN } from '@/store/mutation-types';
+
+export default defineComponent({
+  name: 'pptList',
+  props: {
+    pptData: {
+      type: Object,
+      default: () => ({})
+    },
+    fromType: {
+      type: String // 'PLATFORM' | 'TEACHER' | 'CLASS'
+    }
+  },
+  emits: ['initPPT', 'changeSlideIndex', 'init'],
+  setup(props, { emit, expose }) {
+    const Authorization = storage.get(ACCESS_TOKEN);
+    const iframeRef = ref<HTMLIFrameElement>();
+    const src = `${vaildPPTUrl()}/#/mobileScreen?id=${
+      props.pptData.id
+    }&Authorization=${Authorization}&hideFullScreen=true&fromType=${
+      props.fromType
+    }`;
+    // 上一页下一页
+    function handleChangeSlide(type: 'prev' | 'next') {
+      iframeRef.value?.contentWindow?.postMessage(
+        { type: 'changePageSlide', content: type },
+        '*'
+      );
+    }
+    function handleMessage(event: any) {
+      const { type, content } = event.data || {};
+      console.log(content, 'message');
+      if (type === 'initPPT') {
+        emit('initPPT', content);
+      } else if (type === 'changeSlideIndex') {
+        emit('changeSlideIndex', content);
+      }
+    }
+    emit('init');
+    onMounted(() => {
+      window.addEventListener('message', handleMessage);
+    });
+    onUnmounted(() => {
+      window.removeEventListener('message', handleMessage);
+    });
+    expose({
+      handleChangeSlide
+    });
+    return () => (
+      <div class={styles.pptList}>
+        <iframe
+          ref={iframeRef}
+          class={[styles.container]}
+          frameborder="0"
+          src={src}></iframe>
+      </div>
+    );
+  }
+});

+ 13 - 0
src/views/courseware-play/component/PptList/pptList.module.less

@@ -0,0 +1,13 @@
+.pptList {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  .container {
+    position: relative;
+    display: block;
+    border: none;
+    width: 100%;
+    height: 100%;
+    z-index: 10;
+  }
+}

+ 5 - 1
src/views/courseware-play/index.module.less

@@ -230,6 +230,10 @@
     opacity: .3;
     pointer-events: none;
   }
+
+  &.hideBtn{
+    display: none;
+  }
 }
 
 
@@ -286,4 +290,4 @@
   display: flex;
   justify-content: center;
   align-items: center;
-}
+}

+ 81 - 4
src/views/courseware-play/index.tsx

@@ -60,6 +60,7 @@ import TempoItem from './component/tempo-item';
 import ListenItem from './component/listen-item';
 import SelectCoursewareMember from '@/components/select-courseware-member';
 import request from '@/helpers/request';
+import PptList from './component/PptList';
 
 export default defineComponent({
   name: 'CoursewarePlay',
@@ -173,7 +174,15 @@ export default defineComponent({
       videoState: 'init' as 'init' | 'play',
       videoItemRef: null as any,
       animationState: 'start' as 'start' | 'end',
-      coursewareList: []
+      coursewareList: [],
+      coursewareType: 'CLASSIC' as 'CLASSIC' | 'PPT' // 课件类型
+    });
+    const pptData = reactive({
+      pptEl: null as any,
+      slidesLen: 1,
+      activeLen: 0,
+      disable: false,
+      isAnimationed: true
     });
     const activeData = reactive({
       isAutoPlay: true, // 是否自动播放
@@ -296,6 +305,8 @@ export default defineComponent({
                 : item.coverImg
           };
         });
+        data.coursewareType =
+          courseList[0].type === 'PPT_JSON' ? 'PPT' : 'CLASSIC';
       }
       // 当前章节下的所有资源列表
       let allResource: any = [];
@@ -714,6 +725,19 @@ export default defineComponent({
 
     // 上一个知识点, 下一个知识点
     const handlePreAndNext = async (type: string) => {
+      // 这里新加了ppt 逻辑所以需要
+      if (data.coursewareType === 'PPT') {
+        if (type === 'up' && pptData.activeLen > 0) {
+          pptData.pptEl?.handleChangeSlide('prev');
+          return;
+        } else if (
+          type === 'down' &&
+          (pptData.activeLen < pptData.slidesLen - 1 || !pptData.isAnimationed)
+        ) {
+          pptData.pptEl?.handleChangeSlide('next');
+          return;
+        }
+      }
       // 层级关系:单元〉章节〉知识点〉课件资源
       if (type === 'up') {
         // 判断上面是否还有章节
@@ -903,6 +927,12 @@ export default defineComponent({
 
     // 是否允许上一页
     const isUpArrow = computed(() => {
+      if (data.coursewareType === 'PPT') {
+        if (pptData.disable) return false;
+        if (pptData.activeLen > 0) {
+          return true;
+        }
+      }
       /**
        * 1,判断当前课程中是否处在第一个资源;
        * 2,判断当前课程是否在当前章节的第一个;
@@ -971,6 +1001,15 @@ export default defineComponent({
 
     // 是否允许下一页
     const isDownArrow = computed(() => {
+      if (data.coursewareType === 'PPT') {
+        if (pptData.disable) return false;
+        if (
+          pptData.activeLen < pptData.slidesLen - 1 ||
+          !pptData.isAnimationed
+        ) {
+          return true;
+        }
+      }
       if (popupData.activeIndex < data.itemList.length - 1) {
         return true;
       }
@@ -1413,7 +1452,29 @@ export default defineComponent({
                         />
                       )}
                     </>
-                    {/* )} */}
+                    {m.type === 'PPT_JSON' && (
+                      <PptList
+                        ref={el => {
+                          pptData.pptEl = el;
+                        }}
+                        onInit={() => {
+                          pptData.disable = true;
+                        }}
+                        onInitPPT={({ slidesLen, isAnimationed }) => {
+                          pptData.disable = false;
+                          pptData.slidesLen = slidesLen;
+                          pptData.isAnimationed = isAnimationed;
+                          pptData.activeLen = 0;
+                        }}
+                        onChangeSlideIndex={({ slideIndex, isAnimationed }) => {
+                          pptData.activeLen = slideIndex;
+                          pptData.isAnimationed = isAnimationed;
+                        }}
+                        pptData={m}
+                        fromType={
+                          route.query.tab == 'course' ? 'CLASS' : 'PLATFORM'
+                        }></PptList>
+                    )}
                   </div>
                 ) : (
                   <div
@@ -1453,8 +1514,24 @@ export default defineComponent({
                 </div>
 
                 <div
-                  class={[styles.fullBtn, styles.point]}
-                  onClick={() => (popupData.open = true)}>
+                  class={[
+                    styles.fullBtn,
+                    styles.point,
+                    data.coursewareType === 'PPT' && data.allList.length <= 1
+                      ? styles.hideBtn
+                      : ''
+                  ]}
+                  onClick={() => {
+                    // 现在 如果当前是ppt,并且有多个课件的时候,就直接出现选择课件
+                    if (
+                      data.coursewareType === 'PPT' &&
+                      data.allList.length > 1
+                    ) {
+                      checkCourseware({}, 'same');
+                    } else {
+                      popupData.open = true;
+                    }
+                  }}>
                   <img src={iconMenu} />
                   <span>课件</span>
                 </div>

+ 1 - 1
src/views/creation/index.tsx

@@ -614,7 +614,7 @@ export default defineComponent({
           演奏:{state.musicDetail?.username}
         </div>
         <Sticky zIndex={1000} offsetTop={state.heightV - 1 + "px"}>
-          <div class={[styles.playSection, plyrState.mediaTimeShow && styles.mediaTimeShow, isLandscapeScreen.value&&styles.isLandscapeScreen]} id="playMediaSection" onClick={handlerClickPlay}>
+          <div data-html2canvas-ignore="true" class={[styles.playSection, plyrState.mediaTimeShow && styles.mediaTimeShow, isLandscapeScreen.value&&styles.isLandscapeScreen]} id="playMediaSection" onClick={handlerClickPlay}>
             {
               isLandscapeScreen.value &&
                 <div class={styles.backBox}>