|
@@ -21,7 +21,7 @@ import {
|
|
TransitionGroup
|
|
TransitionGroup
|
|
} from 'vue'
|
|
} from 'vue'
|
|
import iconBack from './image/back.svg'
|
|
import iconBack from './image/back.svg'
|
|
-import styles from './index.module.less'
|
|
|
|
|
|
+import styles from './play.module.less'
|
|
import 'plyr/dist/plyr.css'
|
|
import 'plyr/dist/plyr.css'
|
|
import request from '@/helpers/request'
|
|
import request from '@/helpers/request'
|
|
import { state } from '@/state'
|
|
import { state } from '@/state'
|
|
@@ -44,8 +44,7 @@ import { Vue3Lottie } from 'vue3-lottie'
|
|
import playLoadData from './datas/data.json'
|
|
import playLoadData from './datas/data.json'
|
|
import { usePageVisibility, useRect } from '@vant/use'
|
|
import { usePageVisibility, useRect } from '@vant/use'
|
|
import PlayRecordTime from './playRecordTime'
|
|
import PlayRecordTime from './playRecordTime'
|
|
-import dayjs from 'dayjs'
|
|
|
|
-
|
|
|
|
|
|
+import VideoPlay from './component/video-play'
|
|
import {
|
|
import {
|
|
Pagination,
|
|
Pagination,
|
|
Navigation,
|
|
Navigation,
|
|
@@ -73,11 +72,11 @@ export default defineComponent({
|
|
const activeItem = data.itemList[popupData.activeIndex]
|
|
const activeItem = data.itemList[popupData.activeIndex]
|
|
if (activeItem.type != 'VIDEO') return
|
|
if (activeItem.type != 'VIDEO') return
|
|
if (value == 'hidden') {
|
|
if (value == 'hidden') {
|
|
- isPlay.value = !activeItem.paused
|
|
|
|
- handlePaused(activeItem)
|
|
|
|
|
|
+ isPlay.value = !activeItem.videoEle.paused
|
|
|
|
+ togglePlay(activeItem, false)
|
|
} else {
|
|
} else {
|
|
// 页面显示,并且
|
|
// 页面显示,并且
|
|
- if (isPlay.value) handlePlay(activeItem)
|
|
|
|
|
|
+ if (isPlay.value) togglePlay(activeItem, true)
|
|
}
|
|
}
|
|
})
|
|
})
|
|
/** 设置播放容器 16:9 */
|
|
/** 设置播放容器 16:9 */
|
|
@@ -96,22 +95,20 @@ export default defineComponent({
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const handleInit = (type = 0) => {
|
|
const handleInit = (type = 0) => {
|
|
- // postMessage({
|
|
|
|
- // api: 'courseLoading',
|
|
|
|
- // content: {
|
|
|
|
- // show: true,
|
|
|
|
- // type: 'fullscreen'
|
|
|
|
- // }
|
|
|
|
- // })
|
|
|
|
//设置容器16:9
|
|
//设置容器16:9
|
|
setContainer()
|
|
setContainer()
|
|
// 横屏
|
|
// 横屏
|
|
- postMessage({
|
|
|
|
- api: 'setRequestedOrientation',
|
|
|
|
- content: {
|
|
|
|
- orientation: type
|
|
|
|
|
|
+ postMessage(
|
|
|
|
+ {
|
|
|
|
+ api: 'setRequestedOrientation',
|
|
|
|
+ content: {
|
|
|
|
+ orientation: type
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ () => {
|
|
|
|
+ console.log(234)
|
|
}
|
|
}
|
|
- })
|
|
|
|
|
|
+ )
|
|
// 头,包括返回箭头
|
|
// 头,包括返回箭头
|
|
postMessage({
|
|
postMessage({
|
|
api: 'setTitleBarVisibility',
|
|
api: 'setTitleBarVisibility',
|
|
@@ -149,7 +146,8 @@ export default defineComponent({
|
|
itemList: [] as any,
|
|
itemList: [] as any,
|
|
showHead: true,
|
|
showHead: true,
|
|
isCourse: false,
|
|
isCourse: false,
|
|
- isRecordPlay: false
|
|
|
|
|
|
+ isRecordPlay: false,
|
|
|
|
+ videoRefs: {}
|
|
})
|
|
})
|
|
const activeData = reactive({
|
|
const activeData = reactive({
|
|
nowTime: 0,
|
|
nowTime: 0,
|
|
@@ -208,57 +206,31 @@ export default defineComponent({
|
|
if (localData?.content?.localPath) {
|
|
if (localData?.content?.localPath) {
|
|
material.url = material.content
|
|
material.url = material.content
|
|
material.content = localData.content.localPath
|
|
material.content = localData.content.localPath
|
|
- // console.log("🚀 ~ material", material)
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- let videoItem = {}
|
|
|
|
- if (material.type === 'VIDEO') {
|
|
|
|
- videoItem = {
|
|
|
|
- currentTime: 0,
|
|
|
|
- duration: 0,
|
|
|
|
- progress: 0,
|
|
|
|
- paused: true,
|
|
|
|
- loop: false,
|
|
|
|
- videoEle: null,
|
|
|
|
- timer: null,
|
|
|
|
- playModel: false,
|
|
|
|
- isprepare: false,
|
|
|
|
- isDrage: false,
|
|
|
|
- muted: true // 是否静音
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
list.push({
|
|
list.push({
|
|
...material,
|
|
...material,
|
|
- ...videoItem,
|
|
|
|
iframeRef: null,
|
|
iframeRef: null,
|
|
|
|
+ videoEle: null,
|
|
tabName: item.name,
|
|
tabName: item.name,
|
|
isLast: j === itemLength, // 当前知识点
|
|
isLast: j === itemLength, // 当前知识点
|
|
autoPlay: false, //加载完成是否自动播放
|
|
autoPlay: false, //加载完成是否自动播放
|
|
- display: false
|
|
|
|
|
|
+ isprepare: false, // 视频是否加载完成
|
|
|
|
+ isRender: false // 是否渲染了
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- let item: any = null
|
|
|
|
- if (route.query.kId) {
|
|
|
|
- item = list.find((n: any) => n.materialId == route.query.kId)
|
|
|
|
- const _firstIndex = list.findIndex((n: any) => n.materialId == route.query.kId)
|
|
|
|
- console.log('🚀 ~ item:', _firstIndex, list)
|
|
|
|
- popupData.firstIndex = _firstIndex > -1 ? _firstIndex : 0
|
|
|
|
- }
|
|
|
|
- item = item ? item : list[0] || {}
|
|
|
|
- if (item) {
|
|
|
|
- popupData.tabName = item.tabName
|
|
|
|
- popupData.tabActive = item.knowledgePointId
|
|
|
|
- popupData.itemActive = item.id
|
|
|
|
- popupData.itemName = item.name
|
|
|
|
- popupData.activeIndex = popupData.firstIndex
|
|
|
|
- console.log("🚀 ~ popupData.activeIndex:", popupData.activeIndex)
|
|
|
|
- item.autoPlay = true
|
|
|
|
- item.muted = true
|
|
|
|
- item.display = true
|
|
|
|
- }
|
|
|
|
|
|
+ let _firstIndex = list.findIndex((n: any) => n.materialId == route.query.kId)
|
|
|
|
+ _firstIndex = _firstIndex > -1 ? _firstIndex : 0
|
|
|
|
+ const item = list[_firstIndex]
|
|
|
|
+ item.autoPlay = true
|
|
|
|
+ popupData.activeIndex = _firstIndex
|
|
|
|
+ popupData.tabName = item.tabName
|
|
|
|
+ popupData.tabActive = item.knowledgePointId
|
|
|
|
+ popupData.itemActive = item.id
|
|
|
|
+ popupData.itemName = item.name
|
|
// console.log('🚀 ~ list', list)
|
|
// console.log('🚀 ~ list', list)
|
|
nextTick(() => {
|
|
nextTick(() => {
|
|
data.itemList = list
|
|
data.itemList = list
|
|
@@ -270,8 +242,6 @@ export default defineComponent({
|
|
}
|
|
}
|
|
})
|
|
})
|
|
})
|
|
})
|
|
- // setTimeout(() => {
|
|
|
|
- // }, 300)
|
|
|
|
}
|
|
}
|
|
const getDetail = async () => {
|
|
const getDetail = async () => {
|
|
try {
|
|
try {
|
|
@@ -303,15 +273,18 @@ export default defineComponent({
|
|
}
|
|
}
|
|
} catch (error) {}
|
|
} catch (error) {}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ const iframTime = ref()
|
|
// ifram事件处理
|
|
// ifram事件处理
|
|
const iframeHandle = (ev: MessageEvent) => {
|
|
const iframeHandle = (ev: MessageEvent) => {
|
|
if (ev.data?.api === 'headerTogge') {
|
|
if (ev.data?.api === 'headerTogge') {
|
|
- // console.log("🚀 ~ ev.data", ev.data)
|
|
|
|
- activeData.model = ev.data.show || (ev.data.playState == 'play' ? true : false)
|
|
|
|
|
|
+ clearTimeout(iframTime.value)
|
|
|
|
+ iframTime.value = setTimeout(() => {
|
|
|
|
+ activeData.model = ev.data.show || (ev.data.playState == 'play' ? false : true)
|
|
|
|
+ }, 500)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- const swiperDom = ref()
|
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
const hasVip = handleCheckVip()
|
|
const hasVip = handleCheckVip()
|
|
if (!hasVip) {
|
|
if (!hasVip) {
|
|
@@ -343,9 +316,7 @@ export default defineComponent({
|
|
postMessage({ api: 'goBack' })
|
|
postMessage({ api: 'goBack' })
|
|
}
|
|
}
|
|
|
|
|
|
- const swipeRef = ref<SwipeInstance>()
|
|
|
|
const popupData = reactive({
|
|
const popupData = reactive({
|
|
- firstIndex: 0,
|
|
|
|
open: false,
|
|
open: false,
|
|
activeIndex: 0,
|
|
activeIndex: 0,
|
|
tabActive: '',
|
|
tabActive: '',
|
|
@@ -357,25 +328,17 @@ export default defineComponent({
|
|
|
|
|
|
/**停止所有的播放 */
|
|
/**停止所有的播放 */
|
|
const handleStop = () => {
|
|
const handleStop = () => {
|
|
- const activeItem = data.itemList[popupData.activeIndex]
|
|
|
|
for (let i = 0; i < data.itemList.length; i++) {
|
|
for (let i = 0; i < data.itemList.length; i++) {
|
|
- const item = data.itemList[i]
|
|
|
|
- // 停止视频播放
|
|
|
|
- if (item.type === 'VIDEO') {
|
|
|
|
- // console.log("🚀 ~ item", item)
|
|
|
|
- if (item?.id != activeItem.id) {
|
|
|
|
- item.currentTime = 0
|
|
|
|
- item.progress = 0
|
|
|
|
- if (item.videoEle) {
|
|
|
|
- item.videoEle.currentTime = 0
|
|
|
|
- item.videoEle.pause()
|
|
|
|
- }
|
|
|
|
|
|
+ const activeItem = data.itemList[i]
|
|
|
|
+ if (popupData.activeIndex !== i) {
|
|
|
|
+ if (activeItem.type === 'VIDEO' && activeItem.videoEle) {
|
|
|
|
+ activeItem.videoEle.stop()
|
|
|
|
+ }
|
|
|
|
+ // console.log('🚀 ~ activeItem:', activeItem)
|
|
|
|
+ // 停止曲谱的播放
|
|
|
|
+ if (activeItem.type === 'SONG') {
|
|
|
|
+ activeItem.iframeRef?.contentWindow?.postMessage({ api: 'setPlayState' }, '*')
|
|
}
|
|
}
|
|
- }
|
|
|
|
- // 停止曲谱的播放
|
|
|
|
- if (item.type === 'SONG') {
|
|
|
|
- item.iframeRef?.contentWindow?.postMessage({ api: 'setPlayState' }, '*')
|
|
|
|
- item.display = false
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -383,10 +346,7 @@ export default defineComponent({
|
|
const toggleMaterial = () => {
|
|
const toggleMaterial = () => {
|
|
const index = data.itemList.findIndex((n: any) => n.id == popupData.itemActive)
|
|
const index = data.itemList.findIndex((n: any) => n.id == popupData.itemActive)
|
|
if (index > -1) {
|
|
if (index > -1) {
|
|
- // swipeRef.value?.swipeTo(index, {
|
|
|
|
- // immediate: true
|
|
|
|
- // })
|
|
|
|
- swiperDom.value?.slideTo(index, 1000)
|
|
|
|
|
|
+ handleSwipeChange(index)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/** 延迟收起模态框 */
|
|
/** 延迟收起模态框 */
|
|
@@ -395,37 +355,9 @@ export default defineComponent({
|
|
closeToast()
|
|
closeToast()
|
|
activeData.timer = setTimeout(() => {
|
|
activeData.timer = setTimeout(() => {
|
|
activeData.model = false
|
|
activeData.model = false
|
|
|
|
+ Object.values(data.videoRefs).map((n: any) => n.toggleHideControl(false))
|
|
}, 4000)
|
|
}, 4000)
|
|
}
|
|
}
|
|
- // 轮播切换
|
|
|
|
- const handleSwipeChange = (val: any) => {
|
|
|
|
- console.log('轮播切换')
|
|
|
|
- popupData.activeIndex = val
|
|
|
|
- const item = data.itemList[val]
|
|
|
|
- handleStop()
|
|
|
|
- if (item) {
|
|
|
|
- popupData.tabActive = item.knowledgePointId
|
|
|
|
- popupData.itemActive = item.id
|
|
|
|
- popupData.itemName = item.name
|
|
|
|
- popupData.tabName = item.tabName
|
|
|
|
- if (item.type == 'SONG') {
|
|
|
|
- activeData.model = true
|
|
|
|
- item.display = true
|
|
|
|
- }
|
|
|
|
- if (item.type === 'VIDEO') {
|
|
|
|
- // console.log("🚀 ~ item", item)
|
|
|
|
- // 自动播放下一个视频
|
|
|
|
- clearTimeout(activeData.timer)
|
|
|
|
- closeToast()
|
|
|
|
- item.currentTime = 0
|
|
|
|
- item.videoEle && (item.videoEle.currentTime = 0)
|
|
|
|
- nextTick(() => {
|
|
|
|
- item.autoPlay = true
|
|
|
|
- item.videoEle?.play()
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
|
|
// 去点名,签退
|
|
// 去点名,签退
|
|
const gotoRollCall = (pageTag: string) => {
|
|
const gotoRollCall = (pageTag: string) => {
|
|
@@ -442,7 +374,6 @@ export default defineComponent({
|
|
|
|
|
|
// 双击
|
|
// 双击
|
|
const handleDbClick = (item: any) => {
|
|
const handleDbClick = (item: any) => {
|
|
- // console.log(item)
|
|
|
|
if (item && item.type === 'VIDEO') {
|
|
if (item && item.type === 'VIDEO') {
|
|
const videoEle: HTMLVideoElement = item.videoEle
|
|
const videoEle: HTMLVideoElement = item.videoEle
|
|
if (videoEle) {
|
|
if (videoEle) {
|
|
@@ -457,419 +388,354 @@ export default defineComponent({
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- // 暂停播放
|
|
|
|
- const handlePaused = (m: any) => {
|
|
|
|
- m.videoEle?.pause()
|
|
|
|
- m.paused = true
|
|
|
|
- }
|
|
|
|
- // 开始播放
|
|
|
|
- const handlePlay = (m: any) => {
|
|
|
|
- closeToast()
|
|
|
|
- m.videoEle?.play()
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 调整播放进度
|
|
|
|
- const handleChangeSlider = (m: any) => {
|
|
|
|
- if (m?.videoEle) {
|
|
|
|
- // console.log('进度条', m.progress)
|
|
|
|
- m.currentTime = m.duration * (m.progress / 100)
|
|
|
|
- m.videoEle.currentTime = m.currentTime
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //当前视频播放完
|
|
|
|
- const handleEnded = (m: any) => {
|
|
|
|
- // console.log(m)
|
|
|
|
- if (popupData.activeIndex != data.itemList.length - 1) {
|
|
|
|
- swiperDom.value.slideNext(800)
|
|
|
|
|
|
+ // 切换播放
|
|
|
|
+ const togglePlay = (m: any, isPlay: boolean) => {
|
|
|
|
+ if (isPlay) {
|
|
|
|
+ m.videoEle?.play()
|
|
|
|
+ } else {
|
|
|
|
+ m.videoEle?.pause()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ const showIndex = ref(-4)
|
|
|
|
+ const effectIndex = ref(0)
|
|
const effects = [
|
|
const effects = [
|
|
{
|
|
{
|
|
prev: {
|
|
prev: {
|
|
- shadow: true,
|
|
|
|
- translate: [0, 0, -400]
|
|
|
|
|
|
+ transform: 'translate3d(0, 0, -800px) rotateX(180deg)'
|
|
},
|
|
},
|
|
next: {
|
|
next: {
|
|
- translate: ['100%', 0, 0]
|
|
|
|
|
|
+ transform: 'translate3d(0, 0, -800px) rotateX(-180deg)'
|
|
}
|
|
}
|
|
},
|
|
},
|
|
{
|
|
{
|
|
prev: {
|
|
prev: {
|
|
- shadow: true,
|
|
|
|
- translate: ['-120%', 0, -500]
|
|
|
|
|
|
+ transform: 'translate3d(-100%, 0, -800px)'
|
|
},
|
|
},
|
|
next: {
|
|
next: {
|
|
- shadow: true,
|
|
|
|
- translate: ['120%', 0, -500]
|
|
|
|
|
|
+ transform: 'translate3d(100%, 0, -800px)'
|
|
}
|
|
}
|
|
},
|
|
},
|
|
{
|
|
{
|
|
prev: {
|
|
prev: {
|
|
- shadow: true,
|
|
|
|
- translate: ['-20%', 0, -1]
|
|
|
|
|
|
+ transform: 'translate3d(-50%, 0, -800px) rotateY(80deg)'
|
|
},
|
|
},
|
|
next: {
|
|
next: {
|
|
- translate: ['100%', 0, 0]
|
|
|
|
|
|
+ transform: 'translate3d(50%, 0, -800px) rotateY(-80deg)'
|
|
}
|
|
}
|
|
},
|
|
},
|
|
{
|
|
{
|
|
prev: {
|
|
prev: {
|
|
- shadow: true,
|
|
|
|
- translate: [0, 0, -800],
|
|
|
|
- rotate: [-180, 0, 0]
|
|
|
|
|
|
+ transform: 'translate3d(-100%, 0, -800px) rotateY(-120deg)'
|
|
},
|
|
},
|
|
next: {
|
|
next: {
|
|
- shadow: true,
|
|
|
|
- translate: [0, 0, -800],
|
|
|
|
- rotate: [180, 0, 0]
|
|
|
|
|
|
+ transform: 'translate3d(100%, 0, -800px) rotateY(120deg)'
|
|
}
|
|
}
|
|
},
|
|
},
|
|
|
|
+ //风车4
|
|
{
|
|
{
|
|
prev: {
|
|
prev: {
|
|
- shadow: true,
|
|
|
|
- translate: ['-125%', 0, -800],
|
|
|
|
- rotate: [0, 0, -90]
|
|
|
|
|
|
+ transform: 'translate3d(-50%, 50%, -800px) rotateZ(-14deg)',
|
|
|
|
+ opacity: 0
|
|
},
|
|
},
|
|
next: {
|
|
next: {
|
|
- shadow: true,
|
|
|
|
- translate: ['125%', 0, -800],
|
|
|
|
- rotate: [0, 0, 90]
|
|
|
|
|
|
+ transform: 'translate3d(50%, 50%, -800px) rotateZ(14deg)',
|
|
|
|
+ opacity: 0
|
|
}
|
|
}
|
|
},
|
|
},
|
|
|
|
+ //翻页5
|
|
{
|
|
{
|
|
prev: {
|
|
prev: {
|
|
- shadow: true,
|
|
|
|
- origin: 'right center',
|
|
|
|
- translate: ['5%', 0, -200],
|
|
|
|
- rotate: [0, -100, 0]
|
|
|
|
|
|
+ transform: 'translateZ(-800px) rotate3d(0, -1, 0, 90deg)',
|
|
|
|
+ opacity: 0
|
|
},
|
|
},
|
|
next: {
|
|
next: {
|
|
- origin: 'left center',
|
|
|
|
- translate: ['-5%', 0, -200],
|
|
|
|
- rotate: [0, 100, 0]
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- prev: {
|
|
|
|
- scale: 0.3,
|
|
|
|
- opacity: 0.4
|
|
|
|
|
|
+ transform: 'translateZ(-800px) rotate3d(0, 1, 0, 90deg)',
|
|
|
|
+ opacity: 0
|
|
},
|
|
},
|
|
- next: {
|
|
|
|
- opacity: 0.4,
|
|
|
|
- scale: 0.3
|
|
|
|
- }
|
|
|
|
|
|
+ current: { transitionDelay: '700ms' }
|
|
}
|
|
}
|
|
]
|
|
]
|
|
- const swiperType = ref(effects[3])
|
|
|
|
- console.log("🚀 ~ swiperType:", swiperType.value)
|
|
|
|
- // 上一个知识点, 下一个知识点
|
|
|
|
- const handlePreAndNext = (type: string) => {
|
|
|
|
|
|
+
|
|
|
|
+ // 轮播切换
|
|
|
|
+ const handleSwipeChange = (index: number) => {
|
|
|
|
+ if (popupData.activeIndex == index) return
|
|
|
|
+ // console.log('轮播切换')
|
|
|
|
+ popupData.activeIndex = index
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
- if (type === 'up') {
|
|
|
|
- swiperDom.value.slidePrev(800)
|
|
|
|
- } else {
|
|
|
|
- swiperDom.value.slideNext(800)
|
|
|
|
|
|
+ handleStop()
|
|
|
|
+ const item = data.itemList[index]
|
|
|
|
+ if (item) {
|
|
|
|
+ popupData.tabActive = item.knowledgePointId
|
|
|
|
+ popupData.itemActive = item.id
|
|
|
|
+ popupData.itemName = item.name
|
|
|
|
+ popupData.tabName = item.tabName
|
|
|
|
+ if (item.type == 'SONG') {
|
|
|
|
+ activeData.model = true
|
|
|
|
+ }
|
|
|
|
+ if (item.type === 'VIDEO') {
|
|
|
|
+ // 自动播放下一个视频
|
|
|
|
+ clearTimeout(activeData.timer)
|
|
|
|
+ closeToast()
|
|
|
|
+ item.autoPlay = true
|
|
|
|
+ nextTick(() => {
|
|
|
|
+ item.videoEle?.play()
|
|
|
|
+ })
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- }, 400)
|
|
|
|
|
|
+ }, 800)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 上一个知识点, 下一个知识点
|
|
|
|
+ const handlePreAndNext = (type: string) => {
|
|
|
|
+ if (type === 'up') {
|
|
|
|
+ handleSwipeChange(popupData.activeIndex - 1)
|
|
|
|
+ } else {
|
|
|
|
+ handleSwipeChange(popupData.activeIndex + 1)
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
return () => (
|
|
return () => (
|
|
<div class={styles.playContent}>
|
|
<div class={styles.playContent}>
|
|
- <div class={styles.coursewarePlay} style={{ width: parentContainer.width }}>
|
|
|
|
- {data.itemList.length && (
|
|
|
|
- <Swiper
|
|
|
|
- style={{ height: '100%' }}
|
|
|
|
- class={styles.swiperContainer}
|
|
|
|
- effect="creative"
|
|
|
|
- modules={[Pagination, Navigation, EffectCreative]}
|
|
|
|
- creativeEffect={swiperType.value}
|
|
|
|
- direction="vertical"
|
|
|
|
- navigation
|
|
|
|
- allowTouchMove={false}
|
|
|
|
- onSwiper={(swiper: any) => {
|
|
|
|
- swiperDom.value = swiper
|
|
|
|
- }}
|
|
|
|
- onSlideChange={(swiper: any) => {
|
|
|
|
- handleSwipeChange(swiper.activeIndex)
|
|
|
|
- }}
|
|
|
|
- initialSlide={popupData.activeIndex}
|
|
|
|
- >
|
|
|
|
|
|
+ <div
|
|
|
|
+ onClick={() => {
|
|
|
|
+ clearTimeout(activeData.timer)
|
|
|
|
+ activeData.model = !activeData.model
|
|
|
|
+ Object.values(data.videoRefs).map((n: any) => n.toggleHideControl(activeData.model))
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ <div
|
|
|
|
+ class={styles.coursewarePlay}
|
|
|
|
+ style={{ width: parentContainer.width }}
|
|
|
|
+ onClick={(e: Event) => {
|
|
|
|
+ e.stopPropagation()
|
|
|
|
+ setModelOpen()
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ <div class={styles.wraps}>
|
|
{data.itemList.map((m: any, mIndex: number) => {
|
|
{data.itemList.map((m: any, mIndex: number) => {
|
|
- return (
|
|
|
|
- <SwiperSlide class={styles.swipeItem} key={'index' + mIndex}>
|
|
|
|
- <div
|
|
|
|
- class={[styles.itemDiv]}
|
|
|
|
- onClick={() => {
|
|
|
|
- clearTimeout(activeData.timer)
|
|
|
|
- if (Date.now() - activeData.nowTime < 300) {
|
|
|
|
- handleDbClick(m)
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
- activeData.nowTime = Date.now()
|
|
|
|
- activeData.timer = setTimeout(() => {
|
|
|
|
- activeData.model = !activeData.model
|
|
|
|
|
|
+ const isRender = m.isRender || Math.abs(popupData.activeIndex - mIndex) < 2
|
|
|
|
+ if (isRender) {
|
|
|
|
+ m.isRender = true
|
|
|
|
+ }
|
|
|
|
+ return isRender ? (
|
|
|
|
+ <div
|
|
|
|
+ key={'index' + mIndex}
|
|
|
|
+ class={[styles.itemDiv, popupData.activeIndex === mIndex && styles.itemActive]}
|
|
|
|
+ style={
|
|
|
|
+ mIndex < popupData.activeIndex
|
|
|
|
+ ? effects[effectIndex.value].prev
|
|
|
|
+ : mIndex > popupData.activeIndex
|
|
|
|
+ ? effects[effectIndex.value].next
|
|
|
|
+ : effects[effectIndex.value].current
|
|
|
|
+ }
|
|
|
|
+ onClick={(e: Event) => {
|
|
|
|
+ e.stopPropagation()
|
|
|
|
+ clearTimeout(activeData.timer)
|
|
|
|
+ if (Date.now() - activeData.nowTime < 300) {
|
|
|
|
+ handleDbClick(m)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ activeData.nowTime = Date.now()
|
|
|
|
+ activeData.timer = setTimeout(() => {
|
|
|
|
+ activeData.model = !activeData.model
|
|
|
|
+ Object.values(data.videoRefs).map((n: any) =>
|
|
|
|
+ n.toggleHideControl(activeData.model)
|
|
|
|
+ )
|
|
|
|
+ if (activeData.model) {
|
|
setModelOpen()
|
|
setModelOpen()
|
|
- }, 300)
|
|
|
|
- }}
|
|
|
|
- >
|
|
|
|
- {m.type === 'VIDEO' ? (
|
|
|
|
- <>
|
|
|
|
- <video
|
|
|
|
- class={['player']}
|
|
|
|
- playsinline="false"
|
|
|
|
- muted={m.muted}
|
|
|
|
- preload="auto"
|
|
|
|
- data-vid={m.id}
|
|
|
|
- src={m.content}
|
|
|
|
- loop={m.loop}
|
|
|
|
- autoplay={m.autoPlay}
|
|
|
|
- onLoadedmetadata={(e: Event) => {
|
|
|
|
- const videoEle = e.target as unknown as HTMLVideoElement
|
|
|
|
- m.currentTime = videoEle.currentTime
|
|
|
|
- m.duration = videoEle.duration
|
|
|
|
- m.videoEle = videoEle
|
|
|
|
|
|
+ }
|
|
|
|
+ }, 300)
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ {m.type === 'VIDEO' ? (
|
|
|
|
+ <>
|
|
|
|
+ <VideoPlay
|
|
|
|
+ ref={(v: any) => (data.videoRefs[mIndex] = v)}
|
|
|
|
+ item={m}
|
|
|
|
+ onLoadedmetadata={(videoItem: any) => {
|
|
|
|
+ m.videoEle = videoItem
|
|
|
|
+ }}
|
|
|
|
+ onTogglePlay={(paused: boolean) => {
|
|
|
|
+ // console.log('播放切换', paused)
|
|
|
|
+ // 首次播放完成
|
|
|
|
+ if (!m.isprepare) {
|
|
m.isprepare = true
|
|
m.isprepare = true
|
|
- }}
|
|
|
|
- onTimeupdate={(e: Event) => {
|
|
|
|
- if (!m.isprepare) return
|
|
|
|
- const videoEle = e.target as unknown as HTMLVideoElement
|
|
|
|
- m.currentTime = videoEle.currentTime
|
|
|
|
- m.progress = Number((videoEle.currentTime / m.duration) * 100)
|
|
|
|
- }}
|
|
|
|
- onPlay={() => {
|
|
|
|
- // 播放
|
|
|
|
- m.paused = false
|
|
|
|
- console.log('播放')
|
|
|
|
- setModelOpen()
|
|
|
|
- // 第一次播放
|
|
|
|
- if (m.muted) {
|
|
|
|
- m.muted = false
|
|
|
|
- m.autoPlay = false
|
|
|
|
- }
|
|
|
|
- }}
|
|
|
|
- onPause={() => {
|
|
|
|
- //暂停
|
|
|
|
|
|
+ }
|
|
|
|
+ m.autoPlay = false
|
|
|
|
+ if (paused || popupData.open || popupData.guideOpen) {
|
|
clearTimeout(activeData.timer)
|
|
clearTimeout(activeData.timer)
|
|
- m.paused = true
|
|
|
|
- }}
|
|
|
|
- onEnded={() => handleEnded(m)}
|
|
|
|
- >
|
|
|
|
- <source src={m.content} type="video/mp4" />
|
|
|
|
- </video>
|
|
|
|
- {m.muted && (
|
|
|
|
|
|
+ } else {
|
|
|
|
+ setModelOpen()
|
|
|
|
+ }
|
|
|
|
+ }}
|
|
|
|
+ onEnded={() => handleSwipeChange(popupData.activeIndex + 1)}
|
|
|
|
+ onReset={() => {
|
|
|
|
+ if (!m.videoEle?.paused) {
|
|
|
|
+ setModelOpen()
|
|
|
|
+ }
|
|
|
|
+ }}
|
|
|
|
+ />
|
|
|
|
+ <Transition name="van-fade">
|
|
|
|
+ {!m.isprepare && (
|
|
<div class={styles.loadWrap}>
|
|
<div class={styles.loadWrap}>
|
|
<Vue3Lottie animationData={playLoadData}></Vue3Lottie>
|
|
<Vue3Lottie animationData={playLoadData}></Vue3Lottie>
|
|
</div>
|
|
</div>
|
|
)}
|
|
)}
|
|
- <div
|
|
|
|
- style={{ transform: activeData.model ? '' : 'translateY(100%)' }}
|
|
|
|
- class={styles.bottomFixedContainer}
|
|
|
|
- onClick={(e: Event) => {
|
|
|
|
- e.stopPropagation()
|
|
|
|
- setModelOpen()
|
|
|
|
- }}
|
|
|
|
- >
|
|
|
|
- <div style={{ opacity: m.isprepare ? '1' : '0' }}>
|
|
|
|
- <div class={styles.time}>
|
|
|
|
- <span>{getSecondRPM(m.currentTime)}</span>
|
|
|
|
- <span>{getSecondRPM(m.duration)}</span>
|
|
|
|
- </div>
|
|
|
|
- <div class={styles.slider}>
|
|
|
|
- <Slider
|
|
|
|
- onClick={() => setModelOpen()}
|
|
|
|
- buttonSize={16}
|
|
|
|
- step={1}
|
|
|
|
- modelValue={m.progress}
|
|
|
|
- onUpdate:modelValue={(val: any) => {
|
|
|
|
- console.log('val', val)
|
|
|
|
- m.progress = val
|
|
|
|
- handleChangeSlider(m)
|
|
|
|
- }}
|
|
|
|
- onDragStart={(e: Event) => {
|
|
|
|
- // 开始拖动,暂停播放
|
|
|
|
- console.log('开始拖动')
|
|
|
|
- // 如果拖动之前,视频是播放状态,拖动完毕后继续播放
|
|
|
|
- if (!m.paused) {
|
|
|
|
- m.isDrage = true
|
|
|
|
- }
|
|
|
|
- handlePaused(m)
|
|
|
|
- }}
|
|
|
|
- onDragEnd={(e: Event) => {
|
|
|
|
- console.log('结束拖动')
|
|
|
|
- if (m.isDrage) {
|
|
|
|
- m.isDrage = false
|
|
|
|
- handlePlay(m)
|
|
|
|
- }
|
|
|
|
- }}
|
|
|
|
- min={0}
|
|
|
|
- max={100}
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
- <div class={styles.actions}>
|
|
|
|
- <div class={styles.actionBtn}>
|
|
|
|
- {m.isprepare ? (
|
|
|
|
- <>
|
|
|
|
- {m.paused ? (
|
|
|
|
- <img src={iconplay} onClick={(e: Event) => handlePlay(m)} />
|
|
|
|
- ) : (
|
|
|
|
- <img
|
|
|
|
- src={iconpause}
|
|
|
|
- onClick={(e: Event) => handlePaused(m)}
|
|
|
|
- />
|
|
|
|
- )}
|
|
|
|
- </>
|
|
|
|
- ) : (
|
|
|
|
- <Loading color="#fff" />
|
|
|
|
- )}
|
|
|
|
-
|
|
|
|
- {m.loop ? (
|
|
|
|
- <img
|
|
|
|
- src={iconLoopActive}
|
|
|
|
- onClick={(e: Event) => (m.loop = false)}
|
|
|
|
- />
|
|
|
|
- ) : (
|
|
|
|
- <img src={iconLoop} onClick={(e: Event) => (m.loop = true)} />
|
|
|
|
- )}
|
|
|
|
- </div>
|
|
|
|
- <div>{m.name}</div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </>
|
|
|
|
- ) : m.type === 'IMG' ? (
|
|
|
|
- <img src={m.content} />
|
|
|
|
- ) : (
|
|
|
|
- <MusicScore
|
|
|
|
- data-vid={m.id}
|
|
|
|
- music={m}
|
|
|
|
- onSetIframe={(el: any) => {
|
|
|
|
- m.iframeRef = el
|
|
|
|
- }}
|
|
|
|
- />
|
|
|
|
- )}
|
|
|
|
- </div>
|
|
|
|
- </SwiperSlide>
|
|
|
|
- )
|
|
|
|
|
|
+ </Transition>
|
|
|
|
+ </>
|
|
|
|
+ ) : m.type === 'IMG' ? (
|
|
|
|
+ <img src={m.content} />
|
|
|
|
+ ) : (
|
|
|
|
+ <MusicScore
|
|
|
|
+ data-vid={m.id}
|
|
|
|
+ music={m}
|
|
|
|
+ onSetIframe={(el: any) => {
|
|
|
|
+ m.iframeRef = el
|
|
|
|
+ }}
|
|
|
|
+ />
|
|
|
|
+ )}
|
|
|
|
+ </div>
|
|
|
|
+ ) : null
|
|
})}
|
|
})}
|
|
- </Swiper>
|
|
|
|
- )}
|
|
|
|
-
|
|
|
|
- <div
|
|
|
|
- style={{ transform: activeData.model ? '' : 'translateY(-100%)' }}
|
|
|
|
- id="coursePlayHeader"
|
|
|
|
- class={styles.headerContainer}
|
|
|
|
- ref={headeRef}
|
|
|
|
- >
|
|
|
|
- <div class={styles.backBtn} onClick={() => goback()}>
|
|
|
|
- <Icon name={iconBack} />
|
|
|
|
- 返回
|
|
|
|
</div>
|
|
</div>
|
|
- <div class={styles.menu}>{popupData.tabName}</div>
|
|
|
|
- {data.isCourse && <PlayRecordTime ref={playRef} list={data.itemList} />}
|
|
|
|
- </div>
|
|
|
|
- <Transition name="right">
|
|
|
|
- {activeData.model && (
|
|
|
|
- <div class={styles.rightFixedBtns}>
|
|
|
|
- <div class={styles.btnsWrap}>
|
|
|
|
- <div
|
|
|
|
- class={[styles.fullBtn, styles.point]}
|
|
|
|
- onClick={() => {
|
|
|
|
- clearTimeout(activeData.timer)
|
|
|
|
- popupData.open = true
|
|
|
|
- }}
|
|
|
|
- >
|
|
|
|
- <img src={iconMenu} />
|
|
|
|
- <span>知识点</span>
|
|
|
|
|
|
+ <Transition name="right">
|
|
|
|
+ {activeData.model && (
|
|
|
|
+ <div
|
|
|
|
+ class={styles.rightFixedBtns}
|
|
|
|
+ onClick={(e: Event) => {
|
|
|
|
+ e.stopPropagation()
|
|
|
|
+ clearTimeout(activeData.timer)
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ <div class={styles.btnsWrap}>
|
|
|
|
+ <div
|
|
|
|
+ class={[styles.fullBtn, styles.point]}
|
|
|
|
+ onClick={() => (popupData.open = true)}
|
|
|
|
+ >
|
|
|
|
+ <img src={iconMenu} />
|
|
|
|
+ <span>知识点</span>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
|
|
|
|
- <div class={[styles.btnsWrap, styles.btnsBottom]}>
|
|
|
|
- <div class={styles.fullBtn} onClick={() => (popupData.guideOpen = true)}>
|
|
|
|
- <img src={iconTouping} />
|
|
|
|
- <span>投屏</span>
|
|
|
|
|
|
+ <div class={[styles.btnsWrap, styles.btnsBottom]}>
|
|
|
|
+ <div class={styles.fullBtn} onClick={() => (popupData.guideOpen = true)}>
|
|
|
|
+ <img src={iconTouping} />
|
|
|
|
+ <span>投屏</span>
|
|
|
|
+ </div>
|
|
|
|
+ {data.isCourse && (
|
|
|
|
+ <>
|
|
|
|
+ <div
|
|
|
|
+ class={styles.fullBtn}
|
|
|
|
+ onClick={() => gotoRollCall('student_roll_call')}
|
|
|
|
+ >
|
|
|
|
+ <img src={iconDian} />
|
|
|
|
+ <span>点名</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div class={styles.fullBtn} onClick={() => gotoRollCall('sign_out')}>
|
|
|
|
+ <img src={iconPoint} />
|
|
|
|
+ <span>签退</span>
|
|
|
|
+ </div>
|
|
|
|
+ </>
|
|
|
|
+ )}
|
|
</div>
|
|
</div>
|
|
- {data.isCourse && (
|
|
|
|
- <>
|
|
|
|
- <div class={styles.fullBtn} onClick={() => gotoRollCall('student_roll_call')}>
|
|
|
|
- <img src={iconDian} />
|
|
|
|
- <span>点名</span>
|
|
|
|
|
|
+ </div>
|
|
|
|
+ )}
|
|
|
|
+ </Transition>
|
|
|
|
+
|
|
|
|
+ <Transition name="left">
|
|
|
|
+ {activeData.model && (
|
|
|
|
+ <div class={styles.leftFixedBtns} onClick={(e: Event) => e.stopPropagation()}>
|
|
|
|
+ {popupData.activeIndex != 0 && (
|
|
|
|
+ <div class={[styles.btnsWrap, styles.prePoint]}>
|
|
|
|
+ <div class={styles.fullBtn} onClick={() => handlePreAndNext('up')}>
|
|
|
|
+ <img src={iconUp} />
|
|
|
|
+ <span style={{ textAlign: 'center' }}>上一个</span>
|
|
</div>
|
|
</div>
|
|
- <div class={styles.fullBtn} onClick={() => gotoRollCall('sign_out')}>
|
|
|
|
- <img src={iconPoint} />
|
|
|
|
- <span>签退</span>
|
|
|
|
|
|
+ </div>
|
|
|
|
+ )}
|
|
|
|
+ {popupData.activeIndex != data.itemList.length - 1 && (
|
|
|
|
+ <div class={styles.btnsWrap}>
|
|
|
|
+ <div class={styles.fullBtn} onClick={() => handlePreAndNext('down')}>
|
|
|
|
+ <span style={{ textAlign: 'center' }}>下一个</span>
|
|
|
|
+ <img src={iconDown} />
|
|
</div>
|
|
</div>
|
|
- </>
|
|
|
|
|
|
+ </div>
|
|
)}
|
|
)}
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
- )}
|
|
|
|
- </Transition>
|
|
|
|
- <Transition name="left">
|
|
|
|
- {activeData.model && (
|
|
|
|
- <div class={styles.leftFixedBtns}>
|
|
|
|
- {popupData.activeIndex != 0 && (
|
|
|
|
- <div class={[styles.btnsWrap, styles.prePoint]}>
|
|
|
|
- <div
|
|
|
|
- class={styles.fullBtn}
|
|
|
|
- onClick={() => handlePreAndNext('up')}
|
|
|
|
- >
|
|
|
|
- <img src={iconUp} />
|
|
|
|
- <span style={{ textAlign: 'center' }}>上一个</span>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- )}
|
|
|
|
- {popupData.activeIndex != data.itemList.length - 1 && (
|
|
|
|
- <div class={[styles.btnsWrap, styles.prePoint]}>
|
|
|
|
- <div class={styles.fullBtn} onClick={() => handlePreAndNext('down')}>
|
|
|
|
- <span style={{ textAlign: 'center' }}>下一个</span>
|
|
|
|
- <img src={iconDown} />
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- )}
|
|
|
|
- </div>
|
|
|
|
- )}
|
|
|
|
- </Transition>
|
|
|
|
- <Popup
|
|
|
|
- class={styles.popup}
|
|
|
|
- overlayClass={styles.overlayClass}
|
|
|
|
- position="right"
|
|
|
|
- round
|
|
|
|
- v-model:show={popupData.open}
|
|
|
|
- onClose={() => {
|
|
|
|
- const item = data.itemList[popupData.activeIndex]
|
|
|
|
- if (item?.type == 'VIDEO') {
|
|
|
|
- setModelOpen()
|
|
|
|
|
|
+ )}
|
|
|
|
+ </Transition>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div
|
|
|
|
+ style={{ transform: activeData.model ? '' : 'translateY(-100%)' }}
|
|
|
|
+ id="coursePlayHeader"
|
|
|
|
+ class={styles.headerContainer}
|
|
|
|
+ ref={headeRef}
|
|
|
|
+ >
|
|
|
|
+ <div class={styles.backBtn} onClick={() => goback()}>
|
|
|
|
+ <Icon name={iconBack} />
|
|
|
|
+ 返回
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ class={styles.menu}
|
|
|
|
+ onClick={() => {
|
|
|
|
+ showIndex.value += 1
|
|
|
|
+ if (showIndex.value > 0) {
|
|
|
|
+ effectIndex.value = effectIndex.value >= effects.length ? 0 : effectIndex.value + 1
|
|
}
|
|
}
|
|
|
|
+ setModelOpen()
|
|
}}
|
|
}}
|
|
>
|
|
>
|
|
- <Points
|
|
|
|
- data={data.knowledgePointList}
|
|
|
|
- tabActive={popupData.tabActive}
|
|
|
|
- itemActive={popupData.itemActive}
|
|
|
|
- onHandleSelect={(res: any) => {
|
|
|
|
- // console.log(res)
|
|
|
|
- popupData.tabActive = res.tabActive
|
|
|
|
- popupData.itemActive = res.itemActive
|
|
|
|
- popupData.tabName = res.tabName
|
|
|
|
- popupData.open = false
|
|
|
|
- toggleMaterial()
|
|
|
|
- }}
|
|
|
|
- />
|
|
|
|
- </Popup>
|
|
|
|
-
|
|
|
|
- <Popup
|
|
|
|
- class={styles.popup}
|
|
|
|
- overlayClass={styles.overlayClass}
|
|
|
|
- position="right"
|
|
|
|
- round
|
|
|
|
- v-model:show={popupData.guideOpen}
|
|
|
|
- >
|
|
|
|
- <OGuide />
|
|
|
|
- </Popup>
|
|
|
|
|
|
+ {popupData.tabName} {showIndex.value > 0 ? `动画${effectIndex.value}` : ''}
|
|
|
|
+ </div>
|
|
|
|
+ {data.isCourse && <PlayRecordTime ref={playRef} list={data.itemList} />}
|
|
</div>
|
|
</div>
|
|
|
|
+
|
|
|
|
+ <Popup
|
|
|
|
+ class={styles.popup}
|
|
|
|
+ overlayClass={styles.overlayClass}
|
|
|
|
+ position="right"
|
|
|
|
+ round
|
|
|
|
+ v-model:show={popupData.open}
|
|
|
|
+ onClose={() => {
|
|
|
|
+ const item = data.itemList[popupData.activeIndex]
|
|
|
|
+ if (item?.type == 'VIDEO' && !item.videoEle?.paused) {
|
|
|
|
+ setModelOpen()
|
|
|
|
+ }
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ <Points
|
|
|
|
+ data={data.knowledgePointList}
|
|
|
|
+ tabActive={popupData.tabActive}
|
|
|
|
+ itemActive={popupData.itemActive}
|
|
|
|
+ onHandleSelect={(res: any) => {
|
|
|
|
+ // console.log(res)
|
|
|
|
+ popupData.tabActive = res.tabActive
|
|
|
|
+ popupData.itemActive = res.itemActive
|
|
|
|
+ popupData.tabName = res.tabName
|
|
|
|
+ popupData.open = false
|
|
|
|
+ toggleMaterial()
|
|
|
|
+ }}
|
|
|
|
+ />
|
|
|
|
+ </Popup>
|
|
|
|
+
|
|
|
|
+ <Popup
|
|
|
|
+ class={styles.popup}
|
|
|
|
+ overlayClass={styles.overlayClass}
|
|
|
|
+ position="right"
|
|
|
|
+ round
|
|
|
|
+ v-model:show={popupData.guideOpen}
|
|
|
|
+ onClose={() => {
|
|
|
|
+ const item = data.itemList[popupData.activeIndex]
|
|
|
|
+ if (item?.type == 'VIDEO' && !item.videoEle?.paused) {
|
|
|
|
+ setModelOpen()
|
|
|
|
+ }
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ <OGuide />
|
|
|
|
+ </Popup>
|
|
</div>
|
|
</div>
|
|
)
|
|
)
|
|
}
|
|
}
|