修改答题步骤

main
king 1 year ago
parent ab5241ebbf
commit 77dbdb87c1
  1. 4
      .env
  2. 1
      src/api/curriculum.ts
  3. 2
      src/app.scss
  4. 10
      src/components/topic/judge.tsx
  5. 14
      src/components/topic/multi.tsx
  6. 24
      src/components/topic/shortAnswer.tsx
  7. 11
      src/components/topic/topic.scss
  8. 21
      src/pages/business/hourHistory/hourHistory.tsx
  9. 2
      src/pages/business/videoInfo/components/catalogue.tsx
  10. 93
      src/pages/business/videoInfo/components/course.tsx
  11. 8
      src/pages/business/videoInfo/components/hours.tsx
  12. 7
      src/pages/business/videoInfo/videoInfo.scss
  13. 14
      src/pages/business/videoInfo/videoInfo.tsx
  14. 12
      src/static/css/module.scss

@ -1,5 +1,5 @@
#TARO_APP_API=https://yjx.dev.yaojiankang.top
TARO_APP_API=https://playedu.yaojiankang.top
TARO_APP_API=https://yjx.dev.yaojiankang.top
#TARO_APP_API=https://playedu.yaojiankang.top
TARO_APP_LGOIN=true

@ -10,6 +10,7 @@ export interface CourseDepData {
chapters: Chapters[]
course: Curriculum
hours: Hours
duration: number
/** 是否必修 */
is_required: boolean
learn_hour_records: LearnHourRecords[]

@ -267,7 +267,7 @@
.text-dark { color: #343a40;}
.text-hover-dark{ color: #121416;}
.text-body { color: #212529;}
.text-muted { color: #6c757d;}
.text-muted { color: #909795;}
/* 圆角 */

@ -1,19 +1,15 @@
import {FC, useEffect, useState} from "react";
import { Radio, RadioGroup, Text, View} from "@tarojs/components";
import './topic.scss'
import MyButton from "@/components/button/MyButton";
interface Props {
data: ShareSubject
onAnswer: (isAnswer: boolean) => void
onUpAndDown?: (index: number) => void
index: number
validate: boolean
frequency?: number
end?: boolean
}
const Judge: FC<Props> = ({data, onAnswer, onUpAndDown, index, validate, frequency, end}) => {
const Judge: FC<Props> = ({data, onAnswer, validate, frequency}) => {
const [rightAnswer, setRightAnswer] = useState<string | null>(null) //答案
const rightKey = data.right_answer ? 'correct' : 'error' // 正确答案数组
const [error, setError] = useState(false)
@ -58,10 +54,6 @@ const Judge: FC<Props> = ({data, onAnswer, onUpAndDown, index, validate, frequen
</Radio>
</RadioGroup>
{onUpAndDown && <View className='upAndDown'>
{index > 0 && <MyButton size='mini' width={150} onClick={() => onUpAndDown(index - 1)}></MyButton>}
{!end && <MyButton size='mini' width={150} onClick={() => onUpAndDown(index + 1)}></MyButton>}
</View>}
{error && frequency == 0 && <View className='mt-3'>

@ -1,19 +1,15 @@
import {FC, useEffect, useState} from "react";
import {Checkbox, CheckboxGroup, Radio, RadioGroup, Text, View} from "@tarojs/components";
import './topic.scss'
import MyButton from "@/components/button/MyButton";
interface Props {
data: Multi
onAnswer: (isAnswer: boolean) => void
onUpAndDown?: (index: number) => void
index: number
validate: boolean
frequency?: number
end?: boolean
}
const Multi: FC<Props> = ({data, onAnswer, onUpAndDown, index, validate, frequency, end}) => {
const Multi: FC<Props> = ({data, onAnswer, validate, frequency}) => {
const [rightAnswer, setRightAnswer] = useState<string[]>([]) //答案
const rightKey = data?.right_answer?.split(',') || [] // 正确答案数组
@ -46,7 +42,7 @@ const Multi: FC<Props> = ({data, onAnswer, onUpAndDown, index, validate, frequen
return (
<View className='topic'>
<View className='mb-3'>
<Text className={'topicType'}>{data.type ? "多选题" : '单选题'}</Text>
<Text className='topicType'>{data.type ? "多选题" : '单选题'}</Text>
<Text>{data.question}</Text>
</View>
@ -75,12 +71,6 @@ const Multi: FC<Props> = ({data, onAnswer, onUpAndDown, index, validate, frequen
}
</View>
{onUpAndDown && <View className='upAndDown'>
{index > 0 && <MyButton size='mini' width={150} onClick={() => onUpAndDown?.(index - 1)}></MyButton>}
{!end && <MyButton size='mini' width={150} onClick={() => onUpAndDown?.(index + 1)}></MyButton>}
</View>}
{error && frequency == 0 && <View className='mt-3'>
<View className='right_answer'>{data.right_answer}</View>
<View className='font-weight my-3'></View>

@ -1,30 +1,20 @@
import {Button, Text, Textarea, View} from "@tarojs/components";
import {Text, Textarea, View} from "@tarojs/components";
import {FC, useEffect, useState} from "react";
import Taro from "@tarojs/taro";
import './topic.scss'
interface Props {
data: ShareSubject
onAnswer: (isAnswer: boolean) => void
onUpAndDown?: (index: number) => void
index: number
validate: boolean
frequency?: number
end?: boolean
}
const ShortAnswer: FC<Props> = ({data, onAnswer, onUpAndDown, index, validate, frequency, end}) => {
const ShortAnswer: FC<Props> = ({data, onAnswer, 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) {
if (value.length < 1) {
onAnswer(false)
} else {
onAnswer(true)
@ -42,17 +32,9 @@ const ShortAnswer: FC<Props> = ({data, onAnswer, onUpAndDown, index, validate, f
<Textarea
placeholder='请输入答案'
className='Textarea'
onBlur={onBlur}
maxlength={255}
onInput={(e) => setValue(e.detail.value)}/>
<View className='text-muted mt-2'>3</View>
{onUpAndDown && <View className='upAndDown'>
{index > 0 && <Button className='button' onClick={() => onUpAndDown?.(index - 1)}></Button>}
{!end && <Button className='button' onClick={() => onUpAndDown?.(index + 1)}></Button>}
</View>}
{frequency == 0 && <View className='mt-3'>
<View className='font-weight my-3'></View>

@ -7,10 +7,10 @@
.topicType {
display: inline-block;
background: #45D4A8;
border-radius: 5rpx;
border-radius: 10rpx;
color: #fff;
padding: 0 10rpx;
font-size: 30rpx;
font-size: 26rpx;
margin-right: 20rpx;
}
@ -28,7 +28,8 @@
.statistics {
border-top: 1px solid #F5F8F7;
padding: 30rpx 0;
height: 60rpx;
padding: 20rpx 0;
display: flex;
align-items: center;
justify-content: space-between;
@ -36,10 +37,10 @@
.upAndDown {
display: flex;
height: 50rpx;
justify-content: space-between;
position: absolute;
bottom: 20rpx;
width: 100%;
padding: 10rpx 0;
}

@ -42,8 +42,8 @@ const HourHistory: FC = () => {
<Image className={styles.image} src={cur?.thumb || ''} mode='center'/>
<View className={styles.classHour}>{cur?.class_hour}/{cur?.finished_hour_count || 0}</View>
<View className={styles.title}>
<View>{cur?.title}</View>
<View>{hour?.title}</View>
<View></View>
<View>{hour?.title}</View>
</View>
</View>
@ -55,7 +55,7 @@ const HourHistory: FC = () => {
<View>{formatDateTime(new Date(d.start_at), 'MM-dd')}</View>
<Progress
className={styles.progress}
percent={d.duration / (hour?.duration || 0)}
percent={Number((d.duration / (hour?.duration || 0)).toFixed(2))}
showInfo
borderRadius={10}
active
@ -70,21 +70,6 @@ const HourHistory: FC = () => {
: <Empty name='暂无数据'/>
}
{/*{times.length ? times.map((d, index) =>*/}
{/* <View key={index} className={styles.category}>*/}
{/* <View className={styles.thumb}>*/}
{/* <Image src={d.course.thumb} className={styles.image}/>*/}
{/* <View className={styles.count}>共{d.total_hour_count}节/已学{d.finished_count}节</View>*/}
{/* </View>*/}
{/* <View className={styles.text}>*/}
{/* <View>{d.course.title}</View>*/}
{/* <View className={styles.describe}>*/}
{/* <Text className='mr-4'>观看{formatMinute(d.duration)}</Text>*/}
{/* <Text>学习进度:{(d.finished_count / d.total_hour_count * 100).toFixed(0)}%</Text>*/}
{/* </View>*/}
{/* </View>*/}
{/* </View>) : <Empty name='无历史记录'/>}*/}
</View>
)
}

@ -105,7 +105,7 @@ const Catalogue: FC<Props> = ({data, setHors, id, playId}) => {
<View className='py-2 hours'>
{current === 0 && <View className='short_desc'>{data?.course.short_desc || data?.course.title}</View>}
{current === 1 && <View>
<View className='font-weight'></View>
<View className='my-2'></View>
{data?.chapters.length ? Object.values(data?.chapters || {}).map((d, index) => <View>
<Collapse title={`${index + 1}.${d.name}`}>
<Hours

@ -1,4 +1,4 @@
import {ScrollView, Swiper, SwiperItem, View} from "@tarojs/components";
import {ScrollView, Swiper, SwiperItem, Text, View} from "@tarojs/components";
import {FC, useEffect, useState} from "react";
import HVideo from "@/components/video/video";
import {CurEndParam, curriculum, HourPlayData} from "@/api";
@ -10,6 +10,7 @@ import ShortAnswer from "@/components/topic/shortAnswer";
import unique_ident from "@/hooks/unique_ident";
import CustomPageContainer from "@/components/custom-page-container/custom-page-container";
import MyButton from "@/components/button/MyButton";
import {formatMinute} from "@/utils/time";
interface Props {
id: number,
@ -100,28 +101,34 @@ const Course: FC<Props> = ({id, courseId, preview, curEnd}: Props) => {
setNewRecord(record)
}
function init() {
function init(show = true) {
record = []
setTime(0)
setShow(false)
setIndex(0)
show && setShow(false)
setValidate(false)
setNewRecord([])
setTime(0)
if (process.env.TARO_ENV === 'h5') {
setTimeout(() => {
setIndex(0)
}, 200)
} else {
setIndex(0)
}
}
/** 再来一次 */
function onceMore() {
const oldTime: number = time
init()
init(false)
setTimeout(() => {
setShow(true)
setTime(oldTime)
})
}
/** 重新看 */
function again() {
if (frequency === 0 && show) {
if (examAll?.[time]?.length) {
const {id: question_id, question_type} = examAll?.[time]?.[0]
curriculum.answerRecord(id, {
is_pass: false,
@ -159,7 +166,24 @@ const Course: FC<Props> = ({id, courseId, preview, curEnd}: Props) => {
seek(time)
init()
} else {
Taro.showToast({title: '答案错误', icon: 'error', duration: 3000})
if ((frequency - 1) !== 0) {
Taro.showModal({
title: '考试未通过',
content: '剩余考试次数:' + (frequency - 1),
confirmText: '重考',
success({confirm}) {
confirm && onceMore()
}
})
} else {
Taro.showModal({
title: '考试未通过',
content: '请重新学习',
success({confirm}) {
confirm && again()
}
})
}
}
}, [newRecord])
@ -186,18 +210,17 @@ const Course: FC<Props> = ({id, courseId, preview, curEnd}: Props) => {
position='bottom'
round
onAfterLeave={again}
onClickOverlay={again}
>
<View className='text-center mt-2 text-muted'>
<Text className='mr-2'>{formatMinute(time)}</Text>
<Text>{index + 1}/{examAll?.[time]?.length}</Text>
</View>
<Swiper
style={{height: "60vh"}}
snapToEdge
current={index}
onChange={(e) => {
if ((e.target as any)?.current) {
setIndex((e.target as any).current)
}
}}>
{examAll?.[time]?.map((d, index) =>
onChange={(e) => setIndex(e.detail.current)}>
{examAll?.[time]?.map((d) =>
<SwiperItem key={d.id}>
<ScrollView style='height:70vh' scrollY>
{d.question_type === 1 &&
@ -205,42 +228,50 @@ const Course: FC<Props> = ({id, courseId, preview, curEnd}: Props) => {
frequency={frequency}
data={d as Multi}
onAnswer={onAnswer}
onUpAndDown={(index) => setIndex(index)}
index={index}
validate={validate}
end={index === examAll?.[time].length - 1}
/>}
{d.question_type === 2 &&
<Judge
frequency={frequency}
onUpAndDown={(index) => setIndex(index)}
index={index}
data={d as ShareSubject}
validate={validate}
onAnswer={onAnswer}
end={index === examAll?.[time].length - 1}
/>}
{d.question_type === 3 &&
<ShortAnswer
frequency={frequency}
data={d as ShareSubject}
onAnswer={onAnswer}
onUpAndDown={(index) => setIndex(index)}
index={index}
validate={validate}
end={index === examAll?.[time].length - 1}
/>}
</ScrollView>
</SwiperItem>
)}
</Swiper>
<View className='statistics'>
<View>{frequency}</View>
<View>{index + 1}/{examAll?.[time]?.length}</View>
<View>
<View className='statistics'>
<View>{frequency}</View>
{
(index + 1) === examAll?.[time]?.length && <View>
{!validate && <MyButton width={150} fillet onClick={() => setValidate(true)}></MyButton>}
{frequency > 0 && validate && <MyButton width={150} fillet onClick={onceMore}></MyButton>}
{frequency === 0 && validate && <MyButton width={150} fillet onClick={again}></MyButton>}
</View>
}
{!validate && <MyButton width={150} fillet onClick={() => setValidate(true)}></MyButton>}
{frequency > 0 && validate && <MyButton width={150} fillet onClick={onceMore}></MyButton>}
{frequency === 0 && validate && <MyButton width={150} fillet onClick={again}></MyButton>}
</View>
<View className='upAndDown'>
<View>
{index !== 0 && <MyButton size='mini' width={150} onClick={() => setIndex(index - 1)}></MyButton>}
</View>
<View>
{
(index + 1) !== examAll?.[time]?.length
&& <MyButton size='mini' width={150} onClick={() => setIndex(index + 1)}></MyButton>
}
</View>
</View>
</View>
</CustomPageContainer>
</View>

@ -53,7 +53,7 @@ const Hours: FC<Props> = ({data, click, learn_hour_records}) => {
}
if (upId && complete(upId) !== 1) {
Taro.showModal({title: '请完成上一个视频'})
Taro.showToast({title: '禁止播放', icon: 'none'})
return
}
@ -63,14 +63,14 @@ const Hours: FC<Props> = ({data, click, learn_hour_records}) => {
return (
<>
{data?.map((d, index) =>
<View className={'hor' + ` ${complete(d.id) ? 'complete' : null}`}
<View className={'hor' + ` ${complete(d.id) ? 'complete' : undefined}`}
key={index}
onClick={() => onClick(d.id, complete(d.id), d, data?.[index - 1]?.id,)}>
onClick={() => onClick(d.id, complete(d.id), d, data?.[index - 1]?.id)}>
<Image src={complete(d.id) ? playOk : play} mode="scaleToFill" className='image'/>
<View className='title'>
<View className='text'>
<View>{index + 1}.{d.title}</View>
<View className='font-26'>{formatMinute(d.duration)}</View>
<View className='font-26 text-muted'>{formatMinute(d.duration)}</View>
{complete(d.id) === 0 && <View className='font-26 text-danger'></View>}
</View>
{

@ -26,7 +26,7 @@
background: #fff;
border-radius: 40rpx;
padding: 0 24rpx 24rpx;
margin-top: 20rpx;
margin-top: 30rpx;
.short_desc {
color: #606563;
@ -36,8 +36,9 @@
}
.hor {
padding: 20px 0;
padding: 20rpx 0;
display: flex;
color: #323635;
.image {
width: 40rpx;
@ -49,7 +50,7 @@
.title {
flex: 1;
width: 710rpx;
padding: 0 0 20rpx 20rpx;
padding: 0 0 30rpx 20rpx;
display: flex;
justify-content: space-between;
box-sizing: border-box;

@ -6,6 +6,7 @@ import Catalogue from "./components/catalogue";
import Course from "./components/course";
import Taro from "@tarojs/taro";
import eventsIndex from "@/hooks/eventsIndex";
import {formatMinute} from "@/utils/time";
const VideoInfo: FC = () => {
const {id, depId} = Taro.getCurrentInstance()?.router?.params as any
@ -14,10 +15,6 @@ const VideoInfo: FC = () => {
const [preview, setPreview] = useState(false)
const [playing, setPlaying] = useState(false)
// Taro.useSaveExitState(() => ({
// data: {playId}
// }))
const getData = useCallback(async () => {
const res = await curriculum.courseDep(id, depId)
if (res) {
@ -110,11 +107,12 @@ const VideoInfo: FC = () => {
<View className='header'>
<View className='flex justify-between text-muted'>
<Text className='font-34 text-warning'>{data?.is_required ? '必修' : '选修'}</Text>
<Text>{data?.course.class_hour}</Text>
<Text className='font-24'>{data?.course.class_hour}</Text>
</View>
<View className='font-weight font-40 my-3'>{data?.course.title}</View>
<View className='text-muted font-26'>
<Text>{data?.learn_hour_records.length || 0}/{data?.course.class_hour}</Text>
<View className='font-weight font-36 my-2'>{data?.course.title}</View>
<View className='text-muted font-26 mt-3'>
<Text className='mr-2'>{formatMinute(data?.duration || 0)}</Text>
<Text>{((data?.learn_hour_records.length || 0) / (data?.course.class_hour || 1) * 100).toFixed(0)}%</Text>
</View>
</View>
<Catalogue data={data} setHors={setHors} id={id} playId={playId}/>

@ -8,17 +8,19 @@ page,
min-height: 100vh;
}
body {
font-size: 32rpx;
}
.weui-cells_checkbox .weui-check:checked + .weui-icon-checked:before,
.taro-checkbox_checked{
color: #45D4A8 !important;
}
taro-button-core::after {
border: none !important;
}
body {
font-size: 32rpx;
}
.input {
background: #F5F8F7;
border-radius: 8px;

Loading…
Cancel
Save