import { closeToast, Icon, Popup, showDialog, showToast } from 'vant'; import { defineComponent, onMounted, reactive, nextTick, 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, useRouter } from 'vue-router'; import { listenerMessage, postMessage, promisefiyPostMessage, removeListenerMessage } 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 Points from './component/points'; import { browser, getSecondRPM } from '@/helpers/utils'; import { Vue3Lottie } from 'vue3-lottie'; import playLoadData from './datas/data.json'; import { usePageVisibility } from '@vant/use'; import AudioItem from './component/audio-item'; import { api_classLessonCoursewareQuery, api_lessonCoursewareKnowledgeDetailDetail } from './api'; import VideoItem from './component/video-item'; import Chapter from './component/chapter'; import { api_classLessonCoursewareDetail, api_lessonCoursewareDetail } from '../courseware-list/api'; import detail from '../information/help-center/detail'; import { state } from '@/state'; export default defineComponent({ name: 'CoursewarePlay', setup() { const pageVisibility = usePageVisibility(); const lastTimeKey = 'lastTime' + (state?.user?.data?.phone ?? ''); /** 设置播放容器 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); }); const getCourseDetail = async () => { try { if (route.query.tab == 'course') { const res = await api_classLessonCoursewareDetail({ id: activeData.courseId as any, subjectId: activeData.subjectId }); if (res?.code == 200 && Array.isArray(res?.data?.lessonList)) { data.courseDetails = res.data.lessonList || []; console.log('🚀 ~ data.details course:', data.courseDetails); } } else { const res = await api_lessonCoursewareDetail({ id: route.query.lessonCoursewareId as any, subjectId: activeData.subjectId }); if (res?.code == 200 && Array.isArray(res?.data?.lessonList)) { data.courseDetails = res.data.lessonList || []; } } console.log(data.courseDetails, 'data.courseDetails'); } catch { // } }; const route = useRoute(); const headeRef = ref(); const loadingClass = ref(false); // 重新加载课件 const data = reactive({ knowledgePointList: [] as any, courseDetails: [] as any, itemList: [] as any, videoRefs: {} as any[], videoState: 'init' as 'init' | 'play', videoItemRef: null as any, animationState: 'start' as 'start' | 'end' }); const activeData = reactive({ isAutoPlay: true, // 是否自动播放 subjectId: route.query.subjectId, lessonCoursewareId: route.query.lessonCoursewareId, lessonCoursewareDetailId: route.query.lessonCoursewareDetailId, coursewareDetailKnowledgeId: route.query.id, courseId: route.query.courseId, // 我的课程专用编号 nowTime: 0, model: true, // 遮罩 isAnimation: true, // 是否动画 videoBtns: true, // 视频 currentTime: 0, duration: 0, timer: null as any, item: null as any }); const getDetail = async () => { let courseList: any[] = []; if (route.query.tab == 'course') { const res = await api_classLessonCoursewareQuery({ coursewareDetailKnowledgeId: activeData.coursewareDetailKnowledgeId, subjectId: activeData.subjectId, page: 1, rows: -1 }); if (res?.code === 200 && Array.isArray(res.data.rows)) { const tempRows = res.data.rows || []; tempRows.forEach((item: any) => { courseList.push({ content: item.content, coverImg: item.coverImg, id: item.id, materialId: item.materialId, name: item.materialName, relOrder: 0, sourceFrom: item.source, type: item.materialType }); }); } } else { const res = await api_lessonCoursewareKnowledgeDetailDetail({ lessonCoursewareKnowledgeDetailId: activeData.coursewareDetailKnowledgeId, subjectId: activeData.subjectId }); if (res?.code === 200 && Array.isArray(res.data)) { courseList = res.data || []; } } // 课程 if (courseList.length > 0) { data.knowledgePointList = courseList.map((item: any) => { return { ...item, url: item.type === 'SONG' ? 'https://gyt.ks3-cn-beijing.ksyuncs.com/courseware/1687916228530.png' : item.coverImg }; }); } data.itemList = data.knowledgePointList.map((m: any, index: number) => { if (!popupData.itemActive) { popupData.itemActive = m.id; popupData.itemName = m.name; } return { ...m, iframeRef: null, videoEle: null, autoPlay: false, //加载完成是否自动播放 isprepare: false, // 视频是否加载完成 isRender: false // 是否渲染了 }; }); 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; } }; onMounted(() => { postMessage({ api: 'courseLoading', content: { show: false, type: 'fullscreen' } }); getDetail(); getCourseDetail(); window.addEventListener('message', iframeHandle); }); 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: route.query.name 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 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(); } 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]; 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) => { 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 == activeData.coursewareDetailKnowledgeId ); let lessonStatus = false; // 当前章节上面是否有内容 let lessonCoursewareDetailId = ''; let coursewareDetailKnowledgeId = ''; let coursewareDetailKnowledgeName = ''; 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; } } if (lessonStatus) { break; } } // 判断当前章节下面课程是否有内容,否则往上一个章节走 if (lessonStatus) { loadingClass.value = true; activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId; activeData.lessonCoursewareDetailId = lessonCoursewareDetailId; await getDetail(); popupData.activeIndex = data.itemList.length - 1 || 0; popupData.itemActive = data.knowledgePointList[data.itemList.length - 1]?.id || data.knowledgePointList[0]?.id; popupData.itemPointName = coursewareDetailKnowledgeName; popupData.itemName = data.knowledgePointList[data.itemList.length - 1]?.name || data.knowledgePointList[0]?.name; localStorage.setItem(lastTimeKey, coursewareDetailKnowledgeId); popupData.chapterOpen = false; loadingClass.value = false; 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; } tempLessonLength--; if (prevLessonStatus) { break; } } if (prevLessonStatus) { break; } } // 判断当前章节下面课程是否有内容,否则往上一个章节走 if (prevLessonStatus) { loadingClass.value = true; activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId; activeData.lessonCoursewareDetailId = lessonCoursewareDetailId; await getDetail(); popupData.activeIndex = data.itemList.length - 1 || 0; popupData.itemActive = data.knowledgePointList[data.itemList.length - 1]?.id || data.knowledgePointList[0]?.id; localStorage.setItem(lastTimeKey, coursewareDetailKnowledgeId); popupData.itemPointName = coursewareDetailKnowledgeName; popupData.itemName = data.knowledgePointList[data.itemList.length - 1]?.name || data.knowledgePointList[0]?.name; popupData.chapterOpen = false; loadingClass.value = false; 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 == activeData.coursewareDetailKnowledgeId ); let lessonStatus = false; // 当前章节下面是否有内容 let lessonCoursewareDetailId = ''; let coursewareDetailKnowledgeId = ''; let coursewareDetailKnowledgeName = ''; 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; } } if (lessonStatus) { break; } } // 判断当前章节下面课程是否有内容,否则往下一个章节走 if (lessonStatus) { loadingClass.value = true; activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId; activeData.lessonCoursewareDetailId = lessonCoursewareDetailId; await getDetail(); popupData.activeIndex = 0; popupData.itemActive = data.knowledgePointList[0].id; popupData.itemName = data.knowledgePointList[0].name; localStorage.setItem(lastTimeKey, coursewareDetailKnowledgeId); popupData.itemPointName = coursewareDetailKnowledgeName; popupData.chapterOpen = false; loadingClass.value = false; 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; } tempLessonLength++; if (nextLessonStatus) { break; } } if (nextLessonStatus) { break; } } // 判断当前章节下面课程是否有内容,否则往上一个章节走 if (nextLessonStatus) { loadingClass.value = true; activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId; activeData.lessonCoursewareDetailId = lessonCoursewareDetailId; await getDetail(); popupData.activeIndex = 0; popupData.itemActive = data.knowledgePointList[0].id; localStorage.setItem(lastTimeKey, coursewareDetailKnowledgeId); popupData.itemName = data.knowledgePointList[0].name; popupData.itemPointName = coursewareDetailKnowledgeName; popupData.chapterOpen = false; loadingClass.value = false; return; } } }; /** 弹窗关闭 */ const handleClosePopup = () => { // setModelOpen(); }; // popupData.activeIndex == 0 && styles.btnsDisabled // popupData.activeIndex == data.itemList.length - 1 // 是否允许上一页 const isUpArrow = computed(() => { /** * 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 == activeData.coursewareDetailKnowledgeId ); // 说明已经是第一单元,第一课 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 (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 == activeData.coursewareDetailKnowledgeId ); // 说明已经是最后-单元,最后一课 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 {} }) return () => (