|
|
@@ -2,63 +2,110 @@
|
|
|
import Back from '@/components/back.uvue'
|
|
|
import Loading from '@/components/loading.uvue'
|
|
|
import { ref, onMounted, getCurrentInstance } from 'vue'
|
|
|
-
|
|
|
+import { type SubjectCourseResult, fetchSubjectCourseApp, updateSubjectProgress } from '@/services/subject/course'
|
|
|
+import { router } from '@/.cool'
|
|
|
const isLoading = ref(true)
|
|
|
const showProgress = ref(true)
|
|
|
-
|
|
|
-onMounted(async () => {
|
|
|
- isLoading.value = false
|
|
|
-})
|
|
|
+const showControls = ref(true)
|
|
|
const videoContext = ref<UniApp.VideoContext>()
|
|
|
const data = ref({
|
|
|
src: 'https://oss.xiaoxiongcode.com/course-1/animate/第1集_观察.mp4'
|
|
|
})
|
|
|
const menuItems = [
|
|
|
- { id: 'watch', name: '看课', icon: '📺', active: true },
|
|
|
- { id: 'practice', name: '练习', icon: '📝', active: false },
|
|
|
- { id: 'experiment', name: '虚拟实验', icon: '🧪', active: false },
|
|
|
- { id: 'diary', name: '科学日记', icon: '📓', active: false }
|
|
|
+ { id: 'watch', name: '看课', icon: 'https://oss.xiaoxiongcode.com/static/home/kanke.png' },
|
|
|
+ { id: 'practice', name: '练习', icon: 'https://oss.xiaoxiongcode.com/static/home/lianxi.png' },
|
|
|
+ { id: 'experiment', name: '虚拟实验', icon: 'https://oss.xiaoxiongcode.com/static/home/shiyan.png' },
|
|
|
+ { id: 'diary', name: '科学日记', icon: 'https://oss.xiaoxiongcode.com/static/home/riji.png' }
|
|
|
+]
|
|
|
+const menu2Items = [
|
|
|
+ { id: '1', name: '观察', icon: 'https://oss.xiaoxiongcode.com/static/home/kanke.png' },
|
|
|
+ { id: '2', name: '提问', icon: 'https://oss.xiaoxiongcode.com/static/home/lianxi.png' },
|
|
|
+ { id: '3', name: '假设', icon: 'https://oss.xiaoxiongcode.com/static/home/shiyan.png' },
|
|
|
+ { id: '4', name: '实验', icon: 'https://oss.xiaoxiongcode.com/static/home/riji.png' },
|
|
|
+ { id: '5', name: '总结', icon: 'https://oss.xiaoxiongcode.com/static/home/riji.png' },
|
|
|
+ { id: '6', name: '拓展', icon: 'https://oss.xiaoxiongcode.com/static/home/riji.png' },
|
|
|
]
|
|
|
+//当前进度
|
|
|
+const progress = ref(1)
|
|
|
+const progress2 = ref(1)
|
|
|
+
|
|
|
+
|
|
|
onReady(() => {
|
|
|
videoContext.value = uni.createVideoContext("video1", getCurrentInstance()!.proxy!)
|
|
|
})
|
|
|
-setTimeout(() => {
|
|
|
- showProgress.value = false
|
|
|
-}, 2000)
|
|
|
-function handleControlsToggle(e) {
|
|
|
- videoContext.value?.requestFullScreen({
|
|
|
- direction: 0
|
|
|
+
|
|
|
+const course = ref<SubjectCourseResult>()
|
|
|
+//通过路由参数获取课程id
|
|
|
+async function fetchCatalog() {
|
|
|
+ course.value = await fetchSubjectCourseApp({ id: router.query().id })
|
|
|
+ data.value.src = course.value?.detailItem?.observeVideoPath || ''
|
|
|
+ if (!course.value?.courseUserProgress) {
|
|
|
+ // await updateSubjectProgress({
|
|
|
+ // courseId: course.value?.id,
|
|
|
+ // mainProgress: 1,
|
|
|
+ // assistantProgress: 1,
|
|
|
+ // status: 0
|
|
|
+ // })
|
|
|
+ progress.value = 1
|
|
|
+ progress2.value = 1
|
|
|
+ } else {
|
|
|
+ progress.value = course.value?.courseUserProgress.mainProgress
|
|
|
+ progress2.value = course.value?.courseUserProgress.assistantProgress
|
|
|
+ }
|
|
|
+}
|
|
|
+onMounted(async () => {
|
|
|
+ await fetchCatalog()
|
|
|
+ isLoading.value = false
|
|
|
+ setTimeout(() => {
|
|
|
+ showProgress.value = false
|
|
|
+ }, 2000)
|
|
|
+})
|
|
|
+async function handleEnded() {
|
|
|
+ await updateSubjectProgress({
|
|
|
+ courseId: course.value?.id,
|
|
|
+ mainProgress: 1,
|
|
|
+ assistantProgress: 2,
|
|
|
+ status: 0
|
|
|
})
|
|
|
+ progress2.value = 2
|
|
|
+}
|
|
|
+
|
|
|
+function handleControlsToggle(e) {
|
|
|
+ console.log(e)
|
|
|
+ showControls.value = e.detail.show
|
|
|
}
|
|
|
</script>
|
|
|
<template>
|
|
|
<Loading v-show="isLoading" />
|
|
|
<cl-page v-show="!isLoading">
|
|
|
- <Back />
|
|
|
+ <Back v-show="showProgress" />
|
|
|
<view class="w-[64vw] h-[36vw] absolute top-1/2 z-[1] left-[7vw] translate50"
|
|
|
:class="{ ' rounded-2xl p-[3px] bg-black mt-[25px] ': showProgress, 'video-container': !showProgress }">
|
|
|
<video id="video1" class="w-full h-full " :class="{ 'rounded-2xl': showProgress }" :src="data.src"
|
|
|
- :show-center-play-btn="false" autoplay>
|
|
|
+ :show-center-play-btn="false" :show-background-playback-button="false" :show-fullscreen-btn="false"
|
|
|
+ :show-casting-button="false" autoplay @controlstoggle="handleControlsToggle" @ended="handleEnded">
|
|
|
</video>
|
|
|
- <template>
|
|
|
- <view class="video-fullscreen_controls" @click="handleControlsToggle">
|
|
|
- <view class="control-btn">
|
|
|
- <text class="control-icon">23123123123</text>
|
|
|
- </view>
|
|
|
- <view class="control-btn">
|
|
|
- <text class="control-icon">123213</text>
|
|
|
- </view>
|
|
|
- <view class="control-btn">
|
|
|
- <text class="control-icon">123123123123</text>
|
|
|
+ <view class="video-fullscreen_title" v-show="showControls">
|
|
|
+ <Back v-show="!showProgress" />
|
|
|
+ <view class="text-[20px] font-bold text-white">
|
|
|
+ {{ course?.mainTitle }}是的
|
|
|
+ </view>
|
|
|
+ <view class="control-progress">
|
|
|
+ <view v-for="(item, i) in menu2Items" :key="item.id"
|
|
|
+ class="px-0 py-3 flex items-center justify-center gap-[5px]"
|
|
|
+ :class="{ '!bg-[#fff] rounded-full': progress2 > i }">
|
|
|
+ <cl-image :src="item.icon" mode="heightFix" class="!h-[30px]"></cl-image>
|
|
|
+ <text class="text-[14px] font-bold" :class="{ '!text-[#2BA0F3]': progress2 == i + 1 }">{{ item.name
|
|
|
+ }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
- </template>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
<view class="course-detail-page" :class="{ 'hidden': !showProgress }">
|
|
|
<!-- 顶部标题栏 -->
|
|
|
<view class="flex-[1] h-[100vh] relative">
|
|
|
<view class="flex flex-row w-full pr-[3vw] pl-[10vw] items-center justify-between absolute top-[30px]">
|
|
|
- <text class="text-[5vh] font-bold">1、物质大揭秘!</text>
|
|
|
+ <text class="text-[5vh] font-bold">{{ course?.mainTitle }}</text>
|
|
|
<text
|
|
|
class="rounded-full p-[1vh] px-[2vh] border-2 border-[#fff] border-solid text-[#fff] text-[3vh] font-bold">课程收获</text>
|
|
|
</view>
|
|
|
@@ -66,21 +113,19 @@ function handleControlsToggle(e) {
|
|
|
</view>
|
|
|
<!-- 右侧功能菜单 -->
|
|
|
<view class="w-[25vw] h-[100vh] bg-[#5CBDFD] flex flex-col justify-center p-5">
|
|
|
- <view v-for="(item, i) in menuItems" :key="item.id" class="h-[20vh] flex flex-row items-center "
|
|
|
- :class="{ active: item.active }">
|
|
|
+ <view v-for="(item, i) in menuItems" :key="item.id" class="h-[20vh] flex flex-row items-center ">
|
|
|
<view
|
|
|
- class="h-[15vh] w-[20vh] bg-[#fff] rounded-2xl border-[.5vh] border-[#254AD9] border-b-[1vh] border-solid flex items-center justify-center gap-[1vh]">
|
|
|
- <cl-image src="https://oss.xiaoxiongcode.com/static/home/4.png" mode="heightFix"
|
|
|
- class="!h-[7vh]"></cl-image>
|
|
|
+ class="h-[15vh] w-[20vh] bg-[#999999] rounded-2xl border-[.5vh] border-[#254AD9] border-b-[1vh] border-solid flex items-center justify-center gap-[1vh]"
|
|
|
+ :class="{ '!bg-[#fff]': progress > i }">
|
|
|
+ <cl-image :src="item.icon" mode="heightFix" class="!h-[7vh]"></cl-image>
|
|
|
<text class="text-[2vh] font-bold">{{ item.name }}</text>
|
|
|
</view>
|
|
|
<view class="flex items-center h-[20vh] ml-[2vh] ">
|
|
|
- <view class="w-[1vh] bg-[#B4DBF7] flex-1"
|
|
|
- :class="{ 'bg-[#71C73D]': item.active, '!bg-[#5CBDFD]': i === 0 }">
|
|
|
+ <view class="w-[1vh] bg-[#B4DBF7] flex-1" :class="{ '!bg-[#71C73D]': progress > i, '!opacity-0': i === 0 }">
|
|
|
</view>
|
|
|
- <view class="w-[5vh] bg-[#fff] h-[5vh] rounded-full" :class="{ 'bg-[#71C73D]': item.active }"></view>
|
|
|
+ <view class="w-[5vh] bg-[#fff] h-[5vh] rounded-full" :class="{ '!bg-[#71C73D]': progress > i }"></view>
|
|
|
<view class="w-[1vh] bg-[#B4DBF7] flex-1"
|
|
|
- :class="{ 'bg-[#71C73D]': item.active, '!bg-[#5CBDFD]': i === menuItems.length - 1 }"></view>
|
|
|
+ :class="{ '!bg-[#71C73D]': progress > i, '!opacity-0': i === menuItems.length - 1 }"></view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -127,16 +172,27 @@ function handleControlsToggle(e) {
|
|
|
transition: all 3s ease-in-out;
|
|
|
}
|
|
|
|
|
|
-.video-fullscreen_controls {
|
|
|
- position: absolute;
|
|
|
- left: 50%;
|
|
|
- transform: translateX(-50%);
|
|
|
- bottom: 0px;
|
|
|
- height: 50px;
|
|
|
- flex-direction: row;
|
|
|
- justify-content: flex-start;
|
|
|
- align-items: center;
|
|
|
- z-index: 10;
|
|
|
- width: 80vw;
|
|
|
+.video-fullscreen_title {
|
|
|
+ @apply absolute top-3 left-0 pl-[80px] w-[100vw] z-10 flex items-center justify-between flex-row;
|
|
|
+ color: #fff;
|
|
|
+
|
|
|
+ .control-progress {
|
|
|
+ @apply flex flex-row gap-[1vh] relative justify-end;
|
|
|
+ flex: 1;
|
|
|
+
|
|
|
+ &:before {
|
|
|
+ content: '';
|
|
|
+ @apply absolute top-1/2 right-0 w-[410px] h-[40px] bg-[#2BA0F3] rounded-l-full;
|
|
|
+ transform: translateY(-30%);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+video::-webkit-media-controls-fullscreen-button,
|
|
|
+video::-webkit-media-controls-enter-fullscreen-button,
|
|
|
+video::-webkit-media-controls-rotate-button,
|
|
|
+video::-webkit-media-controls-seek-back-button,
|
|
|
+video::-webkit-media-controls-seek-forward-button {
|
|
|
+ display: none !important;
|
|
|
}
|
|
|
</style>
|