1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405 |
- import { closeToast, Icon, Popup, showDialog, showToast } from 'vant';
- import {
- defineComponent,
- onMounted,
- reactive,
- onUnmounted,
- ref,
- watch,
- Transition,
- computed
- } from 'vue';
- import iconBack from './image/back.svg';
- import styles from './index.module.less';
- import 'plyr/dist/plyr.css';
- import { useRoute } from 'vue-router';
- import {
- listenerMessage,
- postMessage,
- promisefiyPostMessage
- } from '@/helpers/native-message';
- import MusicScore from './component/musicScore';
- import iconMenu from './image/icon-menu.svg';
- import iconChange from './image/icon-change.svg';
- // import iconDian from './image/icon-dian.svg';
- // import iconPoint from './image/icon-point.svg';
- import iconUp from './image/icon-up.svg';
- import iconDown from './image/icon-down.svg';
- import selectIcon from './image/select_btn.png';
- import memberLockBg from './image/member_lock_bg.png';
- import Points from './component/points';
- import { Vue3Lottie } from 'vue3-lottie';
- import playLoadData from './datas/data.json';
- import { usePageVisibility } from '@vant/use';
- import AudioItem from './component/audio-item';
- import {
- api_lessonCoursewareStudentDetail,
- api_lessonCoursewareDetail
- } from '../courseware-list/api';
- import VideoItem from './component/video-item';
- import Chapter from './component/chapter';
- import { setLogin, state } from '@/state';
- import Theory from './component/theory';
- import InstrumentInfo from './component/instrument-info';
- import TempoItem from './component/tempo-item';
- import ListenItem from './component/listen-item';
- import request from '@/helpers/request';
- import PptList from './component/PptList';
- import SelectCoursewareTip from './select-courseware-tip';
- export default defineComponent({
- name: 'CoursewarePlay',
- setup() {
- const pageVisibility = usePageVisibility();
- // const lastTimeKey = 'lastTime' + (state?.user?.data?.phone ?? '');
- const showSelectCourseware = ref(false);
- const showMember = ref(false);
- const debounceSkip = ref(false);
- /** 设置播放容器 16:9 */
- const parentContainer = reactive({
- width: '100vw'
- });
- const setContainer = () => {
- let min = Math.min(screen.width, screen.height);
- let max = Math.max(screen.width, screen.height);
- let width = min * (16 / 9);
- if (width > max) {
- parentContainer.width = '100vw';
- return;
- } else {
- parentContainer.width = width + 'px';
- }
- };
- const handleInit = (type = 0) => {
- //设置容器16:9
- setContainer();
- // 横屏
- // postMessage(
- // {
- // api: 'setRequestedOrientation',
- // content: {
- // orientation: type
- // }
- // },
- // () => {
- // console.log(234);
- // }
- // );
- // 头,包括返回箭头
- // postMessage({
- // api: 'setTitleBarVisibility',
- // content: {
- // status: type
- // }
- // })
- // 安卓的状态栏
- postMessage({
- api: 'setStatusBarVisibility',
- content: {
- isVisibility: type
- }
- });
- // 进入页面设置常量
- postMessage({
- api: 'keepScreenLongLight',
- content: {
- isOpenLight: type ? true : false
- }
- });
- };
- handleInit();
- onUnmounted(() => {
- handleInit(1);
- window.removeEventListener('message', iframeHandle);
- window.removeEventListener('online', handleOnline);
- window.removeEventListener('offline', handleOffline);
- });
- const getCourseDetail = async () => {
- try {
- const res = await api_lessonCoursewareDetail({
- id: activeData.lessonCoursewareId as any
- });
- if (res?.code == 200 && Array.isArray(res?.data?.lessonList)) {
- data.courseDetails = res.data.lessonList || [];
- }
- } catch {
- //
- }
- };
- const route = useRoute();
- const headeRef = ref();
- const loadingClass = ref(false); // 重新加载课件
- const data = reactive({
- disableScreenRecordingFlag: '0',
- allList: [] as any, // 所选章节下的所有课件列表
- id: route.query.id as string, // 章节ID
- kjId: route.query.id as string, // 所选的课件id
- currentCourse: {} as any, // 当前选中的课件
- zsdId: '' as string, // 知识点id
- courseDetails: [] as any,
- itemList: [] as any,
- videoRefs: {} as any[],
- videoState: 'init' as 'init' | 'play',
- videoItemRef: null as any,
- animationState: 'start' as 'start' | 'end',
- coursewareType: 'CLASSIC' as 'CLASSIC' | 'PPT' // 课件类型
- });
- // 上一下,下一个切换知识点或单元时临时存的数据
- const changeLessonCourseWare = ref<any>({});
- const pptData = reactive({
- pptEl: null as any,
- slidesLen: 1,
- activeLen: 0,
- disable: false,
- isAnimationed: true
- });
- const activeData = reactive({
- isAutoPlay: true, // 是否自动播放
- lessonCoursewareId: route.query.lessonCoursewareId,
- lessonCoursewareDetailId: null, // 单元编号
- // coursewareDetailKnowledgeId: route.query.coursewareDetailKnowledgeId,
- nowTime: 0,
- model: true, // 遮罩
- isAnimation: true, // 是否动画
- timer: null as any,
- item: null as any
- });
- // 切换单元临时数据
- const temporaryData = reactive({
- dyId: '', // 单元id
- zjId: '' // 章节id
- });
- const getDetail = async () => {
- // data.allList = [];
- const res = await api_lessonCoursewareStudentDetail({
- lessonCoursewareKnowledgeDetailId: data.id // 章节id
- });
- if (res?.code !== 200) return;
- // data.allList = [res.data];
- const currentCourse = res?.data;
- const knowledgeList = currentCourse?.knowledgeList || [];
- const courseList: any = [];
- knowledgeList?.forEach((item: any) => {
- if (Array.isArray(item.materialInfo)) {
- item.materialInfo?.forEach((n: any) => {
- n.audioPlayTypesArray = n.audioPlayTypes
- ? n.audioPlayTypes.split(',')
- : [];
- n.url =
- n.coverImg || n.type === 'SONG'
- ? 'https://oss.dayaedu.com/ktqy/1698420034679a22d3f7a.png'
- : n.type === 'PPT'
- ? 'https://oss.dayaedu.com/ktqy/12/1701931810284.png'
- : n.coverImg;
- n.zsdId = item.id; // 知识点id
- n.kjId = currentCourse.id; // 课件id
- n.bizId = n.bizId;
- courseList.push(n);
- });
- }
- });
- data.zsdId = knowledgeList?.[0].id;
- activeData.lessonCoursewareDetailId =
- currentCourse.lessonCoursewareDetailId;
- data.currentCourse = {
- ...currentCourse,
- knowledgeList
- };
- popupData.itemPointName = currentCourse.name || '';
- // 当前的资源id
- let resourceId: any = null;
- // 课程
- if (courseList.length > 0) {
- resourceId = courseList[0].id;
- data.coursewareType =
- courseList[0].type === 'PPT_JSON' ? 'PPT' : 'CLASSIC';
- }
- data.itemList = courseList.map((m: any) => {
- if (!popupData.itemActive) {
- popupData.itemActive = m.id;
- popupData.itemName = m.name;
- }
- return {
- ...m,
- iframeRef: null,
- videoEle: null,
- audioEle: null,
- domEle: null,
- autoPlay:
- showMember.value || m.paymentType === 'FREE'
- ? data.currentCourse.autoPlay || false
- : false, //加载完成是否自动播放
- isprepare: false, // 视频是否加载完成
- isRender: false // 是否渲染了
- };
- });
- const resourceIndex = data.itemList.findIndex(
- (resource: any) => resource.id === resourceId
- );
- setTimeout(() => {
- handleSwipeChange(resourceIndex);
- }, 0);
- //检测是否录屏
- if (data.disableScreenRecordingFlag === '1') {
- handleLimitScreenRecord();
- }
- setTimeout(() => {
- data.animationState = 'end';
- }, 500);
- };
- // ifram事件处理
- const iframeHandle = (ev: MessageEvent) => {
- if (ev.data?.api === 'headerTogge') {
- activeData.model =
- ev.data.show || (ev.data.playState == 'play' ? false : true);
- }
- if (ev.data?.api === 'api_fingerPreView') {
- clearInterval(activeData.timer);
- activeData.model = !ev.data.state;
- }
- if (ev.data?.api === 'clickTempo' || ev.data?.api === 'clickViewFigner') {
- setModelOpen();
- }
- };
- let timers: any = null;
- const checkVideoPlay = (activeItem: any) => {
- const activeVideoRef =
- activeItem.type === 'VIDEO' ? activeItem.videoEle : activeItem.audioEle;
- if (activeVideoRef) {
- timers = setInterval(() => {
- const paused =
- activeItem.type === 'VIDEO'
- ? activeVideoRef.paused()
- : activeVideoRef.paused;
- if (!paused) {
- activeVideoRef.pause();
- clearInterval(timers);
- }
- activeVideoRef.pause();
- }, 100);
- }
- setTimeout(() => {
- clearInterval(timers);
- }, 3000);
- };
- //录屏时间触发
- const handleLimitScreenRecord = async () => {
- const result = await promisefiyPostMessage({
- api: 'getDeviceStatus',
- content: { type: 'video' }
- });
- const { status } = result?.content || {};
- if (status == '1') {
- data.itemList.forEach((item: any) => (item.autoPlay = false));
- handleStop();
- const activeItem = data.itemList[popupData.activeIndex];
- if (activeItem.type === 'VIDEO' || activeItem.type === 'SONG') {
- // 处理事件 - 事件事件后加载的
- checkVideoPlay(activeItem);
- }
- showDialog({
- title: '温馨提示',
- message: '课件内容请勿录屏',
- beforeClose: () => {
- return new Promise(resolve => {
- promisefiyPostMessage({
- api: 'getDeviceStatus',
- content: { type: 'video' }
- }).then((res: any) => {
- const content = res.content;
- if (content?.status == '1') {
- resolve(false);
- } else {
- data.itemList.forEach((item: any) => (item.autoPlay = true));
- resolve(true);
- }
- });
- });
- }
- });
- }
- };
- // 获取支付渠道
- const sysParamConfig = async () => {
- try {
- const res = await request.get(
- '/edu-app/sysParamConfig/queryByParamName',
- {
- params: {
- paramName: 'disable_screen_recording_flag'
- }
- }
- );
- data.disableScreenRecordingFlag = res.data.paramValue || '';
- } catch {
- //
- }
- };
- onMounted(async () => {
- await sysParamConfig();
- if (state?.user?.data.vipMember) {
- showMember.value = true;
- } else {
- showMember.value = false;
- }
- postMessage({
- api: 'courseLoading',
- content: {
- show: false,
- type: 'fullscreen'
- }
- });
- getDetail();
- getCourseDetail();
- window.addEventListener('message', iframeHandle);
- if (data.disableScreenRecordingFlag === '1') {
- //禁止录屏 ios
- listenerMessage('setVideoPlayer', result => {
- if (result?.content?.status == 'pause') {
- handleLimitScreenRecord();
- }
- });
- // 安卓
- postMessage({
- api: 'limitScreenRecord',
- content: {
- type: 1
- }
- });
- }
- window.addEventListener('online', handleOnline);
- window.addEventListener('offline', handleOffline);
- });
- const lineTimer = ref();
- const handleOnline = () => {
- clearTimeout(lineTimer.value);
- };
- const handleOffline = () => {
- showToast('请检查网络');
- };
- const playRef = ref();
- // 返回
- const goback = () => {
- try {
- playRef.value?.handleOut();
- } catch (error) {}
- postMessage({ api: 'goBack' });
- // router.back()
- };
- const popupData = reactive({
- open: false,
- activeIndex: 0,
- itemActive: '',
- itemName: '',
- itemPointName: '' as any,
- chapterOpen: false
- });
- // 切换素材
- const toggleMaterial = (itemActive: any) => {
- // 如果切换了知识点或者切换了课件,需要加载新的
- const index = data.itemList.findIndex((n: any) => n.id == itemActive);
- if (index > -1) {
- handleSwipeChange(index);
- }
- };
- /** 延迟收起模态框 */
- const setModelOpen = () => {
- clearTimeout(activeData.timer);
- closeToast();
- activeData.model = !activeData.model;
- activeData.timer = setTimeout(() => {
- activeData.model = false;
- }, 4000);
- };
- const setModelOpen1 = () => {
- clearTimeout(activeData.timer);
- closeToast();
- activeData.model = true;
- activeData.timer = setTimeout(() => {
- activeData.model = false;
- }, 4000);
- };
- // 双击
- const handleDbClick = (item: any) => {
- if (item && ['VIDEO'].includes(item.type)) {
- console.log('双击');
- }
- };
- const effectIndex = ref(3);
- const effects = [
- {
- prev: {
- transform: 'translate3d(0, 0, -800px) rotateX(180deg)'
- },
- next: {
- transform: 'translate3d(0, 0, -800px) rotateX(-180deg)'
- }
- },
- {
- prev: {
- transform: 'translate3d(-100%, 0, -800px)'
- },
- next: {
- transform: 'translate3d(100%, 0, -800px)'
- }
- },
- {
- prev: {
- transform: 'translate3d(-50%, 0, -800px) rotateY(80deg)'
- },
- next: {
- transform: 'translate3d(50%, 0, -800px) rotateY(-80deg)'
- }
- },
- {
- prev: {
- transform: 'translate3d(-100%, 0, -800px) rotateY(-120deg)',
- opacity: 0
- },
- next: {
- transform: 'translate3d(100%, 0, -800px) rotateY(120deg)',
- opacity: 0
- }
- },
- // 风车4
- {
- prev: {
- transform: 'translate3d(-50%, 50%, -800px) rotateZ(-14deg)',
- opacity: 0
- },
- next: {
- transform: 'translate3d(50%, 50%, -800px) rotateZ(14deg)',
- opacity: 0
- }
- },
- // 翻页5
- {
- prev: {
- transform: 'translateZ(-800px) rotate3d(0, -1, 0, 90deg)',
- opacity: 0
- },
- next: {
- transform: 'translateZ(-800px) rotate3d(0, 1, 0, 90deg)',
- opacity: 0
- },
- current: { transitionDelay: '700ms' }
- }
- ];
- const handleStop = () => {
- // data.videoItemRef?.pause();
- for (let i = 0; i < data.itemList.length; i++) {
- const activeItem = data.itemList[i];
- if (activeItem.type === 'VIDEO' && activeItem.videoEle) {
- activeItem.videoEle?.pause();
- }
- if (activeItem.type === 'SONG' && activeItem.audioEle) {
- activeItem.audioEle?.pause();
- }
- // 停止曲谱的播放
- if (activeItem.type === 'MUSIC') {
- activeItem.iframeRef?.contentWindow?.postMessage(
- { api: 'setPlayState' },
- '*'
- );
- }
- if (
- activeItem.type === 'INSTRUMENT' ||
- activeItem.type === 'MUSICIAN' ||
- activeItem.type === 'MUSIC_WIKI'
- ) {
- activeItem.domEle?.onChangeAudioStop();
- }
- // console.log(activeItem.type, 'activeItem.type');
- if (activeItem.type === 'RHYTHM') {
- activeItem.iframeRef?.contentWindow?.postMessage(
- { api: 'setPlayState', data: false },
- '*'
- );
- }
- if (activeItem.type === 'LISTEN') {
- activeItem.iframeRef?.contentWindow?.postMessage(
- { api: 'setPlayState' },
- '*'
- );
- }
- }
- };
- const acitveTimer = ref();
- // 轮播切换
- const handleSwipeChange = (index: number) => {
- // 如果是当前正在播放 或者是视频最后一个
- if (popupData.activeIndex == index) return;
- data.animationState = 'start';
- data.videoState = 'init';
- handleStop();
- clearTimeout(acitveTimer.value);
- activeData.model = true;
- const item = data.itemList[index];
- data.kjId = item.kjId;
- data.zsdId = item.zsdId;
- popupData.activeIndex = index;
- popupData.itemActive = item.id;
- popupData.itemName = item.name;
- if (item.type == 'MUSIC') {
- activeData.model = true;
- } else if (item.type == 'VIDEO') {
- if (item.error) {
- data.videoRefs[index]?.onPlay();
- }
- setTimeout(() => {
- data.animationState = 'end';
- }, 800);
- }
- };
- // 上一个知识点, 下一个知识点
- 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') {
- // 判断上面是否还有章节
- if (popupData.activeIndex > 0) {
- handleSwipeChange(popupData.activeIndex - 1);
- return;
- }
- // 获取当前是哪个章节
- let detailIndex = data.courseDetails.findIndex(
- (item: any) => item.id == activeData.lessonCoursewareDetailId
- );
- const detailItem = data.courseDetails[detailIndex]?.knowledgeList || [];
- let lessonIndex = detailItem.findIndex(
- (item: any) => item.id == data.id
- );
- let lessonStatus = false; // 当前章节上面是否有内容
- let lessonCoursewareDetailId = '';
- let coursewareDetailKnowledgeId = '';
- let coursewareDetailKnowledgeName = '';
- let coursewareItem = {} as any;
- while (lessonIndex >= 0) {
- lessonIndex--;
- if (lessonIndex >= 0) {
- if (detailItem[lessonIndex].containMaterial) {
- lessonStatus = true;
- lessonCoursewareDetailId =
- detailItem[lessonIndex].lessonCoursewareDetailId;
- coursewareDetailKnowledgeId = detailItem[lessonIndex].id;
- coursewareDetailKnowledgeName = detailItem[lessonIndex].name;
- coursewareItem = detailItem[lessonIndex];
- }
- }
- if (lessonStatus) {
- break;
- }
- }
- // 判断当前章节下面课程是否有内容,否则往上一个章节走
- if (lessonStatus) {
- temporaryData.zjId = coursewareDetailKnowledgeId;
- temporaryData.dyId = lessonCoursewareDetailId;
- changeCourseWareItem(
- {
- ...coursewareItem,
- itemActive: coursewareDetailKnowledgeId
- },
- type
- );
- return;
- }
- let prevLessonStatus = false;
- while (detailIndex >= 0) {
- detailIndex--;
- const tempDetail =
- data.courseDetails[detailIndex]?.knowledgeList || [];
- let tempLessonLength = tempDetail.length;
- while (tempLessonLength > 0) {
- if (tempDetail[tempLessonLength - 1].containMaterial) {
- prevLessonStatus = true;
- lessonCoursewareDetailId =
- tempDetail[tempLessonLength - 1].lessonCoursewareDetailId;
- coursewareDetailKnowledgeId = tempDetail[tempLessonLength - 1].id;
- coursewareDetailKnowledgeName =
- tempDetail[tempLessonLength - 1].name;
- coursewareItem = tempDetail[tempLessonLength - 1];
- }
- tempLessonLength--;
- if (prevLessonStatus) {
- break;
- }
- }
- if (prevLessonStatus) {
- break;
- }
- }
- // 判断当前章节下面课程是否有内容,否则往上一个章节走
- if (prevLessonStatus) {
- temporaryData.zjId = coursewareDetailKnowledgeId;
- temporaryData.dyId = lessonCoursewareDetailId;
- // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
- changeCourseWareItem(
- {
- ...coursewareItem,
- itemActive: coursewareDetailKnowledgeId
- },
- type
- );
- return;
- }
- } else {
- if (popupData.activeIndex < data.itemList.length - 1) {
- handleSwipeChange(popupData.activeIndex + 1);
- return;
- }
- // 获取当前是哪个单元
- let detailIndex = data.courseDetails.findIndex(
- (item: any) => item.id == activeData.lessonCoursewareDetailId
- );
- // 当前章节列表
- const detailItem = data.courseDetails[detailIndex]?.knowledgeList || [];
- // 获取当前是哪个章节
- let lessonIndex = detailItem.findIndex(
- (item: any) => item.id == data.id
- );
- let lessonStatus = false; // 当前章节下面是否有内容
- let lessonCoursewareDetailId = '';
- let coursewareDetailKnowledgeId = '';
- let coursewareDetailKnowledgeName = '';
- let coursewareItem = {} as any;
- while (lessonIndex < detailItem.length - 1) {
- lessonIndex++;
- if (lessonIndex >= 0) {
- if (detailItem[lessonIndex].containMaterial) {
- lessonStatus = true;
- lessonCoursewareDetailId =
- detailItem[lessonIndex].lessonCoursewareDetailId;
- coursewareDetailKnowledgeId = detailItem[lessonIndex].id;
- coursewareDetailKnowledgeName = detailItem[lessonIndex].name;
- coursewareItem = detailItem[lessonIndex];
- }
- }
- if (lessonStatus) {
- break;
- }
- }
- // 判断当前章节下面课程是否有内容,否则往下一个章节走
- if (lessonStatus) {
- temporaryData.zjId = coursewareDetailKnowledgeId;
- temporaryData.dyId = lessonCoursewareDetailId;
- changeCourseWareItem(
- {
- ...coursewareItem,
- itemActive: coursewareDetailKnowledgeId
- },
- type
- );
- return;
- }
- let nextLessonStatus = false;
- while (detailIndex <= data.courseDetails.length - 1) {
- detailIndex++;
- const tempDetail =
- data.courseDetails[detailIndex]?.knowledgeList || [];
- let tempLessonLength = 0;
- while (tempLessonLength <= tempDetail.length - 1) {
- if (tempDetail[tempLessonLength].containMaterial) {
- nextLessonStatus = true;
- lessonCoursewareDetailId =
- tempDetail[tempLessonLength].lessonCoursewareDetailId;
- coursewareDetailKnowledgeId = tempDetail[tempLessonLength].id;
- coursewareDetailKnowledgeName = tempDetail[tempLessonLength].name;
- coursewareItem = tempDetail[tempLessonLength];
- }
- tempLessonLength++;
- if (nextLessonStatus) {
- break;
- }
- }
- if (nextLessonStatus) {
- break;
- }
- }
- // 判断当前章节下面课程是否有内容,否则往下一个单元走
- if (nextLessonStatus) {
- temporaryData.zjId = coursewareDetailKnowledgeId;
- temporaryData.dyId = lessonCoursewareDetailId;
- changeCourseWareItem(
- {
- ...coursewareItem,
- itemActive: coursewareDetailKnowledgeId
- },
- type
- );
- return;
- }
- }
- };
- /** 弹窗关闭 */
- const handleClosePopup = () => {
- // setModelOpen();
- };
- // 是否允许上一页
- const isUpArrow = computed(() => {
- if (data.coursewareType === 'PPT') {
- if (pptData.disable) return false;
- if (pptData.activeLen > 0) {
- return true;
- }
- }
- /**
- * 1,判断当前课程中是否处在第一个资源;
- * 2,判断当前课程是否在当前章节的第一个;
- * 3,判断当前章节,当前课程上面还没有其它课程,是否有资源;
- * 4,判断当前章节上面还没有其它章节;
- * 5,判断上面章节里面课程是否有资源;
- */
- if (popupData.activeIndex > 0) {
- return true;
- }
- // 获取当前是哪个章节
- let detailIndex = data.courseDetails.findIndex(
- (item: any) => item.id == activeData.lessonCoursewareDetailId
- );
- const detailItem = data.courseDetails[detailIndex]?.knowledgeList || [];
- let lessonIndex = detailItem.findIndex((item: any) => item.id == data.id);
- // 说明已经是第一单元,第一课
- if (detailIndex <= 0 && lessonIndex <= 0) {
- return false;
- }
- let lessonStatus = false; // 当前章节上面是否有内容
- while (lessonIndex >= 0) {
- lessonIndex--;
- if (lessonIndex >= 0) {
- if (detailItem[lessonIndex].containMaterial) {
- lessonStatus = true;
- }
- }
- }
- // 判断当前章节下面课程是否有内容,否则往上一个章节走
- if (lessonStatus) {
- return true;
- }
- // 已经是第一个章节了
- if (detailIndex <= 0) {
- return false;
- }
- let prevLessonStatus = false;
- while (detailIndex >= 0) {
- detailIndex--;
- const tempDetail = data.courseDetails[detailIndex]?.knowledgeList || [];
- let tempLessonLength = tempDetail.length;
- while (tempLessonLength > 0) {
- if (tempDetail[tempLessonLength - 1].containMaterial) {
- prevLessonStatus = true;
- }
- tempLessonLength--;
- }
- if (prevLessonStatus) {
- return true;
- }
- }
- return false;
- });
- // 是否允许下一页
- 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;
- }
- // 获取当前是哪个章节
- let detailIndex = data.courseDetails.findIndex(
- (item: any) => item.id == activeData.lessonCoursewareDetailId
- );
- const detailItem = data.courseDetails[detailIndex]?.knowledgeList || [];
- let lessonIndex = detailItem.findIndex((item: any) => item.id == data.id);
- // 说明已经是最后-单元,最后一课
- if (
- detailIndex >= data.courseDetails.length - 1 &&
- lessonIndex >= detailItem.length - 1
- ) {
- return false;
- }
- let lessonStatus = false; // 当前章节下面是否有内容
- while (lessonIndex < detailItem.length - 1) {
- lessonIndex++;
- if (lessonIndex >= 0) {
- if (detailItem[lessonIndex].containMaterial) {
- lessonStatus = true;
- }
- }
- }
- // 判断当前章节下面课程是否有内容,否则往下一个章节走
- if (lessonStatus) {
- return true;
- }
- // 已经是最后一个章节了
- if (detailIndex >= data.courseDetails.length - 1) {
- return false;
- }
- let nextLessonStatus = false;
- while (detailIndex < data.courseDetails.length - 1) {
- detailIndex++;
- const tempDetail = data.courseDetails[detailIndex]?.knowledgeList || [];
- let tempLessonLength = 0;
- while (tempLessonLength <= tempDetail.length - 1) {
- if (tempDetail[tempLessonLength].containMaterial) {
- nextLessonStatus = true;
- }
- tempLessonLength++;
- }
- if (nextLessonStatus) {
- return true;
- }
- }
- return false;
- });
- const activeVideoItem = computed(() => {
- const item = data.itemList[popupData.activeIndex];
- if (item && item.type && item.type.toLocaleUpperCase() === 'VIDEO') {
- return item;
- }
- return {};
- });
- // 加载新的章节里的课件
- const loadNewCourseware = async (item: any) => {
- if (item.id === data.kjId) {
- showSelectCourseware.value = false;
- return;
- }
- if (debounceSkip.value) return;
- debounceSkip.value = true;
- data.itemList = [];
- loadingClass.value = true;
- // activeData.lessonCoursewareDetailId = item.id;
- popupData.chapterOpen = false;
- showSelectCourseware.value = false;
- data.kjId = item.id;
- data.id = item.id;
- popupData.itemActive = '';
- popupData.itemName = '';
- await getDetail();
- popupData.activeIndex = 0;
- loadingClass.value = false;
- debounceSkip.value = false;
- };
- // 通过章节id,检测此章节有几个课件
- const changeCourseWareItem = (item: any, direction: string) => {
- if (item.coursewareNum) {
- changeLessonCourseWare.value = {
- ...item,
- tipMessage:
- direction === 'up'
- ? '当前是课件第一个资源,是否切换上一个课件?'
- : '当前是课件最后一个资源,是否切换下一个课件?'
- };
- showSelectCourseware.value = true;
- }
- };
- const gotoMember = () => {
- postMessage({
- api: 'openWebView',
- content: {
- url: `${
- location.origin.includes('localhost')
- ? 'https://test.lexiaoya.cn'
- : location.origin
- }/classroom-app/#/member-center`,
- orientation: 1
- }
- });
- };
- watch(
- () => pageVisibility.value,
- async (val: any) => {
- // 为了处理从没有会员,到购买会员返回时状态变化
- if (val === 'visible') {
- const userCash = await request.get('/edu-app/user/getUserInfo', {
- initRequest: true // 初始化接口
- });
- setLogin(userCash.data);
- if (state?.user?.data.vipMember) {
- showMember.value = true;
- } else {
- showMember.value = false;
- }
- }
- }
- );
- return () => (
- <div id="playContent" class={styles.playContent}>
- <div
- class={styles.coursewarePlay}
- style={{ width: parentContainer.width }}
- onClick={() => setModelOpen()}>
- {!loadingClass.value && (
- <div class={styles.wraps}>
- <div
- style={
- activeVideoItem.value.type &&
- data.animationState === 'end' &&
- data.videoState === 'play'
- ? {
- zIndex: 15,
- opacity: 1
- }
- : { opacity: 0, zIndex: -1 }
- }
- class={styles.itemDiv}>
- {activeVideoItem.value.paymentType !== 'FREE' &&
- !showMember.value && (
- <div class={styles.memberLock}>
- <img src={memberLockBg} class={styles.memberLockBg} />
- <img
- src={selectIcon}
- class={styles.selectIcon}
- onClick={gotoMember}
- />
- </div>
- )}
- <VideoItem
- ref={(el: any) => (data.videoItemRef = el)}
- item={activeVideoItem.value}
- showModel={activeData.model}
- onLoadedmetadata={(videoItem: any) => {
- if (data.itemList[popupData.activeIndex]) {
- data.itemList[popupData.activeIndex].videoEle = videoItem;
- }
- }}
- onClose={setModelOpen1}
- onCanplay={() => {
- data.videoState = 'play';
- }}
- onPause={() => {
- clearTimeout(activeData.timer);
- activeData.model = true;
- }}
- onEnded={() => {
- // const _index = popupData.activeIndex + 1
- // if (_index < data.itemList.length) {
- // handleSwipeChange(_index);
- // }
- }}
- />
- </div>
- {data.itemList.map((m: any, mIndex: number) => {
- const isRender =
- m.isRender || Math.abs(popupData.activeIndex - mIndex) < 2;
- const isEmtry = Math.abs(popupData.activeIndex - mIndex) > 4;
- if (isRender) {
- m.isRender = true;
- }
- return isRender ? (
- <div
- key={'index' + mIndex}
- class={[
- styles.itemDiv,
- popupData.activeIndex === mIndex && styles.itemActive,
- activeData.isAnimation && styles.acitveAnimation,
- Math.abs(popupData.activeIndex - mIndex) < 2
- ? styles.show
- : styles.hide
- ]}
- style={
- mIndex < popupData.activeIndex
- ? effects[effectIndex.value].prev
- : mIndex > popupData.activeIndex
- ? effects[effectIndex.value].next
- : {}
- }
- onClick={(e: Event) => {
- if (Date.now() - activeData.nowTime < 300) {
- handleDbClick(m);
- return;
- }
- activeData.nowTime = Date.now();
- }}>
- {m.paymentType !== 'FREE' && !showMember.value && (
- <div class={styles.memberLock}>
- <img src={memberLockBg} class={styles.memberLockBg} />
- <img
- src={selectIcon}
- class={styles.selectIcon}
- onClick={gotoMember}
- />
- </div>
- )}
- {m.type === 'IMG' && <img src={m.content} />}
- {m.type === 'PPT' && (
- <iframe
- src={`https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(
- m.content
- )}`}
- width="100%"
- height="100%"
- frameborder="1"></iframe>
- )}
- {m.type === 'VIDEO' && (
- <img
- src={m.coverImg}
- onLoad={() => {
- m.isprepare = true;
- }}
- />
- )}
- {m.type === 'SONG' && (
- <AudioItem
- item={m}
- show={popupData.activeIndex === mIndex}
- pageVisibility={pageVisibility.value}
- showModel={activeData.model}
- isEmtry={isEmtry}
- onLoadedmetadata={(audioEle: any) => {
- console.log(audioEle, 'audioEle', m);
- m.audioEle = audioEle;
- }}
- onEnded={() => {
- const _index = popupData.activeIndex + 1;
- if (_index < data.itemList.length) {
- handleSwipeChange(_index);
- }
- }}
- onClose={() => {
- clearTimeout(activeData.timer);
- activeData.timer = setTimeout(() => {
- activeData.model = false;
- }, 4000);
- }}
- />
- )}
- {m.type === 'MUSIC' && (
- <MusicScore
- pageVisibility={pageVisibility.value}
- show={popupData.activeIndex === mIndex}
- activeModel={activeData.model}
- data-vid={m.id}
- music={m}
- onSetIframe={(el: any) => {
- m.iframeRef = el;
- }}
- />
- )}
- {m.type === 'VIDEO' && (
- <Transition name="van-fade">
- {data.videoState !== 'play' && (
- <div class={styles.loadWrap}>
- <Vue3Lottie
- style={{ width: '100%', height: '100%' }}
- animationData={playLoadData}></Vue3Lottie>
- </div>
- )}
- </Transition>
- )}
- {/* 新增:RHYTHM:节奏练习,THEORY:乐理知识,MUSIC_WIKI:名曲鉴赏 INSTRUMENT:乐器 MUSICIAN:音乐家 资源类型 */}
- {m.type === 'RHYTHM' && (
- <TempoItem
- key={mIndex}
- class={styles.tempoPracticeGroup}
- dataJson={m.dataJson}
- show={popupData.activeIndex === mIndex}
- pageVisibility={pageVisibility.value}
- onSetIframe={(el: any) => {
- m.iframeRef = el;
- }}
- />
- )}
- {m.type === 'THEORY' && <Theory id={m.bizId} />}
- {/* {popupData.activeIndex === mIndex && ( */}
- {m.type === 'MUSIC_WIKI' && (
- <InstrumentInfo
- type={'wiki'}
- id={m.bizId}
- show={popupData.activeIndex === mIndex}
- ref={el => (m.domEle = el)}
- />
- )}
- {m.type === 'INSTRUMENT' && (
- <InstrumentInfo
- type={'instrument'}
- id={m.bizId}
- show={popupData.activeIndex === mIndex}
- ref={el => (m.domEle = el)}
- />
- )}
- {m.type === 'MUSICIAN' && (
- <InstrumentInfo
- type={'musician'}
- id={m.bizId}
- show={popupData.activeIndex === mIndex}
- ref={el => (m.domEle = el)}
- />
- )}
- {m.type === 'LISTEN' && (
- <ListenItem
- pageVisibility={pageVisibility.value}
- show={popupData.activeIndex === mIndex}
- activeModel={activeData.model}
- data-vid={m.id}
- item={m}
- onSetIframe={(el: any) => {
- m.iframeRef = el;
- }}
- />
- )}
- {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
- key={'index' + mIndex}
- class={[
- styles.itemDiv,
- popupData.activeIndex === mIndex && styles.itemActive,
- activeData.isAnimation && styles.acitveAnimation,
- Math.abs(popupData.activeIndex - mIndex) < 2
- ? styles.show
- : styles.hide
- ]}
- style={
- mIndex < popupData.activeIndex
- ? effects[effectIndex.value].prev
- : mIndex > popupData.activeIndex
- ? effects[effectIndex.value].next
- : {}
- }></div>
- );
- })}
- </div>
- )}
- <Transition name="right">
- {activeData.model && (
- <div
- class={styles.rightFixedBtns}
- onClick={(e: Event) => {
- e.stopPropagation();
- clearTimeout(activeData.timer);
- }}>
- <div
- class={[styles.fullBtn, styles.point]}
- onClick={() => (popupData.chapterOpen = true)}>
- <img src={iconChange} />
- <span>切换</span>
- </div>
- <div
- 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>
- <div
- class={[
- styles.fullBtn,
- !isUpArrow.value && styles.btnsDisabled
- ]}
- onClick={() => handlePreAndNext('up')}>
- <img src={iconUp} />
- <span style={{ textAlign: 'center' }}>上一个</span>
- </div>
- <div
- class={[
- styles.fullBtn,
- !isDownArrow.value && styles.btnsDisabled
- ]}
- onClick={() => handlePreAndNext('down')}>
- <span style={{ textAlign: 'center' }}>下一个</span>
- <img src={iconDown} />
- </div>
- </div>
- )}
- </Transition>
- </div>
- <div
- style={{ transform: activeData.model ? '' : 'translateY(-100%)' }}
- class={styles.headerContainer}
- ref={headeRef}>
- <div class={styles.backBtn} onClick={() => goback()}>
- <Icon name={iconBack} />
- 返回
- </div>
- <div class={styles.menu}>{popupData.itemName}</div>
- </div>
- {/* 课件列表 */}
- <Popup
- class={styles.popup}
- style={{ background: 'rgba(0,0,0, 0.75)' }}
- overlayClass={styles.overlayClass}
- position="right"
- round
- v-model:show={popupData.open}
- onClose={handleClosePopup}>
- <Points
- // allList={data.allList}
- currentCourse={data.currentCourse}
- itemActive={popupData.itemActive}
- itemName={popupData.itemPointName}
- kjId={data.kjId}
- zsdId={data.zsdId}
- popShow={popupData.open}
- onHandleSelect={(res: any) => {
- popupData.open = false;
- toggleMaterial(res.itemActive);
- }}
- />
- </Popup>
- {/* 知识点列表 */}
- <Popup
- class={styles.popup}
- style={{ background: 'rgba(0,0,0, 0.75)' }}
- overlayClass={styles.overlayClass}
- position="right"
- round
- v-model:show={popupData.chapterOpen}
- onClose={handleClosePopup}>
- <Chapter
- detail={data.courseDetails}
- itemActive={data.id as any}
- active={activeData.lessonCoursewareDetailId as any}
- popShow={popupData.chapterOpen}
- onHandleSelect={async (item: any) => {
- temporaryData.dyId = item.tabActive;
- temporaryData.zjId = item.itemActive;
- popupData.itemPointName = item.itemName;
- if (item.coursewareNum) {
- loadNewCourseware({
- id: item.itemActive
- });
- }
- }}
- />
- </Popup>
- {showSelectCourseware.value && (
- <SelectCoursewareTip
- message={changeLessonCourseWare.value.tipMessage}
- onClose={() => (showSelectCourseware.value = false)}
- onConfirm={() => loadNewCourseware(changeLessonCourseWare.value)}
- />
- )}
- </div>
- );
- }
- });
|