1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105 |
- <!--
- * @FileDescription: 教程播放
- * @Author: 黄琪勇
- * @Date:2024-04-03 17:31:41
- -->
- <template>
- <div class="coursewarePlay" :class="[!isShowController && 'hideController', fileType === 'SONG' && 'fileType_song']">
- <div class="coursewarePlayCon" @mousemove="handleMousemove" @click="handleClick" @touchstart="handleClick">
- <videoPlay
- v-show="fileType === 'VIDEO'"
- ref="videoPlayDom"
- @ended="handleChangeCourseware(1)"
- @loadedmetadata="
- () => {
- isTempAutoPlay = false
- }
- "
- :autoPlay="true"
- @playbackRate="showController"
- :disableEvents="true"
- :isShowController="isShowController"
- />
- <div class="imgPlayBox" v-if="fileType === 'IMG'">
- <ElImage :hide-on-click-modal="true" fit="contain" :src="activeCourseware?.content" class="imgPlay" />
- </div>
- <div class="songPlayBox" v-if="fileType === 'SONG'">
- <iframe
- ref="songPlayDom"
- :key="activeCourseware?.content"
- class="songIframe"
- @mousemove="handleMousemove"
- :src="songPlaySrc"
- frameborder="0"
- ></iframe>
- <!-- <span></span> -->
- </div>
- </div>
- <div class="leftTools posTools">
- <div class="posBtn" @click="handleToolClick('menu')" v-if="searchObj.source !== 'search'">
- <img src="@/img/coursewarePlay/menu.png" />
- <!-- <div>课程类型</div> -->
- </div>
- <!-- 有没有搜索都展示 -->
- <div class="posBtn" @click="handleToolClick('search')">
- <img src="@/img/coursewarePlay/sousuo.png" />
- <!-- <div>知识点</div> -->
- </div>
- <div class="posBtn" @click="handleToolClick('point')" v-if="searchObj.source !== 'search'">
- <img src="@/img/coursewarePlay/zhishidian.png" />
- <!-- <div>知识点</div> -->
- </div>
- <div
- :class="['posBtn', activeCoursewareIndex > 0 ? '' : 'disabled']"
- @click="
- () => {
- if (activeCoursewareIndex > 0) {
- handleChangeCourseware(-1)
- }
- }
- "
- >
- <img src="@/img/coursewarePlay/shang.png" />
- <!-- <div>上一个</div> -->
- </div>
- <div
- :class="['posBtn', activeCoursewareIndex < flattenCoursewareList.length - 1 ? '' : 'disabled']"
- @click="
- () => {
- if (activeCoursewareIndex < flattenCoursewareList.length - 1) {
- handleChangeCourseware(1)
- }
- }
- "
- >
- <img src="@/img/coursewarePlay/xia.png" />
- <!-- <div>下一个</div> -->
- </div>
- </div>
- <div
- v-if="activeCoursewareResourceId"
- @click="
- () => {
- handleVideoPause()
- handleGoPracticeBtn(activeCoursewareResourceId!)
- }
- "
- class="goPracticeBtn"
- ></div>
- <div class="topTools">
- <div class="leftMenu">
- <img @click="handleGoBack" class="backImg" src="@/img/coursewarePlay/back.png" />
- <div class="title-section">
- <div class="title">{{ activeCourseware?.parentData.name || "" }}</div>
- <div class="content">
- <p>{{ activeCourseware?.name || "" }}</p>
- <!-- <span v-if="activeCourseware?.phaseGoals" @click="onTitleTip('phaseGoals', activeCourseware?.phaseGoals)">阶段目标</span> -->
- <span v-if="lessonTargetDetail" @click="onTitleTip('phaseGoals', lessonTargetDetail)">阶段目标</span>
- <span v-if="activeCourseware?.checkItem" @click="onTitleTip('checkItem', activeCourseware?.checkItem)">检查事项</span>
- </div>
- </div>
- </div>
- <div class="midMenu">
- <playRecordTime
- v-if="route.query.modeId && coursewareTotalTime && userStoreHook.roles === 'GYT'"
- :modeId="route.query.modeId as string"
- :isCurrentCoursewareMenu="isCurrentCoursewareMenu"
- :coursewareTotalTime="coursewareTotalTime"
- />
- </div>
- <div class="rightMenu">
- <div class="posCloseBtn" @click="handleCoursewareEnd">
- <img src="@/img/coursewarePlay/jieshu.png" />
- </div>
- </div>
- </div>
- <el-drawer class="elDrawer elDrawerHeader" direction="ltr" v-model="drawerSearchShow" :show-close="false">
- <template #header="{ close }">
- <myInput
- class="queryIpt"
- v-model="searchObj.queryStr"
- :height="36"
- placeholder="请输入素材关键词"
- clearable
- @handleQuery="handleQuery"
- @keyup.enter="handleQuery"
- />
- <img class="close" @click="close" src="@/img/coursewarePlay/close.png" />
- </template>
- <ElScrollbar class="elScrollbar" v-loading="searchObj.loading">
- <el-empty
- class="empty"
- v-if="!tempCoursewareList.length && !searchObj.loading"
- :image="require('@/img/layout/empty.png')"
- description="暂无搜索结果"
- />
- <courseCollapse
- :activeCollapse="tempActiveCourseware || activeCourseware"
- :search="searchObj.tempSearch || searchObj.search"
- :courseList="tempCoursewareList"
- @handleClick="handleCourseSearchClick"
- />
- </ElScrollbar>
- </el-drawer>
- <el-drawer class="elDrawer" direction="ltr" v-model="drawerShow" :show-close="false">
- <template #header="{ close }">
- <img class="directory" src="@/img/coursewarePlay/kcml.png" />
- <div class="tit">知识点目录</div>
- <img class="close" @click="close" src="@/img/coursewarePlay/close.png" />
- </template>
- <ElScrollbar class="elScrollbar" v-loading="searchObj.loading">
- <el-empty
- class="empty"
- v-if="!tempCoursewareList.length && !searchObj.loading"
- :image="require('@/img/layout/empty.png')"
- description="暂无搜索结果"
- />
- <courseCollapse
- :activeCollapse="tempActiveCourseware || activeCourseware"
- :search="searchObj.tempSearch || searchObj.search"
- :courseList="tempCoursewareList"
- @handleClick="handleCourseClick"
- />
- </ElScrollbar>
- </el-drawer>
- <el-drawer class="elDrawer elCourseMenu" direction="ltr" v-model="drawerMenuShow" :show-close="false">
- <template #header="{ close }">
- <img class="directory" src="@/img/coursewarePlay/menuActive.png" />
- <div class="tit">课程类型</div>
- <img class="close" @click="close" src="@/img/coursewarePlay/close.png" />
- </template>
- <ElScrollbar class="elScrollbar">
- <courseMenuCollapse :courseMenuList="coursewareMenuList" @handleClick="handleCourseMenuClick" />
- </ElScrollbar>
- </el-drawer>
- <practiceForm v-model="isPracticeShow" :practiceUrl="practiceUrl" @close="handlePracticeClose" />
- </div>
- </template>
- <script setup lang="ts">
- import videoPlay from "./videoPlay"
- import {
- getLessonCourseDetail_gym,
- getLessonCoursewareDetail_gyt,
- getLessonCourseDetail_klx,
- getLessonCoursewareCourseList_gym,
- getMyCoursewareDetail_gyt,
- getLessonCoursewareCourseList_klx
- } from "@/api/cloudTextbooks.api"
- import myInput from "@/components/myInput"
- import { checkWebCourse_gyt, refLevel_gym, refLevel_gyt, refLevel_klx } from "@/api/coursewarePlay.api"
- import { httpAjax, httpAjaxErrMsg, httpAjaxLoadingErrMsg } from "@/plugin/httpAjax"
- import userStore from "@/store/modules/user"
- import { useRoute, useRouter } from "vue-router"
- import { shallowRef, ref, computed, onUnmounted, onMounted, watch, nextTick, reactive } from "vue"
- import { ElMessageBox } from "element-plus"
- import courseCollapse from "./components/courseCollapse"
- import courseMenuCollapse from "./components/courseMenuCollapse"
- import playRecordTime from "./components/playRecordTime"
- import practiceForm from "@/businessComponents/practiceForm"
- import { getRecentCourseSchedule_gym } from "@/api/homePage.api"
- import { getToken } from "@/libs/auth"
- import { URL_TEACH_GYT, URL_TEACH_GYM, URL_TEACH_KLX } from "@/config"
- import { handleFullscreen } from "@/libs/fullscreen"
- import useCoursewarePlayTip from "./components/useCoursewarePlayTip"
- import useDialogConfirm from "@/hooks/useDialogConfirm"
- import LoadingBar from "@/plugin/loadingBar"
- import { isPlay, penShow, toolOpen, whitePenShow } from "@/businessComponents/globalTools/globalTools"
- import { closeAllModalFrame } from "@/plugin/modalFrame"
- import { deepCopy } from "@/libs/tools"
- const route = useRoute()
- const router = useRouter()
- const userStoreHook = userStore()
- /* 获取资源 */
- const videoPlayDom = ref<InstanceType<typeof videoPlay>>()
- const songPlayDom = ref<any>() // 曲谱对象
- const lessonTargetDetail = ref<string>("") // 阶段目标
- const coursewareMenuList = shallowRef<any[]>([]) // 课程类型
- const coursewareList = shallowRef<any[]>([]) // 知识点
- const coursewareSearchList = shallowRef<any[]>([]) // 搜索的知识点
- const tempCoursewareList = shallowRef<any[]>([]) // 临时知识点
- const flattenCoursewareList = ref<any[]>([]) // 扁平化coursewareList
- const tempFlattenCoursewareList = ref<any[]>([]) // 临时 扁平化coursewareList
- const isCurrentCoursewareMenu = shallowRef(true) // 是否为当前选的课程类型
- const currentId = ref<any>(route.params.id)
- const isTempAutoPlay = ref(false)
- let coursewareDetailController: AbortController
- const searchObj = reactive({
- loading: false,
- isSearch: false, // 是否搜索 标识
- lessonCoursewareId: null as any, // 课程id,
- queryStr: route.query.search as any,
- source: route.query.source as any, // 从哪里来的
- search: route.query.search as any, // 默认的搜索条件 -
- tempSearch: route.query.search as any
- })
- // 选中的知识点
- const tempActiveCourseware: any = ref() // 临时数据
- const activeCourseware = computed<undefined | Record<string, any>>(() => {
- return flattenCoursewareList.value[activeCoursewareIndex.value]
- })
- // 文件类型
- const fileType = computed<"VIDEO" | "IMG" | "SONG">(() => {
- return activeCourseware.value?.typeCode || activeCourseware.value?.type
- })
- const songPlaySrc = computed<string>(() => {
- if (fileType.value !== "SONG") {
- return ""
- }
- // GYM,GYT,KLX 区分 云教练
- const urlObj = {
- GYT: `${URL_TEACH_GYT}?id=${activeCourseware.value?.content}&modelType=practice&modeType=json&Authorization=${getToken()}&isYjt=1`,
- GYM: `${URL_TEACH_GYM}#/?id=${
- activeCourseware.value?.content
- }&Authorization=${getToken()}&platform=pc&isHideBack=true&isHideMusicList=true&isYjt=1&systemType=teacher`,
- KLX: `${URL_TEACH_KLX}#/?id=${
- activeCourseware.value?.content
- }&Authorization=${getToken()}&platform=pc&isHideBack=true&isHideMusicList=true&isYjt=1&systemType=teacher`
- }
- // const iframeRef = document.querySelector("#songPlayDom") as any
- // iframeRef?.contentWindow.location.replace(urlObj[userStoreHook.roles!])
- // console.log(iframeRef, "iframeRef")
- return urlObj[userStoreHook.roles!]
- })
- // 视频是否自动播放
- // const videoIsAutoPlay = computed<boolean>(() => {
- // // 如果为视频且有阶段目前则不自动播放
- // console.log(fileType.value, isTempAutoPlay.value, "isTempAutoPlay")
- // return (fileType.value === "VIDEO" && activeCourseware.value?.phaseGoals) || isTempAutoPlay.value ? false : true
- // })
- const activeCoursewareIndex = ref(0)
- const drawerSearchShow = ref(false) // 弹窗带搜索条件的
- const drawerShow = ref(false)
- const drawerMenuShow = ref(false)
- // 课程总时间
- const coursewareTotalTime = ref(0)
- // 监控播放
- watch(activeCourseware, () => {
- fileType.value === "VIDEO" &&
- nextTick(() => {
- handlePlayVideo({
- src: activeCourseware.value?.content,
- name: activeCourseware.value?.name
- })
- })
- showController()
- })
- async function getCoursewareList(id?: string) {
- // GYM,GYT,KLX 区分 查询接口
- const LessonCoursewareDetailApi = {
- GYT: getLessonCoursewareDetail_gyt,
- GYM: getLessonCourseDetail_gym,
- KLX: getLessonCourseDetail_klx
- }
- await httpAjaxErrMsg(LessonCoursewareDetailApi[userStoreHook.roles!], id || (route.params.id as string)).then(res => {
- if (res.code === 200) {
- const { lockFlag, knowledgePointList, lessonTargetDesc, lessonCoursewareId } = res.data || {}
- if (lockFlag) {
- ElMessageBox.alert("课件已锁定", "温馨提示", {
- confirmButtonText: "退出",
- type: "error"
- })
- .then(() => {
- handleGoBack()
- })
- .catch(() => {
- handleGoBack()
- })
- return
- }
- if ((knowledgePointList || []).length < 1) {
- ElMessageBox.alert("没有找到课件", "温馨提示", {
- confirmButtonText: "退出",
- type: "error"
- })
- .then(() => {
- handleGoBack()
- })
- .catch(() => {
- handleGoBack()
- })
- return
- }
- lessonTargetDetail.value = lessonTargetDesc ? lessonTargetDesc.replace(/\n/g, "<br />") : ""
- searchObj.lessonCoursewareId = lessonCoursewareId
- // 处理返回的数据
- handlePointList(knowledgePointList)
- }
- })
- // 请求带搜索条件数据
- searchObj.lessonCoursewareId && getLessCoursewareList("onlySearch", searchObj.lessonCoursewareId)
- }
- /**
- * 带搜索条件的
- * @param type onlySearch 只搜索 展示
- */
- async function getLessCoursewareList(type?: string, id?: string) {
- // GYM,GYT,KLX 区分 查询接口
- const LessonCoursewareDetailApi = {
- GYT: getMyCoursewareDetail_gyt,
- GYM: getLessonCoursewareCourseList_gym,
- KLX: getLessonCoursewareCourseList_klx
- }
- if (coursewareDetailController) {
- coursewareDetailController.abort()
- }
- coursewareDetailController = new AbortController()
- searchObj.loading = true
- await httpAjax(LessonCoursewareDetailApi[userStoreHook.roles!], {
- id: id || (route.params.id as string),
- data: {
- search: searchObj.queryStr,
- detailFlag: "1"
- },
- abortController: coursewareDetailController
- }).then(res => {
- searchObj.loading = false
- if (res.code === 200) {
- const result = res.data || []
- for (let i = 0; i < result.length; i++) {
- const itemResult = result[i]
- itemResult.name = itemResult.coursewareDetailName
- itemResult.id = itemResult.coursewareDetailId || itemResult.lessonCoursewareDetailId
- itemResult.lessonTargetDesc = itemResult.lessonTargetDesc ? itemResult.lessonTargetDesc.replace(/\n/g, "<br />") : ""
- itemResult.children = itemResult.knowledgePointList || []
- itemResult.knowledgePointList = []
- }
- if (type === "onlySearch") {
- handlePointListOnlySearch(result)
- } else {
- handlePointList(result, searchObj.isSearch)
- }
- // 初始化检查事项
- const item = flattenCoursewareList.value[activeCoursewareIndex.value]
- const parentId = item ? item.parentData.ids[0] : ""
- if (parentId) {
- const parentItem = coursewareList.value.find((item: any) => item.id === parentId)
- if (parentItem) {
- lessonTargetDetail.value = parentItem.lessonTargetDesc
- }
- }
- }
- // 标识
- searchObj.isSearch = false
- })
- }
- // 处理是从搜索过来的,还是
- if (route.query.source === "search") {
- getLessCoursewareList()
- } else {
- getCoursewareList()
- getCoursewareMenuList()
- }
- function getCoursewareMenuList(id?: string) {
- // GYM,GYT,KLX 区分 查询接口
- const LessonCoursewareMenuDetailApi = {
- GYT: refLevel_gyt,
- GYM: refLevel_gym,
- KLX: refLevel_klx
- }
- httpAjaxErrMsg(LessonCoursewareMenuDetailApi[userStoreHook.roles!], {
- lessonCoursewareDetailId: id || route.params.id,
- courseScheduleId: route.query.modeId as any
- } as any).then(res => {
- if (res.code === 200) {
- coursewareMenuList.value = res.data || []
- }
- })
- }
- let flattenCoursewareListData: any = [] // 临时扁平化数据
- function handlePointList(pointList: any[], isSearch?: boolean) {
- flattenCoursewareListData = []
- const list = filterPointList(pointList)
- if (!isSearch) {
- // 重置数据
- coursewareTotalTime.value = 0
- coursewareList.value = list
- // 如果url里面有materialId 代表指定资料播放
- if (route.query.materialId) {
- const index = flattenCoursewareListData.findIndex((item: any) => {
- return route.query.materialId === item.id + "" && route.query.knowledgePointId === item.knowledgePointId + ""
- })
- index > -1 && (activeCoursewareIndex.value = index)
- }
- flattenCoursewareList.value = deepCopy(flattenCoursewareListData)
- } else {
- if (flattenCoursewareListData[0]) {
- // 默认展开第一个
- tempActiveCourseware.value = {
- ...flattenCoursewareListData[0],
- id: null
- }
- }
- }
- tempCoursewareList.value = list
- tempFlattenCoursewareList.value = deepCopy(flattenCoursewareListData)
- }
- function handlePointListOnlySearch(pointList: any[]) {
- flattenCoursewareListData = []
- const list = filterPointList(pointList)
- if (flattenCoursewareListData[0]) {
- // 默认展开第一个
- tempActiveCourseware.value = {
- ...flattenCoursewareListData[0],
- id: null
- }
- }
- if (!searchObj.isSearch) {
- coursewareSearchList.value = list
- }
- tempCoursewareList.value = list
- }
- function filterPointList(pointList: any[], parentData?: { ids: string[]; name: string }): any[] {
- // 设置父级及以上id数组和父级name
- return pointList.map(point => {
- if (point.children) {
- return Object.assign(point, {
- children: filterPointList(point.children, { ids: [...(parentData?.ids || []), point.id], name: point.name })
- })
- } else {
- // coursewareTotalTime.value += point.totalMaterialTimeSecond
- return Object.assign(point, {
- materialList: point.materialList.map((item: any) => {
- item.parentData = {
- ids: [...(parentData?.ids || []), point.id],
- name: point.name
- }
- flattenCoursewareListData.push(item)
- return item
- })
- })
- }
- })
- }
- function handleChangeCourseware(index: -1 | 1) {
- handleVideoPause()
- handleSongPause()
- const newIndex = index + activeCoursewareIndex.value
- if (newIndex < 0 || newIndex > flattenCoursewareList.value.length - 1) {
- return
- }
- if (searchObj.source === "search") {
- const newItem = flattenCoursewareList.value[newIndex]
- const newParentId = newItem ? newItem.parentData?.ids[0] : ""
- if (newParentId) {
- const parentItem = coursewareList.value.find((item: any) => item.id === newParentId)
- if (parentItem) {
- lessonTargetDetail.value = parentItem.lessonTargetDesc
- }
- }
- }
- activeCoursewareIndex.value = newIndex
- }
- function handleCourseSearchClick(value: any) {
- if (searchObj.source === "search") {
- searchObj.search = searchObj.tempSearch ? JSON.parse(JSON.stringify(searchObj.tempSearch)) : ""
- coursewareList.value = deepCopy(tempCoursewareList.value)
- flattenCoursewareList.value = deepCopy(tempFlattenCoursewareList.value)
- const newIndex = flattenCoursewareList.value.findIndex((item: any) => {
- return value.id === item.id && value.knowledgePointId === item.knowledgePointId
- })
- const newItem = flattenCoursewareList.value[newIndex]
- const newParentId = newItem ? newItem.parentData?.ids[0] : ""
- if (newParentId) {
- const parentItem = coursewareList.value.find((item: any) => item.id === newParentId)
- if (parentItem) {
- lessonTargetDetail.value = parentItem.lessonTargetDesc
- }
- }
- activeCoursewareIndex.value = newIndex
- drawerSearchShow.value = false
- } else {
- const urls = router.resolve({
- path: `/coursewarePlay/${searchObj.lessonCoursewareId}`,
- query: {
- materialId: value.id,
- source: "search",
- knowledgePointId: value.knowledgePointId,
- search: searchObj.tempSearch ? JSON.parse(JSON.stringify(searchObj.tempSearch)) : ""
- }
- })
- console.log(urls, "urls")
- const url = window.location.origin + window.location.pathname + urls.href
- window.open(url)
- }
- }
- function handleCourseClick(value: any) {
- searchObj.search = searchObj.tempSearch ? JSON.parse(JSON.stringify(searchObj.tempSearch)) : ""
- coursewareList.value = deepCopy(tempCoursewareList.value)
- flattenCoursewareList.value = deepCopy(tempFlattenCoursewareList.value)
- const newIndex = flattenCoursewareList.value.findIndex((item: any) => {
- return value.id === item.id && value.knowledgePointId === item.knowledgePointId
- })
- if (searchObj.source === "search") {
- const newItem = flattenCoursewareList.value[newIndex]
- const newParentId = newItem ? newItem.parentData?.ids[0] : ""
- if (newParentId) {
- const parentItem = coursewareList.value.find((item: any) => item.id === newParentId)
- if (parentItem) {
- lessonTargetDetail.value = parentItem.lessonTargetDesc
- }
- }
- }
- activeCoursewareIndex.value = newIndex
- drawerShow.value = false
- }
- async function handleCourseMenuClick(value: any) {
- // 判断是否为当前课程类型
- if (currentId.value === value.id) {
- return
- }
- LoadingBar.loading(true)
- currentId.value = value.id
- isCurrentCoursewareMenu.value = value.id === route.params.id ? true : false
- flattenCoursewareListData = [] // 重置数据
- isTempAutoPlay.value = true
- await getCoursewareList(value.id)
- getCoursewareMenuList(value.id)
- drawerMenuShow.value = false
- activeCoursewareIndex.value = 0
- nextTick(() => {
- // if (!activeCourseware.value?.phaseGoals) {
- // 切换之后默认打开课程目录
- drawerShow.value = true
- // }
- })
- LoadingBar.loading(false)
- }
- /** 曲目相关 */
- // 暂停曲目播放
- function handleSongPause() {
- songPlayDom.value?.contentWindow?.postMessage({ api: "setPlayState" }, "*")
- showController()
- }
- /* 播放器相关 */
- // 视频播放或者暂停
- function handleVideoPlay() {
- videoPlayDom.value?.handlePlay()
- showController()
- }
- // 视频快进快退
- function handleVideoSpeedCurrentTime(type: "fast" | "slow") {
- videoPlayDom.value?.speedCurrentTime(type)
- showController()
- }
- // 视频暂停
- function handleVideoPause() {
- videoPlayDom.value?.pauseVideo()
- showController()
- }
- // 播放视频
- function handlePlayVideo({ src, name }: { src: string; name: string }) {
- videoPlayDom.value?.playVideo({
- src,
- name
- })
- showController()
- }
- // 全屏显示
- handleFullscreen(true, false)
- /* 按键事件相关 */
- onMounted(() => {
- document.addEventListener("keydown", handleKeydown)
- document.addEventListener("contextmenu", preventDefaultContextmenu)
- showController()
- })
- onUnmounted(() => {
- document.removeEventListener("keydown", handleKeydown)
- document.removeEventListener("contextmenu", preventDefaultContextmenu)
- })
- function preventDefaultContextmenu(event: MouseEvent) {
- event.preventDefault()
- }
- function handleKeydown(e: KeyboardEvent) {
- const key = e.key
- // 打开弹窗之后快捷键失效
- if (drawerShow.value || drawerMenuShow.value || drawerSearchShow.value) {
- return
- }
- if (key === " ") {
- closeAllModalFrame()
- drawerShow.value = false
- // 视频类型的时候才触发
- fileType.value === "VIDEO" && handleVideoPlay()
- } else if (key === "ArrowLeft") {
- closeAllModalFrame()
- drawerShow.value = false
- // 视频类型的时候才触发
- fileType.value === "VIDEO" && handleVideoSpeedCurrentTime("slow")
- } else if (key === "ArrowRight") {
- closeAllModalFrame()
- drawerShow.value = false
- // 视频类型的时候才触发
- fileType.value === "VIDEO" && handleVideoSpeedCurrentTime("fast")
- } else if (key === "ArrowDown") {
- closeAllModalFrame()
- drawerShow.value = false
- handleChangeCourseware(1)
- } else if (key === "ArrowUp") {
- closeAllModalFrame()
- drawerShow.value = false
- handleChangeCourseware(-1)
- }
- }
- function handleToolClick(type: string) {
- fileType.value === "VIDEO" && handleVideoPause()
- if (type === "menu") {
- drawerMenuShow.value = true
- } else if (type === "point") {
- tempCoursewareList.value = deepCopy(coursewareList.value)
- searchObj.queryStr = searchObj.search ? JSON.parse(JSON.stringify(searchObj.search)) : ""
- tempActiveCourseware.value = null
- drawerShow.value = true
- } else if (type === "search") {
- if (searchObj.source === "search") {
- tempCoursewareList.value = deepCopy(coursewareList.value)
- tempActiveCourseware.value = null
- } else {
- tempCoursewareList.value = deepCopy(coursewareSearchList.value)
- tempActiveCourseware.value = {}
- }
- searchObj.queryStr = searchObj.search ? JSON.parse(JSON.stringify(searchObj.search)) : ""
- drawerSearchShow.value = true
- }
- }
- function handleMousemove() {
- showController()
- }
- function handleClick() {
- fileType.value === "VIDEO" && isShowController.value && handleVideoPlay()
- showController()
- }
- // 是否显示控制器
- const isShowController = ref(true)
- let _showTimer: any
- function showController() {
- isShowController.value = true
- _showTimer && clearTimeout(_showTimer)
- _showTimer = setTimeout(hideController, 3000)
- }
- function hideController() {
- // 取消暂停的时候收起
- // if (fileType.value === "VIDEO" && videoPlayDom.value?.playType === "pause") {
- // return
- // }
- isShowController.value = false
- }
- /* 结束课程 */
- function handleGoBack() {
- // window.open("about:blank", "_self")
- // window.close()
- // 如果从课件列表进来的,直接关闭
- if (!router.options.history.state?.back) {
- window.close()
- return
- }
- router.go(-1)
- }
- function handleCoursewareEnd() {
- if (route.query.modeId) {
- if (userStoreHook.roles === "GYM") {
- httpAjaxLoadingErrMsg(getRecentCourseSchedule_gym, route.query.modeId as string).then(res => {
- if (res.code === 200) {
- if (res.data?.signOutStatusEnum === 3) {
- useDialogConfirm({
- headImg: require("@/img/coursewarePlay/ts.png"),
- text: `请确认是否结束课程,结束后请到APP进行签退。`,
- btnShow: [true, true],
- onOk() {
- handleGoBack()
- }
- })
- } else {
- handleGoBack()
- }
- }
- })
- } else if (userStoreHook.roles === "GYT") {
- httpAjaxLoadingErrMsg(checkWebCourse_gyt, route.query.modeId as string).then(res => {
- if (res.code === 200) {
- if (res.data?.signOut === false) {
- useDialogConfirm({
- headImg: require("@/img/coursewarePlay/ts.png"),
- text: `请确认是否结束课程,结束后请到APP进行签退。`,
- btnShow: [true, true],
- onOk() {
- handleGoBack()
- }
- })
- } else {
- handleGoBack()
- }
- }
- })
- }
- } else {
- handleGoBack()
- }
- }
- // 是否收起
- watch(
- () => isShowController.value,
- () => {
- if (isShowController.value) {
- isPlay.value = false
- } else {
- isPlay.value = true
- toolOpen.value = false
- }
- }
- )
- // 白板的批注打开时暂停播放
- watch(
- () => [whitePenShow.value, penShow.value],
- () => {
- if (whitePenShow.value || penShow.value) {
- handleVideoPause()
- handleSongPause()
- }
- }
- )
- // 去练习
- const activeCoursewareResourceId = computed<string | undefined>(() => {
- const materialRefs = activeCourseware.value?.materialRefs
- return materialRefs ? (["GYM", "KLX"].includes(userStoreHook.roles!) ? materialRefs[0]?.resourceIdStr : materialRefs[0]?.resourceId) : undefined
- })
- const isPracticeShow = ref(false)
- const practiceUrl = ref("")
- function handleGoPracticeBtn(activeCoursewareResourceId: string) {
- // GYM,GYT,KLX 区分 云教练
- const urlObj = {
- GYT: `${URL_TEACH_GYT}?id=${activeCoursewareResourceId}&modelType=practice&modeType=json&Authorization=${getToken()}&isYjt=1&&isHideBack=false`,
- GYM: `${URL_TEACH_GYM}#/?id=${activeCoursewareResourceId}&Authorization=${getToken()}&platform=pc&isYjt=1&systemType=teacher&isHideMusicList=true`,
- KLX: `${URL_TEACH_KLX}#/?id=${activeCoursewareResourceId}&Authorization=${getToken()}&platform=pc&isYjt=1&systemType=teacher&isHideMusicList=true`
- }
- isPracticeShow.value = true
- practiceUrl.value = urlObj[userStoreHook.roles!]
- //window.open(urlObj[userStoreHook.roles!], "_blank")
- }
- function handlePracticeClose() {
- isPracticeShow.value = false
- practiceUrl.value = ""
- }
- function onTitleTip(type: "phaseGoals" | "checkItem", text: string) {
- useCoursewarePlayTip({
- headImg: require(`@/img/coursewarePlay/${type === "phaseGoals" ? "ts3" : "ts4"}.png`),
- text,
- btnShow: [false, false]
- })
- handleVideoPause()
- }
- function handleQuery() {
- //
- searchObj.isSearch = true
- searchObj.tempSearch = searchObj.queryStr ? JSON.parse(JSON.stringify(searchObj.queryStr)) : ""
- if (searchObj.source === "search") {
- getLessCoursewareList()
- } else {
- getLessCoursewareList("onlySearch", searchObj.lessonCoursewareId)
- }
- }
- </script>
- <style lang="scss" scoped>
- .coursewarePlay {
- width: 100%;
- height: 100%;
- position: relative;
- overflow: hidden;
- &.hideController {
- .leftTools {
- opacity: 0;
- transform: translate(-100%, -50%);
- }
- .topTools {
- opacity: 0;
- transform: translateY(-100%);
- }
- .goPracticeBtn {
- transform: translateY(74px);
- }
- }
- &.fileType_song.hideController {
- .leftTools {
- opacity: initial;
- transform: translateY(-50%);
- }
- .goPracticeBtn {
- transform: initial;
- }
- }
- .coursewarePlayCon {
- width: 100%;
- height: 100%;
- overflow: hidden;
- .imgPlayBox {
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- .imgPlay {
- width: 84%;
- height: 100%;
- }
- }
- .songPlayBox {
- width: 100%;
- height: 100%;
- .songIframe {
- display: block;
- width: 100%;
- height: 100%;
- }
- }
- }
- .topTools {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- background: linear-gradient(180deg, rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0) 100%);
- transition: all 0.5s;
- display: flex;
- align-items: flex-start;
- justify-content: space-between;
- padding: 20px 30px 40px;
- .leftMenu {
- display: flex;
- align-items: flex-start;
- .backImg {
- cursor: pointer;
- width: 22px;
- padding-top: 5px;
- &:hover {
- opacity: $opacity-hover;
- }
- }
- .title-section {
- font-weight: 500;
- font-size: 22px;
- color: #ffffff;
- line-height: 30px;
- padding-left: 20px;
- .content {
- padding-top: 6px;
- font-weight: 500;
- font-size: 18px;
- color: #ffffff;
- line-height: 26px;
- display: flex;
- align-items: center;
- p {
- line-height: 1;
- padding-top: 1px;
- }
- span {
- background: rgba(0, 0, 0, 0.1);
- border-radius: 16px;
- border: 1px solid rgba(255, 255, 255, 0.7);
- font-size: 14px;
- color: #ffffff;
- line-height: 22px;
- padding: 2px 10px;
- margin-left: 10px;
- cursor: pointer;
- }
- }
- }
- }
- .midMenu {
- position: absolute;
- left: 50%;
- top: 23px;
- // transform: translate(-50%, -50%);
- transform: translateX(-50%);
- }
- .rightMenu {
- .posCloseBtn {
- cursor: pointer;
- img {
- width: 34px;
- height: 34px;
- padding: 6px;
- box-sizing: content-box;
- &:hover {
- background-color: rgba(255, 255, 255, 0.2);
- border-radius: 6px;
- }
- }
- }
- }
- }
- .posTools {
- position: absolute;
- top: 50%;
- transform: translateY(-50%);
- transition: all 0.5s;
- &.leftTools {
- background: rgba(0, 0, 0, 0.4);
- border-radius: 8px;
- left: 32px;
- }
- .posBtn {
- padding: 14px 6px;
- font-weight: 500;
- font-size: 16px;
- color: #ffffff;
- display: flex;
- flex-direction: column;
- align-items: center;
- cursor: pointer;
- // &:hover {
- // opacity: $opacity-hover;
- // }
- &.disabled {
- opacity: $opacity-disabled;
- }
- > img {
- width: 34px;
- height: 34px;
- padding: 6px;
- box-sizing: content-box;
- &:hover {
- background-color: rgba(255, 255, 255, 0.2);
- border-radius: 6px;
- }
- }
- }
- }
- .goPracticeBtn {
- position: absolute;
- right: 32px;
- bottom: 24px;
- width: 143px;
- height: 50px;
- background: url("@/img/coursewarePlay/goPracticeBtn.png") no-repeat;
- background-size: 100% 100%;
- cursor: pointer;
- transition: all 0.5s;
- &:hover {
- opacity: $opacity-hover;
- }
- }
- &:deep(.elDrawer.el-drawer) {
- width: 348px !important;
- .el-drawer__header {
- height: 54px;
- background: #ededed;
- padding: 0 20px;
- margin-bottom: 0;
- .directory {
- flex-grow: 0;
- flex-shrink: 0;
- width: 24px;
- height: 24px;
- }
- .tit {
- flex-grow: 1;
- margin-left: 10px;
- font-weight: 600;
- font-size: 18px;
- color: #333333;
- }
- .close {
- cursor: pointer;
- width: 14px;
- flex-shrink: 0;
- &:hover {
- opacity: $opacity-hover;
- }
- }
- .el-input {
- margin-right: 10px;
- font-size: 14px;
- }
- .btnSelect {
- width: 56px;
- height: 26px;
- line-height: 26px;
- font-size: 14px;
- }
- }
- .el-drawer__body {
- padding: 0;
- overflow: hidden;
- & > .elScrollbar {
- .el-scrollbar__view {
- padding: 0 22px;
- width: 100%;
- }
- .el-scrollbar__wrap {
- overflow-x: hidden;
- }
- }
- }
- }
- &:deep(.elDrawerHeader.el-drawer) {
- .el-drawer__header {
- padding: 0 10px;
- }
- }
- &:deep(.elCourseMenu.el-drawer) {
- width: 363px !important;
- .el-drawer__body {
- & > .elScrollbar {
- .el-scrollbar__view {
- padding: 0;
- }
- }
- }
- }
- }
- .empty {
- height: calc(100vh - 54px);
- :deep(.el-empty__image) {
- width: 228px;
- }
- :deep(.el-empty__description) {
- color: #aaa;
- p {
- font-size: 18px;
- }
- }
- }
- </style>
|