<script lang="ts" setup>
|
import type { TmsQuizAnswerPaper } from '#/views/x/tms/record/types';
|
|
import { computed } from 'vue';
|
|
const props = withDefaults(
|
defineProps<{
|
paper: TmsQuizAnswerPaper | null;
|
loading?: boolean;
|
/** 学员答案 / 我的答案 */
|
answerLabel?: string;
|
}>(),
|
{
|
loading: false,
|
answerLabel: '学员答案',
|
},
|
);
|
|
const passed = computed(() => {
|
const f = props.paper?.passFlag;
|
return f === 'pass' || f === '1';
|
});
|
|
const passText = computed(() => {
|
if (passed.value) return '合格';
|
const f = props.paper?.passFlag;
|
if (f === 'fail' || f === '0') return '不合格';
|
return f || '-';
|
});
|
|
const correctCount = computed(() => (props.paper?.items || []).filter((x) => x.correct).length);
|
const totalCount = computed(() => (props.paper?.items || []).length);
|
</script>
|
|
<template>
|
<a-spin :spinning="loading">
|
<div v-if="paper" class="quiz-paper">
|
<div class="quiz-paper__summary" :class="passed ? 'is-pass' : 'is-fail'">
|
<div class="quiz-paper__score-block">
|
<div class="quiz-paper__score-num">{{ paper.totalScore ?? '-' }}</div>
|
<div class="quiz-paper__score-label">总分</div>
|
</div>
|
<div class="quiz-paper__summary-main">
|
<div class="quiz-paper__result">
|
<span class="quiz-paper__badge" :class="passed ? 'ok' : 'bad'">
|
{{ passText }}
|
</span>
|
<span class="quiz-paper__ratio">答对 {{ correctCount }}/{{ totalCount }} 题</span>
|
</div>
|
<div class="quiz-paper__time">提交时间:{{ paper.quizTime || '-' }}</div>
|
</div>
|
</div>
|
|
<div class="quiz-paper__list">
|
<div
|
v-for="(it, idx) in paper.items || []"
|
:key="it.id || idx"
|
class="quiz-paper__item"
|
:class="it.correct ? 'is-ok' : 'is-bad'"
|
>
|
<div class="quiz-paper__head">
|
<span class="quiz-paper__no">第 {{ it.sortNo ?? idx + 1 }} 题</span>
|
<span class="quiz-paper__badge sm" :class="it.correct ? 'ok' : 'bad'">
|
{{ it.correct ? '正确' : '错误' }}
|
</span>
|
<span class="quiz-paper__got">得分 {{ it.score ?? 0 }}</span>
|
</div>
|
<div class="quiz-paper__stem">{{ it.question || '-' }}</div>
|
<div class="quiz-paper__compare">
|
<div class="quiz-paper__row">
|
<span class="quiz-paper__k">{{ answerLabel }}</span>
|
<span class="quiz-paper__v" :class="it.correct ? 'ok' : 'bad'">
|
{{ it.userAnswer || '(未作答)' }}
|
</span>
|
</div>
|
<div class="quiz-paper__row">
|
<span class="quiz-paper__k">参考答案</span>
|
<span class="quiz-paper__v ref">{{ it.refAnswer || '-' }}</span>
|
</div>
|
</div>
|
</div>
|
<a-empty v-if="!(paper.items || []).length" description="暂无答卷明细" />
|
</div>
|
</div>
|
</a-spin>
|
</template>
|
|
<style scoped>
|
.quiz-paper {
|
padding: 4px 2px 8px;
|
}
|
|
.quiz-paper__summary {
|
display: flex;
|
gap: 20px;
|
align-items: center;
|
padding: 20px 22px;
|
margin-bottom: 20px;
|
border-radius: 10px;
|
border: 1px solid #f0f0f0;
|
background: #fafafa;
|
}
|
|
.quiz-paper__summary.is-pass {
|
border-color: #b7eb8f;
|
background: #f6ffed;
|
}
|
|
.quiz-paper__summary.is-fail {
|
border-color: #ffccc7;
|
background: #fff2f0;
|
}
|
|
.quiz-paper__score-block {
|
min-width: 88px;
|
text-align: center;
|
padding-right: 20px;
|
border-right: 1px solid rgba(0, 0, 0, 0.06);
|
}
|
|
.quiz-paper__score-num {
|
font-size: 32px;
|
font-weight: 600;
|
line-height: 1.15;
|
color: rgba(0, 0, 0, 0.88);
|
}
|
|
.quiz-paper__score-label {
|
margin-top: 8px;
|
font-size: 13px;
|
color: rgba(0, 0, 0, 0.45);
|
}
|
|
.quiz-paper__summary-main {
|
flex: 1;
|
min-width: 0;
|
}
|
|
.quiz-paper__result {
|
display: flex;
|
flex-wrap: wrap;
|
align-items: center;
|
gap: 12px;
|
margin-bottom: 10px;
|
}
|
|
.quiz-paper__ratio {
|
font-size: 14px;
|
color: rgba(0, 0, 0, 0.65);
|
}
|
|
.quiz-paper__time {
|
font-size: 13px;
|
line-height: 1.5;
|
color: rgba(0, 0, 0, 0.45);
|
}
|
|
.quiz-paper__badge {
|
display: inline-flex;
|
align-items: center;
|
height: 28px;
|
padding: 0 12px;
|
border-radius: 4px;
|
font-size: 13px;
|
font-weight: 500;
|
line-height: 1;
|
}
|
|
.quiz-paper__badge.sm {
|
height: 24px;
|
padding: 0 10px;
|
font-size: 12px;
|
}
|
|
.quiz-paper__badge.ok {
|
color: #389e0d;
|
background: #f6ffed;
|
border: 1px solid #b7eb8f;
|
}
|
|
.quiz-paper__badge.bad {
|
color: #cf1322;
|
background: #fff2f0;
|
border: 1px solid #ffccc7;
|
}
|
|
.quiz-paper__list {
|
max-height: min(62vh, 560px);
|
overflow: auto;
|
padding-right: 4px;
|
}
|
|
.quiz-paper__item {
|
padding: 18px 18px 16px;
|
margin-bottom: 14px;
|
border: 1px solid #f0f0f0;
|
border-radius: 10px;
|
border-left-width: 3px;
|
background: #fff;
|
}
|
|
.quiz-paper__item.is-ok {
|
border-left-color: #52c41a;
|
}
|
|
.quiz-paper__item.is-bad {
|
border-left-color: #ff4d4f;
|
}
|
|
.quiz-paper__item:last-child {
|
margin-bottom: 0;
|
}
|
|
.quiz-paper__head {
|
display: flex;
|
flex-wrap: wrap;
|
align-items: center;
|
gap: 10px;
|
margin-bottom: 12px;
|
}
|
|
.quiz-paper__no {
|
font-size: 14px;
|
font-weight: 600;
|
color: rgba(0, 0, 0, 0.88);
|
}
|
|
.quiz-paper__got {
|
margin-left: auto;
|
font-size: 13px;
|
color: rgba(0, 0, 0, 0.45);
|
}
|
|
.quiz-paper__stem {
|
margin-bottom: 14px;
|
font-size: 15px;
|
font-weight: 500;
|
line-height: 1.65;
|
white-space: pre-wrap;
|
color: rgba(0, 0, 0, 0.88);
|
}
|
|
.quiz-paper__compare {
|
display: flex;
|
flex-direction: column;
|
gap: 12px;
|
padding: 14px 16px;
|
border-radius: 8px;
|
background: #fafafa;
|
}
|
|
.quiz-paper__row {
|
display: grid;
|
grid-template-columns: 80px 1fr;
|
gap: 12px;
|
align-items: start;
|
font-size: 14px;
|
line-height: 1.65;
|
}
|
|
.quiz-paper__k {
|
padding-top: 1px;
|
color: rgba(0, 0, 0, 0.45);
|
}
|
|
.quiz-paper__v {
|
white-space: pre-wrap;
|
word-break: break-word;
|
color: rgba(0, 0, 0, 0.88);
|
}
|
|
.quiz-paper__v.ok {
|
color: #389e0d;
|
}
|
|
.quiz-paper__v.bad {
|
color: #cf1322;
|
}
|
|
.quiz-paper__v.ref {
|
color: rgba(0, 0, 0, 0.65);
|
}
|
</style>
|
|
<style>
|
.tms-quiz-paper-modal .ant-modal-body {
|
padding: 20px 24px 24px;
|
}
|
</style>
|