import { Icon, showConfirmDialog, showDialog, Slider, Swipe, SwipeItem } from 'vant' import { defineComponent, onMounted, reactive, onUnmounted, ref, watch, Transition, nextTick, computed } from 'vue' import styles from './index.module.less' import 'plyr/dist/plyr.css' import request from '@/helpers/request' import { state } from '@/state' import { useRoute, useRouter } from 'vue-router' import iconBack from '../coursewarePlay/image/back.svg' import { postMessage, promisefiyPostMessage } from '@/helpers/native-message' import iconLoop from '../coursewarePlay/image/icon-loop.svg' import iconLoopActive from '../coursewarePlay/image/icon-loop-active.svg' import iconplay from '../coursewarePlay/image/icon-play.svg' import iconpause from '../coursewarePlay/image/icon-pause.svg' import iconVideobg from '../coursewarePlay/image/icon-videobg.png' import { browser, getSecondRPM } from '@/helpers/utils' import qs from 'query-string' import { Vue3Lottie } from 'vue3-lottie' import playLoadData from '../coursewarePlay/datas/data.json' import { handleCheckVip } from '../hook/useFee' import item from '@/student/coupons/item' const materialType = { 视频: 'VIDEO', 图片: 'IMG', 曲目: 'SONG' } export default defineComponent({ name: 'exercise-after-class', setup() { /** 设置播放容器 16:9 */ const parentContainer = reactive({ width: '100vw' }) const setContainer = () => { let min = Math.min(screen.width, screen.height) let max = Math.max(screen.width, screen.height) let width = min * (16 / 9) if (width > max) { parentContainer.width = '100vw' return } else { parentContainer.width = width + 'px' } } const handleInit = (type = 0) => { setContainer() // 横屏 postMessage({ api: 'setRequestedOrientation', content: { orientation: type } }) // 头,包括返回箭头 // postMessage({ // api: 'setTitleBarVisibility', // content: { // status: type // } // }) // 安卓的状态栏 postMessage({ api: 'setStatusBarVisibility', content: { isVisibility: type } }) } handleInit() onUnmounted(() => { handleInit(1) }) const route = useRoute() const router = useRouter() const query = route.query const browserInfo = browser() const headeRef = ref() const data = reactive({ videoData: null as any, trainings: [] as any[], trainingTimes: 0, itemList: [] as any, showHead: true, loading: true, recordLoading: false, isPlayBaseStatus: true, // 初始状态是否播放完 isPlayAll: true // 是否全部做完 }) const activeData = reactive({ nowTime: 0, model: true, // 遮罩 timer: null as any, item: null as any }) // 获取课后练习记录 const getTrainingRecord = async () => { try { const res: any = await request.post( state.platformApi + `/studentLessonTraining/trainingRecord/${query.courseScheduleId}?userId=${state.user?.data?.id}`, { hideLoading: true } ) if (Array.isArray(res?.data?.trainings)) { const trainings = res?.data?.trainings || [] const tempLessonTraining: any = [] trainings.forEach((item: any) => { tempLessonTraining.push(...(item.studentLessonTrainingDetails || [])) }) // 没有播放完 tempLessonTraining.forEach((item: any) => { let trainingContent: any = {} try { trainingContent = JSON.parse(item.trainingContent) } catch (error) { trainingContent = '' } if (trainingContent.practiceTimes !== item.trainingTimes + '') { data.isPlayAll = false } if (item.materialId == route.query.materialId) { popupData.tabName = item.knowledgePointName } }) return tempLessonTraining } } catch (error) {} return [] } const setRecord = async (trainings: any[]) => { if (Array.isArray(trainings)) { console.log(trainings, 'trainings') data.trainings = trainings.map((n: any) => { try { n.trainingContent = JSON.parse(n.trainingContent) } catch (error) { n.trainingContent = '' } return { ...n, currentTime: 0, duration: 100, paused: true, loop: false, videoEle: null, timer: null, muted: true, // 静音 autoplay: true //自动播放 } }) data.itemList = data.trainings.filter((n: any) => n.materialId == route.query.materialId) data.videoData = data.itemList[0] handleExerciseCompleted() } } onMounted(async () => { const trainings = await getTrainingRecord() // 初始化状态 trainings.forEach((record: any) => { let trainingContent: any = {} try { trainingContent = JSON.parse(record.trainingContent) } catch (error) { trainingContent = '' } if (trainingContent.practiceTimes !== record.trainingTimes + '') { data.isPlayBaseStatus = false } }) setRecord(trainings) handleCheckVip() }) // 返回 const goback = () => { postMessage({ api: 'back' }) } const swipeRef = ref() const popupData = reactive({ firstIndex: 0, open: false, activeIndex: -1, tabActive: '', tabName: '', itemActive: '', itemName: '' }) // 达到指标,记录 const addTrainingRecord = async (m: any) => { if (data.recordLoading) return console.log('记录观看次数') data.recordLoading = true const query = route.query const body = { materialType: 'VIDEO', record: { sourceTime: m.duration, clientType: state.platformType, feature: 'LESSON_TRAINING', deviceType: browserInfo.android ? 'ANDROID' : browserInfo.isApp ? 'IOS' : 'WEB' }, courseScheduleId: query.courseScheduleId, lessonTrainingId: query.lessonTrainingId, materialId: data.videoData?.materialId || '' } try { const res: any = await request.post( state.platformApi + '/studentLessonTraining/lessonTrainingRecord', { data: body, hideLoading: true } ) } catch (error) {} data.recordLoading = false try { const trainings: any[] = await getTrainingRecord() if (Array.isArray(trainings)) { const item = trainings.find((n: any) => n.materialId == data.videoData?.materialId) if (item) { data.videoData.trainingTimes = item.trainingTimes handleExerciseCompleted() } } } catch (error) {} } // 停止所有的播放 const handleStopVideo = () => { data.itemList.forEach((m: any) => { m.videoEle?.pause() }) } // 判断练习是否完成 const handleExerciseCompleted = () => { if ( data?.videoData?.trainingTimes != 0 && data?.videoData?.trainingTimes + '' === data.videoData?.trainingContent?.practiceTimes ) { let isLastIndex = false let itemIndex = 0 console.log(data.isPlayBaseStatus, data.isPlayAll, data.trainings) if (data.isPlayBaseStatus) { itemIndex = data.trainings.findIndex( (n: any) => n.materialId == data.videoData?.materialId ) isLastIndex = itemIndex === data.trainings.length - 1 } else { let i = -1 let status = true data.trainings.forEach((item: any, index: number) => { if (item.trainingContent.practiceTimes !== item.trainingTimes + '' && i === -1) { console.log(i, item.trainingContent.practiceTimes, item.trainingTimes, index) i = index } if (item.trainingContent.practiceTimes !== item.trainingTimes + '') { status = false } }) itemIndex = i != -1 ? i - 1 : -1 console.log(status) isLastIndex = status } showConfirmDialog({ title: '课后作业', message: '你已完成该练习~', confirmButtonColor: 'var(--van-primary)', confirmButtonText: isLastIndex ? '完成' : '下一题', cancelButtonText: '继续' }) .then(() => { if (!isLastIndex) { const nextItem = data.trainings[itemIndex + 1] if (nextItem?.type === materialType.视频) { data.itemList = [nextItem] data.videoData = nextItem handleExerciseCompleted() } 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 postMessage({ api: 'openAccompanyWebView', content: { url: src, orientation: 0, isHideTitle: true, statusBarTextColor: false, isOpenLight: true } }) } } else { postMessage({ api: 'goBack' }) } }) .catch(() => { data.trainings[itemIndex].currentTime = 0 }) } } return () => (