|
@@ -1,9 +1,6 @@
|
|
|
import {
|
|
|
- closeToast,
|
|
|
Icon,
|
|
|
- Popup,
|
|
|
showConfirmDialog,
|
|
|
- showToast,
|
|
|
Slider,
|
|
|
Swipe,
|
|
|
SwipeItem
|
|
@@ -12,12 +9,10 @@ import {
|
|
|
defineComponent,
|
|
|
onMounted,
|
|
|
reactive,
|
|
|
- nextTick,
|
|
|
onUnmounted,
|
|
|
ref,
|
|
|
watch,
|
|
|
Transition,
|
|
|
- computed
|
|
|
} from 'vue'
|
|
|
import styles from './index.module.less'
|
|
|
import 'plyr/dist/plyr.css'
|
|
@@ -72,10 +67,13 @@ export default defineComponent({
|
|
|
})
|
|
|
|
|
|
const route = useRoute()
|
|
|
- watch(() => route.query, () => {
|
|
|
- getDetail()
|
|
|
- trainingRecord()
|
|
|
- })
|
|
|
+ watch(
|
|
|
+ () => route.query,
|
|
|
+ () => {
|
|
|
+ getDetail()
|
|
|
+ trainingRecord()
|
|
|
+ }
|
|
|
+ )
|
|
|
const router = useRouter()
|
|
|
const query = route.query
|
|
|
const browserInfo = browser()
|
|
@@ -95,21 +93,8 @@ export default defineComponent({
|
|
|
timer: null as any,
|
|
|
item: null as any
|
|
|
})
|
|
|
- // 获取缓存路径
|
|
|
- const getCacheFilePath = async (material: any) => {
|
|
|
- const res = await promisefiyPostMessage({
|
|
|
- api: 'getCourseFilePath',
|
|
|
- content: {
|
|
|
- url: material.content,
|
|
|
- localPath: '',
|
|
|
- materialId: material.id,
|
|
|
- updateTime: material.updateTime,
|
|
|
- type: material.type
|
|
|
- }
|
|
|
- })
|
|
|
- return res
|
|
|
- }
|
|
|
const getDetail = async () => {
|
|
|
+ data.itemList = []
|
|
|
let details = []
|
|
|
try {
|
|
|
const res: any = await request.get(
|
|
@@ -129,16 +114,6 @@ export default defineComponent({
|
|
|
try {
|
|
|
videoData.training = JSON.parse(videoData?.lessonTrainingTemp?.trainingConfigJson)
|
|
|
} catch (error) {}
|
|
|
- //请求本地缓存
|
|
|
- if (browserInfo.isApp && videoData.updateTime && ['VIDEO'].includes(videoData.type)) {
|
|
|
- console.log('开始检查本地缓存')
|
|
|
- const localData = await getCacheFilePath(videoData)
|
|
|
- console.log("🚀 ~ 本地缓存数据", localData)
|
|
|
- if (localData?.content?.localPath) {
|
|
|
- videoData.url = videoData.content
|
|
|
- videoData.content = localData.content.localPath
|
|
|
- }
|
|
|
- }
|
|
|
data.itemList.push({
|
|
|
...videoData,
|
|
|
id: videoData.materialId,
|
|
@@ -148,7 +123,8 @@ export default defineComponent({
|
|
|
loop: false,
|
|
|
videoEle: null,
|
|
|
timer: null,
|
|
|
- playModel: true
|
|
|
+ muted: true, // 静音
|
|
|
+ autoplay: true, //自动播放
|
|
|
})
|
|
|
popupData.itemActive = videoData.id
|
|
|
popupData.tabName = videoData.materialName
|
|
@@ -199,27 +175,10 @@ export default defineComponent({
|
|
|
itemName: ''
|
|
|
})
|
|
|
|
|
|
- // 双击
|
|
|
- const handleDbClick = (item: any) => {
|
|
|
- if (item && item.type === 'VIDEO') {
|
|
|
- const videoEle: HTMLVideoElement = document.querySelector(`[data-vid='${item.id}']`)!
|
|
|
- if (videoEle) {
|
|
|
- if (videoEle.paused) {
|
|
|
- closeToast()
|
|
|
- videoEle.play()
|
|
|
- } else {
|
|
|
- showToast('已暂停')
|
|
|
- videoEle.pause()
|
|
|
- }
|
|
|
- }
|
|
|
- item.timer = setTimeout(() => {
|
|
|
- activeData.model = false
|
|
|
- }, 3000)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
// 达到指标,记录
|
|
|
const addTrainingRecord = async (m: any) => {
|
|
|
+ if (data.recordLoading) return
|
|
|
+ console.log('记录观看次数')
|
|
|
data.recordLoading = true
|
|
|
const query = route.query
|
|
|
const body = {
|
|
@@ -243,9 +202,7 @@ export default defineComponent({
|
|
|
)
|
|
|
trainingRecord()
|
|
|
} catch (error) {}
|
|
|
- setTimeout(() => {
|
|
|
- data.recordLoading = false
|
|
|
- }, 2000)
|
|
|
+ data.recordLoading = false
|
|
|
}
|
|
|
// 停止所有的播放
|
|
|
const handleStopVideo = () => {
|
|
@@ -271,45 +228,50 @@ export default defineComponent({
|
|
|
confirmButtonColor: 'var(--van-primary)',
|
|
|
confirmButtonText: isLastIndex ? '完成' : '下一题',
|
|
|
cancelButtonText: '继续'
|
|
|
- }).then(() => {
|
|
|
- if (!isLastIndex) {
|
|
|
- const nextItem = data.details[itemIndex + 1]
|
|
|
- if (nextItem?.type === materialType.视频) {
|
|
|
- console.log('下一题视频',data.details[itemIndex].materialId, nextItem.materialId)
|
|
|
- router.replace({
|
|
|
- path: '/exerciseAfterClass',
|
|
|
- query: {
|
|
|
- ...query,
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ if (!isLastIndex) {
|
|
|
+ const nextItem = data.details[itemIndex + 1]
|
|
|
+ if (nextItem?.type === materialType.视频) {
|
|
|
+ // console.log('下一题视频', data.details[itemIndex].materialId, nextItem.materialId)
|
|
|
+ router.replace({
|
|
|
+ path: '/exerciseAfterClass',
|
|
|
+ query: {
|
|
|
+ ...query,
|
|
|
+ materialId: nextItem.materialId
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (nextItem?.type === materialType.曲目) {
|
|
|
+ handleInit(1)
|
|
|
+ goback()
|
|
|
+ const parmas = qs.stringify({
|
|
|
+ id: nextItem.content,
|
|
|
+ courseScheduleId: query.courseScheduleId,
|
|
|
+ lessonTrainingId: query.lessonTrainingId,
|
|
|
materialId: nextItem.materialId
|
|
|
- }
|
|
|
- })
|
|
|
+ })
|
|
|
+ let src = `${location.origin}/orchestra-music-score/?` + parmas
|
|
|
+ // console.log("🚀 ~ src", src)
|
|
|
+ postMessage({
|
|
|
+ api: 'openAccompanyWebView',
|
|
|
+ content: {
|
|
|
+ url: src,
|
|
|
+ orientation: 0,
|
|
|
+ isHideTitle: true,
|
|
|
+ statusBarTextColor: false,
|
|
|
+ isOpenLight: true
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
- if (nextItem?.type === materialType.曲目) {
|
|
|
- handleInit(1)
|
|
|
- goback()
|
|
|
- const parmas = qs.stringify({
|
|
|
- id: nextItem.content,
|
|
|
- courseScheduleId: query.courseScheduleId,
|
|
|
- lessonTrainingId: query.lessonTrainingId,
|
|
|
- materialId: nextItem.materialId
|
|
|
- })
|
|
|
- let src = `${location.origin}/orchestra-music-score/?` + parmas
|
|
|
- // console.log("🚀 ~ src", src)
|
|
|
- postMessage({
|
|
|
- api: 'openAccompanyWebView',
|
|
|
- content: {
|
|
|
- url: src,
|
|
|
- orientation: 0,
|
|
|
- isHideTitle: true,
|
|
|
- statusBarTextColor: false,
|
|
|
- isOpenLight: true
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ data.details[itemIndex].currentTime = 0
|
|
|
+ })
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
return () => (
|
|
|
<div class={styles.coursewarePlay}>
|
|
|
<Swipe
|
|
@@ -328,16 +290,8 @@ export default defineComponent({
|
|
|
<div
|
|
|
class={styles.itemDiv}
|
|
|
onClick={() => {
|
|
|
- clearTimeout(activeData.timer)
|
|
|
clearTimeout(m.timer)
|
|
|
- if (Date.now() - activeData.nowTime < 300) {
|
|
|
- handleDbClick(m)
|
|
|
- return
|
|
|
- }
|
|
|
- activeData.nowTime = Date.now()
|
|
|
- activeData.timer = setTimeout(() => {
|
|
|
- activeData.model = !activeData.model
|
|
|
- }, 300)
|
|
|
+ activeData.model = !activeData.model
|
|
|
}}
|
|
|
>
|
|
|
<video
|
|
@@ -348,101 +302,81 @@ export default defineComponent({
|
|
|
data-vid={m.id}
|
|
|
src={m.content}
|
|
|
loop={m.loop}
|
|
|
- onLoadedmetadata={(e: Event) => {
|
|
|
+ autoplay={m.autoplay}
|
|
|
+ muted={m.muted}
|
|
|
+ onLoadedmetadata={async (e: Event) => {
|
|
|
const videoEle = e.target as unknown as HTMLVideoElement
|
|
|
- m.currentTime = videoEle.currentTime
|
|
|
m.duration = videoEle.duration
|
|
|
m.videoEle = videoEle
|
|
|
}}
|
|
|
onTimeupdate={(e: Event) => {
|
|
|
const videoEle = e.target as unknown as HTMLVideoElement
|
|
|
m.currentTime = videoEle.currentTime
|
|
|
- if (m.duration - m.currentTime < 1) {
|
|
|
- if (data.recordLoading) return
|
|
|
- console.log('完成观看次数')
|
|
|
- addTrainingRecord(m)
|
|
|
- }
|
|
|
}}
|
|
|
onPlay={() => {
|
|
|
// 播放
|
|
|
m.paused = false
|
|
|
+ if (m.muted){
|
|
|
+ m.muted = false
|
|
|
+ m.videoEle.pause()
|
|
|
+ }
|
|
|
}}
|
|
|
onPause={() => {
|
|
|
//暂停
|
|
|
- clearTimeout(m.timer)
|
|
|
m.paused = true
|
|
|
}}
|
|
|
+ onEnded={() => addTrainingRecord(m)}
|
|
|
>
|
|
|
<source src={m.content} type="video/mp4" />
|
|
|
</video>
|
|
|
- <Transition name="bottom">
|
|
|
- {activeData.model && (
|
|
|
- <div class={styles.bottomFixedContainer}>
|
|
|
- <div class={styles.time}>
|
|
|
- <span>{getSecondRPM(m.currentTime)}</span>
|
|
|
- <span>{getSecondRPM(m.duration)}</span>
|
|
|
- </div>
|
|
|
- <div class={styles.slider}>
|
|
|
+ </div>
|
|
|
+ <Transition name="bottom">
|
|
|
+ {activeData.model && (
|
|
|
+ <div class={styles.bottomFixedContainer}>
|
|
|
+ <div class={styles.time}>
|
|
|
+ <span>{getSecondRPM(m.currentTime)}</span>
|
|
|
+ <span>{getSecondRPM(m.duration)}</span>
|
|
|
+ </div>
|
|
|
+ <div class={styles.slider}>
|
|
|
+ {m.duration && (
|
|
|
<Slider
|
|
|
buttonSize={16}
|
|
|
- step={0.01}
|
|
|
modelValue={m.currentTime}
|
|
|
min={0}
|
|
|
max={m.duration}
|
|
|
/>
|
|
|
- </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
|
|
|
- <div class={styles.actions}>
|
|
|
- <div>
|
|
|
- {m.paused ? (
|
|
|
- <Icon
|
|
|
- name={iconplay}
|
|
|
- onClick={(e: Event) => {
|
|
|
- e.stopPropagation()
|
|
|
- clearTimeout(m.timer)
|
|
|
- closeToast()
|
|
|
- m.videoEle?.play()
|
|
|
- m.paused = false
|
|
|
- m.timer = setTimeout(() => {
|
|
|
- activeData.model = false
|
|
|
- }, 3000)
|
|
|
- }}
|
|
|
- />
|
|
|
- ) : (
|
|
|
- <Icon
|
|
|
- name={iconpause}
|
|
|
- onClick={(e: Event) => {
|
|
|
- e.stopPropagation()
|
|
|
- console.log('点击暂停')
|
|
|
- m.videoEle?.pause()
|
|
|
- m.paused = true
|
|
|
- }}
|
|
|
- />
|
|
|
- )}
|
|
|
- {m.loop ? (
|
|
|
- <Icon
|
|
|
- name={iconLoopActive}
|
|
|
- onClick={(e: Event) => {
|
|
|
- e.stopPropagation()
|
|
|
- m.loop = false
|
|
|
- }}
|
|
|
- />
|
|
|
- ) : (
|
|
|
- <Icon
|
|
|
- name={iconLoop}
|
|
|
- onClick={(e: Event) => {
|
|
|
- e.stopPropagation()
|
|
|
- m.loop = true
|
|
|
- }}
|
|
|
- />
|
|
|
- )}
|
|
|
- </div>
|
|
|
- <div>{m.name}</div>
|
|
|
+ <div class={styles.actions}>
|
|
|
+ <div class={styles.actionBtn}>
|
|
|
+ {m.paused ? (
|
|
|
+ <img
|
|
|
+ src={iconplay}
|
|
|
+ onClick={(e: Event) => {
|
|
|
+ clearTimeout(m.timer)
|
|
|
+ m.videoEle?.play()
|
|
|
+ m.paused = false
|
|
|
+ m.timer = setTimeout(() => {
|
|
|
+ activeData.model = false
|
|
|
+ }, 4000)
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ ) : (
|
|
|
+ <img
|
|
|
+ src={iconpause}
|
|
|
+ onClick={(e: Event) => {
|
|
|
+ clearTimeout(m.timer)
|
|
|
+ m.videoEle?.pause()
|
|
|
+ m.paused = true
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ )}
|
|
|
</div>
|
|
|
</div>
|
|
|
- )}
|
|
|
- </Transition>
|
|
|
- </div>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </Transition>
|
|
|
</>
|
|
|
</SwipeItem>
|
|
|
)
|