lex-xin há 8 meses atrás
pai
commit
e1388c7091

+ 28 - 2
src/api/coursewarePlay.api.ts

@@ -1,4 +1,4 @@
-import { httpAxios_gyt } from "@/api/ApiInstance"
+import { httpAxios_gym, httpAxios_gyt, httpAxios_klx } from "@/api/ApiInstance"
 
 /**
  * 管乐团
@@ -36,6 +36,32 @@ export const refLevel_gyt = (data: string) => {
    return httpAxios_gyt.axioseRquest({
       method: "post",
       url: `/api-teacher/lessonCoursewareDetail/refLevel`,
-      params: data
+      data
+   })
+}
+
+/**
+ * 酷乐秀
+ */
+
+// 查询关联课程
+export const refLevel_klx = (data: string) => {
+   return httpAxios_klx.axioseRquest({
+      method: "post",
+      url: `/api-teacher/tenantAlbumMusic/refLevel`,
+      data
+   })
+}
+
+/**
+ * 酷乐秀
+ */
+
+// 查询关联课程
+export const refLevel_gym = (data: string) => {
+   return httpAxios_gym.axioseRquest({
+      method: "post",
+      url: `/api-teacher/lessonCourseware/refLevel`,
+      data
    })
 }

+ 2 - 0
src/businessComponents/globalTools/globalTools.ts

@@ -6,3 +6,5 @@ export const toolOpen = ref(false)
 export const penShow = ref(false)
 // 白板
 export const whitePenShow = ref(false)
+// 是否正在播放
+export const isPlay = ref(false)

+ 131 - 34
src/businessComponents/globalTools/globalTools.vue

@@ -4,83 +4,178 @@
 * @Date:2024年10月14日10:03:11
 -->
 <template>
-   <div class="globalTools">
-      <div :class="['iconTools', toolOpen ? 'hideTools' : '']" @click="openTool">
-         <img src="@/img/layout/icon-tool.png" />
+   <div class="globalTools" :class="isPlay ? 'isPlay' : ''">
+      <div :class="['iconTools', toolOpen ? 'hideTools' : '']" ref="iconToolsDom">
+         <img @click="openTool" src="@/img/layout/icon-tool.png" />
       </div>
 
-      <div :class="['expendTools', toolOpen ? 'showTools' : '']">
+      <div :class="['expendTools', toolOpen ? 'showTools' : '']" ref="expendToolsDom">
          <img @click="openType('note')" src="@/img/layout/icon-note.png" />
          <img @click="openType('whiteboard')" class="iconWhiteboard" src="@/img/layout/icon-whiteboard.png" />
          <img @click="openTool" class="iconArrow" src="@/img/layout/g-arrow-right.png" />
       </div>
-
-      <pen
-         :close="
-            () => {
-               penShow = false
-            }
-         "
-         v-model="penShow"
-      />
-      <pen
-         :is-white="true"
-         :close="
-            () => {
-               whitePenShow = false
-            }
-         "
-         v-model="whitePenShow"
-      />
    </div>
+   <pen
+      :close="
+         () => {
+            penShow = false
+         }
+      "
+      v-model="penShow"
+   />
+   <pen
+      :is-white="true"
+      :close="
+         () => {
+            whitePenShow = false
+         }
+      "
+      v-model="whitePenShow"
+   />
 </template>
 
 <script setup lang="ts">
+import { baseSize, baseWidth, size } from "@/libs/rem"
 import pen from "@/views/coursewarePlay/components/pen"
-import { toolOpen, whitePenShow, penShow } from "./globalTools"
+import { toolOpen, whitePenShow, penShow, isPlay } from "./globalTools"
+import { onMounted, ref } from "vue"
+
+const iconToolsDom = ref<HTMLDivElement>()
+const expendToolsDom = ref<HTMLDivElement>()
 
 function openTool() {
+   if (isLock) return
    toolOpen.value = !toolOpen.value
 }
 
 function openType(type: "note" | "whiteboard") {
    console.log(type, "type")
+   if (isLock) return
    if (type === "note") {
       penShow.value = true
    } else if (type === "whiteboard") {
       whitePenShow.value = true
    }
 }
+
+function computePos(type: "width" | "height", value: number | string) {
+   const clientNum = type == "width" ? baseWidth : document.documentElement.clientHeight
+   return typeof value === "string"
+      ? {
+           pos:
+              type == "width"
+                 ? ((clientNum - (parseInt(value) / 100) * clientNum) / 2 / baseSize).toFixed(5)
+                 : (clientNum - (parseInt(value) / 100) * clientNum) / 2,
+           unit: value
+        }
+      : {
+           pos: type == "width" ? ((clientNum - value) / 2 / baseSize).toFixed(5) : (clientNum - value * (size / baseSize)) / 2,
+           unit: (value / baseSize).toFixed(5) + "rem"
+        }
+}
+
+/* 拖拽还没有兼容rem */
+let isLock = false
+function drag(el: HTMLElement) {
+   function mousedown(e: MouseEvent) {
+      e.stopPropagation()
+      e.preventDefault()
+      isLock = false
+      const parentElement = el
+      const parentElementRect = parentElement.getBoundingClientRect()
+      // const downX = e.clientX
+      const downY = e.clientY
+      // const clientWidth = document.documentElement.clientWidth
+      const clientHeight = document.documentElement.clientHeight
+      // const minLeft = 0
+      const minTop = 0
+      // const maxLeft = clientWidth - parentElementRect.width
+      const maxTop = clientHeight - parentElementRect.height
+      function onMousemove(e: MouseEvent) {
+         // let moveX = parentElementRect.left + (e.clientX - downX)
+         let moveY = parentElementRect.top + (e.clientY - downY)
+         // let moveY = e.clientY - downY
+         // moveX = moveX < minLeft ? minLeft : moveX > maxLeft ? maxLeft : moveX
+         moveY = moveY < minTop ? minTop : moveY > maxTop ? maxTop : moveY
+         document.documentElement.style.setProperty("--toolTranslateY", `${moveY}px`)
+         isLock = true
+      }
+      function onMouseup() {
+         document.removeEventListener("mousemove", onMousemove)
+         document.removeEventListener("mouseup", onMouseup)
+      }
+      document.addEventListener("mousemove", onMousemove)
+      document.addEventListener("mouseup", onMouseup)
+   }
+   el.addEventListener("mousedown", mousedown, true)
+}
+//重新计算位置 居中
+function refreshPos() {
+   const posHeight = computePos("height", iconToolsDom.value?.clientHeight || 0)
+   if (iconToolsDom.value) {
+      document.documentElement.style.setProperty("--toolTranslateY", `${posHeight.pos}px`)
+   }
+}
+
+onMounted(() => {
+   drag(iconToolsDom.value!)
+   drag(expendToolsDom.value!)
+   refreshPos()
+
+   iconToolsDom.value!.onclick = (e: any) => {
+      e.stopPropagation()
+   }
+})
 </script>
 
 <style lang="scss" scoped>
 .globalTools {
+   &.isPlay {
+      .iconTools,
+      .expendTools {
+         opacity: $opacity-disabled;
+      }
+   }
    .iconTools,
    .expendTools {
       position: fixed;
       right: 0;
-      top: 50%;
-      transform: translateY(-50%);
-      z-index: 99;
+      top: 0;
+      transform: translateY(var(--toolTranslateY));
+      // margin-top: -29px;
+      z-index: 2001;
       padding: 8px 14px 8px 16px;
       background: rgba(0, 0, 0, 0.4);
       border-radius: 200px 0px 0px 200px;
       border: 2px solid rgba(255, 255, 255, 0.3);
       border-right-width: 0;
       cursor: pointer;
-      transition: transform 0.2s ease;
+      // transition: transform 0.2s ease;
       img {
          width: 34px;
          height: 34px;
+         -moz-user-select: none;
+         /* 火狐浏览器 */
+         -webkit-user-drag: none;
+         /* 谷歌、Safari和Opera浏览器 */
+         -webkit-user-select: none;
+         /* 谷歌、Safari和Opera浏览器 */
+         -ms-user-select: none;
+         /* IE10+浏览器 */
+         user-select: none;
+         /* 通用 */
+         -webkit-touch-callout: none;
+         /* iOS Safari */
       }
    }
 
    .iconTools {
-      transition-delay: 0.2s;
+      // transition-delay: 0.2s;
    }
 
    .expendTools {
-      transform: translate(100%, -50%);
+      // transform: translateX(100%);
+      display: none;
       img {
          cursor: pointer;
       }
@@ -94,14 +189,16 @@ function openType(type: "note" | "whiteboard") {
    }
 
    .hideTools {
-      transition: transform 0.2s ease;
-      transform: translate(100%, -50%);
+      // transition: transform 0.2s ease;
+      transform: translateY(var(--toolTranslateY));
+      display: none;
    }
 
    .showTools {
-      transform: translateY(-50%);
-      transition: transform 0.2s ease;
-      transition-delay: 0.2s;
+      // transition: transform 0.2s ease;
+      // transition-delay: 0.2s;
+      transform: translateY(var(--toolTranslateY));
+      display: block;
    }
 }
 </style>

+ 29 - 22
src/views/coursewarePlay/components/courseMenuCollapse/courseMenuCollapse.vue

@@ -1,36 +1,39 @@
 <template>
    <div class="courseMenuCollapse">
-      <div class="courseMenuItem">
+      <div class="courseMenuItem" v-for="item in props.courseMenuList" :key="item.id" :name="item.id" @click="handleClick(item)">
          <div class="cover">
-            <img />
-            <div class="current">当前</div>
+            <img :src="item.coverImg" />
+            <div class="current" v-if="item.useFlag">当前</div>
          </div>
          <div class="text">
-            <ellipsisScroll :autoScroll="true" :title="'长笛Level1长笛Level1'" />
+            <ellipsisScroll :autoScroll="item.useFlag" :title="item.lessonCoursewareName" />
          </div>
       </div>
-      <div class="courseMenuItem">
-         <div class="cover">
-            <img />
-            <div class="current">当前</div>
-         </div>
-         <div class="text">
-            <ellipsisScroll :title="'长笛Level1长笛Level1长笛Level1长笛Level1'" />
-         </div>
-      </div>
-      <div class="courseMenuItem">
-         <div class="cover">
-            <img />
-            <div class="current">当前</div>
-         </div>
-         <div class="text">长笛Level1</div>
-      </div>
    </div>
 </template>
 
 <script lang="ts" setup>
-// import Ellipsis from "@/components/ellipsis"
-// import EllipsisScroll from "@/components/ellipsisScroll"
+// import { ref, watch } from "vue"
+type courseMenuListType = {
+   id: string
+   lessonCoursewareId: string
+   lessonCoursewareName: string
+   coverImg: string
+   courseTypeCode: string
+   lockFlag: boolean | null
+   useFlag: boolean
+}[]
+
+const props = defineProps<{
+   courseMenuList: courseMenuListType
+}>()
+
+const emits = defineEmits<{
+   (e: "handleClick", value: any): void
+}>()
+function handleClick(value: any) {
+   emits("handleClick", value)
+}
 </script>
 
 <style lang="scss" scoped>
@@ -59,6 +62,10 @@
             height: 100%;
             background: url("@/img/coursewarePlay/book-cover-line.png");
          }
+         img {
+            width: inherit;
+            height: inherit;
+         }
          .current {
             position: absolute;
             top: 4px;

+ 43 - 16
src/views/coursewarePlay/components/playRecordTime/playRecordTime.vue

@@ -4,7 +4,7 @@
 * @Date:2024-04-07 16:49:23
 -->
 <template>
-   <div class="playRecordTime">
+   <div class="playRecordTime" :class="!isCurrentCoursewareMenu ? 'hide' : ''">
       <div class="drop"></div>
       <div class="time">{{ `${formatTime(playTime)}/${formatTime(props.coursewareTotalTime)}` }}</div>
    </div>
@@ -14,9 +14,10 @@
 import { formatTime } from "../../videoPlay/tools"
 import { getCoursewarePlayTime_gyt, coursewarePlayTime_gyt } from "@/api/coursewarePlay.api"
 import { httpAjax } from "@/plugin/httpAjax"
-import { ref, onUnmounted } from "vue"
+import { ref, onUnmounted, watch } from "vue"
 const props = defineProps<{
    coursewareTotalTime: number
+   isCurrentCoursewareMenu: boolean
    modeId: string
 }>()
 
@@ -27,6 +28,20 @@ let timeRecord = 0
 onUnmounted(() => {
    _time && clearInterval(_time)
 })
+
+watch(
+   () => props.isCurrentCoursewareMenu,
+   () => {
+      if (!props.isCurrentCoursewareMenu) {
+         handleCoursewarePlayTime(props.modeId, timeRecord)
+         timeRecord = 0
+         _time && clearInterval(_time)
+      } else {
+         timerCount()
+      }
+   }
+)
+
 getCoursewarePlayTime()
 function getCoursewarePlayTime() {
    httpAjax(getCoursewarePlayTime_gyt, props.modeId).then(res => {
@@ -35,20 +50,28 @@ function getCoursewarePlayTime() {
       }
    })
 }
-_time = setInterval(() => {
-   // 播放时间大于总时间
-   if (playTime.value >= props.coursewareTotalTime) {
-      _time && clearInterval(_time)
-      timeRecord > 0 && handleCoursewarePlayTime(props.modeId, timeRecord)
-      return
-   }
-   timeRecord++
-   playTime.value++
-   if (timeRecord === timeNum) {
-      handleCoursewarePlayTime(props.modeId, timeRecord)
-      timeRecord = 0
-   }
-}, 1000)
+// 判断如果为同一个则计时
+console.log(props.isCurrentCoursewareMenu, "props.isCurrentCoursewareMenu")
+if (props.isCurrentCoursewareMenu) {
+   timerCount()
+}
+
+function timerCount() {
+   _time = setInterval(() => {
+      // 播放时间大于总时间
+      if (playTime.value >= props.coursewareTotalTime) {
+         _time && clearInterval(_time)
+         timeRecord > 0 && handleCoursewarePlayTime(props.modeId, timeRecord)
+         return
+      }
+      timeRecord++
+      playTime.value++
+      if (timeRecord === timeNum) {
+         handleCoursewarePlayTime(props.modeId, timeRecord)
+         timeRecord = 0
+      }
+   }, 1000)
+}
 function handleCoursewarePlayTime(id: string, time: number) {
    httpAjax(coursewarePlayTime_gyt, id, time).then(() => {})
 }
@@ -62,6 +85,10 @@ function handleCoursewarePlayTime(id: string, time: number) {
    padding: 10px 16px;
    background: rgba(100, 100, 100, 0.5);
    border-radius: 28px;
+
+   &.hide {
+      opacity: 0;
+   }
    .drop {
       margin-right: 12px;
       width: 8px;

+ 1 - 5
src/views/coursewarePlay/components/useCoursewarePlayTip/coursewarePlayTip.vue

@@ -81,14 +81,10 @@ function ok() {
    }
    .textCon {
       flex-grow: 1;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      padding: 0 18px 0 22px;
+      padding: 20px 20px 0 32px;
       overflow: hidden;
       .text {
          font-size: 20px;
-         color: #a04d11;
          line-height: 32px;
       }
    }

+ 81 - 52
src/views/coursewarePlay/coursewarePlay.vue

@@ -11,6 +11,7 @@
             ref="videoPlayDom"
             @ended="handleChangeCourseware(1)"
             @playbackRate="showController"
+            :autoPlay="videoIsAutoPlay"
             :disableEvents="true"
             :isShowController="isShowController"
          />
@@ -22,11 +23,11 @@
          </div>
       </div>
       <div class="leftTools posTools">
-         <div class="posBtn" @click="drawerMenuShow = true">
+         <div class="posBtn" @click="handleToolClick('menu')">
             <img src="@/img/coursewarePlay/menu.png" />
             <!-- <div>课程类型</div> -->
          </div>
-         <div class="posBtn" @click="drawerShow = true">
+         <div class="posBtn" @click="handleToolClick('point')">
             <img src="@/img/coursewarePlay/zhishidian.png" />
             <!-- <div>知识点</div> -->
          </div>
@@ -90,8 +91,8 @@
                <div class="title">{{ activeCourseware?.parentData.name || "" }}</div>
                <div class="content">
                   {{ activeCourseware?.name || "" }}
-                  <span v-if="!activeCourseware?.phaseGoals" @click="onTitleTip('phaseGoals', activeCourseware?.phaseGoals)">阶段目标</span>
-                  <span v-if="!activeCourseware?.checkItem" @click="onTitleTip('checkItem', activeCourseware?.checkItem)">检查事项</span>
+                  <span v-if="activeCourseware?.phaseGoals" @click="onTitleTip('phaseGoals', activeCourseware?.phaseGoals)">阶段目标</span>
+                  <span v-if="activeCourseware?.checkItem" @click="onTitleTip('checkItem', activeCourseware?.checkItem)">检查事项</span>
                </div>
             </div>
          </div>
@@ -99,6 +100,7 @@
             <playRecordTime
                v-if="route.query.modeId && coursewareTotalTime && userStoreHook.roles === 'GYT'"
                :modeId="route.query.modeId as string"
+               :isCurrentCoursewareMenu="isCurrentCoursewareMenu"
                :coursewareTotalTime="coursewareTotalTime"
             />
          </div>
@@ -121,7 +123,7 @@
       <el-drawer class="elDrawer elCourseMenu" v-model="drawerMenuShow" :show-close="false">
          <template #header="{ close }">
             <img class="directory" src="@/img/coursewarePlay/menuActive.png" />
-            <div class="tit">课程目录</div>
+            <div class="tit">课程类型</div>
             <img class="close" @click="close" src="@/img/coursewarePlay/close.png" />
          </template>
          <ElScrollbar class="elScrollbar">
@@ -135,7 +137,7 @@
 <script setup lang="ts">
 import videoPlay from "./videoPlay"
 import { getLessonCourseDetail_gym, getLessonCoursewareDetail_gyt, getLessonCourseDetail_klx } from "@/api/cloudTextbooks.api"
-import { checkWebCourse_gyt, refLevel_gyt } from "@/api/coursewarePlay.api"
+import { checkWebCourse_gyt, refLevel_gym, refLevel_gyt, refLevel_klx } from "@/api/coursewarePlay.api"
 import { httpAjaxErrMsg, httpAjaxLoadingErrMsg } from "@/plugin/httpAjax"
 import userStore from "@/store/modules/user"
 import { useRoute, useRouter } from "vue-router"
@@ -150,6 +152,9 @@ 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"
 
 const route = useRoute()
 const router = useRouter()
@@ -158,7 +163,8 @@ const userStoreHook = userStore()
 const videoPlayDom = ref<InstanceType<typeof videoPlay>>()
 const coursewareMenuList = shallowRef<any[]>([]) // 课程类型
 const coursewareList = shallowRef<any[]>([]) // 知识点
-const flattenCoursewareList = shallowRef<any[]>([]) // 扁平化coursewareList
+const flattenCoursewareList = ref<any[]>([]) // 扁平化coursewareList
+const isCurrentCoursewareMenu = shallowRef(true) // 是否为当前选的课程类型
 // 选中的知识点
 const activeCourseware = computed<undefined | Record<string, any>>(() => {
    return flattenCoursewareList.value[activeCoursewareIndex.value]
@@ -183,6 +189,11 @@ const songPlaySrc = computed<string>(() => {
    }
    return urlObj[userStoreHook.roles!]
 })
+// 视频是否自动播放
+const videoIsAutoPlay = computed<boolean>(() => {
+   // 如果为视频且有阶段目前则不自动播放
+   return fileType.value === "VIDEO" && activeCourseware.value?.phaseGoals ? false : true
+})
 const activeCoursewareIndex = ref(0)
 const drawerShow = ref(false)
 const drawerMenuShow = ref(false)
@@ -191,6 +202,9 @@ const coursewareTotalTime = ref(0)
 // 监控播放
 watch(activeCourseware, () => {
    handleVideoPause()
+   if (activeCourseware.value?.phaseGoals) {
+      onTitleTip("phaseGoals", activeCourseware.value?.phaseGoals)
+   }
    fileType.value === "VIDEO" &&
       nextTick(() => {
          handlePlayVideo({
@@ -201,14 +215,14 @@ watch(activeCourseware, () => {
    showController()
 })
 getCoursewareList()
-function getCoursewareList() {
+async function getCoursewareList(id?: string) {
    //  GYM,GYT,KLX 区分   查询接口
    const LessonCoursewareDetailApi = {
       GYT: getLessonCoursewareDetail_gyt,
       GYM: getLessonCourseDetail_gym,
       KLX: getLessonCourseDetail_klx
    }
-   httpAjaxErrMsg(LessonCoursewareDetailApi[userStoreHook.roles!], route.params.id as string).then(res => {
+   await httpAjaxErrMsg(LessonCoursewareDetailApi[userStoreHook.roles!], id || (route.params.id as string)).then(res => {
       if (res.code === 200) {
          const { lockFlag, knowledgePointList } = res.data || {}
          if (lockFlag) {
@@ -242,48 +256,21 @@ function getCoursewareList() {
       }
    })
 }
-// getCoursewareMenuList()
-function getCoursewareMenuList() {
+getCoursewareMenuList()
+function getCoursewareMenuList(id?: string) {
    //  GYM,GYT,KLX 区分   查询接口
    const LessonCoursewareMenuDetailApi = {
       GYT: refLevel_gyt,
-      GYM: getLessonCourseDetail_gym,
-      KLX: getLessonCourseDetail_klx
+      GYM: refLevel_gym,
+      KLX: refLevel_klx
    }
+
    httpAjaxErrMsg(LessonCoursewareMenuDetailApi[userStoreHook.roles!], {
-      lessonCoursewareDetailId: "1689564396456579073",
-      courseScheduleId: "1844948199117283329"
+      lessonCoursewareDetailId: id || route.params.id
+      // courseScheduleId: "1844948199117283329"
    } as any).then(res => {
       if (res.code === 200) {
-         const { lockFlag, knowledgePointList } = 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
-         }
-         // 处理返回的数据
-         handlePointList(knowledgePointList)
+         coursewareMenuList.value = res.data || []
       }
    })
 }
@@ -332,10 +319,23 @@ function handleCourseClick(value: any) {
    activeCoursewareIndex.value = flattenCoursewareList.value.findIndex((item: any) => {
       return value.id === item.id && value.knowledgePointId === item.knowledgePointId
    })
+   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
+   }
+   await getCoursewareList(value.id)
+   getCoursewareMenuList(value.id)
+   drawerMenuShow.value = false
+   activeCoursewareIndex.value = 0
 
-function handleCourseMenuClick(value: any) {
-   console.log(value, "value")
+   LoadingBar.loading(false)
 }
 
 /* 播放器相关 */
@@ -395,6 +395,14 @@ function handleKeydown(e: KeyboardEvent) {
       handleChangeCourseware(-1)
    }
 }
+function handleToolClick(type: string) {
+   fileType.value === "VIDEO" && handleVideoPause()
+   if (type === "menu") {
+      drawerMenuShow.value = true
+   } else if (type === "point") {
+      drawerShow.value = true
+   }
+}
 function handleMousemove() {
    showController()
 }
@@ -463,7 +471,27 @@ function handleCoursewareEnd() {
       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()
+      }
+   }
+)
 // 去练习
 const activeCoursewareResourceId = computed<string | undefined>(() => {
    const materialRefs = activeCourseware.value?.materialRefs
@@ -493,6 +521,7 @@ function onTitleTip(type: "phaseGoals" | "checkItem", text: string) {
       text,
       btnShow: [false, false]
    })
+   handleVideoPause()
 }
 </script>
 
@@ -516,7 +545,7 @@ function onTitleTip(type: "phaseGoals" | "checkItem", text: string) {
          transform: translateY(-100%);
       }
       .goPracticeBtn {
-         transform: translatex(-135px);
+         transform: translateY(74px);
       }
    }
    &.fileType_song.hideController {
@@ -661,10 +690,10 @@ function onTitleTip(type: "phaseGoals" | "checkItem", text: string) {
    }
    .goPracticeBtn {
       position: absolute;
-      left: 30px;
-      bottom: 124px;
-      width: 178px;
-      height: 64px;
+      right: 32px;
+      bottom: 24px;
+      width: 143px;
+      height: 50px;
       background: url("@/img/coursewarePlay/goPracticeBtn.png") no-repeat;
       background-size: 100% 100%;
       cursor: pointer;

+ 4 - 1
src/views/coursewarePlay/videoPlay/videoPlay.vue

@@ -87,6 +87,7 @@ import { NSlider } from "naive-ui"
 const props = defineProps<{
    disableEvents?: boolean
    isShowController?: boolean
+   autoPlay?: boolean
 }>()
 const emits = defineEmits<{
    (e: "ready"): void //播放器初始化完成
@@ -172,7 +173,9 @@ function initVideo() {
    })
    playerVm.on("loadedmetadata", () => {
       console.log("loadedmetadata")
-      playerVm.play()
+      if (props.autoPlay) {
+         playerVm.play()
+      }
    })
    //总时长变化时候
    playerVm.on("durationchange", () => {