| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- <template>
- <view class="px-16 py-26 bg-white rounded-15 mt-20">
- <view class="text-30 text-fore-title font-bold">答题情况</view>
- <view v-if="showStats" class="mt-20 flex items-center">
- <view class="flex-1 text-center">
- <view class="text-40 text-fore-title font-bold">{{ totalQuestions }}</view>
- <view class="mt-5 text-28 text-fore-light">题量</view>
- </view>
- <view class="flex-1 text-center">
- <view class="text-40 text-fore-title font-bold">{{ paperInfo.score }}</view>
- <view class="mt-5 text-28 text-fore-light">总分</view>
- </view>
- <view class="flex-1 text-center">
- <view class="text-40 text-fore-title font-bold">{{ stats.score }}</view>
- <view class="mt-5 text-28 text-fore-light">得分</view>
- </view>
- <view class="flex-1 text-center">
- <view class="text-40 text-fore-title font-bold">{{ stats.rate }}%</view>
- <view class="mt-5 text-28 text-fore-light">正确率</view>
- </view>
- </view>
- <view v-if="showStats" class="h-1 bg-[#E6E6E6] my-20 mb-40 "></view>
- <view class="flex items-center justify-end gap-x-30">
- <view class="flex items-center gap-x-12" :class="{ 'is-filter': !filterTypes.includes('correct') }"
- @click="handleFilter('correct')">
- <view class="icon w-18 h-18 rounded-full bg-[#2CC6A0]"></view>
- <view class="legend text-20 text-fore-subtitle">答对</view>
- </view>
- <view class="flex items-center gap-x-12" :class="{ 'is-filter': !filterTypes.includes('incorrect') }"
- @click="handleFilter('incorrect')">
- <view class="icon w-18 h-18 rounded-full bg-[#FF5B5C]"></view>
- <view class="legend text-20 text-fore-subtitle">答错</view>
- </view>
- <view class="flex items-center gap-x-12" :class="{ 'is-filter': !filterTypes.includes('unanswered') }"
- @click="handleFilter('unanswered')">
- <view class="icon w-18 h-18 rounded-full is-unanswered"></view>
- <view class="legend text-20 text-fore-subtitle">未答</view>
- </view>
- </view>
- <view class="mt-30 grid grid-cols-5 gap-x-10 gap-y-30 place-items-center">
- <view class="question-item" v-for="item in questionList" :key="item.id"
- :class="[item.isNotAnswer ? 'is-unanswered' : (item.isRight ? 'is-correct' : 'is-incorrect')]"
- @click="handleDetail(item)">
- <view class="text-36 font-bold">{{ item.originalIndex }}</view>
- </view>
- </view>
- </view>
- </template>
- <script lang="ts" setup>
- import { EnumPaperType, EnumQuestionType } from '@/common/enum';
- import { useTransferPage } from '@/hooks/useTransferPage';
- import { Study } from '@/types';
- const { transferTo } = useTransferPage();
- const emit = defineEmits<{
- (e: 'detail', item: Study.ExamineeQuestion): void;
- }>();
- const props = defineProps<{
- data: Study.Examinee;
- showStats: boolean;
- }>();
- interface QuestionItem extends Study.ExamineeQuestion {
- originalIndex?: number;
- isRight?: boolean;
- isNotAnswer?: boolean;
- }
- const paperInfo = computed(() => {
- return props.data.paperInfo || {};
- });
- const stats = computed(() => {
- return props.data.stats || {};
- });
- const totalQuestions = computed(() => {
- return (props.data.questions || []).length;
- });
- const filterTypes = ref<('correct' | 'incorrect' | 'unanswered')[]>(['correct', 'incorrect', 'unanswered']);
- const questionList = computed(() => {
- const list: QuestionItem[] = [];
- let offset = 0 ;
- (props.data.questions || []).forEach((item, index) => {
- if (item.subQuestions && item.subQuestions.length > 0) {
- item.subQuestions.forEach((subItem, subIndex) => {
- offset++;
- list.push({
- ...subItem,
- originalIndex: index + subIndex + 1, // 保存原始序号
- isRight: judgeCorrect(subItem),
- isNotAnswer: !subItem.answers.filter(item => item !== ' ').length
- });
- });
- } else {
- list.push({
- ...item,
- originalIndex: index + offset + 1, // 保存原始序号
- isRight: judgeCorrect(item),
- isNotAnswer: !item.answers.filter(item => item !== ' ').length
- });
- }
- });
- return list.filter((item: QuestionItem) => {
- // 判断是否答对
- if (item.isRight && filterTypes.value.includes('correct')) {
- return true;
- }
- // 判断是否答错(答了但是错了)
- if (!item.isRight && !item.isNotAnswer && filterTypes.value.includes('incorrect')) {
- return true;
- }
- // 判断是否未答
- if (item.isNotAnswer && filterTypes.value.includes('unanswered')) {
- return true;
- }
- return false;
- });
- });
- const judgeCorrect = (qs: Study.ExamineeQuestion) => {
- if (qs.typeId === EnumQuestionType.SINGLE_CHOICE
- || qs.typeId === EnumQuestionType.JUDGMENT) {
- return qs.answers.includes(qs.answer1);
- } else if (qs.typeId === EnumQuestionType.MULTIPLE_CHOICE) {
- const rightAnswers = qs.answer1.split('').filter(item => item !== ' ');
- return rightAnswers.length === qs.answers.length && rightAnswers.every(item => qs.answers.includes(item));
- }
- }
- const handleFilter = (type: 'correct' | 'incorrect' | 'unanswered') => {
- if (filterTypes.value.includes(type)) {
- filterTypes.value = filterTypes.value.filter(item => item !== type);
- } else {
- filterTypes.value.push(type);
- }
- console.log(filterTypes.value)
- }
- const handleDetail = (item: Study.ExamineeQuestion) => {
- emit('detail', item);
- }
- </script>
- <style lang="scss" scoped>
- .question-item {
- @apply w-80 h-80 rounded-full overflow-hidden flex items-center justify-center text-20 text-fore-subtitle;
- }
- .is-unanswered {
- background: #EEF4FA;
- color: #B3B3B3;
- }
- .is-correct {
- background: #E7FCF8;
- color: #2CC6A0;
- }
- .is-incorrect {
- background: #FEEDE9;
- color: #FF5B5C;
- }
- .is-filter {
- .icon {
- background: #bbbbbb;
- }
- .legend {
- color: #bbbbbb;
- }
- }
- </style>
|