feat: 调试练题
This commit is contained in:
@@ -13,7 +13,7 @@ const MENULIST = [
|
||||
{
|
||||
key: 'prictiseQuestion',
|
||||
title: '练题',
|
||||
route: '/practice-questions',
|
||||
route: '/practise-questions',
|
||||
finished: true
|
||||
},
|
||||
{
|
||||
|
@@ -40,16 +40,16 @@ const router = createBrowserRouter([
|
||||
Component: lazy(() => import('@views/personal-center'))
|
||||
},
|
||||
{
|
||||
path: 'practice-questions',
|
||||
Component: lazy(() => import('@views/practise/practice-questions'))
|
||||
path: 'practise-questions',
|
||||
Component: lazy(() => import('@views/practise/practise-questions'))
|
||||
},
|
||||
{
|
||||
path: 'practice-detail/:id',
|
||||
Component: lazy(() => import('@views/practise/practice-details/index1.jsx'))
|
||||
path: 'practise-detail/:setId',
|
||||
Component: lazy(() => import('@views/practise/practise-details/index.jsx'))
|
||||
},
|
||||
{
|
||||
path: 'practice-analytic/:id',
|
||||
Component: lazy(() => import('@views/practise/practice-analytic'))
|
||||
path: 'practise-analytic/:id',
|
||||
Component: lazy(() => import('@views/practise/practise-analytic'))
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -1,312 +0,0 @@
|
||||
import AnalysisAtlas from '@components/analysis-atlas'
|
||||
import { splicingQuery } from '@utils'
|
||||
import req from '@utils/request'
|
||||
import { Button, Spin } from 'antd'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { ApiName, ModuleName } from '../../constant'
|
||||
import RecommendList from '../recommend-list'
|
||||
|
||||
import './index.less'
|
||||
|
||||
const AssessmentReport = props => {
|
||||
const navigate = useNavigate()
|
||||
const [title, setTitle] = useState('测试试卷')
|
||||
const [correctSubject, setCorrectSubject] = useState('3')
|
||||
const [spinning, setSpinning] = useState(false)
|
||||
const [recommendSetList, setRecommendSetList] = useState([])
|
||||
const [skill, setSkill] = useState([
|
||||
{
|
||||
name: '名称1',
|
||||
star: 50
|
||||
},
|
||||
{
|
||||
name: '名称2',
|
||||
star: 70
|
||||
},
|
||||
{
|
||||
name: '名称3',
|
||||
star: 90
|
||||
},
|
||||
{
|
||||
name: '名称4',
|
||||
star: 80
|
||||
}
|
||||
])
|
||||
|
||||
useEffect(() => {}, [])
|
||||
|
||||
/**
|
||||
* 答案解析-获得评估报告
|
||||
*/
|
||||
const getReport = async () => {
|
||||
const { practiceId } = this.props
|
||||
let params = {
|
||||
practiceId: practiceId
|
||||
}
|
||||
await req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: ApiName.getReport
|
||||
})
|
||||
.then(res => {
|
||||
if (res?.data) {
|
||||
let list = res.data.skill || []
|
||||
let len = res.data.skill.length
|
||||
if (len === 1) {
|
||||
let l1 = [
|
||||
{ name: res.data.skill[0].name + ' ', star: res.data.skill[0].star },
|
||||
{
|
||||
name: ' ' + res.data.skill[0].name + ' ',
|
||||
star: res.data.skill[0].star
|
||||
}
|
||||
]
|
||||
list = list.concat(l1)
|
||||
} else if (len === 2) {
|
||||
let l1 = [{ name: res.data.skill[1].name + ' ', star: res.data.skill[1].star }]
|
||||
list = list.concat(l1)
|
||||
}
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
title: res.data.title,
|
||||
correctSubject: res.data.correctSubject,
|
||||
recommendSetList: res.data.recommendSetList,
|
||||
skill: list
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(err => console.log(err))
|
||||
}
|
||||
|
||||
/**
|
||||
* 练习其他技能
|
||||
*/
|
||||
const onChangePracticeOther = () => {
|
||||
// this.props.history.push('/practice-questions')
|
||||
navigate('/practice-questions')
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看答案解析
|
||||
*/
|
||||
const onChangeAnswerAnalysis = () => {
|
||||
props.onHandleAnswerAnalysis && props.onHandleAnswerAnalysis(ModuleName.analysis)
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击推荐套题
|
||||
* @param {*} setId
|
||||
* @returns
|
||||
*/
|
||||
const onChangeSetId = setId => {
|
||||
this.props.history.push(
|
||||
splicingQuery('/practice-details', {
|
||||
setId
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Spin spinning={spinning}>
|
||||
<div className='assessment-report-box'>
|
||||
<div className='assessment-report-top'>
|
||||
<div className='assessment-report-main'>
|
||||
{/* <div className="assessment-report-defen">
|
||||
<img src={ImgObj.defen} className="assessment-report-defen-icon" />
|
||||
得分:12
|
||||
</div> */}
|
||||
<div className='assessment-report-item'>试卷:{title}</div>
|
||||
<div className='assessment-report-item'>正确题数:{correctSubject}</div>
|
||||
<Button
|
||||
className='assessment-report-submit'
|
||||
type='primary'
|
||||
onClick={onChangePracticeOther}
|
||||
>
|
||||
练习其他技能
|
||||
</Button>
|
||||
</div>
|
||||
<div className='assessment-report-tupu'>
|
||||
<div className='assessment-report-tupu-tip'>你的技能图谱</div>
|
||||
<div className='assessment-report-tupu-content'>
|
||||
<AnalysisAtlas
|
||||
aliasStr='正确率'
|
||||
atlasList={skill || []}
|
||||
atlasMin={-25}
|
||||
atlasWidth={200}
|
||||
atlasHeight={200}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{recommendSetList?.length > 0 && (
|
||||
<RecommendList recommendSetList={recommendSetList} onHandleSetId={onChangeSetId} />
|
||||
)}
|
||||
<div className='assessment-report-answer-analysis'>
|
||||
<Button
|
||||
className='assessment-report-answer-btn'
|
||||
type='primary'
|
||||
onClick={onChangeAnswerAnalysis}
|
||||
>
|
||||
查看答案解析
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Spin>
|
||||
)
|
||||
}
|
||||
|
||||
// class AssessmentReport extends Component {
|
||||
// constructor(props) {
|
||||
// super(props)
|
||||
// this.state = {
|
||||
// correctSubject: '3',
|
||||
// recommendSetList: [],
|
||||
// skill: [
|
||||
// {
|
||||
// name: '名称1',
|
||||
// star: 50
|
||||
// },
|
||||
// {
|
||||
// name: '名称2',
|
||||
// star: 70
|
||||
// },
|
||||
// {
|
||||
// name: '名称3',
|
||||
// star: 90
|
||||
// },
|
||||
// {
|
||||
// name: '名称4',
|
||||
// star: 80
|
||||
// }
|
||||
// ],
|
||||
// title: '测试试卷',
|
||||
// isLoading: false
|
||||
// }
|
||||
// }
|
||||
|
||||
// componentDidMount() {
|
||||
// this.getReport()
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 答案解析-获得评估报告
|
||||
// */
|
||||
// getReport = async () => {
|
||||
// const { practiceId } = this.props
|
||||
// let params = {
|
||||
// practiceId: practiceId
|
||||
// }
|
||||
// await req({
|
||||
// method: 'post',
|
||||
// data: params,
|
||||
// url: ApiName.getReport
|
||||
// })
|
||||
// .then(res => {
|
||||
// if (res?.data) {
|
||||
// let list = res.data.skill || []
|
||||
// let len = res.data.skill.length
|
||||
// if (len === 1) {
|
||||
// let l1 = [
|
||||
// { name: res.data.skill[0].name + ' ', star: res.data.skill[0].star },
|
||||
// {
|
||||
// name: ' ' + res.data.skill[0].name + ' ',
|
||||
// star: res.data.skill[0].star
|
||||
// }
|
||||
// ]
|
||||
// list = list.concat(l1)
|
||||
// } else if (len === 2) {
|
||||
// let l1 = [{ name: res.data.skill[1].name + ' ', star: res.data.skill[1].star }]
|
||||
// list = list.concat(l1)
|
||||
// }
|
||||
// this.setState({
|
||||
// isLoading: false,
|
||||
// title: res.data.title,
|
||||
// correctSubject: res.data.correctSubject,
|
||||
// recommendSetList: res.data.recommendSetList,
|
||||
// skill: list
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// .catch(err => console.log(err))
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 练习其他技能
|
||||
// */
|
||||
// onChangePracticeOther = () => {
|
||||
// this.props.history.push('/practice-questions')
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 查看答案解析
|
||||
// */
|
||||
// onChangeAnswerAnalysis = () => {
|
||||
// this.props.onHandleAnswerAnalysis && this.props.onHandleAnswerAnalysis(ModuleName.analysis)
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 点击推荐套题
|
||||
// * @param {*} setId
|
||||
// * @returns
|
||||
// */
|
||||
// onChangeSetId = setId => {
|
||||
// this.props.history.push(
|
||||
// splicingQuery('/practice-details', {
|
||||
// setId
|
||||
// })
|
||||
// )
|
||||
// }
|
||||
|
||||
// render() {
|
||||
// const { correctSubject, recommendSetList, skill, title, isLoading } = this.state
|
||||
// return (
|
||||
// <Spin spinning={isLoading}>
|
||||
// <div className='assessment-report-box'>
|
||||
// <div className='assessment-report-top'>
|
||||
// <div className='assessment-report-main'>
|
||||
// {/* <div className="assessment-report-defen">
|
||||
// <img src={ImgObj.defen} className="assessment-report-defen-icon" />
|
||||
// 得分:12
|
||||
// </div> */}
|
||||
// <div className='assessment-report-item'>试卷:{title}</div>
|
||||
// <div className='assessment-report-item'>正确题数:{correctSubject}</div>
|
||||
// <Button
|
||||
// className='assessment-report-submit'
|
||||
// type='primary'
|
||||
// onClick={this.onChangePracticeOther}
|
||||
// >
|
||||
// 练习其他技能
|
||||
// </Button>
|
||||
// </div>
|
||||
// <div className='assessment-report-tupu'>
|
||||
// <div className='assessment-report-tupu-tip'>你的技能图谱</div>
|
||||
// <div className='assessment-report-tupu-content'>
|
||||
// <AnalysisAtlas
|
||||
// aliasStr='正确率'
|
||||
// atlasList={skill || []}
|
||||
// atlasMin={-25}
|
||||
// atlasWidth={200}
|
||||
// atlasHeight={200}
|
||||
// />
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// {recommendSetList?.length > 0 && (
|
||||
// <RecommendList recommendSetList={recommendSetList} onHandleSetId={this.onChangeSetId} />
|
||||
// )}
|
||||
// <div className='assessment-report-answer-analysis'>
|
||||
// <Button
|
||||
// className='assessment-report-answer-btn'
|
||||
// type='primary'
|
||||
// onClick={this.onChangeAnswerAnalysis}
|
||||
// >
|
||||
// 查看答案解析
|
||||
// </Button>
|
||||
// </div>
|
||||
// </div>
|
||||
// </Spin>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
||||
export default AssessmentReport
|
@@ -1,53 +0,0 @@
|
||||
export const ModuleName = {
|
||||
/**
|
||||
* 评估报告
|
||||
*/
|
||||
assessment: 'assessment',
|
||||
/**
|
||||
* 答案解析
|
||||
*/
|
||||
analysis: 'analysis',
|
||||
};
|
||||
|
||||
export const ImgObj = {
|
||||
defen: 'https://img10.360buyimg.com/imagetools/jfs/t1/197806/1/18639/2369/61a095a8E09f4e860/493d753073a4a9fa.png',
|
||||
};
|
||||
|
||||
export const ApiName = {
|
||||
/**
|
||||
* 获得评价
|
||||
*/
|
||||
getReport: '/admin/practice/detail/getReport',
|
||||
/**
|
||||
* 答案详情
|
||||
*/
|
||||
getSubjectDetail: '/admin/practice/detail/getSubjectDetail',
|
||||
/**
|
||||
* 获得题号
|
||||
*/
|
||||
getScoreDetail: 'admin/practice/detail/getScoreDetail',
|
||||
};
|
||||
|
||||
/**
|
||||
* id对应字母
|
||||
*/
|
||||
export const IdKeyLetterKey = {
|
||||
1: 'A',
|
||||
2: 'B',
|
||||
3: 'C',
|
||||
4: 'D',
|
||||
5: 'E',
|
||||
6: 'F',
|
||||
7: 'G',
|
||||
8: 'H',
|
||||
};
|
||||
|
||||
/**
|
||||
* 推荐对应的背景图
|
||||
*/
|
||||
export const RecommendBackImg = {
|
||||
0: 'https://img11.360buyimg.com/imagetools/jfs/t1/202713/11/17151/312/61a5dea1E5623fea6/2922d716cae01b28.png',
|
||||
1: 'https://img10.360buyimg.com/imagetools/jfs/t1/142359/35/22866/2975/61a5dea0E3fcd563c/78ee45555dd19cda.png',
|
||||
2: 'https://img13.360buyimg.com/imagetools/jfs/t1/161380/34/26207/1078/61a5dea0E7824463e/4e18f74e8c6439ad.png',
|
||||
3: 'https://img14.360buyimg.com/imagetools/jfs/t1/160815/15/27226/880/61a5e1e6E152b08b7/fb698b8321d08246.png',
|
||||
};
|
@@ -1,69 +0,0 @@
|
||||
import { Tabs } from 'antd'
|
||||
import React, { Component } from 'react'
|
||||
import AnswerAnalysis from './components/answer-analysis'
|
||||
import AssessmentReport from './components/assessment-report'
|
||||
import { ModuleName } from './constant'
|
||||
import './index.less'
|
||||
const { TabPane } = Tabs
|
||||
|
||||
const practiceAnalyticTabList = [
|
||||
{ tab: '评估报告', key: ModuleName.assessment },
|
||||
{ tab: '答案解析', key: ModuleName.analysis }
|
||||
]
|
||||
export default class PracticeAnalytic extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = { currentKey: ModuleName.assessment }
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换card tab
|
||||
* @param {*} key
|
||||
*/
|
||||
onTabChange = key => {
|
||||
this.setState({ currentKey: key })
|
||||
}
|
||||
|
||||
render() {
|
||||
const { currentKey } = this.state
|
||||
console.log(this.props)
|
||||
// const urlParams = queryParse(this.props.location.search)
|
||||
// if (!urlParams.practiceId) {
|
||||
// return null
|
||||
// }
|
||||
return (
|
||||
<div className='practice-analytic-box'>
|
||||
<Tabs
|
||||
size='default'
|
||||
type='card'
|
||||
style={{ width: '100%' }}
|
||||
activeKey={currentKey}
|
||||
defaultActiveKey={currentKey}
|
||||
tabBarStyle={{
|
||||
height: '41px',
|
||||
background: '#fff',
|
||||
borderBottom: '1px solid #1890ff',
|
||||
margin: 0
|
||||
}}
|
||||
onChange={key => {
|
||||
this.onTabChange(key, 'key')
|
||||
}}
|
||||
>
|
||||
{practiceAnalyticTabList.map(item => {
|
||||
return <TabPane tab={item.tab} key={item.key}></TabPane>
|
||||
})}
|
||||
</Tabs>
|
||||
{currentKey == ModuleName.assessment ? (
|
||||
<AssessmentReport
|
||||
onHandleAnswerAnalysis={key => {
|
||||
this.onTabChange(key, 'key')
|
||||
}}
|
||||
practiceId={1}
|
||||
/>
|
||||
) : (
|
||||
<AnswerAnalysis practiceId={1} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
export const mark = {
|
||||
0: '标记一下',
|
||||
1: '已标记',
|
||||
};
|
||||
|
||||
export const collection = {
|
||||
0: '未收藏',
|
||||
1: '已收藏',
|
||||
};
|
||||
|
||||
export const quetionsType = {
|
||||
1: '单选题',
|
||||
2: '多选题',
|
||||
3: '判断题',
|
||||
};
|
||||
|
||||
export const ApiName = {
|
||||
/**
|
||||
* 获取练习题目
|
||||
*/
|
||||
getSubjects: '/admin/practice/set/getSubjects',
|
||||
|
||||
/**
|
||||
* 获取练习题目详情
|
||||
*/
|
||||
getPracticeSubject: '/admin/practice/set/getPracticeSubject',
|
||||
|
||||
/**
|
||||
* 交卷
|
||||
*/
|
||||
submitSubject: '/admin/practice/detail/submit',
|
||||
};
|
||||
|
||||
export const ImgObj = {
|
||||
stop: 'https://img10.360buyimg.com/imagetools/jfs/t1/206561/1/10729/2819/619f783cE77dd49ed/54eb1fc4b3144a97.png',
|
||||
run: 'https://img11.360buyimg.com/imagetools/jfs/t1/161735/6/25253/2598/619f783cEa897a673/fbf4e8c05d40feb5.png',
|
||||
info: 'https://img13.360buyimg.com/imagetools/jfs/t1/217399/4/5733/2641/619f7b91E0894649e/2f6353fe0d35fb46.png',
|
||||
questionMark:
|
||||
'https://img12.360buyimg.com/imagetools/jfs/t1/201809/8/16630/2674/61a04963E92475548/ede8a7f006113cae.png',
|
||||
mark: 'https://img12.360buyimg.com/imagetools/jfs/t1/207329/30/11079/2474/61a70ad0E64730d1c/ed75ee746fb33926.png',
|
||||
advanceTip:
|
||||
'https://img11.360buyimg.com/imagetools/jfs/t1/161028/16/25609/6746/61a08d83E06659dfa/e6418acdab948134.png',
|
||||
};
|
@@ -1,511 +0,0 @@
|
||||
import Timer from '@components/timerCom/FlipClock'
|
||||
import { getCurrentTime, splicingQuery } from '@utils'
|
||||
import req from '@utils/request'
|
||||
import { Checkbox, Modal, Radio } from 'antd'
|
||||
import _ from 'lodash'
|
||||
import React, { Component } from 'react'
|
||||
import PracticeAction from './components/practice-action'
|
||||
import PracticeAdvance from './components/practice-advance'
|
||||
import PracticePaging from './components/practice-paging'
|
||||
import { ApiName, ImgObj, quetionsType } from './constant'
|
||||
import './index.less'
|
||||
|
||||
export default class PracticeDetails extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
isMark: 0, // 是否标记
|
||||
isCollection: 0,
|
||||
currentActive: '',
|
||||
subjectList: [], // 总题目列表
|
||||
subjectObject: {}, //题目
|
||||
currentIndex: 0,
|
||||
isShowAdvanOverceBox: false,
|
||||
isShowStopBox: false
|
||||
}
|
||||
}
|
||||
|
||||
timerRef = React.createRef()
|
||||
subjectTitle = ''
|
||||
singleLength = 0
|
||||
multipleLength = 0
|
||||
judgeLength = 0
|
||||
setId = ''
|
||||
|
||||
componentDidMount() {
|
||||
// const urlParams = queryParse(this.props.location.search)
|
||||
// this.setId = urlParams.setId
|
||||
this.getSubjectList()
|
||||
this.timerRef.current.run()
|
||||
// window.addEventListener('beforeunload', this.listener);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
// window.addEventListener('beforeunload', this.listener);
|
||||
}
|
||||
|
||||
//监听屏幕刷新,关闭默认事件,界面没有动,不会拦截
|
||||
listener = ev => {
|
||||
ev.preventDefault()
|
||||
ev.returnValue = ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得题目列表
|
||||
*/
|
||||
getSubjectList = () => {
|
||||
let params = {
|
||||
setId: this.setId
|
||||
}
|
||||
this.subjectTitle = '热门题目练习'
|
||||
this.singleLength = 1
|
||||
this.multipleLength = 1
|
||||
this.judgeLength = 1
|
||||
const list = [
|
||||
{
|
||||
subjectType: 1,
|
||||
subjectId: 1
|
||||
},
|
||||
{
|
||||
subjectType: 2,
|
||||
subjectId: 2
|
||||
},
|
||||
{
|
||||
subjectType: 3,
|
||||
subjectId: 3
|
||||
}
|
||||
]
|
||||
this.setState({
|
||||
subjectList: [...list]
|
||||
})
|
||||
_.set(list, [0, 'active'], true)
|
||||
this.getPracticeSubject(list[0], list, 0, [])
|
||||
// req({
|
||||
// method: 'post',
|
||||
// data: params,
|
||||
// url: ApiName.getSubjects
|
||||
// })
|
||||
// .then(res => {
|
||||
// if (res.data && res.data?.subjectList?.length > 0) {
|
||||
// let list = res.data.subjectList
|
||||
// this.singleLength =
|
||||
// list?.length > 0 ? list.filter(item => item.subjectType === 1).length : 0
|
||||
// this.multipleLength =
|
||||
// list?.length > 0 ? list.filter(item => item.subjectType === 2).length : 0
|
||||
// this.judgeLength =
|
||||
// list?.length > 0 ? list.filter(item => item.subjectType === 3).length : 0
|
||||
// this.subjectTitle = res.data?.title || '' // 总题目列表
|
||||
// this.getPracticeSubject(list[0], list, 0, [])
|
||||
// }
|
||||
// })
|
||||
// .catch(err => console.log(err))
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得题目详情
|
||||
* @param {*} item 选择的项
|
||||
* @param {*} subjectList 题目列表
|
||||
* @param {*} index 选择的下标
|
||||
* @param {*} activeList 选中的列表
|
||||
* @param {*} isMark 是否被标记
|
||||
*/
|
||||
getPracticeSubject = (item, subjectList, index, activeList, isMark = 0) => {
|
||||
let params = {
|
||||
subjectId: item.subjectId,
|
||||
subjectType: item.subjectType
|
||||
}
|
||||
|
||||
const optionList =
|
||||
item.subjectType === 3
|
||||
? [
|
||||
{
|
||||
optionContent: '正确',
|
||||
optionType: 1
|
||||
},
|
||||
{
|
||||
optionContent: '错误',
|
||||
optionType: 0
|
||||
}
|
||||
]
|
||||
: [
|
||||
{
|
||||
optionType: 1,
|
||||
optionContent: '<p>题目答案1</p>'
|
||||
},
|
||||
{
|
||||
optionType: 2,
|
||||
optionContent: '<p>题目答案2</p>'
|
||||
},
|
||||
{
|
||||
optionType: 3,
|
||||
optionContent: '<p>题目答案3</p>'
|
||||
}
|
||||
]
|
||||
|
||||
return this.setState({
|
||||
currentIndex: index,
|
||||
currentActive: item.subjectType === 2 ? activeList : activeList[0],
|
||||
subjectObject: {
|
||||
subjectName: '题干内容',
|
||||
subjectType: item.subjectType,
|
||||
optionList,
|
||||
// subjectList: subjectList,
|
||||
// currentIndex: index,
|
||||
// currentActive: item.sub??jectType === 2 ? activeList : activeList[0],
|
||||
isMark: isMark
|
||||
}
|
||||
})
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: ApiName.getPracticeSubject
|
||||
})
|
||||
.then(res => {
|
||||
if (res.data) {
|
||||
let subjectObject = res.data
|
||||
if (item.subjectType === 3) {
|
||||
subjectObject.optionList = [
|
||||
{
|
||||
optionContent: '正确',
|
||||
optionType: 1
|
||||
},
|
||||
{
|
||||
optionContent: '错误',
|
||||
optionType: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
this.setState({
|
||||
subjectObject: res.data,
|
||||
subjectList: subjectList,
|
||||
currentIndex: index,
|
||||
currentActive: item.subjectType === 2 ? activeList : activeList[0],
|
||||
isMark: isMark
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(err => console.log(err))
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择单选
|
||||
* @param {*} e
|
||||
* @returns
|
||||
*/
|
||||
onChangeRadio = e => () => {
|
||||
let { currentIndex, subjectList } = this.state
|
||||
_.set(subjectList, [currentIndex, 'activeList'], [e])
|
||||
this.setState({
|
||||
currentActive: e,
|
||||
subjectList
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择多选
|
||||
* @param {*} e
|
||||
* @returns
|
||||
*/
|
||||
onChangeCheck = e => {
|
||||
let { currentIndex, subjectList } = this.state
|
||||
_.set(subjectList, [currentIndex, 'activeList'], e)
|
||||
this.setState({
|
||||
currentActive: e,
|
||||
subjectList
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停计时
|
||||
*/
|
||||
onChangeStop = () => {
|
||||
this.setState({ isShowStopBox: true })
|
||||
this.timerRef.current.stop()
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记一下
|
||||
*/
|
||||
onChangeMark = () => {
|
||||
let { currentIndex, subjectList, subjectObject } = this.state
|
||||
let flag = 1
|
||||
if (subjectList[currentIndex]?.isMark) {
|
||||
flag = 0
|
||||
}
|
||||
_.set(subjectList, [currentIndex, 'isMark'], flag)
|
||||
this.setState({
|
||||
subjectList,
|
||||
isMark: flag,
|
||||
subjectObject
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择答题卡
|
||||
* @param {*} index
|
||||
* @param {*} item
|
||||
* @returns
|
||||
*/
|
||||
onChangePaging = index => {
|
||||
let { currentIndex } = this.state
|
||||
// 如果点击当前题目,直接return
|
||||
if (currentIndex === index) {
|
||||
return
|
||||
}
|
||||
this.changeData(index)
|
||||
}
|
||||
|
||||
/**
|
||||
* 交卷
|
||||
*/
|
||||
onChangeOver = () => {
|
||||
const { subjectList } = this.state
|
||||
let answerDetails = []
|
||||
subjectList.forEach(item => {
|
||||
let obj = {
|
||||
subjectId: item.subjectId,
|
||||
subjectType: item.subjectType,
|
||||
answerContents: []
|
||||
}
|
||||
if (item?.activeList && item?.activeList?.length > 0) {
|
||||
obj.answerContents = item.activeList
|
||||
}
|
||||
answerDetails.push(obj)
|
||||
})
|
||||
let params = {
|
||||
setId: this.setId,
|
||||
timeUse: this.timerRef.current.getUseTime(),
|
||||
submitTime: getCurrentTime(),
|
||||
answerDetails: answerDetails
|
||||
}
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: ApiName.submitSubject
|
||||
})
|
||||
.then(res => {
|
||||
if (res.data && res.data.practiceId) {
|
||||
//关闭定时器
|
||||
this.timerRef.current.end()
|
||||
this.props.history.replace(
|
||||
splicingQuery('/practice-analytic', {
|
||||
practiceId: res.data.practiceId
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
.catch(err => console.log(err))
|
||||
}
|
||||
|
||||
/**
|
||||
* 提前交卷弹框-直接交卷
|
||||
*/
|
||||
onHandleSubmitModal = () => {
|
||||
this.onChangeOver()
|
||||
}
|
||||
|
||||
/**
|
||||
* 提前交卷弹框-继续做题
|
||||
*/
|
||||
onHandleCancelModal = () => {
|
||||
this.setState({ isShowAdvanOverceBox: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* 提前交卷
|
||||
*/
|
||||
onChangeAdvanceOver = () => {
|
||||
this.setState({
|
||||
isShowAdvanOverceBox: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 下一题
|
||||
* @returns
|
||||
*/
|
||||
onChangeNext = () => {
|
||||
let { currentIndex } = this.state
|
||||
currentIndex += 1
|
||||
this.changeData(currentIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
* 改变数据
|
||||
* @param {*} index 当前点击下标
|
||||
*/
|
||||
changeData = index => {
|
||||
let { subjectList } = this.state
|
||||
let subObj = subjectList[index]
|
||||
let activeList = [] // 多选 选中的答案项
|
||||
let isMark = 0 // 是否被标记
|
||||
|
||||
// 将其他item设置为未选中
|
||||
subjectList.forEach(item => {
|
||||
item.active = false
|
||||
})
|
||||
_.set(subjectList, [index, 'active'], true)
|
||||
|
||||
// if当前选择的有选答案,则直接显示出来
|
||||
if (subObj?.activeList?.length > 0) {
|
||||
activeList = subObj?.activeList
|
||||
}
|
||||
|
||||
// if当前已被标记,则直接显示出来
|
||||
if (subObj?.isMark == 1) {
|
||||
isMark = 1
|
||||
}
|
||||
|
||||
this.getPracticeSubject(subObj, subjectList, index, activeList, isMark)
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停弹框-继续做题
|
||||
*/
|
||||
onChangeSubmitModal = () => {
|
||||
this.timerRef.current.run()
|
||||
this.setState({ isShowStopBox: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停弹框-再次再做
|
||||
*/
|
||||
onChangeCancelModal = () => {
|
||||
this.props.history.goBack()
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
isMark,
|
||||
isCollection,
|
||||
currentIndex,
|
||||
currentActive,
|
||||
subjectList,
|
||||
subjectObject,
|
||||
isShowAdvanOverceBox,
|
||||
isShowStopBox
|
||||
} = this.state
|
||||
const isLast = currentIndex === subjectList?.length - 1
|
||||
// 获得已答的题目个数
|
||||
const noAnswerNum =
|
||||
subjectList.filter(item => item.activeList && item.activeList.length > 0).length || 0
|
||||
return (
|
||||
<div className='details-container'>
|
||||
<div className='container-box'>
|
||||
<div className='container-box-title'>
|
||||
<div className='title-title'>{this.subjectTitle}</div>
|
||||
<div className='title-time'>
|
||||
<div className='title-timer-img' onClick={this.onChangeStop}>
|
||||
<img src={isShowStopBox ? ImgObj.stop : ImgObj.run} className='title-timer-icon' />
|
||||
</div>
|
||||
<Timer ref={this.timerRef} />
|
||||
</div>
|
||||
</div>
|
||||
<div className='details-question-number'>
|
||||
<div className='question-number-number'>
|
||||
{currentIndex + 1}/{subjectList?.length}
|
||||
</div>
|
||||
<img src={ImgObj.questionMark} className='question-number-mark' />
|
||||
<div className='question-number-type'>[{quetionsType[subjectObject.subjectType]}]</div>
|
||||
</div>
|
||||
<div className='practice-main'>
|
||||
<div className='practice-text'>
|
||||
<div className='practice-question'>{subjectObject.subjectName}</div>
|
||||
{subjectObject.subjectType === 2 ? (
|
||||
<Checkbox.Group
|
||||
className='practice-answer-list'
|
||||
onChange={this.onChangeCheck}
|
||||
value={currentActive || []}
|
||||
key={currentIndex}
|
||||
>
|
||||
{subjectObject?.optionList?.length > 0 &&
|
||||
subjectObject?.optionList.map(item => {
|
||||
return (
|
||||
<Checkbox
|
||||
key={item.optionType}
|
||||
className={`practice-answer-item ${
|
||||
currentActive.includes(item.optionType)
|
||||
? 'practice-answer-item-active'
|
||||
: ''
|
||||
}`}
|
||||
value={item.optionType}
|
||||
>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: item.optionContent
|
||||
}}
|
||||
></div>
|
||||
</Checkbox>
|
||||
)
|
||||
})}
|
||||
</Checkbox.Group>
|
||||
) : (
|
||||
<Radio.Group
|
||||
className='practice-answer-list'
|
||||
value={currentActive}
|
||||
key={currentIndex}
|
||||
>
|
||||
{subjectObject?.optionList?.length > 0 &&
|
||||
subjectObject?.optionList.map(item => {
|
||||
return (
|
||||
<Radio
|
||||
key={item.optionType}
|
||||
onClick={this.onChangeRadio(item.optionType)}
|
||||
className={`practice-answer-item ${
|
||||
currentActive === item.optionType ? 'practice-answer-item-active' : ''
|
||||
}`}
|
||||
value={item.optionType}
|
||||
>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: item.optionContent
|
||||
}}
|
||||
></div>
|
||||
</Radio>
|
||||
)
|
||||
})}
|
||||
</Radio.Group>
|
||||
)}
|
||||
</div>
|
||||
<PracticeAction
|
||||
isLast={isLast}
|
||||
isMark={isMark}
|
||||
onHandleMark={this.onChangeMark}
|
||||
onHandleOver={this.onChangeOver}
|
||||
onHandleAdvanceOver={this.onChangeAdvanceOver}
|
||||
onHandleNext={this.onChangeNext}
|
||||
/>
|
||||
</div>
|
||||
<PracticePaging
|
||||
subjectList={subjectList}
|
||||
onHandlePaging={this.onChangePaging}
|
||||
singleLength={this.singleLength}
|
||||
multipleLength={this.multipleLength}
|
||||
judgeLength={this.judgeLength}
|
||||
/>
|
||||
</div>
|
||||
<PracticeAdvance
|
||||
isShowModalBox={isShowAdvanOverceBox}
|
||||
onHandleSubmitModal={this.onHandleSubmitModal}
|
||||
onHandleCancelModal={this.onHandleCancelModal}
|
||||
/>
|
||||
<Modal
|
||||
closable={false}
|
||||
maskClosable={false}
|
||||
style={{ padding: 20 }}
|
||||
open={isShowStopBox}
|
||||
onOk={this.onChangeSubmitModal}
|
||||
onCancel={this.onChangeCancelModal}
|
||||
okText='继续做题'
|
||||
cancelText='下次再做'
|
||||
>
|
||||
<div style={{ padding: 40 }}>
|
||||
<img src={ImgObj.info} className='details-container-box-info' />
|
||||
休息一下吧!共{subjectList?.length}道题,还剩
|
||||
{subjectList?.length - noAnswerNum}道没做哦~
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
.front-box {
|
||||
.ant-descriptions-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 18px;
|
||||
color: rgba(51, 51, 51, 0.7);
|
||||
}
|
||||
.ant-checkbox-wrapper {
|
||||
font-size: 14px;
|
||||
color: rgba(51, 51, 51, 0.5);
|
||||
}
|
||||
.box {
|
||||
display: flex;
|
||||
width: 1200px;
|
||||
.box1 {
|
||||
flex: 1;
|
||||
}
|
||||
.box2 {
|
||||
flex: 1;
|
||||
// float: right;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,90 +0,0 @@
|
||||
import req from '@utils/request'
|
||||
import { Card, Checkbox, Descriptions } from 'antd'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
const apiName = {
|
||||
/**
|
||||
* 查询大类
|
||||
*/
|
||||
queryPrimaryCategory: '/category/queryPrimaryCategory',
|
||||
|
||||
// 查询分类及标签
|
||||
queryCategoryAndLabel: '/category/queryCategoryAndLabel'
|
||||
}
|
||||
|
||||
const PracticeHome = () => {
|
||||
const [primaryList, setPrimaryList] = useState<Record<string, any>[]>([])
|
||||
const [cateAndLabelList, setCateAndLabelList] = useState<Record<string, any>[]>([])
|
||||
const [currentPrimaryId, setCurrentPrimaryId] = useState()
|
||||
|
||||
const queryPrimaryList = () => {
|
||||
req({
|
||||
method: 'post',
|
||||
url: apiName.queryPrimaryCategory,
|
||||
data: { categoryType: 1 }
|
||||
})
|
||||
.then((res: Record<string, any>) => {
|
||||
if (res.data && res.data.length > 0) {
|
||||
setCurrentPrimaryId(res.data[0].id)
|
||||
setPrimaryList([...res.data].map(t => ({ tab: t.categoryName, key: t.id })))
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
queryPrimaryList()
|
||||
}, [])
|
||||
|
||||
const getCategoryAndLabel = () => {
|
||||
req({
|
||||
method: 'post',
|
||||
url: apiName.queryCategoryAndLabel,
|
||||
data: { id: currentPrimaryId }
|
||||
})
|
||||
.then(res => {
|
||||
if (res.data && res.data.length > 0) {
|
||||
res.data = res.data.map(item => {
|
||||
return {
|
||||
...item,
|
||||
children: item.labelDTOList.map(t => ({ label: t.labelName, value: t.id }))
|
||||
}
|
||||
})
|
||||
setCateAndLabelList([...res.data])
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (currentPrimaryId) {
|
||||
getCategoryAndLabel()
|
||||
}
|
||||
}, [currentPrimaryId])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Card tabList={primaryList}>
|
||||
{cateAndLabelList.map(item => {
|
||||
return (
|
||||
<Descriptions title={item.categoryName} extra={<Checkbox>全选</Checkbox>}>
|
||||
<Descriptions.Item label=''>
|
||||
<Checkbox.Group
|
||||
// value={secondItem.activeList}
|
||||
options={item.children}
|
||||
// onChange={this.onChange(secondIndex)}
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
)
|
||||
})}
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PracticeHome
|
@@ -32,11 +32,14 @@ export default class AnswerAnalysis extends Component {
|
||||
let params = {
|
||||
practiceId: practiceId
|
||||
}
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: ApiName.getScoreDetail
|
||||
})
|
||||
req(
|
||||
{
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: ApiName.getScoreDetail
|
||||
},
|
||||
'/practice'
|
||||
)
|
||||
.then(res => {
|
||||
if (res?.data && res?.data?.length > 0) {
|
||||
this.setState(
|
||||
@@ -64,11 +67,14 @@ export default class AnswerAnalysis extends Component {
|
||||
subjectId: subjectItem.subjectId,
|
||||
subjectType: subjectItem.subjectType
|
||||
}
|
||||
JDreq({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: ApiName.getSubjectDetail
|
||||
})
|
||||
req(
|
||||
{
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: ApiName.getSubjectDetail
|
||||
},
|
||||
'/practice'
|
||||
)
|
||||
.then(res => {
|
||||
if (res.data) {
|
||||
let respondAnswer = res.data.respondAnswer
|
@@ -0,0 +1,138 @@
|
||||
import AnalysisAtlas from '@components/analysis-atlas'
|
||||
import { splicingQuery } from '@utils'
|
||||
import req from '@utils/request'
|
||||
import { Button, Spin } from 'antd'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { ApiName, ModuleName } from '../../constant'
|
||||
import RecommendList from '../recommend-list'
|
||||
|
||||
import './index.less'
|
||||
|
||||
const AssessmentReport = props => {
|
||||
const navigate = useNavigate()
|
||||
const [title, setTitle] = useState('测试试卷')
|
||||
const [correctSubject, setCorrectSubject] = useState('3')
|
||||
const [spinning, setSpinning] = useState(false)
|
||||
const [recommendSetList, setRecommendSetList] = useState([])
|
||||
const [skill, setSkill] = useState([])
|
||||
|
||||
useEffect(() => {
|
||||
getReport()
|
||||
}, [props.practiceId])
|
||||
|
||||
/**
|
||||
* 答案解析-获得评估报告
|
||||
*/
|
||||
const getReport = async () => {
|
||||
const { practiceId } = props
|
||||
let params = {
|
||||
practiceId
|
||||
}
|
||||
await req(
|
||||
{
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: ApiName.getReport
|
||||
},
|
||||
'/practice'
|
||||
)
|
||||
.then(res => {
|
||||
if (res?.data) {
|
||||
const { skill, correctSubject, title } = res.data
|
||||
let list = skill || []
|
||||
let len = skill.length
|
||||
if (len === 1) {
|
||||
let l1 = [
|
||||
{ name: skill[0].name + ' ', star: skill[0].star },
|
||||
{
|
||||
name: ' ' + skill[0].name + ' ',
|
||||
star: skill[0].star
|
||||
}
|
||||
]
|
||||
list = list.concat(l1)
|
||||
} else if (len === 2) {
|
||||
let l1 = [{ name: skill[1].name + ' ', star: skill[1].star }]
|
||||
list = list.concat(l1)
|
||||
}
|
||||
setSkill(list)
|
||||
setCorrectSubject(correctSubject)
|
||||
setTitle(title)
|
||||
}
|
||||
})
|
||||
.catch(err => console.log(err))
|
||||
}
|
||||
|
||||
/**
|
||||
* 练习其他技能
|
||||
*/
|
||||
const onChangePracticeOther = () => {
|
||||
navigate('/practise-questions')
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看答案解析
|
||||
*/
|
||||
const onChangeAnswerAnalysis = () => {
|
||||
props.onHandleAnswerAnalysis && props.onHandleAnswerAnalysis(ModuleName.analysis)
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击推荐套题
|
||||
* @param {*} setId
|
||||
* @returns
|
||||
*/
|
||||
const onChangeSetId = setId => {
|
||||
this.props.history.push(
|
||||
splicingQuery('/practise-details', {
|
||||
setId
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Spin spinning={spinning}>
|
||||
<div className='assessment-report-box'>
|
||||
<div className='assessment-report-top'>
|
||||
<div className='assessment-report-main'>
|
||||
<div className='assessment-report-item'>试卷:{title}</div>
|
||||
<div className='assessment-report-item'>正确题数:{correctSubject}</div>
|
||||
<Button
|
||||
className='assessment-report-submit'
|
||||
type='primary'
|
||||
onClick={onChangePracticeOther}
|
||||
>
|
||||
练习其他技能
|
||||
</Button>
|
||||
</div>
|
||||
<div className='assessment-report-tupu'>
|
||||
<div className='assessment-report-tupu-tip'>你的技能图谱</div>
|
||||
<div className='assessment-report-tupu-content'>
|
||||
<AnalysisAtlas
|
||||
aliasStr='正确率'
|
||||
atlasList={skill || []}
|
||||
atlasMin={-25}
|
||||
atlasWidth={200}
|
||||
atlasHeight={200}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{recommendSetList?.length > 0 && (
|
||||
<RecommendList recommendSetList={recommendSetList} onHandleSetId={onChangeSetId} />
|
||||
)}
|
||||
<div className='assessment-report-answer-analysis'>
|
||||
<Button
|
||||
className='assessment-report-answer-btn'
|
||||
type='primary'
|
||||
onClick={onChangeAnswerAnalysis}
|
||||
>
|
||||
查看答案解析
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Spin>
|
||||
)
|
||||
}
|
||||
|
||||
export default AssessmentReport
|
54
src/views/practise/practise-analytic/constant.js
Normal file
54
src/views/practise/practise-analytic/constant.js
Normal file
@@ -0,0 +1,54 @@
|
||||
export const ModuleName = {
|
||||
/**
|
||||
* 评估报告
|
||||
*/
|
||||
assessment: 'assessment',
|
||||
/**
|
||||
* 答案解析
|
||||
*/
|
||||
analysis: 'analysis'
|
||||
}
|
||||
|
||||
export const ImgObj = {
|
||||
defen:
|
||||
'https://img10.360buyimg.com/imagetools/jfs/t1/197806/1/18639/2369/61a095a8E09f4e860/493d753073a4a9fa.png'
|
||||
}
|
||||
|
||||
export const ApiName = {
|
||||
/**
|
||||
* 获得评价
|
||||
*/
|
||||
getReport: '/practice/detail/getReport',
|
||||
/**
|
||||
* 答案详情
|
||||
*/
|
||||
getSubjectDetail: '/practice/detail/getSubjectDetail',
|
||||
/**
|
||||
* 获得题号
|
||||
*/
|
||||
getScoreDetail: '/practice/detail/getScoreDetail'
|
||||
}
|
||||
|
||||
/**
|
||||
* id对应字母
|
||||
*/
|
||||
export const IdKeyLetterKey = {
|
||||
1: 'A',
|
||||
2: 'B',
|
||||
3: 'C',
|
||||
4: 'D',
|
||||
5: 'E',
|
||||
6: 'F',
|
||||
7: 'G',
|
||||
8: 'H'
|
||||
}
|
||||
|
||||
/**
|
||||
* 推荐对应的背景图
|
||||
*/
|
||||
export const RecommendBackImg = {
|
||||
0: 'https://img11.360buyimg.com/imagetools/jfs/t1/202713/11/17151/312/61a5dea1E5623fea6/2922d716cae01b28.png',
|
||||
1: 'https://img10.360buyimg.com/imagetools/jfs/t1/142359/35/22866/2975/61a5dea0E3fcd563c/78ee45555dd19cda.png',
|
||||
2: 'https://img13.360buyimg.com/imagetools/jfs/t1/161380/34/26207/1078/61a5dea0E7824463e/4e18f74e8c6439ad.png',
|
||||
3: 'https://img14.360buyimg.com/imagetools/jfs/t1/160815/15/27226/880/61a5e1e6E152b08b7/fb698b8321d08246.png'
|
||||
}
|
56
src/views/practise/practise-analytic/index.jsx
Normal file
56
src/views/practise/practise-analytic/index.jsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { Tabs } from 'antd'
|
||||
import React, { useState } from 'react'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import AnswerAnalysis from './components/answer-analysis'
|
||||
import AssessmentReport from './components/assessment-report'
|
||||
import { ModuleName } from './constant'
|
||||
import './index.less'
|
||||
|
||||
const { TabPane } = Tabs
|
||||
|
||||
const practiceAnalyticTabList = [
|
||||
{ tab: '评估报告', key: ModuleName.assessment },
|
||||
{ tab: '答案解析', key: ModuleName.analysis }
|
||||
]
|
||||
|
||||
const PracticeAnalytic = () => {
|
||||
const [currentKey, setCurrentKey] = useState(ModuleName.assessment)
|
||||
const { id } = useParams()
|
||||
|
||||
/**
|
||||
* 切换card tab
|
||||
* @param {*} key
|
||||
*/
|
||||
const onTabChange = key => {
|
||||
setCurrentKey(key)
|
||||
}
|
||||
return (
|
||||
<div className='practice-analytic-box'>
|
||||
<Tabs
|
||||
size='default'
|
||||
type='card'
|
||||
style={{ width: '100%' }}
|
||||
activeKey={currentKey}
|
||||
defaultActiveKey={currentKey}
|
||||
tabBarStyle={{
|
||||
height: '41px',
|
||||
background: '#fff',
|
||||
borderBottom: '1px solid #1890ff',
|
||||
margin: 0
|
||||
}}
|
||||
onChange={onTabChange}
|
||||
>
|
||||
{practiceAnalyticTabList.map(item => {
|
||||
return <TabPane tab={item.tab} key={item.key}></TabPane>
|
||||
})}
|
||||
</Tabs>
|
||||
{currentKey == ModuleName.assessment ? (
|
||||
<AssessmentReport onHandleAnswerAnalysis={onTabChange} practiceId={id} />
|
||||
) : (
|
||||
<AnswerAnalysis practiceId={id} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PracticeAnalytic
|
@@ -1,6 +1,6 @@
|
||||
.practice-analytic-box {
|
||||
margin: 0 auto;
|
||||
width: 1430px;
|
||||
width: 1200px;
|
||||
border: 1px solid #e0e0e0;
|
||||
overflow-y: auto;
|
||||
.ant-tabs.ant-tabs-card .ant-tabs-card-bar .ant-tabs-tab {
|
55
src/views/practise/practise-details/constant.ts
Normal file
55
src/views/practise/practise-details/constant.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
export const mark = {
|
||||
0: '标记一下',
|
||||
1: '已标记'
|
||||
}
|
||||
|
||||
export const collection = {
|
||||
0: '未收藏',
|
||||
1: '已收藏'
|
||||
}
|
||||
|
||||
export enum Type {
|
||||
/**单选 */
|
||||
Single = 1,
|
||||
Multiple,
|
||||
Judge
|
||||
}
|
||||
|
||||
export const quetionsType = {
|
||||
[Type.Single]: '单选题',
|
||||
[Type.Multiple]: '多选题',
|
||||
[Type.Judge]: '判断题'
|
||||
}
|
||||
|
||||
export const ApiName = {
|
||||
/**
|
||||
* 获取练习题目
|
||||
*/
|
||||
getSubjects: '/practice/set/getSubjects',
|
||||
|
||||
/**
|
||||
* 获取练习题目详情
|
||||
*/
|
||||
getPracticeSubject: '/practice/set/getPracticeSubject',
|
||||
|
||||
/**
|
||||
* 单个题目提交
|
||||
* */
|
||||
submitSubject: '/practice/detail/submitSubject',
|
||||
|
||||
/**
|
||||
* 交卷
|
||||
*/
|
||||
submit: '/practice/detail/submit'
|
||||
}
|
||||
|
||||
export const ImgObj = {
|
||||
stop: 'https://img10.360buyimg.com/imagetools/jfs/t1/206561/1/10729/2819/619f783cE77dd49ed/54eb1fc4b3144a97.png',
|
||||
run: 'https://img11.360buyimg.com/imagetools/jfs/t1/161735/6/25253/2598/619f783cEa897a673/fbf4e8c05d40feb5.png',
|
||||
info: 'https://img13.360buyimg.com/imagetools/jfs/t1/217399/4/5733/2641/619f7b91E0894649e/2f6353fe0d35fb46.png',
|
||||
questionMark:
|
||||
'https://img12.360buyimg.com/imagetools/jfs/t1/201809/8/16630/2674/61a04963E92475548/ede8a7f006113cae.png',
|
||||
mark: 'https://img12.360buyimg.com/imagetools/jfs/t1/207329/30/11079/2474/61a70ad0E64730d1c/ed75ee746fb33926.png',
|
||||
advanceTip:
|
||||
'https://img11.360buyimg.com/imagetools/jfs/t1/161028/16/25609/6746/61a08d83E06659dfa/e6418acdab948134.png'
|
||||
}
|
@@ -1,18 +1,19 @@
|
||||
import Timer from '@components/timerCom/FlipClock'
|
||||
import { getCurrentTime } from '@utils'
|
||||
import req from '@utils/request'
|
||||
import { Checkbox, Modal, Radio } from 'antd'
|
||||
import _ from 'lodash'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import PracticeAction from './components/practice-action'
|
||||
import PracticeAdvance from './components/practice-advance'
|
||||
import PracticePaging from './components/practice-paging'
|
||||
import { useNavigate, useParams } from 'react-router-dom'
|
||||
import PracticeAction from './components/practise-action'
|
||||
import PracticeAdvance from './components/practise-advance'
|
||||
import PracticePaging from './components/practise-paging'
|
||||
import { ApiName, ImgObj, quetionsType } from './constant'
|
||||
import './index.less'
|
||||
|
||||
const PracticeDetails = props => {
|
||||
const navigate = useNavigate()
|
||||
|
||||
const { setId } = useParams()
|
||||
const [isMark, setIsMark] = useState(0) // 是否标记
|
||||
const [currentActive, setCurrentActive] = useState('')
|
||||
const [subjectList, setSubjectList] = useState([])
|
||||
@@ -20,13 +21,15 @@ const PracticeDetails = props => {
|
||||
const [currentIndex, setCurrentIndex] = useState(0)
|
||||
const [isShowAdvanOverceBox, setIsShowAdvanOverceBox] = useState(false)
|
||||
const [isShowStopBox, setIsShowStopBox] = useState(false)
|
||||
const [subjectInfo, setSubjectInfo] = useState({
|
||||
practiceId: null,
|
||||
subjectTitle: '热门题目练习',
|
||||
singleLength: 0,
|
||||
multipleLength: 0,
|
||||
judgeLength: 0
|
||||
})
|
||||
|
||||
const timerRef = React.createRef()
|
||||
let subjectTitle = ''
|
||||
let singleLength = 0
|
||||
let multipleLength = 0
|
||||
let judgeLength = 0
|
||||
const setId = ''
|
||||
|
||||
const isLast = currentIndex === subjectList?.length - 1
|
||||
|
||||
@@ -35,49 +38,30 @@ const PracticeDetails = props => {
|
||||
*/
|
||||
const getSubjectList = () => {
|
||||
let params = {
|
||||
setId: setId
|
||||
setId
|
||||
}
|
||||
subjectTitle = '热门题目练习'
|
||||
singleLength = 1
|
||||
multipleLength = 1
|
||||
judgeLength = 1
|
||||
const list = [
|
||||
req(
|
||||
{
|
||||
subjectType: 1,
|
||||
subjectId: 1,
|
||||
active: true
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: ApiName.getSubjects
|
||||
},
|
||||
{
|
||||
subjectType: 2,
|
||||
subjectId: 2
|
||||
},
|
||||
{
|
||||
subjectType: 3,
|
||||
subjectId: 3
|
||||
}
|
||||
]
|
||||
setSubjectList([...list])
|
||||
// _.set(list, [0, 'active'], true)
|
||||
getPracticeSubject(list[0], list, 0, [])
|
||||
// req({
|
||||
// method: 'post',
|
||||
// data: params,
|
||||
// url: ApiName.getSubjects
|
||||
// })
|
||||
// .then(res => {
|
||||
// if (res.data && res.data?.subjectList?.length > 0) {
|
||||
// let list = res.data.subjectList
|
||||
// singleLength =
|
||||
// list?.length > 0 ? list.filter(item => item.subjectType === 1).length : 0
|
||||
// multipleLength =
|
||||
// list?.length > 0 ? list.filter(item => item.subjectType === 2).length : 0
|
||||
// judgeLength =
|
||||
// list?.length > 0 ? list.filter(item => item.subjectType === 3).length : 0
|
||||
// subjectTitle = res.data?.title || '' // 总题目列表
|
||||
// getPracticeSubject(list[0], list, 0, [])
|
||||
// }
|
||||
// })
|
||||
// .catch(err => console.log(err))
|
||||
'/practice'
|
||||
)
|
||||
.then(res => {
|
||||
if (res.data && res.data?.subjectList?.length > 0) {
|
||||
const { subjectList, title, practiceId } = res.data
|
||||
setSubjectInfo({
|
||||
practiceId,
|
||||
subjectTitle: title,
|
||||
singleLength: subjectList.filter(item => item.subjectType === 1).length,
|
||||
multipleLength: subjectList.filter(item => item.subjectType === 2).length,
|
||||
judgeLength: subjectList.filter(item => item.subjectType === 3).length
|
||||
})
|
||||
getPracticeSubject(subjectList[0], subjectList, 0, [])
|
||||
}
|
||||
})
|
||||
.catch(err => console.log(err))
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
@@ -98,55 +82,18 @@ const PracticeDetails = props => {
|
||||
subjectId: item.subjectId,
|
||||
subjectType: item.subjectType
|
||||
}
|
||||
|
||||
const optionList =
|
||||
item.subjectType === 3
|
||||
? [
|
||||
{
|
||||
optionContent: '正确',
|
||||
optionType: 1
|
||||
},
|
||||
{
|
||||
optionContent: '错误',
|
||||
optionType: 0
|
||||
}
|
||||
]
|
||||
: [
|
||||
{
|
||||
optionType: 1,
|
||||
optionContent: '<p>题目答案1</p>'
|
||||
},
|
||||
{
|
||||
optionType: 2,
|
||||
optionContent: '<p>题目答案2</p>'
|
||||
},
|
||||
{
|
||||
optionType: 3,
|
||||
optionContent: '<p>题目答案3</p>'
|
||||
}
|
||||
]
|
||||
setCurrentActive(item.subjectType === 2 ? activeList : activeList[0])
|
||||
setCurrentIndex(index)
|
||||
setSubjectObject({
|
||||
subjectName: '题干内容',
|
||||
subjectType: item.subjectType,
|
||||
optionList,
|
||||
// subjectList: subjectList,
|
||||
// currentIndex: index,
|
||||
// currentActive: item.sub??jectType === 2 ? activeList : activeList[0],
|
||||
isMark: isMark
|
||||
})
|
||||
|
||||
return
|
||||
req({
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: ApiName.getPracticeSubject
|
||||
})
|
||||
req(
|
||||
{
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: ApiName.getPracticeSubject
|
||||
},
|
||||
'/practice'
|
||||
)
|
||||
.then(res => {
|
||||
if (res.data) {
|
||||
let subjectObject = res.data
|
||||
if (item.subjectType === 3) {
|
||||
if (subjectObject.subjectType === 3) {
|
||||
subjectObject.optionList = [
|
||||
{
|
||||
optionContent: '正确',
|
||||
@@ -158,13 +105,10 @@ const PracticeDetails = props => {
|
||||
}
|
||||
]
|
||||
}
|
||||
setState({
|
||||
subjectObject: res.data,
|
||||
subjectList: subjectList,
|
||||
currentIndex: index,
|
||||
currentActive: item.subjectType === 2 ? activeList : activeList[0],
|
||||
isMark: isMark
|
||||
})
|
||||
setCurrentActive(subjectObject.subjectType === 2 ? activeList : activeList[0])
|
||||
setCurrentIndex(index)
|
||||
setSubjectObject({ ...subjectObject, isMark })
|
||||
setSubjectList(subjectList)
|
||||
}
|
||||
})
|
||||
.catch(err => console.log(err))
|
||||
@@ -188,7 +132,6 @@ const PracticeDetails = props => {
|
||||
* @returns
|
||||
*/
|
||||
const onChangeCheck = e => {
|
||||
// let { currentIndex, subjectList } = state
|
||||
const list = [...subjectList]
|
||||
_.set(list, [currentIndex, 'activeList'], e)
|
||||
setCurrentActive(e)
|
||||
@@ -199,7 +142,6 @@ const PracticeDetails = props => {
|
||||
* 暂停计时
|
||||
*/
|
||||
const onChangeStop = () => {
|
||||
// setState({ isShowStopBox: true })
|
||||
setIsShowStopBox(true)
|
||||
timerRef.current.stop()
|
||||
}
|
||||
@@ -237,43 +179,28 @@ const PracticeDetails = props => {
|
||||
*/
|
||||
const onChangeOver = () => {
|
||||
timerRef.current.end()
|
||||
navigate('/practice-analytic/1', { replace: true })
|
||||
// const list = [...subjectList]
|
||||
// let answerDetails = []
|
||||
// list.forEach(item => {
|
||||
// let obj = {
|
||||
// subjectId: item.subjectId,
|
||||
// subjectType: item.subjectType,
|
||||
// answerContents: []
|
||||
// }
|
||||
// if (item?.activeList && item?.activeList?.length > 0) {
|
||||
// obj.answerContents = item.activeList
|
||||
// }
|
||||
// answerDetails.push(obj)
|
||||
// })
|
||||
// let params = {
|
||||
// setId: setId,
|
||||
// timeUse: timerRef.current.getUseTime(),
|
||||
// submitTime: getCurrentTime(),
|
||||
// answerDetails: answerDetails
|
||||
// }
|
||||
// req({
|
||||
// method: 'post',
|
||||
// data: params,
|
||||
// url: ApiName.submitSubject
|
||||
// })
|
||||
// .then(res => {
|
||||
// if (res.data && res.data.practiceId) {
|
||||
// //关闭定时器
|
||||
// timerRef.current.end()
|
||||
// props.history.replace(
|
||||
// splicingQuery('/practice-analytic', {
|
||||
// practiceId: res.data.practiceId
|
||||
// })
|
||||
// )
|
||||
// }
|
||||
// })
|
||||
// .catch(err => console.log(err))
|
||||
let params = {
|
||||
setId,
|
||||
practiceId: subjectInfo.practiceId,
|
||||
timeUse: timerRef.current.getUseTime(),
|
||||
submitTime: getCurrentTime()
|
||||
}
|
||||
req(
|
||||
{
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: ApiName.submit
|
||||
},
|
||||
'/practice'
|
||||
)
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
//关闭定时器
|
||||
timerRef.current.end()
|
||||
navigate('/practise-analytic/' + subjectInfo.practiceId, { replace: true })
|
||||
}
|
||||
})
|
||||
.catch(err => console.log(err))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,8 +215,6 @@ const PracticeDetails = props => {
|
||||
*/
|
||||
const onHandleCancelModal = () => {
|
||||
setIsShowAdvanOverceBox(false)
|
||||
|
||||
// setState({ isShowAdvanOverceBox: false })
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -297,9 +222,6 @@ const PracticeDetails = props => {
|
||||
*/
|
||||
const onChangeAdvanceOver = () => {
|
||||
setIsShowAdvanOverceBox(true)
|
||||
// setState({
|
||||
// isShowAdvanOverceBox: true
|
||||
// })
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,8 +229,28 @@ const PracticeDetails = props => {
|
||||
* @returns
|
||||
*/
|
||||
const onChangeNext = () => {
|
||||
// let { currentIndex } = state
|
||||
// currentIndex += 1
|
||||
console.log(subjectList)
|
||||
const { subjectId, subjectType, activeList } = subjectList[currentIndex]
|
||||
|
||||
let params = {
|
||||
practiceId: subjectInfo.practiceId,
|
||||
timeUse: timerRef.current.getUseTime(),
|
||||
subjectId: subjectId,
|
||||
subjectType: subjectType,
|
||||
answerContents: activeList
|
||||
}
|
||||
req(
|
||||
{
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: ApiName.submitSubject
|
||||
},
|
||||
'/practice'
|
||||
)
|
||||
.then(res => {
|
||||
console.log(res)
|
||||
})
|
||||
.catch(err => console.log(err))
|
||||
setCurrentIndex(currentIndex + 1)
|
||||
changeData(currentIndex + 1)
|
||||
}
|
||||
@@ -318,7 +260,6 @@ const PracticeDetails = props => {
|
||||
* @param {*} index 当前点击下标
|
||||
*/
|
||||
const changeData = index => {
|
||||
// let { subjectList } = state
|
||||
const list = [...subjectList]
|
||||
let subObj = list[index]
|
||||
let activeList = [] // 多选 选中的答案项
|
||||
@@ -349,14 +290,12 @@ const PracticeDetails = props => {
|
||||
const onChangeSubmitModal = () => {
|
||||
timerRef.current.run()
|
||||
setIsShowStopBox(false)
|
||||
// setState({ isShowStopBox: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停弹框-再次再做
|
||||
*/
|
||||
const onChangeCancelModal = () => {
|
||||
// props.history.goBack()
|
||||
navigate(-1)
|
||||
}
|
||||
|
||||
@@ -367,7 +306,7 @@ const PracticeDetails = props => {
|
||||
<div className='details-container'>
|
||||
<div className='container-box'>
|
||||
<div className='container-box-title'>
|
||||
<div className='title-title'>{subjectTitle}</div>
|
||||
<div className='title-title'>{subjectInfo.subjectTitle}</div>
|
||||
<div className='title-time'>
|
||||
<div className='title-timer-img' onClick={onChangeStop}>
|
||||
<img src={isShowStopBox ? ImgObj.stop : ImgObj.run} className='title-timer-icon' />
|
||||
@@ -453,9 +392,9 @@ const PracticeDetails = props => {
|
||||
<PracticePaging
|
||||
subjectList={subjectList}
|
||||
onHandlePaging={onChangePaging}
|
||||
singleLength={singleLength}
|
||||
multipleLength={multipleLength}
|
||||
judgeLength={judgeLength}
|
||||
singleLength={subjectInfo.singleLength}
|
||||
multipleLength={subjectInfo.multipleLength}
|
||||
judgeLength={subjectInfo.judgeLength}
|
||||
/>
|
||||
</div>
|
||||
<PracticeAdvance
|
@@ -85,7 +85,7 @@ class FrontEnd extends Component {
|
||||
.then(res => {
|
||||
if (res.data) {
|
||||
this.props.history.push(
|
||||
splicingQuery('/practice-details', {
|
||||
splicingQuery('/practise-details', {
|
||||
setId: res.data.setId
|
||||
})
|
||||
)
|
@@ -0,0 +1,4 @@
|
||||
.bottom-btn {
|
||||
text-align: right;
|
||||
margin-top: 50px;
|
||||
}
|
@@ -0,0 +1,138 @@
|
||||
import req from '@utils/request'
|
||||
import { Button, Card, Checkbox, Descriptions } from 'antd'
|
||||
import type { CardTabListType } from 'antd/es/card'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import './index.less'
|
||||
const apiName = {
|
||||
/**
|
||||
* 查询专项练习
|
||||
*/
|
||||
getSpecialPracticeContent: '/practice/set/getSpecialPracticeContent',
|
||||
|
||||
/**
|
||||
* 开始练习
|
||||
*/
|
||||
addPractice: 'practice/set/addPractice'
|
||||
}
|
||||
|
||||
const PracticeHome = () => {
|
||||
const navigate = useNavigate()
|
||||
|
||||
const [primaryList, setPrimaryList] = useState<CardTabListType[]>([])
|
||||
const [dataList, setDataList] = useState([])
|
||||
const [currentCateId, setCurrentCateId] = useState()
|
||||
const [checkedInfo, setCheckedInfo] = useState({})
|
||||
|
||||
const getContent = () => {
|
||||
req(
|
||||
{
|
||||
method: 'post',
|
||||
url: apiName.getSpecialPracticeContent
|
||||
},
|
||||
'/practice'
|
||||
).then((res: any) => {
|
||||
if (res.success && res.data) {
|
||||
setPrimaryList(
|
||||
res.data.map(t => ({ tab: t.primaryCategoryName, key: t.primaryCategoryId }))
|
||||
)
|
||||
setDataList(
|
||||
res.data[0].categoryList.map(item => {
|
||||
return {
|
||||
...item,
|
||||
children: item.labelList.map(t => ({ label: t.labelName, value: t.assembleId }))
|
||||
}
|
||||
})
|
||||
)
|
||||
setCurrentCateId(res.data[0].primaryCategoryId)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getContent()
|
||||
}, [])
|
||||
|
||||
const onCheckAllChange = (e: any, categoryId: number) => {
|
||||
const checked = e.target.checked
|
||||
const checkedInfoNew = { ...checkedInfo }
|
||||
checkedInfoNew[categoryId] = checked
|
||||
? dataList.filter(t => t.categoryId === categoryId)[0].children.map(t => t.value)
|
||||
: []
|
||||
setCheckedInfo({ ...checkedInfoNew })
|
||||
}
|
||||
|
||||
const changeItem = (id, value) => {
|
||||
setCheckedInfo({
|
||||
...checkedInfo,
|
||||
[id]: value
|
||||
})
|
||||
}
|
||||
|
||||
const startPractice = () => {
|
||||
console.log(checkedInfo)
|
||||
const params = {
|
||||
assembleIds: Object.values(checkedInfo).flat()
|
||||
}
|
||||
req(
|
||||
{
|
||||
method: 'post',
|
||||
url: apiName.addPractice,
|
||||
data: params
|
||||
},
|
||||
'/practice'
|
||||
).then(res => {
|
||||
if (res.success && res.data) {
|
||||
navigate('/practise-detail/' + res.data.setId)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Card tabList={primaryList}>
|
||||
{dataList.map((item: { categoryName: string; categoryId: number; children: any[] }) => {
|
||||
return (
|
||||
<Descriptions
|
||||
title={item.categoryName}
|
||||
extra={
|
||||
<Checkbox
|
||||
onChange={e => onCheckAllChange(e, item.categoryId)}
|
||||
checked={checkedInfo?.[item.categoryId]?.length === item.children.length}
|
||||
indeterminate={
|
||||
checkedInfo?.[item.categoryId]?.length > 0 &&
|
||||
checkedInfo?.[item.categoryId]?.length < item.children.length
|
||||
}
|
||||
>
|
||||
全选
|
||||
</Checkbox>
|
||||
}
|
||||
key={item.categoryId}
|
||||
>
|
||||
<Descriptions.Item>
|
||||
<Checkbox.Group
|
||||
value={checkedInfo[item.categoryId]}
|
||||
options={item.children}
|
||||
onChange={value => changeItem(item.categoryId, value)}
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
)
|
||||
})}
|
||||
</Card>
|
||||
<div className='bottom-btn'>
|
||||
<Button
|
||||
onClick={startPractice}
|
||||
type='primary'
|
||||
shape='round'
|
||||
size='large'
|
||||
disabled={Object.values(checkedInfo).flat().length === 0}
|
||||
>
|
||||
开始练习
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PracticeHome
|
@@ -1,8 +1,8 @@
|
||||
// import req from '@utils/request'
|
||||
import { Card, Input, Pagination, Spin, Tooltip } from 'antd'
|
||||
import React, { useState } from 'react'
|
||||
import req from '@utils/request'
|
||||
import { Card, Empty, Input, Pagination, Spin, Tooltip } from 'antd'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import './index.less'
|
||||
|
||||
const { Search } = Input
|
||||
@@ -23,53 +23,51 @@ const tabList = [
|
||||
]
|
||||
|
||||
const PaperView = props => {
|
||||
const { type } = props
|
||||
const navigate = useNavigate()
|
||||
|
||||
const [spinning, setSpinning] = useState(false)
|
||||
const [paperList, setPaperList] = useState([
|
||||
{
|
||||
setId: 1,
|
||||
setName: '测试试卷',
|
||||
setHeat: 1,
|
||||
setDesc: '描述'
|
||||
}
|
||||
])
|
||||
const [paperList, setPaperList] = useState([])
|
||||
const [orderType, setOrderType] = useState(0)
|
||||
const [setId, setSetId] = useState(0)
|
||||
const [pageInfo, setPageInfo] = useState({
|
||||
total: 0,
|
||||
pageIndex: 1
|
||||
})
|
||||
const [searchText, setSearchText] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
getPreSetContent()
|
||||
}, [props.type])
|
||||
|
||||
const getPreSetContent = () => {
|
||||
// const { menuId, menuType } = this.props
|
||||
// const { orderType, searchText } = this.state
|
||||
// let params = {
|
||||
// menuId: menuId,
|
||||
// menuType: menuType,
|
||||
// orderType: orderType,
|
||||
// pageInfo: {
|
||||
// pageIndex: this.pageIndex,
|
||||
// pageSize: 8
|
||||
// },
|
||||
// setName: searchText
|
||||
// }
|
||||
// req({
|
||||
// method: 'post',
|
||||
// data: params,
|
||||
// url: 'admin/practice/set/getPreSetContent'
|
||||
// })
|
||||
// .then(res => {
|
||||
// if (res.data.pageList && res.data.pageList?.length > 0) {
|
||||
// this.setState({
|
||||
// paperList: res.data.pageList,
|
||||
// total: res.data.pageInfo.total,
|
||||
// isShowSpin: false,
|
||||
// setId: res.data.pageList.setId
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// .catch(err => console.log(err))
|
||||
let api = '/practice/set/getPreSetContent'
|
||||
if (type === 'unfinish') {
|
||||
api = '/practice/set/getUnCompletePractice'
|
||||
}
|
||||
let params = {
|
||||
pageInfo: {
|
||||
pageNo: pageInfo.pageIndex,
|
||||
pageSize: 8
|
||||
}
|
||||
}
|
||||
req(
|
||||
{
|
||||
method: 'post',
|
||||
data: params,
|
||||
url: api
|
||||
},
|
||||
'/practice'
|
||||
)
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
setPageInfo({
|
||||
...pageInfo,
|
||||
total: res.data.total
|
||||
})
|
||||
setPaperList(res.data.result || [])
|
||||
}
|
||||
})
|
||||
.catch(err => console.log(err))
|
||||
}
|
||||
|
||||
const onTabChange = key => {
|
||||
@@ -83,7 +81,7 @@ const PaperView = props => {
|
||||
})
|
||||
}
|
||||
|
||||
const handleJump = setId => navigate('/practice-detail/' + setId)
|
||||
const handleJump = setId => navigate('/practise-detail/' + setId)
|
||||
|
||||
const onSearch = value => {
|
||||
setSearchText(value)
|
||||
@@ -108,7 +106,7 @@ const PaperView = props => {
|
||||
onTabChange={onTabChange}
|
||||
>
|
||||
<div className='ant-card-body'>
|
||||
{paperList?.length > 0 &&
|
||||
{paperList?.length > 0 ? (
|
||||
paperList.map((item, index) => {
|
||||
return (
|
||||
<div
|
||||
@@ -127,7 +125,10 @@ const PaperView = props => {
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
})
|
||||
) : (
|
||||
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
65
src/views/practise/practise-questions/index.tsx
Normal file
65
src/views/practise/practise-questions/index.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import type { GetProp, MenuProps } from 'antd'
|
||||
import { Menu } from 'antd'
|
||||
import { useState } from 'react'
|
||||
import FrontEnd from './components/front-end/index1'
|
||||
import PaperEnd from './components/paper-end'
|
||||
|
||||
import './index.less'
|
||||
|
||||
type MenuItem = GetProp<MenuProps, 'items'>[number]
|
||||
|
||||
function getItem(
|
||||
label: React.ReactNode,
|
||||
key?: React.Key | null,
|
||||
icon?: React.ReactNode,
|
||||
children?: MenuItem[]
|
||||
): MenuItem {
|
||||
return {
|
||||
key,
|
||||
icon,
|
||||
children,
|
||||
label
|
||||
} as MenuItem
|
||||
}
|
||||
|
||||
const PracticeQuestions = () => {
|
||||
const [selectKeys, setSelectKeys] = useState(['1'])
|
||||
|
||||
const menuItems = [
|
||||
getItem('专项练习', '1'),
|
||||
getItem('模拟套卷', '2', '', [getItem('后端', '2-1'), getItem('前端', '2-2')]),
|
||||
getItem('我未完成', '3')
|
||||
]
|
||||
|
||||
const clickMenu = ({ key }: { key: string }) => {
|
||||
setSelectKeys([key])
|
||||
}
|
||||
|
||||
const renderPage = () => {
|
||||
const pageMap = {
|
||||
'1': <FrontEnd />,
|
||||
'2-1': <PaperEnd type='backend' />,
|
||||
'2-2': <PaperEnd />,
|
||||
'3': <PaperEnd type='unfinish' />
|
||||
}
|
||||
return pageMap[selectKeys[0]]
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='practice-questions-container'>
|
||||
<div className='practice-questions-menu'>
|
||||
<Menu
|
||||
style={{ width: 200 }}
|
||||
selectedKeys={selectKeys}
|
||||
defaultOpenKeys={['2']}
|
||||
mode='inline'
|
||||
items={menuItems}
|
||||
onClick={clickMenu}
|
||||
/>
|
||||
</div>
|
||||
<div className='practice-questions-box'>{renderPage()}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PracticeQuestions
|
@@ -8,12 +8,37 @@ import './index.less'
|
||||
|
||||
const { SubMenu } = Menu
|
||||
|
||||
function getItem(label, key, icon, children) {
|
||||
return {
|
||||
key,
|
||||
icon,
|
||||
children,
|
||||
label
|
||||
}
|
||||
}
|
||||
|
||||
export default class PracticeQuestions extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
currentKey: '', // 选中的menu
|
||||
subMenuList: []
|
||||
currentKey: '1', // 选中的menu
|
||||
subMenuList: [
|
||||
{
|
||||
title: '模拟套卷',
|
||||
menuId: '1',
|
||||
menuType: 1
|
||||
},
|
||||
{
|
||||
title: '模拟套卷',
|
||||
detailVOS: [
|
||||
{
|
||||
menuName: '后端',
|
||||
menuId: '10',
|
||||
menuType: 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +53,7 @@ export default class PracticeQuestions extends Component {
|
||||
currentKeyFirstMenuType = 1
|
||||
|
||||
componentDidMount() {
|
||||
this.getPracticeMenu()
|
||||
// this.getPracticeMenu()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,7 +148,7 @@ export default class PracticeQuestions extends Component {
|
||||
title={subMenuItem.title}
|
||||
icon={<MailOutlined />}
|
||||
>
|
||||
{subMenuItem?.detailVOS?.length > 0 &&
|
||||
{subMenuItem?.detailVOS?.length > 0 ? (
|
||||
subMenuItem?.detailVOS?.map(menuItem => {
|
||||
return (
|
||||
<Menu.Item key={menuItem.menuId}>
|
||||
@@ -131,7 +156,13 @@ export default class PracticeQuestions extends Component {
|
||||
{menuItem.menuName}
|
||||
</Menu.Item>
|
||||
)
|
||||
})}
|
||||
})
|
||||
) : (
|
||||
<Menu.Item key={subMenuItem.menuId}>
|
||||
{/* {subMenuItem.menuType == 1 ? 'GRADE ' : ''} */}
|
||||
{/* {subMenuItem.menuName} */}
|
||||
</Menu.Item>
|
||||
)}
|
||||
</SubMenu>
|
||||
)
|
||||
})}
|
@@ -22,7 +22,7 @@ const ContributionList = props => {
|
||||
url: apiName.getContributeList
|
||||
})
|
||||
.then(res => {
|
||||
if (res.data && res.data.length > 0) {
|
||||
if (res.success && res.data) {
|
||||
setLoading(false)
|
||||
setContributionList(res.data)
|
||||
} else {
|
||||
|
@@ -1,7 +1,6 @@
|
||||
import req from '@utils/request'
|
||||
import React, { Component, Fragment } from 'react'
|
||||
import { RankingType, apiName } from '../../constant'
|
||||
import { mockRankingModuleList } from '../../mock'
|
||||
import RankingBox from '../ranking-box'
|
||||
// import {} from 'react-router-dom'
|
||||
|
||||
@@ -9,26 +8,29 @@ class PracticeList extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
contributionList: mockRankingModuleList[0].rankingList,
|
||||
contributionList: [],
|
||||
contributeType: 0,
|
||||
isLoading: false
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// this.getPracticeRankList()
|
||||
this.getPracticeRankList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得练习榜
|
||||
*/
|
||||
getPracticeRankList() {
|
||||
req({
|
||||
method: 'post',
|
||||
url: apiName.getPracticeRankList
|
||||
})
|
||||
req(
|
||||
{
|
||||
method: 'post',
|
||||
url: apiName.getPracticeRankList
|
||||
},
|
||||
'/practice'
|
||||
)
|
||||
.then(res => {
|
||||
if (res.data && res.data.length > 0) {
|
||||
if (res.success && res.data) {
|
||||
this.setState({
|
||||
contributionList: res.data,
|
||||
isLoading: false
|
||||
@@ -58,7 +60,7 @@ class PracticeList extends Component {
|
||||
* 去练题
|
||||
*/
|
||||
onChangeJump = () => {
|
||||
window.open('/practice-questions', '_blank')
|
||||
window.open('/practise-questions', '_blank')
|
||||
}
|
||||
|
||||
render() {
|
@@ -50,6 +50,8 @@ export default function RankingBox(props) {
|
||||
// 获得当前下标的数据
|
||||
let rankingList = contributionList || []
|
||||
|
||||
console.log(rankingList, 'rank list ')
|
||||
|
||||
return (
|
||||
<div className='ranking-list-box'>
|
||||
<div className='ranking-list-header'>
|
||||
|
@@ -13,9 +13,12 @@ export const apiName = {
|
||||
getSubjectPage: '/getSubjectPage',
|
||||
|
||||
/**
|
||||
* 练题排行榜
|
||||
* 贡献榜
|
||||
*/
|
||||
getContributeList: '/getContributeList'
|
||||
getContributeList: '/getContributeList',
|
||||
|
||||
// 练题榜
|
||||
getPracticeRankList: '/practice/detail/getPracticeRankList'
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -4,7 +4,7 @@ import QuestionList from '@components/question-list'
|
||||
import req from '@utils/request'
|
||||
import { memo, useEffect, useState } from 'react'
|
||||
import ContributionList from './components/contribution-list'
|
||||
import PracticeList from './components/practice-list'
|
||||
import PracticeList from './components/practise-list'
|
||||
import { apiName } from './constant'
|
||||
import './index.less'
|
||||
|
||||
|
@@ -44,6 +44,10 @@ export default ({ mode }) => {
|
||||
'/oss': {
|
||||
target: env.VITE_API_HOST,
|
||||
changeOrigin: true
|
||||
},
|
||||
'/practice': {
|
||||
target: env.VITE_API_HOST,
|
||||
changeOrigin: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user