理论题调整

This commit is contained in:
fan 2024-03-07 18:00:34 +08:00
parent 68584fd5fd
commit 2134f027e7
6 changed files with 538 additions and 217 deletions

View File

@ -369,3 +369,10 @@ export function getSeasonContent(id) {
method: 'get'
});
}
export function getTheoryList() {
return request({
url: '/api/exercise/race/paper/questions',
method: 'get'
});
}

View File

@ -107,4 +107,6 @@ export default {
iscsResourcesManage: 'ISCS Resources Manage',
projectManage: 'Project Manage',
frontProjectConfigManage: 'Front Project Config Manage',
}
training: 'Training',
theory: 'Theory'
};

View File

@ -111,4 +111,6 @@ export default {
iscsResourcesManage: 'ISCS资源管理',
projectManage: '项目管理',
frontProjectConfigManage: '前端项目配置管理',
}
training: '实训',
theory: '理论'
};

View File

@ -231,6 +231,7 @@ const ContestScoreEdit = () => import('@/views/contestDataManage/contestTaskScor
const ContestList = () => import('@/views/contest/contestList');
const ContestDetail = () => import('@/views/contest/contestDetail');
const ScoringSettlement = () => import('@/views/contest/ScoringSettlement');
const TheoryPage = () => import('@/views/contest/theory');
// import { GenerateRouteProjectList } from '@/scripts/ProjectConfig';
// import { getSessionStorage } from '@/utils/auth';
@ -676,28 +677,6 @@ export const publicAsyncRoute = [
path: '/pis',
component: PisScreen,
hidden: true
},
{
path: '/contest',
component: Layout,
hidden: true,
children: [
{
path: 'list',
component: ContestList,
hidden: true
},
{
path: 'detail',
component: ContestDetail,
hidden: true
},
{
path: 'scoringSettlement',
component: ScoringSettlement,
hidden: true
}
]
}
];
// 城市轨道项目
@ -2212,6 +2191,54 @@ export const asyncRouter = [
]
}
];
export const dsxlRouter = [
{
path: '/contest',
component: Layout,
redirect: '/contest/list',
meta: {
i18n: 'router.training',
roles: [user]
},
children: [
{
path: 'list',
component: ContestList,
meta: {
i18n: 'router.training'
}
},
{
path: 'detail',
component: ContestDetail,
hidden: true
},
{
path: 'scoringSettlement',
component: ScoringSettlement,
hidden: true
}
]
},
{
path: '/theory',
component: Layout,
redirect: '/theory/list',
meta: {
i18n: 'router.theory',
roles: [user]
},
children: [
{
path: 'list',
component: TheoryPage,
meta: {
i18n: 'router.theory'
}
}
]
}
];
const createRouter = () => new Router({
base: process.env.VUE_APP_PRO == 'local' ? '/' : '/cbtc/',
mode: 'history', // require service support

View File

@ -1,5 +1,5 @@
// import { loginInfo } from '@/scripts/ProjectConfig';
import { userTrainingPlatform, admin, publicAsyncRoute, asyncRouter, constantRoutes, superAdmin, user } from '@/router/index';
import { userTrainingPlatform, admin, publicAsyncRoute, asyncRouter, constantRoutes, superAdmin, user, dsxlRouter } from '@/router/index';
import { getSessionStorage } from '@/utils/auth';
import store from '@/store/index';
@ -42,6 +42,8 @@ function resetAsyncRouter() {
let list = publicAsyncRoute;
if (getSessionStorage('project') !== 'dsxl') {
list = [...list, ...asyncRouter];
} else {
list = [...list, ...dsxlRouter];
}
return list;
}

View File

@ -0,0 +1,281 @@
<template>
<el-row class="container">
<el-col :span="5" class="container-left">
<div class="question-container">
<div v-for="(id,j) in idList" :key="id" class="question-box" :class="{'select-question':index===j}" @click="handleClick(j)">{{ j+1 }}</div>
</div>
</el-col>
<el-col :span="19" class="container-right">
<el-card v-loading="loading" class="box-card">
<div slot="header" style="text-align: center">
<span style="font-size: 28px;">{{ `${index +1}` }}</span>
</div>
<div class="question-title">[{{ questionData.typeString }}] {{ questionData.title }}</div>
<div class="options">
<component
:is="type === 2 ? 'el-checkbox-group' : 'el-radio-group'"
v-model="questionData.answer"
class="options-container"
>
<component
:is="type === 2 ? 'el-checkbox' : 'el-radio'"
v-for="el in questionData.options"
:key="el.value"
:disabled="showAnswer"
class="option"
:label="el.value"
>{{ el.label }}</component>
</component>
</div>
<div class="show-answer">
<span v-if="showAnswer" :class="isCorrect? 'correct': 'error'">{{ isCorrect ? '回答正确' : `回答错误正确答案应为:${tip}` }}</span>
</div>
<div class="footer">
<el-button type="primary" :disabled="index === 0" @click="navigate('-')">上一题</el-button>
<el-button type="primary" :disabled="showAnswer" @click="navigate()">确认</el-button>
<el-button
type="primary"
:disabled="index === idList.length - 1"
@click="navigate('+')"
>下一题</el-button>
</div>
</el-card>
</el-col>
</el-row>
</template>
<script>
const types = {
select: '选择题',
judge: '判断题',
multi: '多选题'
};
import {getQuestionInfo } from '@/api/questionBank';
import { getTheoryList } from '@/api/contest';
export default {
name: 'Theory',
data() {
return {
loading: false,
showAnswer: false,
isCorrect: false,
questionData: {
title: '',
typeString: '',
options: [],
answer: ''
},
currentAnswer: '',
idList: [],
id: '',
type: 1,
index:0,
tip: ''
};
},
watch: {
id(val) {
if (val) {
this.getQuestionInfo(val);
}
}
},
mounted() {
this.getData();
},
beforeDestroy() {
},
methods: {
getData() {
this.loading = true;
getTheoryList().then(resp => {
this.idList = resp.data;
this.id = this.idList[this.index];
}).catch(() => {
this.$message.error('获取试题列表失败!');
});
},
getQuestionInfo(val) {
this.loading = true;
this.showAnswer = false;
this.isCorrect = false;
this.tip = '';
getQuestionInfo(val, {random: false}).then(res => {
const data = res.data;
this.questionData = {
title: data.topic,
typeString: types[data.type],
options: data.optionList.map(opt => ({ label: opt.content, value: opt.id })),
answer: data.type === 'multi' ? [] : NaN
};
if (data.type === 'multi') {
this.type = 2;
} else {
this.type = 1;
}
this.currentAnswer = data.answer;
this.loading = false;
}).catch(() => {
this.loading = false;
this.$message.error('获取试题详情失败!');
});
},
handleClick(j) {
this.index = j;
this.id = this.idList[this.index];
},
compareArrays(arr1, arr2) {
if (arr1.length !== arr2.length) {
return false;
}
for (let i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
},
navigate(direction) {
if (direction === '-') {
this.index--;
this.id = this.idList[this.index];
} else if (direction === '+') {
this.index++;
this.id = this.idList[this.index];
} else {
if (this.questionData.type === 'multi') {
const an = this.currentAnswer.split(',');
if (this.compareArrays(an, this.questionData.answer)) {
this.isCorrect = false;
this.showAnswer = true;
} else {
this.isCorrect = false;
this.showAnswer = true;
let op = '';
this.questionData.options.forEach(ele => {
const nId = ele.value + '';
if (an.includes(nId)) {
const nContent = op ? ';' + ele.label : ele.label;
op += nContent;
}
});
this.tip = op;
}
} else {
if (this.questionData.answer == this.currentAnswer) {
this.isCorrect = true;
this.showAnswer = true;
} else {
this.isCorrect = false;
this.showAnswer = true;
const op = this.questionData.options.find(ele => ele.value == this.currentAnswer);
this.tip = op.label;
}
}
}
}
}
};
</script>
<style lang="scss" scoped>
.show-answer {
height: 30px;
padding: 0 30px;
span {
font-size: 18px;
}
.correct {
color: green;
}
.error {
color: red;
}
}
.select-question {
border: 2px solid #8f079d !important;
color: #8f079d !important;
font-weight: bolder;
}
.question-container {
height: 100%;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
}
.question-box {
border: 1px solid #fff;
margin: 10px;
display: inline-block;
color: #fff;
text-align: center;
line-height: 40px;
width: 40px;
height: 40px;
cursor: pointer;
}
.question-title {
padding: 30px;
font-size: 20px;
}
/deep/.el-checkbox{
color: #fff;
}
/deep/.el-radio{
color: #fff;
}
.options-container {
display: flex;
flex-direction: column;
padding: 30px;
font-size: 20px;
& > .option {
line-height: 2rem;
height: 2rem;
/deep/.el-radio__label{
font-size: 18px;
}
/deep/.el-checkbox__label{
font-size: 18px;
}
}
}
.footer {
display: flex;
justify-content: center;
}
.box-card {
color: #fff;
background-color: transparent;
height: 100%;
border: 1px solid #01468B;
}
.container {
background: linear-gradient(to bottom, #01468B, #00172E);
height: 100%;
}
.container-left{
height: 100%;
padding-top: 10px;
}
.container-right{
background: #00172E;
border: 1px solid #01468B;
height: 100%;
padding: 10px;
}
.custom-tree-node{
color: #fff;
}
.button-group {
width: 20.9%;
text-align: right;
padding: 10px;
border-top: 1px solid #01468B;
position: absolute;
bottom: 0;
}
</style>