Commit 67805b6b by zhanghaozhe

ai测试

parent d1908c5b
...@@ -6282,7 +6282,8 @@ ...@@ -6282,7 +6282,8 @@
}, },
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"bundled": true "bundled": true,
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
...@@ -6300,11 +6301,13 @@ ...@@ -6300,11 +6301,13 @@
}, },
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true "bundled": true,
"optional": true
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
...@@ -6317,15 +6320,18 @@ ...@@ -6317,15 +6320,18 @@
}, },
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true "bundled": true,
"optional": true
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"bundled": true "bundled": true,
"optional": true
}, },
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true "bundled": true,
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
...@@ -6428,7 +6434,8 @@ ...@@ -6428,7 +6434,8 @@
}, },
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"bundled": true "bundled": true,
"optional": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
...@@ -6438,6 +6445,7 @@ ...@@ -6438,6 +6445,7 @@
"is-fullwidth-code-point": { "is-fullwidth-code-point": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
...@@ -6450,17 +6458,20 @@ ...@@ -6450,17 +6458,20 @@
"minimatch": { "minimatch": {
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
}, },
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true "bundled": true,
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.3.5", "version": "2.3.5",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
"yallist": "^3.0.0" "yallist": "^3.0.0"
...@@ -6477,6 +6488,7 @@ ...@@ -6477,6 +6488,7 @@
"mkdirp": { "mkdirp": {
"version": "0.5.1", "version": "0.5.1",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
} }
...@@ -6549,7 +6561,8 @@ ...@@ -6549,7 +6561,8 @@
}, },
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true "bundled": true,
"optional": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
...@@ -6559,6 +6572,7 @@ ...@@ -6559,6 +6572,7 @@
"once": { "once": {
"version": "1.4.0", "version": "1.4.0",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
...@@ -6634,7 +6648,8 @@ ...@@ -6634,7 +6648,8 @@
}, },
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"bundled": true "bundled": true,
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
...@@ -6664,6 +6679,7 @@ ...@@ -6664,6 +6679,7 @@
"string-width": { "string-width": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
...@@ -6681,6 +6697,7 @@ ...@@ -6681,6 +6697,7 @@
"strip-ansi": { "strip-ansi": {
"version": "3.0.1", "version": "3.0.1",
"bundled": true, "bundled": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
...@@ -6719,11 +6736,13 @@ ...@@ -6719,11 +6736,13 @@
}, },
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true "bundled": true,
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.0.3", "version": "3.0.3",
"bundled": true "bundled": true,
"optional": true
} }
} }
}, },
......
...@@ -3,7 +3,6 @@ import './index.scss' ...@@ -3,7 +3,6 @@ import './index.scss'
import { HeaderBar } from "@common/index" import { HeaderBar } from "@common/index"
import Question from "@components/ai-test/common/question" import Question from "@components/ai-test/common/question"
import Navigation from "@components/ai-test/common/navigation" import Navigation from "@components/ai-test/common/navigation"
import { withRouter, Link } from "react-router-dom";
import { html, http } from "@/utils" import { html, http } from "@/utils"
import { Toast } from "antd-mobile"; import { Toast } from "antd-mobile";
import Recommends from '@/components/ai-test/common/recommends' import Recommends from '@/components/ai-test/common/recommends'
...@@ -16,7 +15,7 @@ class Analysis extends Component { ...@@ -16,7 +15,7 @@ class Analysis extends Component {
activeIndex: 0, activeIndex: 0,
userSelect: '', userSelect: '',
rightAnswer: '', rightAnswer: '',
recommends: [], userUnselect: false,
} }
componentDidMount() { componentDidMount() {
...@@ -29,14 +28,11 @@ class Analysis extends Component { ...@@ -29,14 +28,11 @@ class Analysis extends Component {
}).then(res => { }).then(res => {
const {code, msg, data} = res.data const {code, msg, data} = res.data
if (code === 200) { if (code === 200) {
this.getRecommends(data[0].type_id)
this.setState({ this.setState({
questions: data, questions: data,
}, () => { }, () => {
this.getAnswerInfo() this.getAnswerInfo()
}); });
} else { } else {
Toast.fail(msg, 2, null, false) Toast.fail(msg, 2, null, false)
} }
...@@ -51,6 +47,7 @@ class Analysis extends Component { ...@@ -51,6 +47,7 @@ class Analysis extends Component {
this.setState({ this.setState({
userSelect: String.fromCharCode(65 + userAnswerIndex), userSelect: String.fromCharCode(65 + userAnswerIndex),
rightAnswer: String.fromCharCode(65 + rightAnswerIndex), rightAnswer: String.fromCharCode(65 + rightAnswerIndex),
userUnselect: userAnswerIndex < 0,
}); });
} }
...@@ -60,24 +57,8 @@ class Analysis extends Component { ...@@ -60,24 +57,8 @@ class Analysis extends Component {
} }
} }
getRecommends = (typeId) => {
http.post(`${API.home}/sys/get_commend_course`, {
type_id: typeId,
}).then(res => {
const {code, msg, data} = res.data
if (code === 200) {
this.setState({
recommends: data,
})
} else {
Toast.fail(msg, 2, null, msg)
}
})
}
render() { render() {
const {questions, activeIndex, userSelect, rightAnswer, recommends} = this.state const {questions, activeIndex, userSelect, rightAnswer, userUnselect} = this.state
return ( return (
<div className={'analysis-container'}> <div className={'analysis-container'}>
<HeaderBar title={'AI水平测试'} arrow={true}/> <HeaderBar title={'AI水平测试'} arrow={true}/>
...@@ -85,13 +66,14 @@ class Analysis extends Component { ...@@ -85,13 +66,14 @@ class Analysis extends Component {
!!questions.length && <Question activeIndex={activeIndex} question={questions[activeIndex]}/> !!questions.length && <Question activeIndex={activeIndex} question={questions[activeIndex]}/>
} }
<div style={{height: '8px', backgroundColor: '#f5f5f5'}}></div> <div style={{height: '8px', backgroundColor: '#f5f5f5'}}></div>
<Navigation questions={questions} isAnalysis={true} handleClick={(index) => {
this.setState({
activeIndex: index,
});
}}/>
<div className="analysis"> <div className="analysis">
<div className="info">您选择的是{userSelect},正确答案是{rightAnswer} 回答{userSelect === rightAnswer ? '正确' : '错误'}</div> {
userUnselect
? <div className={'info'}>您未作答</div>
: <div className="info">
您选择的是{userSelect},正确答案是{rightAnswer} 回答{userSelect === rightAnswer ? '正确' : '错误'}
</div>
}
<div className="content"> <div className="content">
<div className="head"> <div className="head">
<i className="icon"></i> <i className="icon"></i>
...@@ -106,9 +88,14 @@ class Analysis extends Component { ...@@ -106,9 +88,14 @@ class Analysis extends Component {
{ {
!!questions.length && questions[activeIndex].type_id && <Recommends typeId={questions[activeIndex].type_id}/> !!questions.length && questions[activeIndex].type_id && <Recommends typeId={questions[activeIndex].type_id}/>
} }
<Navigation questions={questions} isAnalysis={true} handleClick={(index) => {
this.setState({
activeIndex: index,
});
}}/>
</div> </div>
); );
} }
} }
export default withRouter(Analysis); export default Analysis;
\ No newline at end of file \ No newline at end of file
...@@ -4,9 +4,8 @@ import { HeaderBar } from "@common/index" ...@@ -4,9 +4,8 @@ import { HeaderBar } from "@common/index"
import Question from "@components/ai-test/common/question" import Question from "@components/ai-test/common/question"
import { html, http } from "@/utils" import { html, http } from "@/utils"
import { Toast } from "antd-mobile"; import { Toast } from "antd-mobile";
import { withRouter, Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { compose } from "redux";
import Recommends from "@components/ai-test/common/recommends" import Recommends from "@components/ai-test/common/recommends"
import classnames from 'classnames' import classnames from 'classnames'
...@@ -147,10 +146,7 @@ class Assist extends Component { ...@@ -147,10 +146,7 @@ class Assist extends Component {
} }
} }
export default compose( export default connect(
connect(
state => state.user, state => state.user,
null, null,
), )(Assist)
withRouter, \ No newline at end of file
)(Assist);
\ No newline at end of file
...@@ -8,11 +8,14 @@ const Navigation = ({questions, answer, handleClick, isAnalysis}) => { ...@@ -8,11 +8,14 @@ const Navigation = ({questions, answer, handleClick, isAnalysis}) => {
<ul> <ul>
{ {
!!questions.length && questions.map((item, index) => { !!questions.length && questions.map((item, index) => {
const userSelectIndex = item.options.findIndex(item => item.user_select)
const rightAnswerIndex = item.options.findIndex(item => item.is_ans)
return <li key={index} onClick={handleClick.bind(this, index)} return <li key={index} onClick={handleClick.bind(this, index)}
className={classnames({ className={classnames({
active: answer && answer[item.id], active: answer && answer[item.id],
correct: isAnalysis && item.options.some(item => item.is_ans && item.user_select), correct: isAnalysis && userSelectIndex === rightAnswerIndex,
error: isAnalysis && item.options.some(item => item.user_select && !item.is_ans), error: isAnalysis && userSelectIndex >= 0 && userSelectIndex !== rightAnswerIndex,
unselect: isAnalysis && userSelectIndex < 0,
})}>{index + 1}</li> })}>{index + 1}</li>
}) })
} }
......
...@@ -40,8 +40,13 @@ ...@@ -40,8 +40,13 @@
&.error { &.error {
border-color: #E64949; border-color: #E64949;
color: #fff;
background-color: #E64949;
}
&.unselect {
border: 1px solid #E64949;
color: #E64949; color: #E64949;
//background-color: #E64949;
} }
} }
} }
import React, { Component } from 'react'; import React, { Component } from 'react';
import './index.scss' import './index.scss'
import Question from '../common/question' import Question from '../common/question'
import { HeaderBar } from "@common/index"
import { browser, getParam, http } from "@/utils" import { browser, getParam, http } from "@/utils"
import { Toast } from 'antd-mobile' import { Toast } from 'antd-mobile'
import { withRouter } from 'react-router-dom'
import storage from 'store2' import storage from 'store2'
import Navigation from "@components/ai-test/common/navigation" import Navigation from "@components/ai-test/common/navigation"
import { differenceInSeconds, differenceInMinutes, differenceInHours, differenceInDays, lightFormat } from "date-fns";
import { isEmpty } from 'lodash'
class Exam extends Component { class Exam extends Component {
...@@ -18,42 +19,47 @@ class Exam extends Component { ...@@ -18,42 +19,47 @@ class Exam extends Component {
questions: [], questions: [],
activeQuestion: 0, activeQuestion: 0,
time: { time: {
d: 0,
h: 0, h: 0,
m: 0, m: 0,
s: 0, s: 0,
}, },
elapsed: 0,
answer: {}, answer: {},
recordId: undefined, recordId: undefined,
} }
componentDidMount() { componentDidMount() {
if (this.store.get('submitted')) {
this.store.remove('submitted')
this.props.history.replace('/ai-test')
}
this.getQuestions() this.getQuestions()
this.unlisten = this.props.history.listen((location, action) => { this.unlisten = this.props.history.listen((location, action) => {
if (action === 'POP' && location.pathname === '/ai-test/scores') { if (action === 'POP') {
this.unlisten()
this.store.clearAll() this.store.clearAll()
} }
this.unlisten()
}) })
} }
componentWillUnmount() {
clearInterval(this.timer)
}
setCounter = () => { setCounter = () => {
this.timer = setInterval(() => { this.timer = setInterval(() => {
this.setState(state => { this.setState(state => {
const time = state.time const s = state.elapsed + 1
if (time.s + 1 >= 60) {
time.s = 0
if (time.m + 1 >= 60) {
time.h = time.h + 1
time.m = 0
} else {
time.m = time.m + 1
}
} else {
time.s = time.s + 1
}
return { return {
time, time: {
d: Math.floor(s / (60 * 60 * 24)),
h: Math.floor(s / (60 * 60)) % 24,
m: Math.floor(s / 60) % 60,
s: s % 60,
},
elapsed: s,
} }
}) })
}, 1000) }, 1000)
...@@ -78,23 +84,18 @@ class Exam extends Component { ...@@ -78,23 +84,18 @@ class Exam extends Component {
.then(res => { .then(res => {
const {code, msg, data} = res.data const {code, msg, data} = res.data
if (code === 200) { if (code === 200) {
let answer = this.store.get('answer') || {}, time = this.store.get('time') let answer = this.store.get('answer') || {}
if (!answer) { if (isEmpty(answer)) {
data.forEach(item => { data.forEach(item => {
answer[item.id] = undefined answer[item.id] = 0
}) })
} }
if (!time) {
time = {h: 0, m: 0, s: 0}
}
this.setState({ this.setState({
questions: data, questions: data,
answer, answer,
time,
recordId: data[0].record_id, recordId: data[0].record_id,
}) })
this.getStartTime(data[0].create_time)
this.setCounter() this.setCounter()
} else if (code === 23007) { } else if (code === 23007) {
this.props.history.replace('/ai-test/scores') this.props.history.replace('/ai-test/scores')
...@@ -104,6 +105,20 @@ class Exam extends Component { ...@@ -104,6 +105,20 @@ class Exam extends Component {
}) })
} }
getStartTime = (timestamp) => {
const now = new Date()
const createTime = new Date(timestamp * 1000)
this.setState({
time: {
d: differenceInDays(now, createTime),
h: differenceInHours(now, createTime) % 24,
m: differenceInMinutes(now, createTime) % 60,
s: differenceInSeconds(now, createTime) % 60,
},
elapsed: differenceInSeconds(now, createTime),
});
}
selectAnswer = (question, optionId) => { selectAnswer = (question, optionId) => {
this.setState(state => { this.setState(state => {
const answer = state.answer const answer = state.answer
...@@ -116,13 +131,18 @@ class Exam extends Component { ...@@ -116,13 +131,18 @@ class Exam extends Component {
const keys = Object.keys(answer) const keys = Object.keys(answer)
const values = Object.values(answer) const values = Object.values(answer)
if (keys.length === questions.length && values.every(item => item)) { if (keys.length === questions.length && values.every(item => item)) {
this.storeData()
}
})
}
storeData = () => {
const {answer, time, recordId, elapsed} = this.state
const {history} = this.props const {history} = this.props
clearInterval(this.timer) clearInterval(this.timer)
const {time, answer, recordId} = this.state this.store.setAll({time, answer, recordId, elapsed})
this.store.setAll({time, answer, recordId})
history.push('/ai-test/submit') history.push('/ai-test/submit')
}
})
} }
render() { render() {
...@@ -137,13 +157,32 @@ class Exam extends Component { ...@@ -137,13 +157,32 @@ class Exam extends Component {
<i className={'iconfont iconzhong'}></i> <i className={'iconfont iconzhong'}></i>
<span> <span>
{ {
!!time.d && time.d
}
{
!!time.h && <>{time.h && time.h.toString().padStart(2, '0')}:</>
}
{time.m.toString().padStart(2, '0')}:
{time.s.toString().padStart(2, '0')}
</span>
</div>
{/*
<div className="time">
<i className={'iconfont iconzhong'}></i>
<span>
{
!!time.d && time.d
}
{
!!time.h && <>{time.h && time.h.toString().padStart(2, '0')}:</> !!time.h && <>{time.h && time.h.toString().padStart(2, '0')}:</>
} }
{time.m.toString().padStart(2, '0')}: {time.m.toString().padStart(2, '0')}:
{time.s.toString().padStart(2, '0')} {time.s.toString().padStart(2, '0')}
</span> </span>
</div> </div>
<div className="count">{Object.values(answer).filter(item => item).length}/{questions.length}</div> */}
<div className="count"
onClick={this.storeData}>{Object.values(answer).filter(item => item).length}/{questions.length}</div>
</header> </header>
<div className="banner"> <div className="banner">
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/ai-test/m/scores/exam-banner.png" alt=""/> <img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/ai-test/m/scores/exam-banner.png" alt=""/>
...@@ -151,7 +190,8 @@ class Exam extends Component { ...@@ -151,7 +190,8 @@ class Exam extends Component {
<div className="question-section"> <div className="question-section">
{ {
!!questions.length && !!questions.length &&
<Question activeIndex={activeQuestion} question={questions[activeQuestion]} selectAnswer={this.selectAnswer} answer={answer}></Question> <Question activeIndex={activeQuestion} question={questions[activeQuestion]} selectAnswer={this.selectAnswer}
answer={answer}></Question>
} }
</div> </div>
<Navigation questions={questions} answer={answer} handleClick={(index) => { <Navigation questions={questions} answer={answer} handleClick={(index) => {
...@@ -164,4 +204,4 @@ class Exam extends Component { ...@@ -164,4 +204,4 @@ class Exam extends Component {
} }
} }
export default withRouter(Exam); export default Exam;
\ No newline at end of file \ No newline at end of file
...@@ -4,29 +4,23 @@ import { Switch, Route } from 'react-router-dom' ...@@ -4,29 +4,23 @@ import { Switch, Route } from 'react-router-dom'
import Scores from './scores' import Scores from './scores'
import Exam from './exam' import Exam from './exam'
import SubmitAnswer from "@components/ai-test/submit-answer" import SubmitAnswer from "@components/ai-test/submit-answer"
import Parse from "@components/ai-test/analysis" import Analysis from "@components/ai-test/analysis"
import Assist from "@components/ai-test/assist" import Assist from "@components/ai-test/assist"
import Help from '@components/ai-test/share'
import Report from '@components/ai-test/report'
class AiTest extends Component { class AiTest extends Component {
render() { render() {
const {match} = this.props const {match} = this.props
return ( return (
<Switch> <Switch>
<Route path={`${match.path}/scores`}> <Route path={`${match.path}/exam`} render={props => <Exam {...props}/>}/>
<Scores/> <Route path={`${match.path}/submit`} render={props => <SubmitAnswer {...props}/>}/>
</Route> <Route path={`${match.path}/analysis/:recordId`} render={props => <Analysis {...props}/>}/>
<Route path={`${match.path}/exam`}> <Route path={`${match.path}/assist/:assistCode`} render={props => <Assist {...props}/>}/>
<Exam/> <Route path={`${match.path}/share`} render={props => <Help {...props}/>}/>
</Route> <Route path={`${match.path}/report`} render={props => <Report {...props}/>}/>
<Route path={`${match.path}/submit`}> <Route render={(props) => <Scores {...props}/>}/>
<SubmitAnswer/>
</Route>
<Route path={`${match.path}/parse/:recordId`}>
<Parse/>
</Route>
<Route path={`${match.path}/assist/:assistCode`}>
<Assist/>
</Route>
</Switch> </Switch>
); );
} }
......
...@@ -5,7 +5,7 @@ import { http } from "@/utils" ...@@ -5,7 +5,7 @@ import { http } from "@/utils"
import storage from 'store2' import storage from 'store2'
import { html } from '@/utils' import { html } from '@/utils'
import { compareDesc } from "date-fns"; import { compareDesc } from "date-fns";
import { withRouter, Link } from "react-router-dom"; import { Link } from "react-router-dom";
class Scores extends Component { class Scores extends Component {
...@@ -161,7 +161,7 @@ class Scores extends Component { ...@@ -161,7 +161,7 @@ class Scores extends Component {
isShowUserAddress, isShowUserAddress,
userAddress, userAddress,
} = this.state } = this.state
const _rankList = isExpandRankList ? rankList : rankList.slice(0, 10) const _rankList = Array.isArray(rankList) ? isExpandRankList ? rankList : rankList.slice(0, 10) : []
return ( return (
<div className={'scores'}> <div className={'scores'}>
<div className="banner"> <div className="banner">
...@@ -176,7 +176,7 @@ class Scores extends Component { ...@@ -176,7 +176,7 @@ class Scores extends Component {
}}>规则</a> }}>规则</a>
</div> </div>
{ {
!!userScore.r_id && userScore.rank !== '-' &&
<div className="score-list"> <div className="score-list">
<Tabs tabs={tabs} tabBarUnderlineStyle={{display: 'none'}} onChange={(tab, i) => { <Tabs tabs={tabs} tabBarUnderlineStyle={{display: 'none'}} onChange={(tab, i) => {
this.getUserScores(i) this.getUserScores(i)
...@@ -205,7 +205,7 @@ class Scores extends Component { ...@@ -205,7 +205,7 @@ class Scores extends Component {
} }
</Tabs> </Tabs>
<div className="share"> <div className="share">
<a href="javascript:void(0);">分享</a> <Link to={'/ai-test/report'}>分享</Link>
</div> </div>
</div> </div>
} }
...@@ -294,7 +294,9 @@ class Scores extends Component { ...@@ -294,7 +294,9 @@ class Scores extends Component {
isShowRule: true, isShowRule: true,
}) })
}}>开始测试<span>(今日可测试{pageState.daily_test_num}次)</span></button> }}>开始测试<span>(今日可测试{pageState.daily_test_num}次)</span></button>
: <button className={'get-chance'}>获取测试机会<span>(今日可测试0次)</span></button> : <Link to={'/ai-test/share'}>
<button className={'get-chance'}>获取测试机会<span>(今日可测试0次)</span></button>
</Link>
: <button className={'unavailable'}>活动已结束</button> : <button className={'unavailable'}>活动已结束</button>
} }
</div> </div>
...@@ -353,4 +355,4 @@ function Rule({neverShow, isNeverShow, rule, close, startTest}) { ...@@ -353,4 +355,4 @@ function Rule({neverShow, isNeverShow, rule, close, startTest}) {
} }
export default withRouter(Scores); export default Scores;
\ No newline at end of file \ No newline at end of file
import React, {Component} from 'react' import React, {Component} from 'react'
import {CopyToClipboard} from 'react-copy-to-clipboard' import {CopyToClipboard} from 'react-copy-to-clipboard'
import {browser, http, getParam, wxShare} from '@/utils' import {browser, http, wxShare} from '@/utils'
import './index.scss' import './index.scss'
import {Toast} from "antd-mobile" import {Toast} from "antd-mobile"
class aiTestHelp extends Component { class aiTestHelp extends Component {
constructor(props) { constructor(props) {
......
...@@ -4,41 +4,91 @@ import { HeaderBar } from "@common/index" ...@@ -4,41 +4,91 @@ import { HeaderBar } from "@common/index"
import storage from 'store2' import storage from 'store2'
import { Toast } from "antd-mobile"; import { Toast } from "antd-mobile";
import { http } from "@/utils" import { http } from "@/utils"
import classnames from 'classnames'
import { Link } from "react-router-dom";
import { isEmpty } from 'lodash'
class SubmitAnswer extends Component { class SubmitAnswer extends Component {
store = storage.namespace('aiTestExam') store = storage.namespace('aiTestExam')
timer = null
state = { state = {
time: this.store.get('time') || {h: 0, m: 0, s: 0}, time: this.store.get('time') || {d: 0, h: 0, m: 0, s: 0},
answer: this.store.get('answer'), answer: this.store.get('answer'),
recordId: this.store.get('recordId'), recordId: this.store.get('recordId'),
analysis: [],
results: [],
elapsed: this.store.get('elapsed'),
}
componentDidMount() {
this.setCounter()
if (isEmpty(this.state.answer) || !this.state.recordId) {
this.props.history.replace('/ai-test')
}
}
componentWillUnmount() {
clearInterval(this.timer)
}
setCounter = () => {
this.timer = setInterval(() => {
this.setState(state => {
const s = state.elapsed + 1
return {
time: {
d: Math.floor(s / (60 * 60 * 24)),
h: Math.floor(s / (60 * 60)) % 24,
m: Math.floor(s / 60) % 60,
s: s % 60,
},
elapsed: s,
}
})
}, 1000)
} }
submit = () => { submit = () => {
const {answer, recordId} = this.state const {answer, recordId} = this.state
http.post(`${API.home}/sys/submit_answer`, { http.post(`${API.home}/sys/submit_answer`, {
answer: answer, answer: JSON.stringify(answer),
cost_time: this.getCostTime(), cost_time: this.state.elapsed,
record_id: recordId, record_id: recordId,
}).then(res => { }).then(res => {
const {code, msg, data} = res.data const {code, msg, data} = res.data
if (code === 200) { if (code === 200) {
this.store.clearAll() this.store.clearAll()
this.store.set('submitted', true)
clearInterval(this.timer)
this.getAnalysis()
} else { } else {
Toast.fail(msg, 2, null, false) Toast.fail(msg, 2, null, false)
} }
}) })
} }
getCostTime = () => { getAnalysis = () => {
const {time} = this.state http.post(`${API.home}/sys/get_analysis`, {
return parseInt(time.h) * 60 * 60 * 1000 + parseInt(time.m) * 60 * 1000 + parseInt(time.s) * 1000 record_id: this.state.recordId,
}).then(res => {
const {code, msg, data} = res.data
if (code === 200) {
this.setState({
analysis: data,
});
} else {
Toast.fail(msg, 2, null, false)
}
})
} }
render() { render() {
const {time, answer} = this.state const {time, answer, analysis, recordId} = this.state
return ( return (
<div className={'submit-answer'}> <div className={'submit-answer'}>
<HeaderBar title={'提交试卷'} arrow={true}/> <HeaderBar title={'提交试卷'} arrow={true}/>
...@@ -46,12 +96,40 @@ class SubmitAnswer extends Component { ...@@ -46,12 +96,40 @@ class SubmitAnswer extends Component {
<div className="cost">用时: <div className="cost">用时:
<span> <span>
{ {
!!time.d && time.d
}
{
!!time.h && <>{time.h && time.h.toString().padStart(2, '0')}:</> !!time.h && <>{time.h && time.h.toString().padStart(2, '0')}:</>
} }
{time.m.toString().padStart(2, '0')}: {time.m.toString().padStart(2, '0')}:
{time.s.toString().padStart(2, '0')} {time.s.toString().padStart(2, '0')}
</span> </span>
</div> </div>
{
analysis.length
? <>
<ul className={'answers'}>
{
analysis.map((item, index) => {
const userSelectIndex = item.options.findIndex(item => item.user_select)
const rightAnswerIndex = item.options.findIndex(item => item.is_ans)
return <li key={item.id}
className={classnames({
correct: userSelectIndex === rightAnswerIndex,
wrong: userSelectIndex >= 0 && userSelectIndex !== rightAnswerIndex,
unselect: userSelectIndex < 0,
})}>{index + 1}</li>
})
}
</ul>
{
!!analysis.length && <div className={'score'}>总分:{analysis[0].score}</div>
}
<Link to={`/ai-test/analysis/${recordId}`}>
<button>查看解析</button>
</Link>
</>
: <>
<ul className={'answers'}> <ul className={'answers'}>
{ {
answer && !!Object.keys(answer).length && Object.keys(answer).map((item, index) => { answer && !!Object.keys(answer).length && Object.keys(answer).map((item, index) => {
...@@ -60,6 +138,8 @@ class SubmitAnswer extends Component { ...@@ -60,6 +138,8 @@ class SubmitAnswer extends Component {
} }
</ul> </ul>
<button onClick={this.submit}>提交</button> <button onClick={this.submit}>提交</button>
</>
}
</div> </div>
</div> </div>
); );
......
...@@ -73,8 +73,32 @@ html, body { ...@@ -73,8 +73,32 @@ html, body {
background-color: #09f; background-color: #09f;
color: #fff; color: #fff;
} }
&.wrong {
background-color: #E64949;
border-color: #E64949;
color: #fff;
}
&.unselect {
border: 1px solid #E64949;
color: #E64949;
}
&.correct {
background-color: #2CDBAF;
border-color: #2CDBAF;
color: #fff;
} }
} }
}
.score {
margin-bottom: 30px;
font-size: 21px;
color: #09f;
text-align: center;
}
button { button {
width: 343px; width: 343px;
......
...@@ -335,14 +335,4 @@ export default [ ...@@ -335,14 +335,4 @@ export default [
path: '/ai-test', path: '/ai-test',
component: loadable(() => import('@/components/ai-test')), component: loadable(() => import('@/components/ai-test')),
}, },
// AI水平测试 成绩报告
{
path: '/scoreReport',
component: loadable(() => import('@/components/scoreReport'))
},
// AI水平测试 邀请好友助力
{
path: '/aiTestHelp',
component: loadable(() => import('@/components/aiTestHelp'))
}
] ]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment