main
parent
aee74e0418
commit
bfbf611931
@ -0,0 +1,69 @@ |
|||||||
|
import {FC, useEffect, useState} from "react"; |
||||||
|
import {Button, Radio, RadioGroup, Text, View} from "@tarojs/components"; |
||||||
|
|
||||||
|
interface Props { |
||||||
|
data: ShareSubject |
||||||
|
onAnswer: (isAnswer: boolean) => void |
||||||
|
onUpAndDown: (index: number) => void |
||||||
|
index: number |
||||||
|
validate: boolean |
||||||
|
frequency:number |
||||||
|
} |
||||||
|
|
||||||
|
const Judge: FC<Props> = ({data, onAnswer, onUpAndDown, index, validate,frequency}) => { |
||||||
|
const [rightAnswer, setRightAnswer] = useState<string | null>(null) //答案
|
||||||
|
const rightKey = data.right_answer ? 'correct' : 'error' // 正确答案数组
|
||||||
|
const [error, setError] = useState(false) |
||||||
|
|
||||||
|
|
||||||
|
function onChange(e) { |
||||||
|
const value = e.detail.value |
||||||
|
setRightAnswer(value) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (validate) { |
||||||
|
onAnswer(rightAnswer === rightKey) |
||||||
|
setError(rightAnswer !== rightKey) |
||||||
|
} |
||||||
|
}, [validate]) |
||||||
|
|
||||||
|
return ( |
||||||
|
<View className='topic'> |
||||||
|
<View className='mb-3'> |
||||||
|
<Text>{data.question}</Text> |
||||||
|
</View> |
||||||
|
|
||||||
|
<RadioGroup onChange={onChange}> |
||||||
|
<Radio |
||||||
|
value={'correct'} |
||||||
|
className='option' |
||||||
|
color={validate ? 'correct' !== rightKey ? 'red' : undefined : undefined} |
||||||
|
disabled={validate ? 'correct' !== rightAnswer : false} |
||||||
|
> |
||||||
|
正确 |
||||||
|
</Radio> |
||||||
|
<Radio |
||||||
|
value={'error'} |
||||||
|
color={validate ? 'error' !== rightKey ? 'red' : undefined : undefined} |
||||||
|
disabled={validate ? 'error' !== rightAnswer : false} |
||||||
|
className='option'> |
||||||
|
错误 |
||||||
|
</Radio> |
||||||
|
</RadioGroup> |
||||||
|
|
||||||
|
<View className='upAndDown'> |
||||||
|
{index > 0 && <Button className='button' onClick={() => onUpAndDown(index - 1)}>上一题</Button>} |
||||||
|
<Button className='button' onClick={() => onUpAndDown(index + 1)}>下一题</Button> |
||||||
|
</View> |
||||||
|
|
||||||
|
{error && frequency === 0 && <View className='mt-3'> |
||||||
|
<View className='font-weight mb-3'>错误答案解析</View> |
||||||
|
<View>{data.analysis}</View> |
||||||
|
</View>} |
||||||
|
</View> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Judge |
@ -0,0 +1,87 @@ |
|||||||
|
import {FC, useEffect, useState} from "react"; |
||||||
|
import {Button, Checkbox, CheckboxGroup, Radio, RadioGroup, Text, View} from "@tarojs/components"; |
||||||
|
|
||||||
|
interface Props { |
||||||
|
data: Multi |
||||||
|
onAnswer: (isAnswer: boolean) => void |
||||||
|
onUpAndDown: (index: number) => void |
||||||
|
index: number |
||||||
|
validate: boolean |
||||||
|
frequency:number |
||||||
|
} |
||||||
|
|
||||||
|
const Multi: FC<Props> = ({data, onAnswer, onUpAndDown, index, validate,frequency}) => { |
||||||
|
const [rightAnswer, setRightAnswer] = useState<string[]>([]) //答案
|
||||||
|
|
||||||
|
const rightKey = data?.right_answer?.split(',') || [] // 正确答案数组
|
||||||
|
const [error, setError] = useState(false) |
||||||
|
|
||||||
|
const answers = [ |
||||||
|
{value: "A", title: data.answerA}, |
||||||
|
{value: "B", title: data.answerB}, |
||||||
|
{value: "C", title: data.answerC}, |
||||||
|
{value: "D", title: data.answerD}, |
||||||
|
] |
||||||
|
|
||||||
|
function onChange(e) { |
||||||
|
const value = e.detail.value |
||||||
|
if (data.type) { |
||||||
|
setRightAnswer(value) |
||||||
|
} else { |
||||||
|
setRightAnswer([value]) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (validate) { |
||||||
|
const isAnswer = rightKey.toString() === rightAnswer.toString() |
||||||
|
onAnswer(isAnswer) |
||||||
|
setError(!isAnswer) |
||||||
|
} |
||||||
|
}, [validate]) |
||||||
|
|
||||||
|
return ( |
||||||
|
<View className='topic'> |
||||||
|
<View className='mb-3'> |
||||||
|
<Text>{data.question}</Text> |
||||||
|
</View> |
||||||
|
|
||||||
|
<View> |
||||||
|
{!data.type ? <CheckboxGroup onChange={onChange}> |
||||||
|
{answers.map(d => <Checkbox |
||||||
|
value={d.value} |
||||||
|
className='option' |
||||||
|
disabled={validate} |
||||||
|
> |
||||||
|
{d.title} |
||||||
|
</Checkbox>)} |
||||||
|
</CheckboxGroup> |
||||||
|
: <RadioGroup onChange={onChange}> |
||||||
|
{answers.map(d => <Radio |
||||||
|
value={d.value} |
||||||
|
className='option' |
||||||
|
color={validate ? rightKey.includes(d.value) ? '#45d4a8' : 'red' : '#45d4a8'} |
||||||
|
disabled={validate ? !rightAnswer.includes(d.value) : false} |
||||||
|
> |
||||||
|
{d.title} |
||||||
|
</Radio>)} |
||||||
|
</RadioGroup> |
||||||
|
} |
||||||
|
</View> |
||||||
|
|
||||||
|
<View className='upAndDown'> |
||||||
|
{index > 0 && <Button className='button' onClick={() => onUpAndDown(index - 1)}>上一题</Button>} |
||||||
|
<Button onClick={() => onUpAndDown(index + 1)} className='button'>下一题</Button> |
||||||
|
</View> |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{error && frequency == 0 && <View className='mt-3'> |
||||||
|
<View className='font-weight mb-3'>错误答案解析</View> |
||||||
|
<View>{data.analysis}</View> |
||||||
|
</View>} |
||||||
|
</View> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Multi |
@ -0,0 +1,60 @@ |
|||||||
|
import {Button, Text, Textarea, View} from "@tarojs/components"; |
||||||
|
import {FC, useEffect, useState} from "react"; |
||||||
|
import Taro from "@tarojs/taro"; |
||||||
|
|
||||||
|
interface Props { |
||||||
|
data: ShareSubject |
||||||
|
onAnswer: (isAnswer: boolean) => void |
||||||
|
onUpAndDown: (index: number) => void |
||||||
|
index: number |
||||||
|
validate: boolean |
||||||
|
frequency: number |
||||||
|
} |
||||||
|
|
||||||
|
const ShortAnswer: FC<Props> = ({data, onAnswer, onUpAndDown, index, validate, frequency}) => { |
||||||
|
const [value, setValue] = useState<string>('') |
||||||
|
|
||||||
|
function onBlur() { |
||||||
|
if (value.length < 3) { |
||||||
|
Taro.showToast({title: '最少3个字', icon: 'error'}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (validate) { |
||||||
|
if (value.length < 3) { |
||||||
|
onAnswer(false) |
||||||
|
} else { |
||||||
|
onAnswer(true) |
||||||
|
} |
||||||
|
} |
||||||
|
}, [validate]) |
||||||
|
|
||||||
|
return ( |
||||||
|
<View className='topic'> |
||||||
|
<View className='mb-3'> |
||||||
|
<Text>{data.question}</Text> |
||||||
|
</View> |
||||||
|
<Textarea |
||||||
|
placeholder='请输入答案' |
||||||
|
adjustPosition |
||||||
|
className='Textarea' |
||||||
|
onBlur={onBlur} |
||||||
|
onInput={(e) => setValue((e.target as HTMLTextAreaElement).value)}/> |
||||||
|
<View className='upAndDown'> |
||||||
|
{index > 0 && <Button className='button' onClick={() => onUpAndDown(index - 1)}>上一题</Button>} |
||||||
|
<Button className='button' onClick={() => onUpAndDown(index + 1)}>下一题</Button> |
||||||
|
</View> |
||||||
|
|
||||||
|
<View>最少3个字</View> |
||||||
|
|
||||||
|
{frequency === 0 && <View className='mt-3'> |
||||||
|
<View className='font-weight mb-3'>解析</View> |
||||||
|
<View>{data.analysis}</View> |
||||||
|
</View>} |
||||||
|
|
||||||
|
</View> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default ShortAnswer |
@ -0,0 +1,41 @@ |
|||||||
|
import {View} from "@tarojs/components"; |
||||||
|
import {FC, useEffect, useState} from "react"; |
||||||
|
import {CurLearningRecord, ManageApi} from "@/api/manage"; |
||||||
|
import PopPut from "@/components/popPut/popPut"; |
||||||
|
|
||||||
|
interface Props { |
||||||
|
id: number |
||||||
|
} |
||||||
|
|
||||||
|
const StudentRecord: FC<Props> = ({id}) => { |
||||||
|
const [data, setData] = useState<CurLearningRecord | null>(null) |
||||||
|
|
||||||
|
async function getDate() { |
||||||
|
try { |
||||||
|
const res = await ManageApi.userRecord(id) |
||||||
|
setData(res) |
||||||
|
} catch (e) { |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function record(id: number): string { |
||||||
|
return `${data?.user_course_records?.[id]?.finished_count || 0}/${data?.course.class_hour || 0}` |
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
getDate() |
||||||
|
}, [id]) |
||||||
|
|
||||||
|
return ( |
||||||
|
<View> |
||||||
|
{data?.data?.map(d => <PopPut |
||||||
|
leftImage={d.avatar} |
||||||
|
title={d.name} |
||||||
|
content={record(d.id)} |
||||||
|
chevron |
||||||
|
/>)} |
||||||
|
</View> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default StudentRecord |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,19 @@ |
|||||||
|
/** 判断题 & 简答题 */ |
||||||
|
interface ShareSubject { |
||||||
|
question_type: 1 | 2 | 3 |
||||||
|
question: string //课题题目
|
||||||
|
score: number //课题分数
|
||||||
|
right_answer?: string // 正确答案
|
||||||
|
analysis: string //课题解析
|
||||||
|
course_id: number |
||||||
|
hour_id: number |
||||||
|
} |
||||||
|
|
||||||
|
/** 选择题 */ |
||||||
|
interface Multi extends ShareSubject { |
||||||
|
type: boolean //是否多选
|
||||||
|
answerA: string |
||||||
|
answerB: string |
||||||
|
answerC: string |
||||||
|
answerD: string |
||||||
|
} |
Loading…
Reference in new issue