| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- <template>
- <view class="question-options">
- <view class="question-option" v-for="option in question.options" :class="getStyleClass(option)" :key="option.id"
- @click="handleSelect(option)">
- <template v-if="!isReadOnly">
- <view v-if="!isOnlySubjective" class="question-option-index">{{ option.no }}</view>
- <view v-else>
- <uv-icon name="info-circle" :color="option.isSelected ? '#31A0FC' : '#999'" size="18" />
- </view>
- </template>
- <view v-else>
- <uv-icon v-if="option.isCorrect" name="checkmark-circle-fill" color="#2CC6A0" size="22" />
- <uv-icon v-else-if="!option.isCorrect && option.isSelected" name="close-circle-fill" color="#FF5B5C"
- size="22" />
- <view v-else class="question-option-index">{{ option.no }}</view>
- </view>
- <view class="question-option-content">
- <uv-parse :content="getOptionContent(option)" containerStyle="display:inline"
- contentStyle="word-break:break-word;"></uv-parse>
- </view>
- </view>
- <!-- 添加不会选项 -->
- <view v-if="question.options.length && !isReadOnly && !isOnlySubjective" class="question-option"
- :class="{ 'question-option-not-know': question.isNotKnow }" @click="handleNotKnow">
- <view class="question-option-index">
- <uv-icon name="info-circle" :color="question.isNotKnow ? '#31A0FC' : '#999'" size="18" />
- </view>
- <view class="question-option-content text-fore-light">不会</view>
- </view>
- <!-- 用于多选题手动提交,背题模式才有 -->
- <view class="mt-40" v-if="practiceSettings.reviewMode === EnumReviewMode.DURING_ANSWER && isMultipleChoice">
- <ie-button type="primary" size="mini" :round="4" :shadow="false" custom-class="w-160"
- @click="handleSubmit">提交</ie-button>
- </view>
- <view v-if="!isReadOnly && isOnlySubjective" class="mt-40 bg-[#EBF9FF] p-12 rounded-8">
- <view class="rounded-8 bg-white px-10 py-20 text-primary text-24 flex gap-x-6 items-center">
- <uv-icon name="info-circle" color="#31A0FC" size="16" />
- <text>请线下答题,查看解析对比后,选“会”或“不会”</text>
- </view>
- <view class="mt-30 mb-20 text-24 text-white bg-primary w-fit mx-auto px-20 py-12 rounded-full text-center"
- @click="handleShowParse">
- 查看解析
- </view>
- </view>
- </view>
- </template>
- <script lang="ts" setup>
- import { EnumQuestionType, EnumReviewMode } from '@/common/enum';
- import { useExam } from '@/composables/useExam';
- import { Study, Transfer } from '@/types';
- import { EXAM_DATA, EXAM_PAGE_OPTIONS, EXAM_AUTO_SUBMIT } from '@/types/injectionSymbols';
- const examPageOptions = inject(EXAM_PAGE_OPTIONS) || {} as Transfer.ExamAnalysisPageOptions;
- const examData = inject(EXAM_DATA) || {} as ReturnType<typeof useExam>;
- const { practiceSettings, nextQuestion, isAllDone } = examData;
- const examAutoSubmit = inject(EXAM_AUTO_SUBMIT);
- const props = defineProps<{
- question: Study.Question;
- }>();
- const isReadOnly = computed(() => {
- const { readonly } = examPageOptions;
- if (readonly) {
- return true;
- }
- // 练习模式下,需要背题模式且题目已经做过且解析过
- if (practiceSettings.value.reviewMode === EnumReviewMode.DURING_ANSWER && props.question.hasParsed) {
- return true;
- }
- return false;
- });
- const isOnlySubjective = computed(() => {
- return [EnumQuestionType.SUBJECTIVE, EnumQuestionType.SHORT_ANSWER, EnumQuestionType.ESSAY].includes(props.question.typeId);
- });
- const isMultipleChoice = computed(() => {
- return props.question.typeId === EnumQuestionType.MULTIPLE_CHOICE;
- });
- const getStyleClass = (option: Study.QuestionOption) => {
- if (!isReadOnly.value) {
- return option.isSelected ? 'question-option-selected' : '';
- }
- let customClass = '';
- let { answers, answer1 } = props.question;
- answers = answers?.filter(item => item !== ' ') || [];
- answer1 = answer1 || ''
- if ([EnumQuestionType.SINGLE_CHOICE, EnumQuestionType.JUDGMENT].includes(props.question.typeId)) {
- if (option.isCorrect) {
- customClass = 'question-option-correct';
- } else if (option.isIncorrect) {
- customClass = 'question-option-incorrect';
- }
- } else if ([EnumQuestionType.MULTIPLE_CHOICE].includes(props.question.typeId)) {
- // 我选择的答案
- if (option.isSelected) {
- if (option.isCorrect) {
- customClass = 'question-option-correct';
- } else {
- customClass = 'question-option-incorrect';
- }
- } else {
- // 漏选的答案
- if (option.isMissed) {
- customClass = 'question-option-miss';
- }
- }
- }
- // console.log(props.question, option)
- return customClass;
- };
- const getOptionContent = (option: Study.QuestionOption) => {
- // sb 问题,浪费几个小时
- return option.name.replace(/\s/g, ' ');
- }
- // 多选题要手动提交才能认为是作答结束
- const handleSubmit = () => {
- props.question.hasParsed = true;
- }
- const handleNotKnow = () => {
- props.question.answers = [];
- props.question.isNotKnow = !props.question.isNotKnow;
- props.question.hasParsed = true;
- handleNext();
- }
- const handleNext = () => {
- // 如果是正常的练习,默认下一题,如果是背题模式,需要根据是否自动下一题来决定
- if (practiceSettings.value.reviewMode === EnumReviewMode.DURING_ANSWER) {
- if (practiceSettings.value.autoNext) {
- nextQuestion();
- }
- } else {
- nextQuestion();
- }
- if (isAllDone.value) {
- examAutoSubmit?.();
- }
- }
- const handleSelect = (option: Study.QuestionOption) => {
- if (isReadOnly.value) {
- return;
- }
- if ([
- EnumQuestionType.JUDGMENT,
- EnumQuestionType.SINGLE_CHOICE,
- EnumQuestionType.SUBJECTIVE,
- EnumQuestionType.SHORT_ANSWER,
- EnumQuestionType.ESSAY,
- EnumQuestionType.ANALYSIS
- ].includes(props.question.typeId)) {
- props.question.answers = [option.no];
- } else if (props.question.typeId === EnumQuestionType.MULTIPLE_CHOICE) {
- if (props.question.answers.includes(option.no)) {
- props.question.answers = props.question.answers.filter(item => item !== option.no);
- } else {
- props.question.answers.push(option.no);
- }
- }
- props.question.isNotKnow = false;
- props.question.hasParsed = true;
- // 多选题不自动切换下一题
- if (props.question.typeId !== EnumQuestionType.MULTIPLE_CHOICE) {
- handleNext();
- }
- }
- const handleShowParse = () => {
- props.question.showParse = !props.question.showParse;
- }
- </script>
- <style lang="scss" scoped>
- .question-options {
- @apply mt-40;
- }
- .question-option {
- @apply flex items-center px-30 py-24 bg-back rounded-8 border border-none border-transparent;
- .question-option-index {
- @apply w-40 h-40 rounded-full bg-transparent text-30 text-fore-light font-bold flex items-center justify-center flex-shrink-0;
- }
- .question-option-content {
- @apply text-28 text-fore-title ml-20 flex-1 min-w-0;
- }
- }
- .question-option-selected {
- @apply bg-[#b5eaff8e];
- .question-option-index {
- @apply bg-primary text-white;
- }
- .question-option-content {
- @apply text-primary;
- }
- }
- .question-option-not-know {
- @apply bg-[#b5eaff8e];
- .question-option-content {
- @apply text-primary;
- }
- }
- .question-option-correct {
- @apply bg-[#E7FCF8] border-[#E7FCF8] text-[#2CC6A0];
- .question-option-index {
- @apply text-[#2CC6A0];
- }
- .question-option-content {
- @apply text-[#2CC6A0];
- }
- }
- .question-option-miss {
- @apply relative overflow-hidden;
- &::before {
- content: '';
- position: absolute;
- right: -56rpx;
- top: 15rpx;
- width: 180rpx;
- height: 36rpx;
- background: rgba(255, 91, 92, 0.2);
- transform: rotate(30deg);
- box-shadow: 0 2rpx 4rpx rgba(255, 91, 92, 0.1);
- }
- &::after {
- content: '漏选';
- position: absolute;
- right: -8rpx;
- top: 14rpx;
- width: 100rpx;
- height: 32rpx;
- color: #FF5B5C;
- font-size: 20rpx;
- // font-weight: bold;
- transform: rotate(30deg);
- display: flex;
- align-items: center;
- justify-content: center;
- line-height: 1;
- }
- }
- .question-option-incorrect {
- @apply bg-[#FEEDE9] border-[#FEEDE9] text-[#FF5B5C];
- .question-option-index {
- @apply text-[#FF5B5C];
- }
- .question-option-content {
- @apply text-[#FF5B5C];
- }
- }
- .question-option+.question-option {
- @apply mt-24;
- }
- </style>
|