You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
zhishifufei_uniapp/pages/topic/problem_detail.vue

459 lines
13 KiB

<template>
<BaseContainer>
<NavBar title="练习答题" />
<view class="question-paper" v-if="questions.length">
<view class="header">
<div class="message">温馨提示请点击答题卡前去提交考试哦</div>
<view class="header-bd">
<navigator
open-type="redirect"
:url="`/pages/topic/problem_sheet?test_id=${test_id}&record_id=${e_id}&index=${activeIndex}`"
>答题卡</navigator
>
</view>
</view>
<view class="pos" >
<view
v-for="(item, idx) of questions"
:key="item.id"
class="swiper-container swiper-slide abs"
:class="activeIndex == idx ? '' : 'on'"
:style="{ left: `${(activeIndex - idx) * -100}vw` }"
>
<view class="type">{{ item.questionType }}</view>
<view class="question" >
<view>{{ item.stem }}</view>
<image mode="widthFix" v-if="item.image" :src="item.image" />
<view
v-if="item.question_type <= 3"
:class="{ image: item.is_img }"
class="label-group"
@click="handleClickOptions"
>
<template v-for="(option, idx) in item.options">
<view class="label" v-if="option.value" :key="option.code">
<view
:data-idx="idx"
class="label-item"
:class="{
checked: item.user_answer.includes(option.code),
ok:
option.right &&
item.is_correct &&
item.user_answer.includes(option.code),
no:
!option.right &&
item.is_correct &&
item.user_answer.includes(option.code),
}"
>
<image v-if="option.is_img" :src="option.value" />
<template v-else>{{ option.value }}</template>
</view>
</view>
</template>
</view>
<view v-else class="subject">
<view class="subject-title">小王同学想利用中国知网平台,查询近1个月内发 表的最新的文献信息,她可以利用的数据库有:()。</view>
<view class="subject-content">
<textarea v-model.trim="item.user_answer" placeholder-style="input-placeholder" placeholder="请填写你的答案"></textarea>
</view>
</view>
</view>
<view v-if="item.is_correct" class="analysis">
<view :class="{ no: item.is_correct === 1 }">
回答{{ item.is_correct === 1 ? "错误" : "正确" }}
</view>
<view :class="{'subject-flex': item.question_type > 3}">
<view>
正确答案:
<view>{{ item.answer }}</view>
</view>
<view>
您的答案:
<view>{{ item.user_answer.toString() }}</view>
</view>
</view>
<view>
试题难度:<span
v-for="star in 5"
:key="star"
:class="{ on: item.difficulty >= star }"
class="iconfont iconxing"
></span>
</view>
<view>答案解析:</view>
<mpHtml container-style="background: #ffffff;" :content="item.analysis"></mpHtml>
<view v-if="item.special.length">关联知识点:</view>
<navigator
open-type="redirect"
v-for="special in item.special"
:key="special.id"
:url="`/pages/special/${
special.is_light ? 'single_details' : 'details'
}?id=${special.id}`"
>{{ special.title }}</navigator
>
</view>
<view class="pl_per"></view>
</view>
<view class="swiper-pagination abs">
<text class="swiper-pagination-current">{{ activeIndex + 1 }}</text>
<text class="swiper-pagination-line"> / </text>
<text class="swiper-pagination-total">{{ questions.length }}</text>
</view>
</view>
<view class="footer">
<view
class="button flex flex-column flex-center"
:class="{ disabled: !activeIndex }"
@click="slidePrev"
>
<i class="iconfont iconshangyige"></i>
<view class="tips">上一题</view>
</view>
<view
class="button flex flex-column flex-center"
:class="{ disabled: !!questions[activeIndex].is_correct }"
@click="submitQuestion"
>
<i class="iconfont icontijiao"></i>
<view class="tips">确认提交</view>
</view>
<view
class="button flex flex-column flex-center"
:class="{ disabled: activeIndex === questions.length - 1 }"
@click="slideNext"
>
<i class="iconfont iconxiayige"></i>
<view class="tips">下一题</view>
</view>
</view>
</view>
<QuestionGuide :visible.sync="guideVisible"></QuestionGuide>
</BaseContainer>
</template>
<script>
import QuestionGuide from "@/components/QuestionGuide/index.vue";
import mpHtml from "mp-html/dist/uni-app/components/mp-html/mp-html.vue";
import { PROBLEM_GUIDE } from "@/constants/storage-keys";
import {
getAnswer,
getAnswerAgain,
getAnswerContinue,
getQuestion,
getSituation,
submitQuestions,
} from "@/api/topic";
export default {
components: {
QuestionGuide,
mpHtml,
},
data() {
return {
questions: [],
test_id: "",
e_id: "",
is_analysis: 0,
activeIndex: 0,
guideVisible: false,
};
},
watch: {
guideVisible(value) {
if (!value) {
this.$util.setStorage(PROBLEM_GUIDE, new Date());
}
},
},
onLoad({ test_id, type, index = 0, e_id, is_analysis }) {
this.test_id = test_id;
this.activeIndex = Number(index);
if (e_id && parseInt(is_analysis)) {
this.is_analysis = 1;
this.e_id = e_id;
this.getQuestions();
} else {
this.getSituation();
}
},
methods: {
handleClickOptions({ target }) {
const { idx } = target.dataset;
if (idx === undefined) return;
const item = this.questions[this.activeIndex];
const option = item.options[idx];
if (!item || !option) return;
if (!!item.is_correct) return;
if (item.question_type === 2) {
const existIdx = item.user_answer.findIndex((i) => i === option.code);
console.log(existIdx);
if (existIdx === -1) {
item.user_answer.push(option.code);
} else {
item.user_answer.splice(existIdx, 1);
}
} else {
if (item.user_answer.includes(option.code)) {
item.user_answer = "";
} else {
item.user_answer = option.code;
}
}
},
// 获取状态
getSituation() {
getSituation(this.test_id).then(({ code, msg, data }) => {
if (code === 400) {
return this.$util.showMsg(msg);
}
switch (data) {
case 0:
this.getAnswer();
break;
case 1:
this.getAnswerAgain();
break;
case 2:
this.getAnswerContinue();
break;
}
});
},
// 开始答题
getAnswer() {
getAnswer({
test_id: this.test_id,
type: 1,
}).then(({ code, msg, data }) => {
if (code === 200) {
this.e_id = data;
this.$util.setCookie("e_id", this.e_id);
this.getQuestions();
} else {
this.$util.showMsg(msg);
uni.navigateTo({
url: "/pages/topic/question_user?type=1",
});
}
});
},
// 再次答题
getAnswerAgain() {
getAnswerAgain({
test_id: this.test_id,
type: 1,
}).then(({ code, data, msg }) => {
if (code === 200) {
this.e_id = data;
this.$util.setCookie("e_id", this.e_id);
this.getQuestions();
} else {
this.$util.showMsg(msg);
uni.navigateTo({
url: "/pages/topic/question_user?type=1",
});
}
});
},
// 继续答题
getAnswerContinue() {
getAnswerContinue({
test_id: this.test_id,
type: 1,
}).then(({ code, data, msg }) => {
if (code === 200) {
this.e_id = data;
this.$util.setCookie("e_id", this.e_id);
this.getQuestions();
} else {
this.$util.showMsg(msg);
uni.navigateTo({
url: "/pages/topic/question_user?type=1",
});
}
});
},
// 获取练习题
async getQuestions() {
uni.showLoading({ mask: true });
try {
const { data: questions } = await getQuestion({
test_id: this.test_id,
record_id: this.e_id,
type: 1,
});
uni.hideLoading();
questions.forEach((question) => {
question.options = [];
if (Array.isArray(question.option)) {
question.option.forEach((option, index) => {
let code = String.fromCharCode(index + 65);
question.options.push({
code,
value: option,
right: question.answer.includes(code),
});
});
} else {
for (let key in question.option) {
if (Object.hasOwnProperty.call(question.option, key)) {
question.options.push({
code: key,
value: question.option[key],
right: question.answer.includes(key),
});
}
}
}
if (!Array.isArray(question.userAnswer)) {
Object.assign(question, question.userAnswer);
}
if (!("is_correct" in question)) {
question.is_correct = 0;
}
if (!("user_answer" in question)) {
question.user_answer = "";
}
if (question.question_type === 2) {
question.user_answer = question.user_answer
? question.user_answer.split(",")
: [];
}
switch (question.question_type) {
case 1:
question.questionType = "单选题";
break;
case 2:
question.questionType = "多选题";
break;
case 3:
question.questionType = "判断题";
break;
}
});
console.log(questions);
this.questions = questions;
} catch (err) {
uni.hideLoading();
this.$util.showMsg(err);
}
},
// 提交本题
async submitQuestion() {
let question = this.questions[this.activeIndex];
let data = {
e_id: this.e_id,
questions_id: question.questions_id,
answer: question.answer,
score: question.score,
type: 1,
};
if (!question.user_answer.length) {
return this.$util.showMsg("请作答后提交本题");
}
if (question.question_type === 2) {
question.user_answer.sort();
data.user_answer = question.user_answer.toString();
} else {
data.user_answer = question.user_answer;
}
data.is_correct = data.user_answer === question.answer ? 2 : 1;
uni.showLoading({ mask: true });
try {
const { code, msg } = await submitQuestions(data);
uni.hideLoading();
if (code === 200) {
question.is_correct = data.is_correct;
} else {
this.$util.showMsg(msg);
}
} catch (err) {
uni.hideLoading();
this.$util.showMsg(err);
}
},
// 上一题
slidePrev() {
if (this.activeIndex) {
this.activeIndex--;
}
},
// 下一题
slideNext() {
if (this.activeIndex !== this.questions.length - 1) {
this.activeIndex++;
if (this.activeIndex === this.questions.length - 1) {
this.$util.showMsg("答完全部考题后\n点击左上角“答题卡”前去提交练习");
}
}
},
},
};
</script>
<style>
page {
background-color: #f5f5f5;
}
.pl_per{
/* #ifdef MP-WEIXIN */
height:100rpx;
/* #endif */
}
</style>
<style scoped lang="scss">
@import "@/static/style/question.scss";
.message{
height:80rpx;
border-radius: 12rpx 12rpx 0 0;
background-color: #FFF0E5;
text-align: center;
font-size: 24rpx;
line-height: 80rpx;
color: #FF6B00;
}
.abs.on{
display: none;
}
.question {
.subject {
.subject-title {
font-size: 30rpx;
color: #333;
margin: 40rpx 0 30rpx;
}
.subject-content {
::v-deep {
.uni-textarea-placeholder {
color: #BFBFBF;
font-size: 26rpx;
}
textarea {
width: 100%;
height: 349rpx;
border-radius: 13rpx;
border: 1px solid #CCCCCC;
padding: 28rpx 30rpx;
}
}
}
}
}
.analysis {
.subject-flex {
display: flex;
flex-direction: column;
view:nth-child(2) {
margin-top: 20rpx;
}
}
}
</style>