提交 566dc4b0 authored 作者: lihuihui's avatar lihuihui

Merge branch 'master' of https://gitlab.ezijing.com/ezijing/x-learn

# Conflicts: # src/components/exam/examCard.vue
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
</div> </div>
<div class="exam-main"> <div class="exam-main">
<div class="left"> <div class="left">
<question-list :data="currentExam"> <question-list :data="currentExam" :index="index" :disabled="disabled" :hasResult="hasResult">
<template #index>{{ index + 1 }}/{{ data.questions.total_question_count }}</template> <template #index>{{ index + 1 }}/{{ data.questions.total_question_count }}</template>
</question-list> </question-list>
</div> </div>
...@@ -56,12 +56,14 @@ export default { ...@@ -56,12 +56,14 @@ export default {
}, },
data() { data() {
return { return {
disabled: false,
hasResult: false,
index: 0, // 当前题的下标 index: 0, // 当前题的下标
questionList: [], // 所有试题
cacheAnswerTime: null, // 缓存题计时器 cacheAnswerTime: null, // 缓存题计时器
countDownTime: null, // 倒计时计时器 countDownTime: null, // 倒计时计时器
duration: 0, // 答题所用时间 duration: 0, // 答题所用时间
examTimeText: '' examTimeText: '',
questionList: [] // 所有试题
} }
}, },
computed: { computed: {
...@@ -187,21 +189,24 @@ export default { ...@@ -187,21 +189,24 @@ export default {
}, },
// 组装试题数据 // 组装试题数据
genQuestions(data) { genQuestions(data) {
const { questions = [], answers } = data const { questions = [], answers = {} } = data
let orderNum = 1
console.log(answers)
if (!questions) return [] if (!questions) return []
this.questionList = questions.question_items.reduce((result, question) => { this.questionList = questions.question_items.reduce((result, question) => {
question.question_list.forEach(list => { question.question_list.forEach(list => {
list = list.map(item => { list = list.map(item => {
let answerData = {} let userAnswers = []
if (answers !== null && answers[question.question_item_id]) { let sign = false
answerData = answers[question.question_item_id][item.id] if (answers) {
} // 大题答案包含所有小题答案
item.sign = answerData.sign || false const bigQuestionAnswer = answers[question.question_item_id]
item.qOrder = orderNum++ if (bigQuestionAnswer) {
return { ...item, user_answer: answerData.answer || [] } // 小题答案
// return { ...item, user_answer: [] } const questionAnswer = bigQuestionAnswer[item.id] || {}
userAnswers = questionAnswer.answer || []
sign = questionAnswer.sign || false
}
}
return { ...item, user_answer: userAnswers, sign }
}) })
result.push(Object.assign({}, question, { question_list: list })) result.push(Object.assign({}, question, { question_list: list }))
}) })
...@@ -218,6 +223,7 @@ export default { ...@@ -218,6 +223,7 @@ export default {
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;
height: 100vh; height: 100vh;
overflow: hidden;
// background: #f9f9f9; // background: #f9f9f9;
.head { .head {
border-bottom: 1px solid #ccc; border-bottom: 1px solid #ccc;
...@@ -265,6 +271,7 @@ export default { ...@@ -265,6 +271,7 @@ export default {
.exam-main { .exam-main {
flex: 1; flex: 1;
display: flex; display: flex;
overflow: hidden;
.left { .left {
background: #fff; background: #fff;
flex: 1; flex: 1;
...@@ -290,10 +297,6 @@ export default { ...@@ -290,10 +297,6 @@ export default {
} }
.foot { .foot {
border-top: 1px solid #ccc; border-top: 1px solid #ccc;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 60px; height: 60px;
background: #ffffff; background: #ffffff;
display: flex; display: flex;
......
...@@ -7,11 +7,12 @@ ...@@ -7,11 +7,12 @@
<div class="question-list-bd"> <div class="question-list-bd">
<h2 class="question-list-title" v-if="conmonTitle">{{ conmonTitle }}</h2> <h2 class="question-list-title" v-if="conmonTitle">{{ conmonTitle }}</h2>
<question-list-item <question-list-item
v-for="(item, index) in data.question_list" v-for="(item, i) in data.question_list"
:data="item" :data="item"
:question="data" :question="data"
:index="index" :index="data.question_list.length > 1 ? i : index"
:key="index" :key="item.id"
v-bind="$attrs"
v-on="$listeners" v-on="$listeners"
/> />
</div> </div>
...@@ -21,7 +22,7 @@ ...@@ -21,7 +22,7 @@
<script> <script>
import QuestionListItem from './questionListItem.vue' import QuestionListItem from './questionListItem.vue'
export default { export default {
props: { data: { type: Object, default: () => ({}) } }, props: { data: { type: Object, default: () => ({}) }, index: { type: Number, default: 0 } },
components: { QuestionListItem }, components: { QuestionListItem },
computed: { computed: {
// 试题类型 // 试题类型
...@@ -39,10 +40,16 @@ export default { ...@@ -39,10 +40,16 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.question-list {
position: relative;
}
.question-list-hd { .question-list-hd {
position: sticky;
top: 0;
display: flex; display: flex;
align-items: center; align-items: center;
height: 45px; height: 45px;
background-color: #fff;
} }
.question-list-hd__title { .question-list-hd__title {
flex: 1; flex: 1;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<div class="question-list-item-bd"> <div class="question-list-item-bd">
<!-- 单选 --> <!-- 单选 -->
<template v-if="questionType === 1"> <template v-if="questionType === 1">
<el-radio-group v-model="data.user_answer[0]"> <el-radio-group v-model="data.user_answer[0]" :disabled="disabled">
<div class="question-option-item" v-for="item in currentOptions" :key="item.id"> <div class="question-option-item" v-for="item in currentOptions" :key="item.id">
<el-radio :label="item.id"> <el-radio :label="item.id">
<div class="question-option-item__text" v-html="item.abc_option"></div> <div class="question-option-item__text" v-html="item.abc_option"></div>
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
</template> </template>
<!-- 多选 --> <!-- 多选 -->
<template v-if="[2, 6].includes(questionType)"> <template v-if="[2, 6].includes(questionType)">
<el-checkbox-group v-model="data.user_answer"> <el-checkbox-group v-model="data.user_answer" :disabled="disabled">
<div class="question-option-item" v-for="item in currentOptions" :key="item.id"> <div class="question-option-item" v-for="item in currentOptions" :key="item.id">
<el-checkbox :label="item.id"> <el-checkbox :label="item.id">
<div class="question-option-item__text" v-html="item.abc_option"></div> <div class="question-option-item__text" v-html="item.abc_option"></div>
...@@ -27,14 +27,37 @@ ...@@ -27,14 +27,37 @@
</template> </template>
<!-- 简答题 --> <!-- 简答题 -->
<template v-if="questionType === 3"> <template v-if="questionType === 3">
<el-input type="textarea" v-model="data.user_answer[0]"></el-input> <el-input
type="textarea"
v-model="data.user_answer[0]"
placeholder="请输入答案内容"
:autosize="{ minRows: 4, maxRows: 6 }"
:disabled="disabled"
></el-input>
</template> </template>
</div> </div>
<div class="question-list-item-ft"> <div class="question-list-item-ft" v-if="hasResult">
<h3>答案解析</h3> <h3 class="question-list-item-ft__title">答案解析</h3>
<!-- <p>正确答案:{{ correctAnswerText }}</p> <template v-if="questionType !== 3">
<p>您的答案:{{ submitAnswerText }}</p> --> <div class="answer-item">
<p>解析:{{ data.question_analysis }}</p> <div class="answer-item-label">正确答案:</div>
<div class="answer-item-content">{{ correctAnswerText }}</div>
</div>
<div class="answer-item">
<div class="answer-item-label">您的答案:</div>
<div class="answer-item-content">{{ correctAnswerText }}</div>
</div>
</template>
<template v-else>
<div class="answer-item">
<div class="answer-item-label">老师点评:</div>
<div class="answer-item-content">{{ correctAnswerText }}</div>
</div>
</template>
<div class="answer-item" v-if="data.question_analysis">
<div class="answer-item-label">解析:</div>
<div class="answer-item-content">{{ data.question_analysis }}</div>
</div>
</div> </div>
</div> </div>
</template> </template>
...@@ -44,7 +67,9 @@ export default { ...@@ -44,7 +67,9 @@ export default {
props: { props: {
index: { type: Number, default: 0 }, index: { type: Number, default: 0 },
data: { type: Object, default: () => ({}) }, // 小题 data: { type: Object, default: () => ({}) }, // 小题
question: { type: Object, default: () => ({}) } // 大题 question: { type: Object, default: () => ({}) }, // 大题
disabled: { type: Boolean, default: false },
hasResult: { type: Boolean, default: false }
}, },
data() { data() {
return {} return {}
...@@ -77,30 +102,41 @@ export default { ...@@ -77,30 +102,41 @@ export default {
// 英文字母 + 名称 // 英文字母 + 名称
item.abc = this.A_Z[index] item.abc = this.A_Z[index]
item.abc_option = `${this.A_Z[index]}. ${item.option}` item.abc_option = `${this.A_Z[index]}. ${item.option}`
// 提交时的选中状态
item.checked = this.data.user_answer.includes(item.id)
// 处理正确的选中状态
const hasChecked = Object.prototype.hasOwnProperty.call(item, 'isRight')
const rightAnswer = this.data.question_answer || []
if (!hasChecked && rightAnswer) {
item.isRight = Array.isArray(rightAnswer) ? rightAnswer.includes(item.id) : rightAnswer === item.id
}
return item return item
}) })
} },
// 正确答案显示的英文字母 // 正确答案显示的英文字母
// correctAnswerText() { correctAnswerText() {
// const result = this.currentOptions.reduce((result, item) => { const result = this.currentOptions.reduce((result, item) => {
// item.checked && result.push(item.abc) item.isRight && result.push(item.abc)
// return result return result
// }, []) }, [])
// return result.join('、') return result.join('、')
// }, },
// // 提交答案显示的英文字母 // // 提交答案显示的英文字母
// submitAnswerText() { submitAnswerText() {
// const result = this.currentOptions.reduce((result, item) => { const result = this.currentOptions.reduce((result, item) => {
// item.selected && result.push(item.abc) item.checked && result.push(item.abc)
// return result return result
// }, []) }, [])
// return result.join('、') return result.join('、')
// } }
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.question-list-item {
margin-bottom: 40px;
}
.question-list-item-hd { .question-list-item-hd {
display: flex; display: flex;
} }
...@@ -119,6 +155,9 @@ export default { ...@@ -119,6 +155,9 @@ export default {
color: #222; color: #222;
line-height: 25px; line-height: 25px;
} }
.question-list-item-bd {
margin-left: 30px;
}
.question-option-item { .question-option-item {
margin-top: 20px; margin-top: 20px;
} }
...@@ -128,12 +167,32 @@ export default { ...@@ -128,12 +167,32 @@ export default {
color: #222; color: #222;
} }
::v-deep .el-radio__inner { ::v-deep .el-radio__inner,
::v-deep .el-checkbox__inner {
width: 18px; width: 18px;
height: 18px; height: 18px;
} }
::v-deep .el-checkbox__inner::after {
width: 4px;
height: 9px;
left: 6px;
}
.question-list-item-ft { .question-list-item-ft {
margin-top: 20px; margin-top: 20px;
margin-left: 30px;
}
.question-list-item-ft__title {
font-size: 18px;
font-weight: bold;
color: #222;
line-height: 25px;
}
.answer-item {
margin-top: 10px;
margin-left: 28px;
display: flex;
font-size: 18px;
color: #222;
line-height: 25px;
} }
</style> </style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论