黄琪勇 1 tahun lalu
induk
melakukan
d43018c8ef
95 mengubah file dengan 996 tambahan dan 0 penghapusan
  1. 1 0
      package.json
  2. TEMPAT SAMPAH
      src/img/coursewarePlay/back.png
  3. TEMPAT SAMPAH
      src/img/coursewarePlay/baiban.png
  4. TEMPAT SAMPAH
      src/img/coursewarePlay/close.png
  5. 0 0
      src/img/coursewarePlay/icon-load.gif
  6. TEMPAT SAMPAH
      src/img/coursewarePlay/jieshu.png
  7. TEMPAT SAMPAH
      src/img/coursewarePlay/kcml.png
  8. TEMPAT SAMPAH
      src/img/coursewarePlay/pizhu.png
  9. TEMPAT SAMPAH
      src/img/coursewarePlay/shang.png
  10. TEMPAT SAMPAH
      src/img/coursewarePlay/xia.png
  11. TEMPAT SAMPAH
      src/img/coursewarePlay/zhishidian.png
  12. 2 0
      src/shims-vue.d.ts
  13. 235 0
      src/views/coursewarePlay/components/courseCollapse/courseCollapse.vue
  14. 2 0
      src/views/coursewarePlay/components/courseCollapse/index.ts
  15. 2 0
      src/views/coursewarePlay/components/pen/index.ts
  16. 62 0
      src/views/coursewarePlay/components/pen/pen.vue
  17. 356 0
      src/views/coursewarePlay/coursewarePlay.vue
  18. 2 0
      src/views/coursewarePlay/index.ts
  19. TEMPAT SAMPAH
      src/views/coursewarePlay/videoPlay/img/bg.png
  20. TEMPAT SAMPAH
      src/views/coursewarePlay/videoPlay/img/iconLoop.png
  21. TEMPAT SAMPAH
      src/views/coursewarePlay/videoPlay/img/iconLoopActive.png
  22. TEMPAT SAMPAH
      src/views/coursewarePlay/videoPlay/img/iconPause.png
  23. TEMPAT SAMPAH
      src/views/coursewarePlay/videoPlay/img/iconPlay.png
  24. TEMPAT SAMPAH
      src/views/coursewarePlay/videoPlay/img/iconSpeed.png
  25. TEMPAT SAMPAH
      src/views/coursewarePlay/videoPlay/img/jia.png
  26. TEMPAT SAMPAH
      src/views/coursewarePlay/videoPlay/img/jian.png
  27. 2 0
      src/views/coursewarePlay/videoPlay/index.ts
  28. 19 0
      src/views/coursewarePlay/videoPlay/tools.ts
  29. 313 0
      src/views/coursewarePlay/videoPlay/videoPlay.vue
  30. 0 0
      src/views/coursewarePlayOld/component/musicScore.module.scss
  31. 0 0
      src/views/coursewarePlayOld/component/musicScore.tsx
  32. 0 0
      src/views/coursewarePlayOld/component/point.module.scss
  33. 0 0
      src/views/coursewarePlayOld/component/points.tsx
  34. 0 0
      src/views/coursewarePlayOld/component/tool.module.scss
  35. 0 0
      src/views/coursewarePlayOld/component/tool.tsx
  36. 0 0
      src/views/coursewarePlayOld/component/tools/pen.module.scss
  37. 0 0
      src/views/coursewarePlayOld/component/tools/pen.tsx
  38. 0 0
      src/views/coursewarePlayOld/component/video-item/index.module.scss
  39. 0 0
      src/views/coursewarePlayOld/component/video-item/index.tsx
  40. 0 0
      src/views/coursewarePlayOld/component/video-item/video-play.tsx
  41. 0 0
      src/views/coursewarePlayOld/component/video-play.tsx
  42. 0 0
      src/views/coursewarePlayOld/component/video.module.scss
  43. 0 0
      src/views/coursewarePlayOld/datas/data.json
  44. 0 0
      src/views/coursewarePlayOld/helpers/helpState.ts
  45. 0 0
      src/views/coursewarePlayOld/helpers/native-message.ts
  46. 0 0
      src/views/coursewarePlayOld/helpers/utils.ts
  47. 0 0
      src/views/coursewarePlayOld/image/back.svg
  48. 0 0
      src/views/coursewarePlayOld/image/bb.png
  49. 0 0
      src/views/coursewarePlayOld/image/icon-arrow.svg
  50. 0 0
      src/views/coursewarePlayOld/image/icon-dian.svg
  51. 0 0
      src/views/coursewarePlayOld/image/icon-down.svg
  52. 0 0
      src/views/coursewarePlayOld/image/icon-image-active.svg
  53. 0 0
      src/views/coursewarePlayOld/image/icon-image.svg
  54. TEMPAT SAMPAH
      src/views/coursewarePlayOld/image/icon-load.gif
  55. 0 0
      src/views/coursewarePlayOld/image/icon-loop-active.svg
  56. 0 0
      src/views/coursewarePlayOld/image/icon-loop.svg
  57. 0 0
      src/views/coursewarePlayOld/image/icon-menu.svg
  58. 0 0
      src/views/coursewarePlayOld/image/icon-more.png
  59. 0 0
      src/views/coursewarePlayOld/image/icon-mulv.svg
  60. 0 0
      src/views/coursewarePlayOld/image/icon-pause.svg
  61. 0 0
      src/views/coursewarePlayOld/image/icon-pen.png
  62. 0 0
      src/views/coursewarePlayOld/image/icon-play.svg
  63. 0 0
      src/views/coursewarePlayOld/image/icon-point.svg
  64. 0 0
      src/views/coursewarePlayOld/image/icon-song-active.svg
  65. 0 0
      src/views/coursewarePlayOld/image/icon-song.svg
  66. 0 0
      src/views/coursewarePlayOld/image/icon-speed-add.png
  67. 0 0
      src/views/coursewarePlayOld/image/icon-speed-bg.png
  68. 0 0
      src/views/coursewarePlayOld/image/icon-speed-cut.png
  69. 0 0
      src/views/coursewarePlayOld/image/icon-start.svg
  70. 0 0
      src/views/coursewarePlayOld/image/icon-touping.svg
  71. 0 0
      src/views/coursewarePlayOld/image/icon-up.svg
  72. 0 0
      src/views/coursewarePlayOld/image/icon-video-active.svg
  73. 0 0
      src/views/coursewarePlayOld/image/icon-video.svg
  74. 0 0
      src/views/coursewarePlayOld/image/icon-videobg.png
  75. 0 0
      src/views/coursewarePlayOld/image/icon-zhibo.svg
  76. 0 0
      src/views/coursewarePlayOld/image/iconImageActive.png
  77. 0 0
      src/views/coursewarePlayOld/image/iconLoop.png
  78. 0 0
      src/views/coursewarePlayOld/image/iconLoopActive.png
  79. 0 0
      src/views/coursewarePlayOld/image/iconPause.png
  80. 0 0
      src/views/coursewarePlayOld/image/iconPlay.png
  81. 0 0
      src/views/coursewarePlayOld/image/iconSongActive.png
  82. 0 0
      src/views/coursewarePlayOld/image/iconSpeed.png
  83. 0 0
      src/views/coursewarePlayOld/image/iconVideoActive.png
  84. 0 0
      src/views/coursewarePlayOld/image/icons.json
  85. 0 0
      src/views/coursewarePlayOld/image/jia.png
  86. 0 0
      src/views/coursewarePlayOld/image/jian.png
  87. 0 0
      src/views/coursewarePlayOld/image/js.png
  88. 0 0
      src/views/coursewarePlayOld/image/kcml.png
  89. 0 0
      src/views/coursewarePlayOld/image/pz.png
  90. 0 0
      src/views/coursewarePlayOld/image/video-speed.png
  91. 0 0
      src/views/coursewarePlayOld/image/zzd.png
  92. 0 0
      src/views/coursewarePlayOld/index.module.scss
  93. 0 0
      src/views/coursewarePlayOld/index.tsx
  94. 0 0
      src/views/coursewarePlayOld/playRecordTime.tsx
  95. 0 0
      src/views/coursewarePlayOld/shims-vue.d.ts

+ 1 - 0
package.json

@@ -22,6 +22,7 @@
       "plyr": "^3.7.8",
       "qrcode.vue": "^3.4.1",
       "screenfull": "^6.0.2",
+      "tcplayer.js": "^4.8.0",
       "vant": "^4.8.7",
       "vue": "^3.2.13",
       "vue-router": "^4.0.3",

TEMPAT SAMPAH
src/img/coursewarePlay/back.png


TEMPAT SAMPAH
src/img/coursewarePlay/baiban.png


TEMPAT SAMPAH
src/img/coursewarePlay/close.png


+ 0 - 0
src/views/coursewarePlay/image/icon-load.gif → src/img/coursewarePlay/icon-load.gif


TEMPAT SAMPAH
src/img/coursewarePlay/jieshu.png


TEMPAT SAMPAH
src/img/coursewarePlay/kcml.png


TEMPAT SAMPAH
src/img/coursewarePlay/pizhu.png


TEMPAT SAMPAH
src/img/coursewarePlay/shang.png


TEMPAT SAMPAH
src/img/coursewarePlay/xia.png


TEMPAT SAMPAH
src/img/coursewarePlay/zhishidian.png


+ 2 - 0
src/shims-vue.d.ts

@@ -18,3 +18,5 @@ declare module "@/assets/export.module.scss" {
    }
    export default exportCss
 }
+
+declare module "tcplayer.js"

+ 235 - 0
src/views/coursewarePlay/components/courseCollapse/courseCollapse.vue

@@ -0,0 +1,235 @@
+<!--
+* @FileDescription: 折叠菜单
+* @Author: 黄琪勇
+* @Date:2024-04-01 18:40:50
+-->
+<template>
+   <el-collapse class="courseCollapse" accordion v-model="activeCollapseId">
+      <el-collapse-item v-for="item in props.courseList" :key="item.id" :name="item.id">
+         <template #title>
+            <div class="courseCollapseHead">
+               <div class="courseCollapseHeadTit">
+                  <template v-if="props.titleType === 'round'">
+                     <div class="roundCon">
+                        <img src="@/img/curriculum/yuan.png" />
+                        <div class="ellipsisBox">
+                           <ellipsisScroll :title="item.name" />
+                        </div>
+                     </div>
+                  </template>
+                  <ellipsisScroll v-else :title="item.name" />
+               </div>
+               <div class="courseCollapseHeadArrow">
+                  <div class="headArrow">
+                     <div>展开</div>
+                     <img src="@/img/curriculum/xiangxia.png" />
+                  </div>
+                  <div class="headArrowActive">
+                     <div>收起</div>
+                     <img src="@/img/curriculum/xiangshang.png" />
+                  </div>
+               </div>
+            </div>
+         </template>
+         <div class="courseCollapseCon">
+            <template v-if="item.materialList">
+               <div class="courseList" v-for="i in item.materialList" :key="i.id" @click="handleClick(i)">
+                  <div class="courseTitleCon">
+                     <img :src="require(`@/img/curriculum/${i.typeCode || i.type}.png`)" />
+                     <div class="ellipsisBox">
+                        <ellipsisScroll :title="i.name" />
+                     </div>
+                  </div>
+                  <div class="iconArrow">
+                     <img v-if="activeCollapse?.id === i.id" src="@/img/coursewarePlay/icon-load.gif" />
+                  </div>
+               </div>
+            </template>
+            <courseCollapse
+               v-else
+               :courseList="item.children || []"
+               :activeCollapse="activeCollapse"
+               :titleType="'round'"
+               @handleClick="handleClick"
+            />
+         </div>
+      </el-collapse-item>
+   </el-collapse>
+</template>
+
+<script setup lang="ts">
+import ellipsisScroll from "@/components/ellipsisScroll"
+import { ref, watch } from "vue"
+
+type materialListType = {
+   id: string
+   type: string
+   typeCode?: string
+   name: string
+}
+type courseListType = {
+   id: string
+   name: string
+   materialList: materialListType[] | null
+   children: courseListType | null
+}[]
+
+const props = withDefaults(
+   defineProps<{
+      activeCollapse: undefined | Record<string, any>
+      courseList: courseListType
+      titleType?: "default" | "round"
+   }>(),
+   {
+      titleType: "default"
+   }
+)
+const emits = defineEmits<{
+   (e: "handleClick", value: any): void
+}>()
+watch(
+   () => props.activeCollapse,
+   () => {
+      activeCollapseId.value = filterActiveId()
+   }
+)
+const activeCollapseId = ref(filterActiveId())
+
+function filterActiveId() {
+   const course = props.courseList.find(item => {
+      return (props.activeCollapse?.parentData.ids || []).includes(item.id)
+   })
+   return course?.id || ""
+}
+function handleClick(value: any) {
+   emits("handleClick", value)
+}
+</script>
+
+<style lang="scss" scoped>
+.courseCollapse.el-collapse {
+   --el-collapse-border-color: #f2f2f2;
+   --el-collapse-header-height: 62px;
+   border: none;
+   & > :deep(.el-collapse-item) {
+      > .el-collapse-item__wrap > .el-collapse-item__content {
+         padding-bottom: 2px;
+      }
+      &:last-child {
+         > .el-collapse-item__wrap {
+            border-bottom: none;
+         }
+         > .el-collapse-item__header {
+            border-bottom: none;
+         }
+      }
+      .el-collapse-item__arrow {
+         display: none;
+      }
+      &.is-active > .el-collapse-item__header {
+         > .courseCollapseHead .courseCollapseHeadArrow {
+            > .headArrow {
+               display: none;
+            }
+            > .headArrowActive {
+               display: flex;
+            }
+         }
+      }
+   }
+   .courseCollapseHead {
+      width: 100%;
+      height: 100%;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      .courseCollapseHeadTit {
+         text-align: left;
+         margin-right: 8px;
+         flex-grow: 1;
+         font-weight: 500;
+         font-size: 18px;
+         color: #333333;
+         overflow: hidden;
+         .roundCon {
+            display: flex;
+            align-items: center;
+            color: #f67146;
+            > .ellipsisBox {
+               flex-grow: 1;
+               overflow: hidden;
+            }
+            > img {
+               flex-shrink: 0;
+               width: 8px;
+               height: 8px;
+               margin-right: 10px;
+            }
+         }
+      }
+      .courseCollapseHeadArrow {
+         flex-shrink: 0;
+         .headArrow,
+         .headArrowActive {
+            display: flex;
+            align-items: center;
+            font-weight: 400;
+            font-size: 17px;
+            color: #999999;
+            > img {
+               margin-left: 5px;
+               width: 12px;
+               height: 8px;
+            }
+         }
+         .headArrowActive {
+            display: none;
+            color: #ff8057;
+         }
+      }
+   }
+   .courseCollapseCon {
+      padding-left: 20px;
+      .courseList {
+         display: flex;
+         justify-content: space-between;
+         align-items: center;
+         height: 68px;
+         border-bottom: 1px solid #f2f2f2;
+         cursor: pointer;
+         &:last-child {
+            border-bottom: initial;
+         }
+         .courseTitleCon {
+            flex-grow: 1;
+            overflow: hidden;
+            margin-right: 8px;
+            display: flex;
+            align-items: center;
+            font-weight: 400;
+            font-size: 18px;
+            color: #333333;
+            > .ellipsisBox {
+               flex-grow: 1;
+               overflow: hidden;
+            }
+            > img {
+               flex-shrink: 0;
+               width: 33px;
+               height: 33px;
+               margin-right: 10px;
+            }
+         }
+         .iconArrow {
+            flex-shrink: 0;
+            width: 35px;
+            height: 35px;
+            > img {
+               width: 100%;
+               height: 100%;
+            }
+         }
+      }
+   }
+}
+</style>

+ 2 - 0
src/views/coursewarePlay/components/courseCollapse/index.ts

@@ -0,0 +1,2 @@
+import courseCollapse from "./courseCollapse.vue"
+export default courseCollapse

+ 2 - 0
src/views/coursewarePlay/components/pen/index.ts

@@ -0,0 +1,2 @@
+import pen from "./pen.vue"
+export default pen

+ 62 - 0
src/views/coursewarePlay/components/pen/pen.vue

@@ -0,0 +1,62 @@
+<!--
+* @FileDescription: 批注
+* @Author: 黄琪勇
+* @Date:2024-04-06 18:40:23
+-->
+<template>
+   <el-dialog modal-class="penModalClass" class="penElDialog" :class="{ isWhite: isWhite }" v-bind="$attrs" :fullscreen="true" :show-close="false">
+      <iframe class="penIframe" frameborder="0" :src="URL_WHITEBOARD"></iframe>
+      <div class="closeSvg" @click="close">
+         <svg width="22px" height="20px" viewBox="0 0 22 20">
+            <path
+               transform="translate(-1.000000, -2.000000)"
+               fill="#FFFFFF"
+               d="M13,2 C13.5522847,2 14,2.44771525 14,3 C14,3.51283584 13.6139598,3.93550716 13.1166211,3.99327227 L13,4 L3,4 L3,20 L13,20 C13.5128358,20 13.9355072,20.3860402 13.9932723,20.8833789 L14,21 C14,21.5128358 13.6139598,21.9355072 13.1166211,21.9932723 L13,22 L2,22 C1.48716416,22 1.06449284,21.6139598 1.00672773,21.1166211 L1,21 L1,3 C1,2.48716416 1.38604019,2.06449284 1.88337887,2.00672773 L2,2 L13,2 Z M17.7071068,7.05025253 L21.9497475,11.2928932 L21.9497475,11.2928932 C22.3402718,11.6834175 22.3402718,12.3165825 21.9497475,12.7071068 L17.7071068,16.9497475 C17.3165825,17.3402718 16.6834175,17.3402718 16.2928932,16.9497475 C15.9023689,16.5592232 15.9023689,15.9260582 16.2928932,15.5355339 L18.828,12.999 L9.29368112,13 C8.74139637,13 8.29368112,12.5522847 8.29368112,12 C8.29368112,11.4871642 8.67972131,11.0644928 9.17706,11.0067277 L9.29368112,11 L18.827,10.999 L16.2928932,8.46446609 C15.9023689,8.0739418 15.9023689,7.44077682 16.2928932,7.05025253 C16.6834175,6.65972824 17.3165825,6.65972824 17.7071068,7.05025253 Z"
+            />
+         </svg>
+      </div>
+   </el-dialog>
+</template>
+
+<script setup lang="ts">
+import { URL_WHITEBOARD } from "@/config/index"
+defineProps<{
+   isWhite?: boolean
+   close: () => void
+}>()
+</script>
+<style lang="scss">
+.penElDialog.el-dialog {
+   padding: 0;
+   background-color: initial;
+   &.isWhite {
+      background-color: #fff;
+   }
+   .el-dialog__header {
+      padding: 0;
+   }
+   .el-dialog__body {
+      width: 100%;
+      height: 100%;
+      .penIframe {
+         display: block;
+         width: 100%;
+         height: 100%;
+      }
+   }
+}
+.penModalClass.el-overlay {
+   background-color: initial;
+   .closeSvg {
+      position: absolute;
+      right: 15px;
+      bottom: 0;
+      width: 50px;
+      height: 54px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      z-index: 10;
+   }
+}
+</style>

+ 356 - 0
src/views/coursewarePlay/coursewarePlay.vue

@@ -0,0 +1,356 @@
+<!--
+* @FileDescription: 教程播放
+* @Author: 黄琪勇
+* @Date:2024-04-03 17:31:41
+-->
+<template>
+   <div class="coursewarePlay">
+      <videoPlay ref="videoPlayDom" @ready="handleVideoReady" @keydown="handleVideoKeydown">
+         <div class="leftTools posTools">
+            <div v-if="activeCoursewareIndex > 0" class="posBtn" @click="handleChangeCourseware(-1)">
+               <img src="@/img/coursewarePlay/shang.png" />
+               <div>上一个</div>
+            </div>
+            <div v-if="activeCoursewareIndex < flattenCoursewareList.length - 1" class="posBtn" @click="handleChangeCourseware(1)">
+               <img src="@/img/coursewarePlay/xia.png" />
+               <div>下一个</div>
+            </div>
+         </div>
+         <div class="rightTools posTools">
+            <div class="posBtn" @click="whitePenShow = true">
+               <img src="@/img/coursewarePlay/baiban.png" />
+               <div>白板</div>
+            </div>
+            <div class="posBtn" @click="penShow = true">
+               <img src="@/img/coursewarePlay/pizhu.png" />
+               <div>批注</div>
+            </div>
+            <div class="posBtn" @click="drawer = true">
+               <img src="@/img/coursewarePlay/zhishidian.png" />
+               <div>知识点</div>
+            </div>
+            <div class="posBtn" @click="handleGoBack">
+               <img src="@/img/coursewarePlay/jieshu.png" />
+               <div>结束</div>
+            </div>
+         </div>
+         <div class="topTools">
+            <div class="leftMenu">
+               <img @click="handleGoBack" class="backImg" src="@/img/coursewarePlay/back.png" />
+            </div>
+            <div class="midMenu">{{ activeCourseware?.parentData.name || "" }}</div>
+            <div class="rightMenu"></div>
+         </div>
+         <div class="activeName">
+            <div>{{ activeCourseware?.name || "" }}</div>
+         </div>
+      </videoPlay>
+      <el-drawer class="elDrawer" v-model="drawer" :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">
+            <courseCollapse :activeCollapse="activeCourseware" :courseList="coursewareList" @handleClick="handleCourseClick" />
+         </ElScrollbar>
+      </el-drawer>
+      <pen
+         :close="
+            () => {
+               penShow = false
+            }
+         "
+         v-model="penShow"
+      />
+      <pen
+         :is-white="true"
+         :close="
+            () => {
+               whitePenShow = false
+            }
+         "
+         v-model="whitePenShow"
+      />
+   </div>
+</template>
+
+<script setup lang="ts">
+import videoPlay from "./videoPlay"
+import { getLessonCourseDetail_gym, getLessonCoursewareDetail_gyt } from "@/api/cloudTextbooks.api"
+import { httpAjaxErrMsg } from "@/plugin/httpAjax"
+import userStore from "@/store/modules/user"
+import { useRoute } from "vue-router"
+import { shallowRef, ref, computed, watchEffect } from "vue"
+import { ElMessageBox } from "element-plus"
+import courseCollapse from "./components/courseCollapse"
+import pen from "./components/pen"
+
+// 批注
+const penShow = ref(false)
+// 白板
+const whitePenShow = ref(false)
+
+const route = useRoute()
+const userStoreHook = userStore()
+const videoPlayDom = ref<InstanceType<typeof videoPlay>>()
+const coursewareList = shallowRef<any[]>([]) // 知识点
+const flattenCoursewareList = shallowRef<any[]>([]) // 扁平化coursewareList
+// 选中的知识点
+const activeCourseware = computed<undefined | Record<string, any>>(() => {
+   return flattenCoursewareList.value[activeCoursewareIndex.value]
+})
+const activeCoursewareIndex = ref(0)
+const drawer = ref(false)
+
+watchEffect(() => {
+   activeCourseware.value && videoPlayDom.value?.playVideo({ src: activeCourseware.value.content })
+})
+
+function getCoursewareList() {
+   httpAjaxErrMsg(userStoreHook.roles === "GYM" ? getLessonCourseDetail_gym : getLessonCoursewareDetail_gyt, route.params.id as string).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)
+      }
+   })
+}
+
+let flattenCoursewareListData: any = [] // 临时扁平化数据
+function handlePointList(pointList: any[]) {
+   coursewareList.value = filterPointList(pointList)
+   // 如果url里面有materialId 代表指定资料播放
+   if (route.query.materialId) {
+      const index = flattenCoursewareListData.findIndex((item: any) => {
+         return route.query.materialId === item.id + ""
+      })
+      index > -1 && (activeCoursewareIndex.value = index)
+   }
+   flattenCoursewareList.value = flattenCoursewareListData
+}
+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 {
+         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 handleVideoReady() {
+   getCoursewareList()
+}
+
+function handleChangeCourseware(index: -1 | 1) {
+   const newIndex = index + activeCoursewareIndex.value
+   if (newIndex < 0 || newIndex > flattenCoursewareList.value.length - 1) {
+      return
+   }
+   activeCoursewareIndex.value = newIndex
+}
+function handleCourseClick(value: any) {
+   activeCoursewareIndex.value = flattenCoursewareList.value.findIndex((item: any) => {
+      return value.id === item.id
+   })
+}
+function handleVideoKeydown(e: KeyboardEvent) {
+   const key = e.key
+   if (key === "ArrowDown") {
+      handleChangeCourseware(1)
+   } else if (key === "ArrowUp") {
+      handleChangeCourseware(-1)
+   }
+}
+function handleGoBack() {
+   window.open("about:blank", "_self")
+   window.close()
+}
+</script>
+
+<style lang="scss" scoped>
+.coursewarePlay {
+   width: 100%;
+   height: 100%;
+   position: relative;
+   .activeName {
+      transition: all 0.5s;
+      position: absolute;
+      height: 120px;
+      right: 30px;
+      bottom: 15px;
+      font-weight: 500;
+      font-size: 22px;
+      color: #ffffff;
+      display: flex;
+      align-items: flex-end;
+      padding-bottom: 13px;
+   }
+   .topTools {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      background: linear-gradient(180deg, rgba(0, 0, 0, 0.6), transparent);
+      transition: all 0.5s;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 20px 30px;
+      .leftMenu {
+         .backImg {
+            cursor: pointer;
+            width: 22px;
+            &:hover {
+               opacity: $opacity-hover;
+            }
+         }
+      }
+      .midMenu {
+         font-weight: 500;
+         font-size: 22px;
+         color: #ffffff;
+      }
+   }
+   .posTools {
+      position: absolute;
+      top: 50%;
+      transform: translateY(-50%);
+      transition: all 0.5s;
+      &.leftTools {
+         left: 12px;
+      }
+      &.rightTools {
+         right: 12px;
+      }
+      .posBtn {
+         background: rgba(0, 0, 0, 0.3);
+         border-radius: 8px;
+         padding: 12px 6px;
+         font-weight: 500;
+         font-size: 16px;
+         color: #ffffff;
+         display: flex;
+         flex-direction: column;
+         align-items: center;
+         cursor: pointer;
+         margin-bottom: 12px;
+         &:hover {
+            opacity: $opacity-hover;
+         }
+         &:last-child {
+            margin-bottom: 0;
+         }
+         > img {
+            margin-bottom: 5px;
+            width: 34px;
+            height: 34px;
+         }
+      }
+   }
+   &:deep(.videoPlay.isHideController) {
+      .leftTools {
+         opacity: 0;
+         transform: translate(-100%, -50%);
+      }
+      .rightTools {
+         opacity: 0;
+         transform: translate(100%, -50%);
+      }
+      .topTools {
+         opacity: 0;
+         transform: translateY(-100%);
+      }
+      .activeName {
+         opacity: 0;
+         transform: translateY(100%);
+      }
+   }
+   &:deep(.elDrawer.el-drawer) {
+      width: 346px !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-drawer__body {
+         padding: 0;
+         overflow: hidden;
+         & > .elScrollbar {
+            .el-scrollbar__view {
+               padding: 0 22px;
+               width: 100%;
+            }
+            .el-scrollbar__wrap {
+               overflow-x: hidden;
+            }
+            .el-scrollbar__bar.is-vertical {
+               width: 4px;
+               right: 0;
+            }
+         }
+      }
+   }
+}
+</style>

+ 2 - 0
src/views/coursewarePlay/index.ts

@@ -0,0 +1,2 @@
+import coursewarePlay from "./coursewarePlay.vue"
+export default coursewarePlay

TEMPAT SAMPAH
src/views/coursewarePlay/videoPlay/img/bg.png


TEMPAT SAMPAH
src/views/coursewarePlay/videoPlay/img/iconLoop.png


TEMPAT SAMPAH
src/views/coursewarePlay/videoPlay/img/iconLoopActive.png


TEMPAT SAMPAH
src/views/coursewarePlay/videoPlay/img/iconPause.png


TEMPAT SAMPAH
src/views/coursewarePlay/videoPlay/img/iconPlay.png


TEMPAT SAMPAH
src/views/coursewarePlay/videoPlay/img/iconSpeed.png


TEMPAT SAMPAH
src/views/coursewarePlay/videoPlay/img/jia.png


TEMPAT SAMPAH
src/views/coursewarePlay/videoPlay/img/jian.png


+ 2 - 0
src/views/coursewarePlay/videoPlay/index.ts

@@ -0,0 +1,2 @@
+import videoPlay from "./videoPlay.vue"
+export default videoPlay

+ 19 - 0
src/views/coursewarePlay/videoPlay/tools.ts

@@ -0,0 +1,19 @@
+function padStart(v: string | number, len = 2, str = "0"): string {
+   v = String(v)
+   if (v.length >= 2) return v
+   for (let i = 0, l = len - v.length; i < l; i++) {
+      v = str + v
+   }
+   return v
+}
+export function formatTime(seconds: number): string {
+   if (!isFinite(seconds)) return "-"
+   if (seconds <= 0) return "00:00"
+
+   seconds = Math.ceil(seconds)
+   if (seconds < 60) return `00:${padStart(seconds)}`
+   if (seconds < 3600) {
+      return `${padStart(Math.floor(seconds / 60))}:${padStart(seconds % 60)}`
+   }
+   return `${padStart(Math.floor(seconds / 3600))}:${padStart(Math.floor((seconds % 3600) / 60))}:${padStart(seconds % 60)}`
+}

+ 313 - 0
src/views/coursewarePlay/videoPlay/videoPlay.vue

@@ -0,0 +1,313 @@
+<!--
+* @FileDescription: 播放器
+* @Author: 黄琪勇
+* @Date:2024-04-03 18:30:09
+-->
+<template>
+   <div
+      @keydown="handleVideoKeydown"
+      @mousemove="handleVideoMousemove"
+      class="videoPlay"
+      :class="{ isHideController: !isShowController }"
+      tabindex="-1"
+   >
+      <video class="videoPlayBox" @click="handlePlay" :id="videoId" preload="auto" playsinline webkit-playsinline></video>
+      <div class="videoController" @click.stop>
+         <div class="timeController">{{ `${formatTime(timeController.currentTime)} / ${formatTime(timeController.duration)}` }}</div>
+         <el-slider
+            class="sliderController"
+            @change="handleTimeChange"
+            @mousedown="handleSilderMousedown"
+            v-model="timeController.currentTimeSilder"
+            :max="timeController.duration"
+            :format-tooltip="
+               (value:number) => {
+                  return formatTime(value)
+               }
+            "
+         />
+         <div class="playController">
+            <div class="leftPlayController">
+               <img @click="handlePlay" :src="require(`./img/${playController.type === 'play' ? 'iconPause' : 'iconPlay'}.png`)" />
+               <img @click="handleLoop" :src="require(`./img/${playController.loop ? 'iconLoopActive' : 'iconLoop'}.png`)" />
+               <el-popover placement="top" trigger="click" :teleported="false" popper-class="palySpeedPopover">
+                  <template #reference>
+                     <img src="./img//iconSpeed.png" />
+                  </template>
+                  <div class="sliderSpeedCon">
+                     <img @click="handlePalySpeed(playController.speedStep)" src="./img/jia.png" />
+                     <el-slider
+                        class="sliderSpeed"
+                        @change="handlePalySpeedChange"
+                        v-model="playController.palySpeed"
+                        vertical
+                        :step="playController.speedStep"
+                        :max="playController.maxSpeed"
+                        :min="playController.minSpeed"
+                     />
+                     <img @click="handlePalySpeed(-playController.speedStep)" src="./img/jian.png" />
+                  </div>
+               </el-popover>
+            </div>
+            <div class="rightPlayController"></div>
+         </div>
+      </div>
+      <slot></slot>
+   </div>
+</template>
+
+<script setup lang="ts">
+import TCPlayer from "tcplayer.js"
+import "tcplayer.js/dist/tcplayer.min.css"
+import { onMounted, onUnmounted, ref, reactive } from "vue"
+import { UUID } from "@/libs/tools"
+import { formatTime } from "./tools"
+
+const emits = defineEmits<{
+   (e: "ready"): void //播放器初始化完成
+}>()
+
+const videoId = "video" + UUID()
+let playerVm: Record<string, any>
+
+/* 时间控制器 */
+const timeController = reactive({
+   currentTime: 0, // 当前时间
+   duration: 0, // 总时长
+   currentTimeSilder: 0,
+   isDrag: false
+})
+/* 播放控制器 */
+const playController = reactive<{
+   type: "play" | "pause"
+   loop: boolean
+   minSpeed: number
+   maxSpeed: number
+   speedStep: number
+   palySpeed: number
+}>({
+   type: "pause", //play|pause
+   loop: false,
+   minSpeed: 0.5,
+   maxSpeed: 1.5,
+   speedStep: 0.1,
+   palySpeed: 1
+})
+/* 是否显示控制器 */
+const isShowController = ref(true)
+let _showTimer: any
+onMounted(() => {
+   initVideo()
+})
+onUnmounted(() => {
+   playerVm?.dispose()
+})
+/**
+ * 初始化播放器
+ */
+function initVideo() {
+   playerVm = TCPlayer(videoId, {
+      controls: false,
+      autoplay: true,
+      loop: false
+   })
+   // 初始化完成
+   playerVm.on("ready", () => {
+      console.log("播放器初始化完成")
+      emits("ready")
+   })
+   // 开始加载数据时
+   playerVm.on("loadstart", () => {
+      // 重新设置播放倍速  因为切换视频播放倍速会重置
+      playerVm.playbackRate(playController.palySpeed)
+   })
+   //总时长变化时候
+   playerVm.on("durationchange", () => {
+      //duration和currentTime 时间向上取整Math.ceil
+      timeController.duration = Math.ceil(playerVm.duration())
+   })
+   //当前播放时间变化
+   playerVm.on("timeupdate", () => {
+      //duration和currentTime 时间向上取整Math.ceil
+      timeController.currentTime = Math.ceil(playerVm.currentTime())
+      if (!timeController.isDrag) {
+         timeController.currentTimeSilder = timeController.currentTime
+      }
+   })
+   playerVm.on("play", () => {
+      playController.type = "play"
+   })
+   playerVm.on("pause", () => {
+      playController.type = "pause"
+   })
+}
+/**
+ * 播放  需要在ready之后调用
+ */
+function playVideo({ src }: { src: string }) {
+   playerVm?.src(src)
+   showController()
+}
+
+/* 时间控制器 */
+function handleTimeChange(value: number | number[]) {
+   playerVm.currentTime(value || 0)
+   timeController.isDrag = false
+}
+function handleSilderMousedown() {
+   timeController.isDrag = true
+}
+/* 播放控制器 */
+function handlePlay() {
+   playController.type === "pause" ? playerVm.play() : playerVm.pause()
+   showController()
+}
+function handleLoop() {
+   playController.loop ? playerVm.loop(false) : playerVm.loop(true)
+   playController.loop = playerVm.loop()
+}
+function handlePalySpeedChange(value: number | number[]) {
+   playerVm.playbackRate(value)
+}
+function handlePalySpeed(value: number) {
+   const palySpeed = parseFloat((playController.palySpeed + value).toFixed(1))
+   if (palySpeed > playController.maxSpeed || palySpeed < playController.minSpeed) {
+      return
+   }
+   playController.palySpeed = palySpeed
+   handlePalySpeedChange(palySpeed)
+}
+/* 是否显示控制器 */
+function handleVideoKeydown(e: KeyboardEvent) {
+   console.log("handleVideoKeydown")
+   const key = e.key
+   if (key === " ") {
+      handlePlay()
+   }
+}
+function handleVideoMousemove() {
+   console.log("handleVideoMousemove")
+   showController()
+}
+function showController() {
+   isShowController.value = true
+   _showTimer && clearTimeout(_showTimer)
+   _showTimer = setTimeout(tryHideController, 3000)
+}
+function tryHideController() {
+   if (playController.type === "play") {
+      isShowController.value = false
+   }
+}
+defineExpose({
+   playVideo
+})
+</script>
+
+<style lang="scss" scoped>
+.videoPlay {
+   width: 100%;
+   height: 100%;
+   position: relative;
+   overflow: hidden;
+   .videoPlayBox {
+      width: 100%;
+      height: 100%;
+   }
+   &.isHideController {
+      cursor: none;
+      .videoController {
+         opacity: 0;
+         transform: translateY(100%);
+      }
+   }
+   .videoController {
+      position: absolute;
+      width: 100%;
+      left: 0;
+      bottom: 0;
+      padding: 0 30px 15px;
+      background: linear-gradient(0deg, rgba(0, 0, 0, 0.5), transparent);
+      color: #fff;
+      transition: all 0.5s;
+      .timeController {
+         font-weight: 500;
+         font-size: 22px;
+         color: #ffffff;
+         line-height: 30px;
+      }
+      & > :deep(.sliderController.el-slider) {
+         --el-slider-button-wrapper-offset: -12px;
+         --el-slider-button-wrapper-size: 28px;
+         --el-slider-height: 4px;
+         --el-slider-border-radius: 2px;
+         --el-slider-main-bg-color: #ff8057;
+         --el-slider-runway-bg-color: rgba(255, 255, 255, 0.5);
+         height: 28px;
+         .el-slider__button {
+            border: none;
+            &:hover {
+               transform: scale(1.1);
+            }
+         }
+      }
+      .playController {
+         display: flex;
+         justify-content: space-between;
+         .leftPlayController {
+            margin-left: -10px;
+            display: flex;
+            & > img {
+               cursor: pointer;
+               width: 48px;
+               height: 48px;
+               margin-right: 26px;
+            }
+            & > :deep(.palySpeedPopover.el-popover.el-popper) {
+               min-width: initial;
+               width: 65px !important;
+               height: 293px;
+               background: url("./img/bg.png") no-repeat;
+               background-size: 100% 100%;
+               box-shadow: none;
+               border: none;
+               padding: 15px 0 22px;
+               .el-popper__arrow {
+                  display: none;
+               }
+               .sliderSpeedCon {
+                  width: 100%;
+                  height: 100%;
+                  display: flex;
+                  justify-content: center;
+                  align-items: center;
+                  flex-direction: column;
+                  & > img {
+                     cursor: pointer;
+                     flex-shrink: 0;
+                     width: 33px;
+                     height: 35px;
+                  }
+                  .sliderSpeed.el-slider {
+                     flex-grow: 1;
+                     padding: 14px 0;
+                     --el-slider-button-wrapper-offset: -11px;
+                     --el-slider-button-wrapper-size: 26px;
+                     --el-slider-height: 6px;
+                     --el-slider-border-radius: 4px;
+                     --el-slider-main-bg-color: #ff8057;
+                     --el-slider-runway-bg-color: rgba(255, 255, 255, 0.5);
+                     .el-slider__button {
+                        border: none;
+                        &:hover {
+                           transform: scale(1.1);
+                        }
+                     }
+                  }
+               }
+            }
+         }
+      }
+   }
+}
+</style>

+ 0 - 0
src/views/coursewarePlay/component/musicScore.module.scss → src/views/coursewarePlayOld/component/musicScore.module.scss


+ 0 - 0
src/views/coursewarePlay/component/musicScore.tsx → src/views/coursewarePlayOld/component/musicScore.tsx


+ 0 - 0
src/views/coursewarePlay/component/point.module.scss → src/views/coursewarePlayOld/component/point.module.scss


+ 0 - 0
src/views/coursewarePlay/component/points.tsx → src/views/coursewarePlayOld/component/points.tsx


+ 0 - 0
src/views/coursewarePlay/component/tool.module.scss → src/views/coursewarePlayOld/component/tool.module.scss


+ 0 - 0
src/views/coursewarePlay/component/tool.tsx → src/views/coursewarePlayOld/component/tool.tsx


+ 0 - 0
src/views/coursewarePlay/component/tools/pen.module.scss → src/views/coursewarePlayOld/component/tools/pen.module.scss


+ 0 - 0
src/views/coursewarePlay/component/tools/pen.tsx → src/views/coursewarePlayOld/component/tools/pen.tsx


+ 0 - 0
src/views/coursewarePlay/component/video-item/index.module.scss → src/views/coursewarePlayOld/component/video-item/index.module.scss


+ 0 - 0
src/views/coursewarePlay/component/video-item/index.tsx → src/views/coursewarePlayOld/component/video-item/index.tsx


+ 0 - 0
src/views/coursewarePlay/component/video-item/video-play.tsx → src/views/coursewarePlayOld/component/video-item/video-play.tsx


+ 0 - 0
src/views/coursewarePlay/component/video-play.tsx → src/views/coursewarePlayOld/component/video-play.tsx


+ 0 - 0
src/views/coursewarePlay/component/video.module.scss → src/views/coursewarePlayOld/component/video.module.scss


+ 0 - 0
src/views/coursewarePlay/datas/data.json → src/views/coursewarePlayOld/datas/data.json


+ 0 - 0
src/views/coursewarePlay/helpers/helpState.ts → src/views/coursewarePlayOld/helpers/helpState.ts


+ 0 - 0
src/views/coursewarePlay/helpers/native-message.ts → src/views/coursewarePlayOld/helpers/native-message.ts


+ 0 - 0
src/views/coursewarePlay/helpers/utils.ts → src/views/coursewarePlayOld/helpers/utils.ts


+ 0 - 0
src/views/coursewarePlay/image/back.svg → src/views/coursewarePlayOld/image/back.svg


+ 0 - 0
src/views/coursewarePlay/image/bb.png → src/views/coursewarePlayOld/image/bb.png


+ 0 - 0
src/views/coursewarePlay/image/icon-arrow.svg → src/views/coursewarePlayOld/image/icon-arrow.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-dian.svg → src/views/coursewarePlayOld/image/icon-dian.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-down.svg → src/views/coursewarePlayOld/image/icon-down.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-image-active.svg → src/views/coursewarePlayOld/image/icon-image-active.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-image.svg → src/views/coursewarePlayOld/image/icon-image.svg


TEMPAT SAMPAH
src/views/coursewarePlayOld/image/icon-load.gif


+ 0 - 0
src/views/coursewarePlay/image/icon-loop-active.svg → src/views/coursewarePlayOld/image/icon-loop-active.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-loop.svg → src/views/coursewarePlayOld/image/icon-loop.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-menu.svg → src/views/coursewarePlayOld/image/icon-menu.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-more.png → src/views/coursewarePlayOld/image/icon-more.png


+ 0 - 0
src/views/coursewarePlay/image/icon-mulv.svg → src/views/coursewarePlayOld/image/icon-mulv.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-pause.svg → src/views/coursewarePlayOld/image/icon-pause.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-pen.png → src/views/coursewarePlayOld/image/icon-pen.png


+ 0 - 0
src/views/coursewarePlay/image/icon-play.svg → src/views/coursewarePlayOld/image/icon-play.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-point.svg → src/views/coursewarePlayOld/image/icon-point.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-song-active.svg → src/views/coursewarePlayOld/image/icon-song-active.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-song.svg → src/views/coursewarePlayOld/image/icon-song.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-speed-add.png → src/views/coursewarePlayOld/image/icon-speed-add.png


+ 0 - 0
src/views/coursewarePlay/image/icon-speed-bg.png → src/views/coursewarePlayOld/image/icon-speed-bg.png


+ 0 - 0
src/views/coursewarePlay/image/icon-speed-cut.png → src/views/coursewarePlayOld/image/icon-speed-cut.png


+ 0 - 0
src/views/coursewarePlay/image/icon-start.svg → src/views/coursewarePlayOld/image/icon-start.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-touping.svg → src/views/coursewarePlayOld/image/icon-touping.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-up.svg → src/views/coursewarePlayOld/image/icon-up.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-video-active.svg → src/views/coursewarePlayOld/image/icon-video-active.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-video.svg → src/views/coursewarePlayOld/image/icon-video.svg


+ 0 - 0
src/views/coursewarePlay/image/icon-videobg.png → src/views/coursewarePlayOld/image/icon-videobg.png


+ 0 - 0
src/views/coursewarePlay/image/icon-zhibo.svg → src/views/coursewarePlayOld/image/icon-zhibo.svg


+ 0 - 0
src/views/coursewarePlay/image/iconImageActive.png → src/views/coursewarePlayOld/image/iconImageActive.png


+ 0 - 0
src/views/coursewarePlay/image/iconLoop.png → src/views/coursewarePlayOld/image/iconLoop.png


+ 0 - 0
src/views/coursewarePlay/image/iconLoopActive.png → src/views/coursewarePlayOld/image/iconLoopActive.png


+ 0 - 0
src/views/coursewarePlay/image/iconPause.png → src/views/coursewarePlayOld/image/iconPause.png


+ 0 - 0
src/views/coursewarePlay/image/iconPlay.png → src/views/coursewarePlayOld/image/iconPlay.png


+ 0 - 0
src/views/coursewarePlay/image/iconSongActive.png → src/views/coursewarePlayOld/image/iconSongActive.png


+ 0 - 0
src/views/coursewarePlay/image/iconSpeed.png → src/views/coursewarePlayOld/image/iconSpeed.png


+ 0 - 0
src/views/coursewarePlay/image/iconVideoActive.png → src/views/coursewarePlayOld/image/iconVideoActive.png


+ 0 - 0
src/views/coursewarePlay/image/icons.json → src/views/coursewarePlayOld/image/icons.json


+ 0 - 0
src/views/coursewarePlay/image/jia.png → src/views/coursewarePlayOld/image/jia.png


+ 0 - 0
src/views/coursewarePlay/image/jian.png → src/views/coursewarePlayOld/image/jian.png


+ 0 - 0
src/views/coursewarePlay/image/js.png → src/views/coursewarePlayOld/image/js.png


+ 0 - 0
src/views/coursewarePlay/image/kcml.png → src/views/coursewarePlayOld/image/kcml.png


+ 0 - 0
src/views/coursewarePlay/image/pz.png → src/views/coursewarePlayOld/image/pz.png


+ 0 - 0
src/views/coursewarePlay/image/video-speed.png → src/views/coursewarePlayOld/image/video-speed.png


+ 0 - 0
src/views/coursewarePlay/image/zzd.png → src/views/coursewarePlayOld/image/zzd.png


+ 0 - 0
src/views/coursewarePlay/index.module.scss → src/views/coursewarePlayOld/index.module.scss


+ 0 - 0
src/views/coursewarePlay/index.tsx → src/views/coursewarePlayOld/index.tsx


+ 0 - 0
src/views/coursewarePlay/playRecordTime.tsx → src/views/coursewarePlayOld/playRecordTime.tsx


+ 0 - 0
src/views/coursewarePlay/shims-vue.d.ts → src/views/coursewarePlayOld/shims-vue.d.ts