You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
4.8 KiB
171 lines
4.8 KiB
import {CoverView, ScrollView, Text, View} from "@tarojs/components";
|
|
import {FC, useEffect, useState} from "react";
|
|
import HVideo from "@/components/video/video";
|
|
import {curriculum, HourPlayData} from "@/api";
|
|
import {Profile} from '@/store'
|
|
import Taro from "@tarojs/taro";
|
|
import Judge from "@/components/topic/judge";
|
|
import unique_ident from "@/hooks/unique_ident";
|
|
import MyButton from "@/components/button/MyButton";
|
|
import {formatMinute} from "@/utils/time";
|
|
import CustomPageContainer from "@/components/custom-page-container/custom-page-container";
|
|
import Single from "@/components/topic/single";
|
|
|
|
interface Props {
|
|
id: number,
|
|
courseId: number
|
|
preview: boolean
|
|
curEnd: (test?: boolean) => void
|
|
}
|
|
|
|
|
|
let seek: (time: number) => void
|
|
const Course: FC<Props> = ({id, courseId, preview, curEnd}) => {
|
|
const [breakpoint, setBreakpoint] = useState<number[]>([]) // 断点
|
|
const [show, setShow] = useState(false) // 题
|
|
const [data, setData] = useState<HourPlayData | null>(null)
|
|
const [examAll, setExamAll] = useState<Record<number, (ShareSubject | Multi)[]>>([]) // 题库
|
|
const [time, setTime] = useState<number>(0) // 进入断点的时间
|
|
const [validate, setValidate] = useState(false) // 开启验证
|
|
const [record, setRecord] = useState<boolean[]>([]) // 考题记录
|
|
const [testId, setTestId] = useState<number | null>(null)
|
|
const {user} = Profile.useContainer()
|
|
|
|
async function onEnded() {
|
|
const startRecording = unique_ident.get()
|
|
startRecording && await curriculum.curEnd(courseId, id, {...startRecording, duration: data?.duration!}) // 结束
|
|
unique_ident.remove()
|
|
|
|
if (testId) {
|
|
if (preview) { // 预览
|
|
Taro.showModal({
|
|
title: "是否前往考试",
|
|
success({confirm}) {
|
|
if (confirm) {
|
|
curEnd(true)
|
|
Taro.navigateTo({url: `/pages/business/test/test?testId=${testId}`})
|
|
} else {
|
|
curEnd()
|
|
}
|
|
}
|
|
})
|
|
return
|
|
}
|
|
Taro.navigateTo({url: `/pages/business/test/test?testId=${testId}`})
|
|
curEnd(true)
|
|
} else {
|
|
curEnd()
|
|
}
|
|
}
|
|
|
|
/** 进入断点 */
|
|
function onBreakpoint(breakpoint: number) {
|
|
setTime(breakpoint)
|
|
setShow(true)
|
|
}
|
|
|
|
async function getData() {
|
|
unique_ident.put(id, Date.now())
|
|
const res = await curriculum.hourPlay(courseId, id)
|
|
if (res) {
|
|
setData(res)
|
|
setBreakpoint(res.timeList)
|
|
setExamAll(res.hourExamQuestions || [])
|
|
setTestId(res?.hour_test?.id || null)
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
init()
|
|
getData()
|
|
}, [id])
|
|
|
|
|
|
function init(show = true) {
|
|
show && setShow(false)
|
|
setValidate(false)
|
|
setRecord([])
|
|
setTime(0)
|
|
}
|
|
|
|
|
|
useEffect(() => {
|
|
if (!record.length) return;
|
|
const pass = record.every(d => d)
|
|
/** 考题正确 */
|
|
const {id: question_id, question_type} = examAll?.[time]?.[0]
|
|
curriculum.answerRecord(id, {
|
|
is_pass: pass,
|
|
user_id: user?.id!,
|
|
time: time,
|
|
question_type,
|
|
question_id
|
|
}).then()
|
|
|
|
/** 删除断点 */
|
|
const old: number[] = JSON.parse(JSON.stringify(breakpoint))
|
|
const index = old.indexOf(time)
|
|
old.splice(index, 1)
|
|
setBreakpoint(old)
|
|
|
|
if (pass) {
|
|
seek(time)
|
|
init()
|
|
}
|
|
}, [record])
|
|
|
|
function videoSeek(fn: (time: number) => void) {
|
|
seek = fn
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<HVideo
|
|
duration={data?.duration || 0}
|
|
preview={preview}
|
|
src={data?.url || ''}
|
|
onEnded={onEnded}
|
|
breakpoint={breakpoint}
|
|
onBreakpoint={onBreakpoint}
|
|
setTime={videoSeek}
|
|
>
|
|
{/*<CoverView className='single-cover'>*/}
|
|
{/* <Single/>*/}
|
|
{/*</CoverView>*/}
|
|
</HVideo>
|
|
|
|
<CustomPageContainer show={show} position='bottom'>
|
|
<View>
|
|
<View className='text-center mt-2 text-muted'>
|
|
<Text className='mr-2'>{formatMinute(time)}考题</Text>
|
|
</View>
|
|
{
|
|
examAll?.[time]?.slice(0, 1)?.map((d) =>
|
|
<ScrollView style='height:60vh' scrollY key={d.id}>
|
|
{d.question_type === 2 &&
|
|
<Judge
|
|
data={d as ShareSubject}
|
|
validate={validate}
|
|
onAnswer={(isAnswer) => setRecord([isAnswer])}
|
|
/>}
|
|
</ScrollView>)
|
|
}
|
|
<View>
|
|
|
|
<View className='statistics'>
|
|
{
|
|
record.length > 0
|
|
? <MyButton fillet onClick={() => {
|
|
init();
|
|
seek(time)
|
|
}}>关闭</MyButton>
|
|
: <MyButton fillet onClick={() => setValidate(true)}>交卷</MyButton>
|
|
}
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</CustomPageContainer>
|
|
</>
|
|
)
|
|
}
|
|
export default Course
|
|
|