feat: 调试练题

This commit is contained in:
秋水浮尘
2024-04-13 23:41:51 +08:00
parent 6734fa72b5
commit f84a199e5c
42 changed files with 734 additions and 1338 deletions

View File

@@ -13,7 +13,7 @@ const MENULIST = [
{
key: 'prictiseQuestion',
title: '练题',
route: '/practice-questions',
route: '/practise-questions',
finished: true
},
{

View File

@@ -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'))
}
]
}

View File

@@ -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

View File

@@ -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',
};

View File

@@ -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>
)
}
}

View File

@@ -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',
};

View File

@@ -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>
)
}
}

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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'
}

View 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

View File

@@ -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 {

View 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'
}

View File

@@ -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

View File

@@ -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
})
)

View File

@@ -0,0 +1,4 @@
.bottom-btn {
text-align: right;
margin-top: 50px;
}

View File

@@ -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

View File

@@ -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>

View 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

View File

@@ -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>
)
})}

View File

@@ -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 {

View File

@@ -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() {

View File

@@ -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'>

View File

@@ -13,9 +13,12 @@ export const apiName = {
getSubjectPage: '/getSubjectPage',
/**
* 练题排行
* 贡献
*/
getContributeList: '/getContributeList'
getContributeList: '/getContributeList',
// 练题榜
getPracticeRankList: '/practice/detail/getPracticeRankList'
}
/**

View File

@@ -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'

View File

@@ -44,6 +44,10 @@ export default ({ mode }) => {
'/oss': {
target: env.VITE_API_HOST,
changeOrigin: true
},
'/practice': {
target: env.VITE_API_HOST,
changeOrigin: true
}
}
}