Commit 5e276db1 by zhanghaozhe

ai测试

parent b6adfec5
......@@ -4479,9 +4479,9 @@
}
},
"date-fns": {
"version": "1.30.1",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
"integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw=="
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.14.0.tgz",
"integrity": "sha512-1zD+68jhFgDIM0rF05rcwYO8cExdNqxjq4xP1QKM60Q45mnO6zaMWB4tOzrIr4M4GSLntsKeE4c9Bdl2jhL/yw=="
},
"date-now": {
"version": "0.1.4",
......@@ -13976,6 +13976,11 @@
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
},
"store2": {
"version": "2.11.2",
"resolved": "https://registry.npmjs.org/store2/-/store2-2.11.2.tgz",
"integrity": "sha512-TQMKs+C6n9idtzLpxluikmDCYiDJrTbbIGn9LFxMg0BVTu+8JZKSlXTWYRpOFKlfKD5HlDWLVpJJyNGZ2e9l1A=="
},
"stream-browserify": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
......
......@@ -22,7 +22,7 @@
"case-sensitive-paths-webpack-plugin": "2.2.0",
"crypto-js": "^3.1.9-1",
"css-loader": "1.0.0",
"date-fns": "^1.30.1",
"date-fns": "^2.14.0",
"dotenv": "6.0.0",
"dotenv-expand": "4.2.0",
"eslint": "5.12.0",
......@@ -81,6 +81,7 @@
"sass-loader": "^7.1.0",
"sass-resources-loader": "^2.0.0",
"socket.io": "^2.2.0",
"store2": "^2.11.2",
"style-loader": "0.23.1",
"swiper": "^4.5.1",
"terser-webpack-plugin": "1.2.2",
......
import React, { Component } from 'react';
import './index.scss'
class Question extends Component {
state = {
selectedId: 0,
}
componentDidMount() {
}
componentDidUpdate(prevProps, prevState) {
if (prevProps.question.id !== this.props.question.id) {
this.setSelectedId()
}
}
setSelectedId = () => {
const {question} = this.props
if (question.selected) {
this.setState({
selectedId: question.selected,
})
}
}
handleSelect = option => {
this.props.selectAnswer(this.props.question, option.id)
this.setState({
selectedId: option.id,
})
}
render() {
const {selectedId} = this.state
const {question} = this.props
return (
<div className={'question-container'}>
<div className="question">{question.ques}</div>
<ul className={'options'}>
{
!!question.options.length && question.options.map((item, index) => {
return <li key={item.id} className={item.id === selectedId ? 'active' : ''}
onClick={this.handleSelect.bind(this, item)}>
<div className={'letter'}>{String.fromCharCode(65 + index)}</div>
<div>{item.des}</div>
</li>
})
}
</ul>
</div>
);
}
}
export default Question;
\ No newline at end of file
.question-container {
padding-bottom: 20px;
.question {
font-size: 16px;
color: #222;
margin-bottom: 21px;
padding: 0 17px;
}
.options {
li {
display: flex;
min-height: 48px;
padding: 0 17px;
align-items: center;
font-size: 16px;
color: #333;
margin-bottom: 12px;
&.active {
background: #F8F8FB;
.letter {
color: #09f;
border-color: #09f;
}
}
}
}
.letter {
flex: 0 0 auto;
width: 24px;
height: 24px;
margin-right: 13px;
border: 1px solid #999;
border-radius: 50%;
text-align: center;
line-height: 24px;
}
}
\ No newline at end of file
import React, { Component } from 'react';
import './index.scss'
import Question from '../common/question'
import { HeaderBar } from "@common/index"
import { browser, getParam, http } from "@/utils"
import { Toast } from 'antd-mobile'
import { withRouter } from 'react-router-dom'
import storage from 'store2'
class Exam extends Component {
store = storage.namespace('aiTestExam')
state = {
questions: [],
activeQuestion: 0,
time: {
h: 0,
m: 0,
s: 0,
},
}
componentDidMount() {
this.getQuestions()
this.setCounter()
}
setCounter = () => {
setInterval(() => {
this.setState(state => {
const time = state.time
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 {
time,
}
})
}, 1000)
}
goBack = () => {
const {state} = this.props.location
if (browser.isWeixin && getParam('code') && getParam('state')) {
window.history.go(-2)
}
if (state.records && state.records.length > 1) {
window.history.go(-1);
} else if (state.from && state.from.pathname) {
location.replace(`${state.from.pathname}${state.from.search}`)
} else {
window.location.href = window.location.origin
}
}
getQuestions = () => {
http.get(`${API.home}/sys/get_question`)
.then(res => {
const {code, msg, data} = res.data
if (code === 200) {
this.setState({
questions: data,
})
} else {
Toast.fail(msg, 2, null, false)
}
})
}
selectAnswer = (question, optionId) => {
this.setState(state => {
const questions = state.questions.slice()
return {
questions: questions.map(item => {
if (item.id === question.id) {
item.selected = optionId
}
return item
}),
}
})
}
render() {
const {questions, activeQuestion, time} = this.state
return (
<div className={'exam'}>
<header>
<div className="go-back">
<i className='iconfont iconiconfront-68' onClick={this.goBack}></i>
</div>
<div className="time">
<i className={'iconfont iconzhong'}></i>
<span>
{
!!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="count">{questions.filter(item => item.selected).length}/{questions.length}</div>
</header>
<div className="banner">
<img src="https://julyedu-cdn.oss-cn-beijing.aliyuncs.com/ai-test/m/scores/exam-banner.png" alt=""/>
</div>
<div className="question-section">
{
!!questions.length &&
<Question question={questions[activeQuestion]} selectAnswer={this.selectAnswer}></Question>
}
</div>
<div className="navigation">
<ul>
{
!!questions.length && questions.map((item, index) => {
return <li key={index} onClick={() => {
this.setState({
activeQuestion: index,
})
}} className={item.selected ? 'active' : ''}>{index + 1}</li>
})
}
</ul>
</div>
</div>
);
}
}
export default withRouter(Exam);
\ No newline at end of file
html, body {
height: 100%;
}
body {
background-color: #f5f5f5;
}
.exam {
background-color: #fff;
header {
display: flex;
height: 49px;
padding: 0 12px;
align-items: center;
justify-content: space-between;
.iconfont {
font-size: 16px;
color: #222;
font-weight: 600;
}
.time {
display: flex;
align-items: center;
.iconfont {
margin-right: 8px;
}
span {
font-size: 18px;
}
}
.count {
font-size: 14px;
color: #09f;
}
}
.banner {
height: 94px;
margin-bottom: 18px;
img {
width: 100%;
height: 100%;
}
}
.navigation {
position: fixed;
bottom: 0;
left: 0;
width: 374px;
height: 55px;
padding: 0 15px;
background: #fff;
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.05);
ul {
height: 55px;
padding-top: 11px;
overflow-x: auto;
white-space: nowrap;
}
li {
display: inline-block;
width: 34px;
height: 34px;
border: 1px solid #09f;
border-radius: 50%;
margin-right: 20px;
color: #09f;
font-size: 18px;
text-align: center;
line-height: 34px;
&.active {
color: #fff;
background-color: #09f;
}
}
}
}
\ No newline at end of file
import React, { Component } from 'react';
import './index.scss'
import {Switch, Route} from 'react-router-dom'
import Scores from './scores'
import Exam from './exam'
class AiTest extends Component {
render() {
const {match} = this.props
return (
<Switch>
<Route path={`${match.path}/scores`}>
<Scores/>
</Route>
<Route path={`${match.path}/exam`}>
<Exam/>
</Route>
</Switch>
);
}
}
export default AiTest;
\ No newline at end of file
.ai-test{
}
\ No newline at end of file
.scores {
$blue-bg: #e5f5ff;
background-color: #2e7ee9;
padding: 0 5px 60px;
.banner {
height: 171px;
margin: 0 -5px;
img {
width: 100%;
height: 100%;
}
}
.info {
position: relative;
height: 70px;
text-align: center;
line-height: 70px;
span {
color: $blue-bg;
font-size: 15px;
}
a {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
text-decoration: underline;
font-size: 14px;
color: #fff;
}
}
.score-list {
border-radius: 6px;
overflow: hidden;
margin-bottom: 30px;
.share {
height: 40px;
text-align: center;
font-size: 16px;
line-height: 40px;
color: #09f;
text-decoration: underline;
background-color: $blue-bg;
}
}
th {
font-weight: normal;
}
.am-tabs {
&-tar-bar-wrap {
border: 0;
}
&-default-bar {
padding: 10px 10px 0;
background-color: $blue-bg !important;
&-tab-active {
background-color: #fff;
color: #0D75E5;
}
&-tab {
width: 80px;
height: 40px;
border-radius: 4px 4px 0 0;
&::after {
display: none !important;
}
}
&-content {
padding-top: 2px;
line-height: 48px;
font-size: 15px;
color: #525B65;
}
}
.title {
display: flex;
justify-content: space-around;
height: 38px;
background-color: #FFD66A;
color: #333;
font-size: 14px;
line-height: 38px;
}
.tab-content {
box-sizing: border-box;
padding-top: 10px;
background-color: #fff;
}
table {
width: 100%;
margin: 0;
text-align: center;
border-collapse: collapse;
a {
color: #09f;
text-decoration: underline;
}
thead tr {
height: 38px;
background-color: #FFD66A;
color: #333;
font-size: 14px;
line-height: 38px;
}
tbody tr {
height: 50px;
line-height: 50px;
}
}
}
.rank-list {
border-radius: 6px;
overflow: hidden;
margin-bottom: 30px;
.head {
height: 68px;
padding-top: 12px;
background-color: $blue-bg;
text-align: center;
div:nth-child(1) {
font-size: 18px;
color: #0E75E6;
margin-bottom: 5px;
}
div:nth-child(2) {
position: relative;
span {
color: #666;
font-size: 12px;
}
a {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
text-decoration: underline;
font-size: 14px;
color: #077EE8;
}
}
}
.list {
background: #fff;
padding-top: 11px;
table {
width: 100%;
border-collapse: collapse;
border-spacing: 0;
border: none;
text-align: center;
td, th {
margin-right: -1px;
padding: 0;
}
.avatar {
margin-right: 6px;
}
td:nth-of-type(1) {
width: 15%;
}
td:nth-of-type(2) {
width: 35%;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
text-align: left;
//padding-left: 10%;
}
thead tr {
height: 38px;
line-height: 38px;
background-color: #FFD76A;
font-size: 14px;
color: #333;
}
tbody tr {
height: 49px;
line-height: 49px;
font-size: 12px;
color: #333;
td:nth-of-type(1) {
font-size: 16px;
img {
width: 14px;
height: 18px;
}
}
td:nth-of-type(2) {
img {
width: 18px;
height: 18px;
border-radius: 50%;
}
}
&:nth-child(even) {
background: #f6fbff;
}
img {
vertical-align: middle;
}
.score {
color: #09f;
}
}
}
}
.expand {
height: 49px;
line-height: 49px;
text-align: center;
background: #fff;
color: #525C65;
font-size: 14px;
.iconfont {
margin-left: 5px;
}
}
}
.btn {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 60px;
background-color: #fff;
padding: 10px;
color: #fff;
font-size: 0;
button {
width: 100%;
height: 100%;
font-size: 16px;
color: #fff;
border: none;
outline: 0;
-webkit-appearance: none;
&.get-chance {
background-color: #FFAE00;
}
&.available {
background: linear-gradient(-90deg, rgba(0, 153, 255, 1) 0%, rgba(61, 177, 255, 1) 100%);
}
&.unavailable {
background: #525C65;
}
}
span {
font-size: 12px;
}
}
.rule-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .8);
z-index: 100;
}
.rule {
position: absolute;
top: 19.7%;
left: 50%;
transform: translateX(-50%);
width: 300px;
height: 311px;
padding: 18px 25px;
background-color: #fff;
border-radius: 5px;
color: #525C65;
text-align: center;
div:nth-child(1) {
font-size: 16px;
margin-bottom: 15px;
}
div:nth-child(2) {
font-size: 14px;
margin-bottom: 16px;
}
label {
font-size: 14px;
color: #555;
opacity: .8;
}
.option {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 21px;
}
input {
position: relative;
width: 15px;
height: 15px;
margin-right: 8px;
border: 1px solid #3799ff;
border-radius: 2px;
-webkit-appearance: none;
&::after {
content: '';
position: absolute;
top: 2px;
left: 3px;
width: 10px;
height: 6px;
display: none;
border-bottom: 1px solid #3799ff;
border-left: 1px solid #3799ff;
transform-origin: 5px 4px;
transform: rotate(-45deg);
}
&:checked {
&::after {
display: block;
}
}
}
button {
width: 94px;
height: 30px;
background: #09f;
color: #fff;
font-size: 14px;
border-radius: 15px;
-webkit-appearance: none;
border: none;
outline: 0;
}
.close {
position: absolute;
bottom: -60px;
left: 50%;
transform: translateX(-50%);
color: #fff;
display: block;
font-size: 30px;
}
}
.user-address-wrapper {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: rgba(0, 0, 0, .6);
}
.user-address {
position: absolute;
top: 20%;
left: 50%;
transform: translateX(-50%);
width: 300px;
height: 309px;
padding: 18px 26px 0;
background: #fff;
border-radius: 5px;
text-align: center;
.title {
font-size: 16px;
color: #525C65;
text-align: center;
margin-bottom: 17px;
}
.tip {
font-size: 12px;
color: #FFAE00;
margin-bottom: 15px;
text-align: left;
}
input {
width: 250px;
height: 40px;
padding-left: 10px;
border: 1px solid #DDD;
margin-bottom: 10px;
font-size: 13px;
&::placeholder {
color: #999;
}
}
button {
padding: 10px 45px;
font-size: 15px;
color: #fff;
background: rgba(82, 92, 101, .3);
border-radius: 17px;
border: none;
outline: 0;
-webkit-appearance: none;
&.available {
background-color: #09f;
}
}
.iconfont {
position: absolute;
bottom: -60px;
left: 50%;
transform: translateX(-50%);
font-size: 30px;
color: #fff;
}
}
}
\ No newline at end of file
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