import { defineComponent, onMounted, reactive, onUnmounted, ref, Transition, computed, nextTick } from 'vue'; import styles from './index.module.less'; import 'plyr/dist/plyr.css'; import MusicScore from './component/musicScore'; import iconChange from './image/icon-change.png'; import iconMenu from './image/icon-menu.png'; import iconUp from './image/icon-up.png'; import iconDown from './image/icon-down.png'; import iconNote from './image/icon-note.png'; import iconWhiteboard from './image/icon-whiteboard.png'; import iconAssignHomework from './image/icon-assignHomework.png'; import iconClose from './image/icon-close.png'; import iconOverPreivew from './image/icon-over-preview.png'; import { Vue3Lottie } from 'vue3-lottie'; import playLoadData from './datas/data.json'; import Moveable from 'moveable'; import VideoPlay from './component/video-play'; import { useMessage, NDrawer, NDrawerContent, NModal, NSpace, NButton, NTooltip, NPopover, NImage } from 'naive-ui'; import CardType from '@/components/card-type'; import Pen from './component/tools/pen'; import AudioPay from './component/audio-pay'; import TrainSettings from './model/train-settings'; import { useRoute } from 'vue-router'; import { courseScheduleUpdate, lessonCoursewareDetail, lessonPreTrainingPage, queryCourseware } from '../prepare-lessons/api'; import Attentguide from '@/custom-plugins/guide-page/attent-guide'; import { vaildUrl } from '/src/utils/urlUtils'; import TimerMeter from '/src/components/timerMeter'; import toneImage from '/src/components/layout/images/toneImage.png'; import toolbox from '/src/components/layout/images/toolbox.png'; import setTimeIcon from '/src/components/layout/images/setTimeIcon.png'; import iconNote2 from '/src/components/layout/images/icon-note.png'; import beatIcon from '/src/components/layout/images/beatIcon.png'; import toneIcon from '/src/components/layout/images/toneIcon.png'; import { eventGlobal, px2vw } from '/src/utils'; import PlaceholderTone from '/src/components/layout/modals/placeholderTone'; import { state as globalState } from '/src/state'; import Chapter from './model/chapter'; export type ToolType = 'init' | 'pen' | 'whiteboard'; export type ToolItem = { type: ToolType; name: string; icon: string; }; export default defineComponent({ name: 'CoursewarePlay', props: { type: { type: String, default: '' }, subjectId: { type: [String, Number], default: '' }, // 教材编号 lessonCourseId: { type: [String, Number], default: '' }, detailId: { type: String, default: '' }, // 班级编号 classGroupId: { type: String, default: '' }, // 上课记录编号 classId: { type: String, defaault: '' }, preStudentNum:{ type: [String, Number], default: '' } }, emits: ['close'], setup(props, { emit }) { const message = useMessage(); const route = useRoute(); /** 设置播放容器 16:9 */ const parentContainer = reactive({ width: '100vw' }); const NPopoverRef = ref(); const setContainer = () => { const min = Math.min(screen.width, screen.height); const max = Math.max(screen.width, screen.height); const width = min * (16 / 9); if (width > max) { parentContainer.width = '100vw'; return; } else { parentContainer.width = width + 'px'; } }; const handleInit = (type = 0) => { //设置容器16:9 // setContainer(); }; handleInit(); const boxBoundaryInfo = reactive({ isBoundary: false, isBoundaryType: '' as any, mainWidth: '' as any, mainHeight: '' as any, subWidth: '' as any, subHeight: '' as any }); onUnmounted(() => { handleInit(1); window.removeEventListener('resize', resetSize); }); const data = reactive({ type: 'class' as '' | 'preview' | 'class', // 预览类型 subjectId: '' as any, // 声部编号 lessonCourseId: '' as any, // 教材编号 lessonCoursewareDetailId: '' as any, // 章节 detailId: '' as any, // 编号 - 课程编号 classGroupId: '' as any, // 上课时需要 班级编号 classId: '' as any, // 上课编号 // detail: null, knowledgePointList: [] as any, itemList: [] as any, // showHead: true, // isCourse: false, // isRecordPlay: false, videoRefs: {} as any[], audioRefs: {} as any[], modelAttendStatus: false, // 布置作业提示弹窗 modalAttendMessage: '本节课未设置课后作业,是否继续?', modelTrainStatus: false, // 训练设置 homeworkStatus: true, // 布置作业完成时 removeVisiable: false, removeTitle: '', removeContent: '' }); const activeData = reactive({ // isAutoPlay: false, // 是否自动播放 nowTime: 0, model: true, // 遮罩 isAnimation: true, // 是否动画 // videoBtns: true, // 视频 // currentTime: 0, // duration: 0, timer: null as any, item: null as any }); const showGuide = ref(false); const getDetail = async () => { try { const res = await queryCourseware({ coursewareDetailKnowledgeId: data.detailId, subjectId: data.subjectId, pag: 1, rows: 99 }); const tempRows = res.data.rows || []; const temp: any = []; tempRows.forEach((row: any) => { if (!row.removeFlag) { temp.push({ id: row.id, materialId: row.materialId, coverImg: row.coverImg, type: row.materialType, title: row.materialName, isCollect: !!row.favoriteFlag, isSelected: row.source === 'PLATFORM' ? true : false, content: row.content }); } }); data.knowledgePointList = temp; data.itemList = data.knowledgePointList.map((m: any) => { return { ...m, iframeRef: null, videoEle: null, audioEle: null, autoPlay: false, //加载完成是否自动播放 isprepare: false, // 视频是否加载完成 isRender: false // 是否渲染了 }; }); setTimeout(() => { showGuide.value = true; }, 500); } catch { // } }; const directionType = ref('left'); const showModalBeat = ref(false); const showModalTone = ref(false); const showModalTime = ref(false); const isDragIng = ref(false); const initMoveable = async () => { if (document.querySelector('.wrap')) { const moveable = new Moveable(document.querySelector('.wrap') as any, { target: document.querySelector('#moveNPopoverA') as any, // If the container is null, the position is fixed. (default: parentElement(document.body)) container: document.querySelector('.wrap') as any, // snappable: true, // bounds: {"left":100,"top":100,"right":100,"bottom":100}, draggable: true, resizable: false, scalable: false, rotatable: false, warpable: false, pinchable: false, // ["resizable", "scalable", "rotatable"] origin: false, keepRatio: false, // Resize, Scale Events at edges. edge: false, throttleDrag: 0, throttleResize: 0, throttleScale: 0, throttleRotate: 0 }); console.log('initMoveable完毕', moveable); moveable .on('dragStart', ({ target, clientX, clientY }) => { console.log('dragStart'); }) .on( 'drag', ({ target, // transform, left, top, right, bottom // beforeDelta, // beforeDist, // delta, // dist, // clientX, // clientY }) => { isDragIng.value = true; if (NPopoverRef.value) { NPopoverRef.value.setShow(false); } const subdEl = document.getElementById( `moveNPopoverA` ) as HTMLDivElement; // console.log(subdEl, "subdEl", "drag"); const subdElStyle = getComputedStyle(subdEl, null); const RectInfo = { left: Number(subdElStyle.left.replace('px', '')), top: Number(subdElStyle.top.replace('px', '')), width: Number(subdElStyle.width.replace('px', '')), height: Number(subdElStyle.height.replace('px', '')) }; // target.style.transition = '' const mainWidth = parseInt( window.getComputedStyle( document.querySelector('.wrap') as Element ).width ) - RectInfo.width; const mainHeight = parseInt( window.getComputedStyle( document.querySelector('.wrap') as Element ).height ) - RectInfo.height; subdEl.style.transition = ''; boxBoundaryInfo.isBoundary = false; boxBoundaryInfo.isBoundaryType = ''; boxBoundaryInfo.mainHeight = mainHeight; boxBoundaryInfo.mainWidth = mainWidth; boxBoundaryInfo.subWidth = RectInfo.width; boxBoundaryInfo.subHeight = RectInfo.height; if (left < 0) { left = 2; boxBoundaryInfo.isBoundary = true; boxBoundaryInfo.isBoundaryType = 'left'; } if (top < 0) { top = 2; boxBoundaryInfo.isBoundary = true; boxBoundaryInfo.isBoundaryType = 'top'; } if (right < 0) { right = 2; } if (bottom < 0) { bottom = 2; } if (left > mainWidth - 2) { left = mainWidth - 2; // top = 2; boxBoundaryInfo.isBoundary = true; boxBoundaryInfo.isBoundaryType = 'right'; } if (top > mainHeight - 2) { top = mainHeight - 2; boxBoundaryInfo.isBoundary = true; boxBoundaryInfo.isBoundaryType = 'bottom'; } target!.style.left = `${left}px`; target!.style.top = `${top}px`; } ) .on( 'dragEnd', async ({ target, // isDrag, clientX // clientY }) => { if (document.body.clientWidth / 2 - clientX > 0) { // 往左出 directionType.value = 'right'; } else { // 往又出 directionType.value = 'left'; } console.log(target.style.left); isDragIng.value = false; // 在这里进行动画 if (boxBoundaryInfo.isBoundary) { // 这里说明贴边了 target.style.transition = '.3s'; actionEnd(target, boxBoundaryInfo.isBoundaryType); } } ); } }; // 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(() => { initMoveable(); const query = route.query; console.log(query,props.preStudentNum,'学生人数') // 先取参数, data.type = props.type || (query.type as any); data.subjectId = props.subjectId || query.subjectId; data.detailId = props.detailId || query.detailId; data.lessonCourseId = props.lessonCourseId || query.lessonCourseId; data.classGroupId = props.classGroupId || query.classGroupId; data.classId = props.classId || query.classId; const subdEl = document.getElementById(`moveNPopoverA`) as HTMLDivElement; initBoundaryWrap(subdEl, boxBoundaryInfo); initBoxRectInfo(subdEl, boxBoundaryInfo); window.addEventListener('message', iframeHandle); getDetail(); getLessonCoursewareDetail(); window.addEventListener('resize', resetSize); }); const resetSize = () => { const subdEl = document.getElementById(`moveNPopoverA`) as HTMLDivElement; subdEl.style.display = 'none'; boxBoundaryInfo.isBoundary = true; boxBoundaryInfo.isBoundaryType = 'right'; if (NPopoverRef.value) { NPopoverRef.value.setShow(false); } setTimeout(() => { subdEl.style.transition = ''; initBoxRectInfo(subdEl, boxBoundaryInfo); initBoundaryWrap(subdEl, boxBoundaryInfo); subdEl.style.display = 'block'; }, 100); }; const initBoundaryWrap = (target: any, wrapInfo: any) => { target.addEventListener('mouseenter', () => { if (wrapInfo.isBoundary) { // 如果在边框 就得还原 元素位置 还原完毕后 去除transition if (wrapInfo.isBoundaryType == 'left') { target.style.left = '2px'; } else if (wrapInfo.isBoundaryType == 'right') { target.style.left = `${wrapInfo.mainWidth - 2}px`; } else if (wrapInfo.isBoundaryType == 'top') { target.style.top = `${2}px`; } else if (wrapInfo.isBoundaryType == 'bottom') { target.style.top = `${wrapInfo.mainHeight - 2}px`; } } rate(target, 0); }); target.addEventListener('mouseleave', () => { console.log('mouseleave', wrapInfo.isBoundary); if (wrapInfo.isBoundary) { // 如果在边框 就得还原 元素位置 还原完毕后 去除transition if (wrapInfo.isBoundaryType == 'left') { actionEnd(target, 'left'); } else if (wrapInfo.isBoundaryType == 'right') { actionEnd(target, 'right'); } else if (wrapInfo.isBoundaryType == 'top') { actionEnd(target, 'top'); } else if (wrapInfo.isBoundaryType == 'bottom') { actionEnd(target, 'bottom'); } } // rate(target, 0) }); // target.addEventListener('contextmenu', (event: any) => { // event.preventDefault(); // dialog.warning({ // title: '提示', // content: '是否收入托盘', // positiveText: '确定', // negativeText: '取消', // onPositiveClick: () => { // console.log('确定') // }, // onNegativeClick: () => { // console.log('取消') // } // }) // }); // actionEnd(target, 'right'); }; // 这里是旋转 const rate = (target: any, rate: any) => { target.style.transform = ' rotate(' + rate + ')'; }; // 这里是选装的方式 const actionEnd = (target: any, type: any) => { switch (type) { case 'left': rate(target, '90deg'); target!.style.left = `${2 - boxBoundaryInfo.subWidth / 2}px`; target!.style.top = `${top}px`; break; case 'right': rate(target, '-90deg'); target!.style.left = `${ boxBoundaryInfo.mainWidth - 2 + boxBoundaryInfo.subWidth / 2 }px`; target!.style.top = `${top}px`; break; case 'top': target!.style.top = `${2 - boxBoundaryInfo.subHeight / 2}px`; rate(target, '-180deg'); break; case 'bottom': target!.style.top = `${ boxBoundaryInfo.mainHeight - 2 + boxBoundaryInfo.subHeight / 2 }px`; break; default: rate(target, '-0'); break; } }; const initBoxRectInfo = (target: any, wrapInfo: any) => { // const subdEl = document.getElementById(`moveNPopoverA`) as HTMLDivElement; // console.log(subdEl, "subdEl", "drag"); const subdElStyle = getComputedStyle(target, null); const RectInfo = { left: Number(subdElStyle.left.replace('px', '')), top: Number(subdElStyle.top.replace('px', '')), width: Number(subdElStyle.width.replace('px', '')), height: Number(subdElStyle.height.replace('px', '')) }; // target.style.transition = '' const mainWidth = parseInt( window.getComputedStyle(document.querySelector('.wrap') as Element) .width ) - RectInfo.width; const mainHeight = parseInt( window.getComputedStyle(document.querySelector('.wrap') as Element) .height ) - RectInfo.height; // boxBoundaryInfo.isBoundary = false; // boxBoundaryInfo.isBoundaryType = ''; wrapInfo.mainHeight = mainHeight; wrapInfo.mainWidth = mainWidth; wrapInfo.subWidth = RectInfo.width; wrapInfo.subHeight = RectInfo.height; target.style.transition = '.3s'; }; const onFullScreen = () => { if (data.type === 'preview') { const el: any = document.querySelector('#app'); if (el.mozRequestFullScreen) { el.mozRequestFullScreen(); } else if (el.webkitRequestFullscreen) { el.webkitRequestFullscreen(); } else if (el.requestFullScreen) { el.requestFullscreen(); } } }; const popupData = reactive({ open: false, activeIndex: 0, toolOpen: false, // 工具弹窗控制 chapterOpen: false, // 切换章节 chapterDetails: [] as any, chapterLoading: false // 加载数据 }); const formatParentId = (id: any, list: any, ids = [] as any) => { for (const item of list) { if (item.knowledgeList && item.knowledgeList.length > 0) { const cIds: any = formatParentId(id, item.knowledgeList, [ ...ids, item.id ]); if (cIds.includes(id)) { return cIds; } } if (item.id === id) { return [...ids, id]; } } return ids; }; /** 获取章节 */ const getLessonCoursewareDetail = async () => { try { const res = await lessonCoursewareDetail({ id: data.lessonCourseId, subjectId: data.subjectId }); popupData.chapterDetails = res.data.lessonList || []; const ids = formatParentId(data.detailId, popupData.chapterDetails); data.lessonCoursewareDetailId = ids[0]; } catch { // } }; /** 更新上课记录 */ const classCourseScheduleUpdate = async () => { try { if (!data.classId) return; await courseScheduleUpdate({ lessonCoursewareKnowledgeDetailId: data.detailId, id: data.classId }); } catch {} }; const activeName = computed(() => { let name = ''; data.knowledgePointList.forEach((item: any, index: number) => { if (popupData.activeIndex === index) { name = item.title; } }); return name; }); /**停止所有的播放 */ const handleStop = () => { for (let i = 0; i < data.itemList.length; i++) { const activeItem = data.itemList[i]; if (activeItem.type === 'VIDEO' && activeItem.videoEle) { activeItem.videoEle.currentTime(0); activeItem.videoEle.pause(); } if (activeItem.type === 'SONG' && activeItem.audioEle) { activeItem.audioEle?.stop(); } // console.log('🚀 ~ activeItem:', activeItem) // 停止曲谱的播放 if (activeItem.type === 'MUSIC') { activeItem.iframeRef?.contentWindow?.postMessage( { api: 'setPlayState' }, '*' ); } } }; // 切换素材 const toggleMaterial = (itemActive: any) => { const index = data.itemList.findIndex((n: any) => n.id == itemActive); if (index > -1) { handleSwipeChange(index); } }; /** 延迟收起模态框 */ const setModelOpen = () => { clearTimeout(activeData.timer); message.destroyAll(); activeData.timer = setTimeout(() => { activeData.model = false; Object.values(data.videoRefs).map((n: any) => n?.toggleHideControl(false) ); Object.values(data.audioRefs).map((n: any) => n?.toggleHideControl(false) ); }, 4000); }; /** 立即收起所有的模态框 */ const clearModel = () => { clearTimeout(activeData.timer); message.destroyAll(); activeData.model = false; Object.values(data.videoRefs).map((n: any) => n?.toggleHideControl(false) ); Object.values(data.audioRefs).map((n: any) => n?.toggleHideControl(false) ); }; const toggleModel = (type = true) => { activeData.model = type; Object.values(data.videoRefs).map((n: any) => n?.toggleHideControl(type)); Object.values(data.audioRefs).map((n: any) => n?.toggleHideControl(type)); }; // 双击 const handleDbClick = (item: any) => { if (item && item.type === 'VIDEO') { const videoEle: HTMLVideoElement = item.videoEle; if (videoEle) { if (videoEle.paused) { message.destroyAll(); videoEle.play(); } else { message.warning('已暂停'); videoEle.pause(); } } } }; // 切换播放 // const togglePlay = (m: any, isPlay: boolean) => { // if (isPlay) { // m.videoEle?.play(); // } else { // m.videoEle?.pause(); // } // }; // const showIndex = ref(-4); 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)' }, next: { transform: 'translate3d(100%, 0, -800px) rotateY(120deg)' } }, // 风车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 acitveTimer = ref(); // 轮播切换 const handleSwipeChange = (index: number) => { // 如果是当前正在播放 或者是视频最后一个 if (popupData.activeIndex == index) return; handleStop(); clearTimeout(acitveTimer.value); checkedAnimation(popupData.activeIndex, index); popupData.activeIndex = index; acitveTimer.value = setTimeout( () => { const item = data.itemList[index]; if (item) { if (item.type == 'MUSIC') { activeData.model = true; } if (item.type === 'SONG') { // 自动播放下一个音频 clearTimeout(activeData.timer); message.destroyAll(); // item.autoPlay = false; // nextTick(() => { // item.audioEle?.onPlay(); // }); } if (item.type === 'VIDEO') { // 自动播放下一个视频 clearTimeout(activeData.timer); message.destroyAll(); nextTick(() => { if (item.error) { console.log(item, 'item error'); item.videoEle?.src(item.content); item.error = false; // item.videoEle?.onPlay(); } }); // item.autoPlay = false; } } // requestAnimationFrame(() => { // const _effectIndex = effectIndex.value + 1; // effectIndex.value = // _effectIndex >= effects.length - 1 ? 0 : _effectIndex; // }); }, activeData.isAnimation ? 800 : 0 ); }; /** 是否有转场动画 */ const checkedAnimation = (index: number, nextIndex?: number) => { const item = data.itemList[index]; const nextItem = data.itemList[nextIndex!]; if (nextItem) { if (nextItem.knowledgePointId != item.knowledgePointId) { activeData.isAnimation = true; return; } const videoEle = item.videoEle; const nextVideo = nextItem.videoEle; if (videoEle && videoEle.duration < 8 && index < nextIndex!) { activeData.isAnimation = false; } else if (nextVideo && nextVideo.duration < 8 && index > nextIndex!) { activeData.isAnimation = false; } else { activeData.isAnimation = true; } } else { activeData.isAnimation = item?.adviseStudyTimeSecond < 8 ? false : true; } }; // 上一个知识点, 下一个知识点 const handlePreAndNext = async (type: string) => { // if (type === 'up') { // handleSwipeChange(popupData.activeIndex - 1); // } else { // handleSwipeChange(popupData.activeIndex + 1); // } if (type === 'up') { // 判断上面是否还有章节 if (popupData.activeIndex > 0) { handleSwipeChange(popupData.activeIndex - 1); return; } // 获取当前是哪个章节 let detailIndex = popupData.chapterDetails.findIndex( (item: any) => item.id == data.lessonCoursewareDetailId ); const detailItem = popupData.chapterDetails[detailIndex]?.knowledgeList || []; let lessonIndex = detailItem.findIndex( (item: any) => item.id == data.detailId ); let lessonStatus = false; // 当前章节上面是否有内容 let lessonCoursewareDetailId = ''; let coursewareDetailKnowledgeId = ''; while (lessonIndex >= 0) { lessonIndex--; if (lessonIndex >= 0) { if (detailItem[lessonIndex].containMaterial) { lessonStatus = true; lessonCoursewareDetailId = detailItem[lessonIndex].lessonCoursewareDetailId; coursewareDetailKnowledgeId = detailItem[lessonIndex].id; } } if (lessonStatus) { break; } } // 判断当前章节下面课程是否有内容,否则往上一个章节走 if (lessonStatus) { popupData.chapterLoading = true; data.detailId = coursewareDetailKnowledgeId; data.lessonCoursewareDetailId = lessonCoursewareDetailId; // 更新上课记录 上课的时候才更新 if (data.type !== 'preview') { await classCourseScheduleUpdate(); } await getDetail(); popupData.activeIndex = data.itemList.length - 1 || 0; popupData.chapterOpen = false; popupData.chapterLoading = false; return; } let prevLessonStatus = false; while (detailIndex >= 0) { detailIndex--; const tempDetail = popupData.chapterDetails[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; } tempLessonLength--; if (prevLessonStatus) { break; } } if (prevLessonStatus) { break; } } // 判断当前章节下面课程是否有内容,否则往上一个章节走 if (prevLessonStatus) { popupData.chapterLoading = true; data.detailId = coursewareDetailKnowledgeId; data.lessonCoursewareDetailId = lessonCoursewareDetailId; await getDetail(); popupData.activeIndex = data.itemList.length - 1 || 0; popupData.chapterLoading = false; return; } } else { if (popupData.activeIndex < data.itemList.length - 1) { handleSwipeChange(popupData.activeIndex + 1); return; } // 获取当前是哪个章节 let detailIndex = popupData.chapterDetails.findIndex( (item: any) => item.id == data.lessonCoursewareDetailId ); const detailItem = popupData.chapterDetails[detailIndex]?.knowledgeList || []; let lessonIndex = detailItem.findIndex( (item: any) => item.id == data.detailId ); let lessonStatus = false; // 当前章节下面是否有内容 let lessonCoursewareDetailId = ''; let coursewareDetailKnowledgeId = ''; while (lessonIndex < detailItem.length - 1) { lessonIndex++; if (lessonIndex >= 0) { if (detailItem[lessonIndex].containMaterial) { lessonStatus = true; lessonCoursewareDetailId = detailItem[lessonIndex].lessonCoursewareDetailId; coursewareDetailKnowledgeId = detailItem[lessonIndex].id; } } if (lessonStatus) { break; } } // 判断当前章节下面课程是否有内容,否则往下一个章节走 if (lessonStatus) { popupData.chapterLoading = true; data.detailId = coursewareDetailKnowledgeId; data.lessonCoursewareDetailId = lessonCoursewareDetailId; // 更新上课记录 上课的时候才更新 if (data.type !== 'preview') { await classCourseScheduleUpdate(); } await getDetail(); popupData.activeIndex = 0; popupData.chapterOpen = false; popupData.chapterLoading = false; return; } let nextLessonStatus = false; while (detailIndex <= popupData.chapterDetails.length - 1) { detailIndex++; const tempDetail = popupData.chapterDetails[detailIndex]?.knowledgeList || []; let tempLessonLength = 0; while (tempLessonLength <= tempDetail.length - 1) { if (tempDetail[tempLessonLength].containMaterial) { nextLessonStatus = true; lessonCoursewareDetailId = tempDetail[tempLessonLength].lessonCoursewareDetailId; coursewareDetailKnowledgeId = tempDetail[tempLessonLength].id; } tempLessonLength++; if (nextLessonStatus) { break; } } if (nextLessonStatus) { break; } } // 判断当前章节下面课程是否有内容,否则往上一个章节走 if (nextLessonStatus) { popupData.chapterLoading = true; data.detailId = coursewareDetailKnowledgeId; data.lessonCoursewareDetailId = lessonCoursewareDetailId; // 更新上课记录 上课的时候才更新 if (data.type !== 'preview') { await classCourseScheduleUpdate(); } await getDetail(); popupData.activeIndex = 0; popupData.chapterOpen = false; popupData.chapterLoading = false; return; } } }; /** 弹窗关闭 */ const handleClosePopup = () => { const item = data.itemList[popupData.activeIndex]; if (item?.type == 'VIDEO' && !item.videoEle?.paused) { setModelOpen(); } if (item?.type == 'SONG' && !item.audioEle?.paused) { setModelOpen(); } }; // 监听页面键盘事件 - 上下切换 document.body.addEventListener('keyup', (e: KeyboardEvent) => { // console.log(e, 'e'); if (e.code === 'ArrowUp') { // if (popupData.activeIndex === 0) return; setModalOpen(); handlePreAndNext('up'); } else if (e.code === 'ArrowDown') { // if (popupData.activeIndex === data.itemList.length - 1) return; setModalOpen(); handlePreAndNext('down'); } }); const setModalOpen = (status = true) => { clearTimeout(activeData.timer); activeData.model = status; Object.values(data.videoRefs).map((n: any) => n?.toggleHideControl(status) ); Object.values(data.audioRefs).map((n: any) => n?.toggleHideControl(status) ); }; /** 教学数据 */ const studyData = reactive({ type: '' as ToolType, penShow: false, whiteboardShow: false }); /** 打开教学工具 */ const openStudyTool = (item: ToolItem) => { const activeItem = data.itemList[popupData.activeIndex]; // 暂停视频和曲谱的播放 if (activeItem.type === 'VIDEO' && activeItem.videoEle) { activeItem.videoEle.pause(); } if (activeItem.type === 'SONG' && activeItem.audioEle) { activeItem.audioEle?.stop(); } if (activeItem.type === 'MUSIC') { activeItem.iframeRef?.contentWindow?.postMessage( { api: 'setPlayState' }, '*' ); } clearModel(); popupData.toolOpen = false; studyData.type = item.type; switch (item.type) { case 'pen': studyData.penShow = true; break; case 'whiteboard': studyData.whiteboardShow = true; } }; /** 关闭教学工具 */ const closeStudyTool = () => { studyData.type = 'init'; toggleModel(); }; const startShowModal = ( val: 'setTimeIcon' | 'beatIcon' | 'toneIcon' | 'iconNote2' ) => { if (val == 'setTimeIcon') { showModalTime.value = true; } if (val == 'beatIcon') { showModalBeat.value = true; } if (val == 'toneIcon') { showModalTone.value = true; } if (val == 'iconNote2') { if (NPopoverRef.value) { NPopoverRef.value.setShow(false); } eventGlobal.emit('teacher-guideInfo-attend-class', 'attend-class'); } }; // 是否允许上一页 const isUpArrow = computed(() => { /** * 1,判断当前课程中是否处在第一个资源; * 2,判断当前课程是否在当前章节的第一个; * 3,判断当前章节,当前课程上面还没有其它课程,是否有资源; * 4,判断当前章节上面还没有其它章节; * 5,判断上面章节里面课程是否有资源; */ if (popupData.activeIndex > 0) { return true; } // 获取当前是哪个章节 let detailIndex = popupData.chapterDetails.findIndex( (item: any) => item.id == data.lessonCoursewareDetailId ); const detailItem = popupData.chapterDetails[detailIndex]?.knowledgeList || []; let lessonIndex = detailItem.findIndex( (item: any) => item.id == data.detailId ); // 说明已经是第一单元,第一课 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 = popupData.chapterDetails[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 = popupData.chapterDetails.findIndex( (item: any) => item.id == data.lessonCoursewareDetailId ); const detailItem = popupData.chapterDetails[detailIndex]?.knowledgeList || []; let lessonIndex = detailItem.findIndex( (item: any) => item.id == data.detailId ); // 说明已经是最后-单元,最后一课 if ( detailIndex >= popupData.chapterDetails.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 >= popupData.chapterDetails.length - 1) { return false; } let nextLessonStatus = false; while (detailIndex < popupData.chapterDetails.length - 1) { detailIndex++; const tempDetail = popupData.chapterDetails[detailIndex]?.knowledgeList || []; let tempLessonLength = 0; while (tempLessonLength <= tempDetail.length - 1) { if (tempDetail[tempLessonLength].containMaterial) { nextLessonStatus = true; } tempLessonLength++; } if (nextLessonStatus) { return true; } } return false; }); return () => (
{data.modalAttendMessage}
{/*倒
{data.removeContent}