|
@@ -10,8 +10,13 @@
|
|
|
v-show="fileType === 'VIDEO'"
|
|
|
ref="videoPlayDom"
|
|
|
@ended="handleChangeCourseware(1)"
|
|
|
+ @loadedmetadata="
|
|
|
+ () => {
|
|
|
+ isTempAutoPlay = false
|
|
|
+ }
|
|
|
+ "
|
|
|
+ :autoPlay="true"
|
|
|
@playbackRate="showController"
|
|
|
- :autoPlay="videoIsAutoPlay"
|
|
|
:disableEvents="true"
|
|
|
:isShowController="isShowController"
|
|
|
/>
|
|
@@ -19,7 +24,7 @@
|
|
|
<ElImage :hide-on-click-modal="true" fit="contain" :src="activeCourseware?.content" class="imgPlay" />
|
|
|
</div>
|
|
|
<div class="songPlayBox" v-if="fileType === 'SONG'">
|
|
|
- <iframe class="songIframe" @mousemove="handleMousemove" :src="songPlaySrc" frameborder="0"></iframe>
|
|
|
+ <iframe ref="songPlayDom" class="songIframe" @mousemove="handleMousemove" :src="songPlaySrc" frameborder="0"></iframe>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="leftTools posTools">
|
|
@@ -57,22 +62,7 @@
|
|
|
<img src="@/img/coursewarePlay/xia.png" />
|
|
|
<!-- <div>下一个</div> -->
|
|
|
</div>
|
|
|
-
|
|
|
- <!-- <div class="posBtn" @click="handleCoursewareEnd">
|
|
|
- <img src="@/img/coursewarePlay/jieshu.png" />
|
|
|
- <div>结束</div>
|
|
|
- </div> -->
|
|
|
</div>
|
|
|
- <!-- <div class="rightTools posTools">
|
|
|
- <div class="posBtn" @click="drawerShow = true">
|
|
|
- <img src="@/img/coursewarePlay/zhishidian.png" />
|
|
|
- <div>知识点</div>
|
|
|
- </div>
|
|
|
- <div class="posBtn" @click="handleCoursewareEnd">
|
|
|
- <img src="@/img/coursewarePlay/jieshu.png" />
|
|
|
- <div>结束</div>
|
|
|
- </div>
|
|
|
- </div> -->
|
|
|
<div
|
|
|
v-if="activeCoursewareResourceId"
|
|
|
@click="
|
|
@@ -90,8 +80,9 @@
|
|
|
<div class="title-section">
|
|
|
<div class="title">{{ activeCourseware?.parentData.name || "" }}</div>
|
|
|
<div class="content">
|
|
|
- {{ activeCourseware?.name || "" }}
|
|
|
- <span v-if="activeCourseware?.phaseGoals" @click="onTitleTip('phaseGoals', activeCourseware?.phaseGoals)">阶段目标</span>
|
|
|
+ <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>
|
|
@@ -110,17 +101,17 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <el-drawer class="elDrawer" v-model="drawerShow" :show-close="false">
|
|
|
+ <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>
|
|
|
+ <div class="tit">知识点目录</div>
|
|
|
<img class="close" @click="close" src="@/img/coursewarePlay/close.png" />
|
|
|
</template>
|
|
|
<ElScrollbar class="elScrollbar">
|
|
|
<courseCollapse :activeCollapse="activeCourseware" :courseList="coursewareList" @handleClick="handleCourseClick" />
|
|
|
</ElScrollbar>
|
|
|
</el-drawer>
|
|
|
- <el-drawer class="elDrawer elCourseMenu" v-model="drawerMenuShow" :show-close="false">
|
|
|
+ <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>
|
|
@@ -155,16 +146,21 @@ 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"
|
|
|
|
|
|
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 flattenCoursewareList = ref<any[]>([]) // 扁平化coursewareList
|
|
|
const isCurrentCoursewareMenu = shallowRef(true) // 是否为当前选的课程类型
|
|
|
+const currentId = ref<any>(route.params.id)
|
|
|
+const isTempAutoPlay = ref(false)
|
|
|
// 选中的知识点
|
|
|
const activeCourseware = computed<undefined | Record<string, any>>(() => {
|
|
|
return flattenCoursewareList.value[activeCoursewareIndex.value]
|
|
@@ -190,10 +186,11 @@ const songPlaySrc = computed<string>(() => {
|
|
|
return urlObj[userStoreHook.roles!]
|
|
|
})
|
|
|
// 视频是否自动播放
|
|
|
-const videoIsAutoPlay = computed<boolean>(() => {
|
|
|
- // 如果为视频且有阶段目前则不自动播放
|
|
|
- return fileType.value === "VIDEO" && activeCourseware.value?.phaseGoals ? false : true
|
|
|
-})
|
|
|
+// 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 drawerShow = ref(false)
|
|
|
const drawerMenuShow = ref(false)
|
|
@@ -201,10 +198,6 @@ const drawerMenuShow = ref(false)
|
|
|
const coursewareTotalTime = ref(0)
|
|
|
// 监控播放
|
|
|
watch(activeCourseware, () => {
|
|
|
- handleVideoPause()
|
|
|
- if (activeCourseware.value?.phaseGoals) {
|
|
|
- onTitleTip("phaseGoals", activeCourseware.value?.phaseGoals)
|
|
|
- }
|
|
|
fileType.value === "VIDEO" &&
|
|
|
nextTick(() => {
|
|
|
handlePlayVideo({
|
|
@@ -224,7 +217,7 @@ async function getCoursewareList(id?: string) {
|
|
|
}
|
|
|
await httpAjaxErrMsg(LessonCoursewareDetailApi[userStoreHook.roles!], id || (route.params.id as string)).then(res => {
|
|
|
if (res.code === 200) {
|
|
|
- const { lockFlag, knowledgePointList } = res.data || {}
|
|
|
+ const { lockFlag, knowledgePointList, lessonTargetDesc } = res.data || {}
|
|
|
if (lockFlag) {
|
|
|
ElMessageBox.alert("课件已锁定", "温馨提示", {
|
|
|
confirmButtonText: "退出",
|
|
@@ -251,6 +244,7 @@ async function getCoursewareList(id?: string) {
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
+ lessonTargetDetail.value = lessonTargetDesc ? lessonTargetDesc.replace(/\n/g, "<br />") : ""
|
|
|
// 处理返回的数据
|
|
|
handlePointList(knowledgePointList)
|
|
|
}
|
|
@@ -266,8 +260,8 @@ function getCoursewareMenuList(id?: string) {
|
|
|
}
|
|
|
|
|
|
httpAjaxErrMsg(LessonCoursewareMenuDetailApi[userStoreHook.roles!], {
|
|
|
- lessonCoursewareDetailId: id || route.params.id
|
|
|
- // courseScheduleId: "1844948199117283329"
|
|
|
+ lessonCoursewareDetailId: id || route.params.id,
|
|
|
+ courseScheduleId: route.query.modeId as any
|
|
|
} as any).then(res => {
|
|
|
if (res.code === 200) {
|
|
|
coursewareMenuList.value = res.data || []
|
|
@@ -276,6 +270,8 @@ function getCoursewareMenuList(id?: string) {
|
|
|
}
|
|
|
let flattenCoursewareListData: any = [] // 临时扁平化数据
|
|
|
function handlePointList(pointList: any[]) {
|
|
|
+ // 重置数据
|
|
|
+ coursewareTotalTime.value = 0
|
|
|
coursewareList.value = filterPointList(pointList)
|
|
|
// 如果url里面有materialId 代表指定资料播放
|
|
|
if (route.query.materialId) {
|
|
@@ -322,22 +318,35 @@ function handleCourseClick(value: any) {
|
|
|
drawerShow.value = false
|
|
|
}
|
|
|
async function handleCourseMenuClick(value: any) {
|
|
|
- LoadingBar.loading(true)
|
|
|
- flattenCoursewareListData = []
|
|
|
- activeCoursewareIndex.value = -1
|
|
|
- if (value.id === route.params.id) {
|
|
|
- isCurrentCoursewareMenu.value = true
|
|
|
- } else {
|
|
|
- isCurrentCoursewareMenu.value = false
|
|
|
+ // 判断是否为当前课程类型
|
|
|
+ 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() {
|
|
@@ -380,18 +389,29 @@ function preventDefaultContextmenu(event: MouseEvent) {
|
|
|
}
|
|
|
function handleKeydown(e: KeyboardEvent) {
|
|
|
const key = e.key
|
|
|
+
|
|
|
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)
|
|
|
}
|
|
|
}
|
|
@@ -489,6 +509,7 @@ watch(
|
|
|
() => {
|
|
|
if (whitePenShow.value || penShow.value) {
|
|
|
handleVideoPause()
|
|
|
+ handleSongPause()
|
|
|
}
|
|
|
}
|
|
|
)
|
|
@@ -536,10 +557,6 @@ function onTitleTip(type: "phaseGoals" | "checkItem", text: string) {
|
|
|
opacity: 0;
|
|
|
transform: translate(-100%, -50%);
|
|
|
}
|
|
|
- .rightTools {
|
|
|
- opacity: 0;
|
|
|
- transform: translate(100%, -50%);
|
|
|
- }
|
|
|
.topTools {
|
|
|
opacity: 0;
|
|
|
transform: translateY(-100%);
|
|
@@ -553,10 +570,6 @@ function onTitleTip(type: "phaseGoals" | "checkItem", text: string) {
|
|
|
opacity: initial;
|
|
|
transform: translateY(-50%);
|
|
|
}
|
|
|
- .rightTools {
|
|
|
- opacity: initial;
|
|
|
- transform: translateY(-50%);
|
|
|
- }
|
|
|
.goPracticeBtn {
|
|
|
transform: initial;
|
|
|
}
|
|
@@ -591,7 +604,7 @@ function onTitleTip(type: "phaseGoals" | "checkItem", text: string) {
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
width: 100%;
|
|
|
- background: linear-gradient(180deg, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0) 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;
|
|
@@ -620,16 +633,23 @@ function onTitleTip(type: "phaseGoals" | "checkItem", text: string) {
|
|
|
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: 11px;
|
|
|
+ border-radius: 16px;
|
|
|
border: 1px solid rgba(255, 255, 255, 0.7);
|
|
|
font-size: 14px;
|
|
|
color: #ffffff;
|
|
|
line-height: 22px;
|
|
|
- padding: 1px 8px;
|
|
|
- margin-left: 6px;
|
|
|
+ padding: 2px 10px;
|
|
|
+ margin-left: 10px;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
}
|
|
@@ -648,6 +668,12 @@ function onTitleTip(type: "phaseGoals" | "checkItem", text: string) {
|
|
|
img {
|
|
|
width: 34px;
|
|
|
height: 34px;
|
|
|
+ padding: 6px;
|
|
|
+ box-sizing: content-box;
|
|
|
+ &:hover {
|
|
|
+ background-color: rgba(255, 255, 255, 0.2);
|
|
|
+ border-radius: 6px;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -662,13 +688,8 @@ function onTitleTip(type: "phaseGoals" | "checkItem", text: string) {
|
|
|
border-radius: 8px;
|
|
|
left: 32px;
|
|
|
}
|
|
|
- &.rightTools {
|
|
|
- right: 12px;
|
|
|
- }
|
|
|
.posBtn {
|
|
|
- // background: rgba(0, 0, 0, 0.3);
|
|
|
- // border-radius: 8px;
|
|
|
- padding: 20px 12px;
|
|
|
+ padding: 14px 6px;
|
|
|
font-weight: 500;
|
|
|
font-size: 16px;
|
|
|
color: #ffffff;
|
|
@@ -676,15 +697,21 @@ function onTitleTip(type: "phaseGoals" | "checkItem", text: string) {
|
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
|
cursor: pointer;
|
|
|
- &:hover {
|
|
|
- opacity: $opacity-hover;
|
|
|
- }
|
|
|
+ // &: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;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|