<script lang="ts" setup>
|
import type { OnlineExamDetail } from './types';
|
|
import { onMounted, ref } from 'vue';
|
import { useRoute, useRouter } from 'vue-router';
|
|
import { useMessage } from '@jnpf/hooks';
|
import {
|
Descriptions as ADescriptions,
|
DescriptionsItem as ADescriptionsItem,
|
Spin,
|
} from 'ant-design-vue';
|
|
import { getMyPaperDetail, startOnlineExam } from '#/api/x/tms/onlineExam';
|
|
import { colorOfMyPaperStatus, labelOfMyPaperStatus } from './constants';
|
|
defineOptions({ name: 'TmsOnlineExamDetail' });
|
|
const route = useRoute();
|
const router = useRouter();
|
const { createMessage } = useMessage();
|
|
const loading = ref(false);
|
const starting = ref(false);
|
const detail = ref<OnlineExamDetail | null>(null);
|
|
onMounted(() => {
|
loadDetail();
|
});
|
|
async function loadDetail() {
|
const id = String(route.params.id || '');
|
if (!id) {
|
router.replace('/tms/onlineExam');
|
return;
|
}
|
loading.value = true;
|
try {
|
detail.value = await getMyPaperDetail(id);
|
} catch (e: any) {
|
createMessage.error(e?.message || '加载详情失败');
|
router.replace('/tms/onlineExam');
|
} finally {
|
loading.value = false;
|
}
|
}
|
|
function goBack() {
|
router.push('/tms/onlineExam');
|
}
|
|
async function handleStart() {
|
if (!detail.value || starting.value) return;
|
starting.value = true;
|
try {
|
const paper = await startOnlineExam(detail.value.id);
|
sessionStorage.setItem('tms_online_exam_paper', JSON.stringify(paper));
|
sessionStorage.setItem('tms_online_exam_myPaperId', detail.value.id);
|
router.push('/tms/onlineExam/exam');
|
} catch (e: any) {
|
createMessage.error(e?.message || '开始考试失败');
|
} finally {
|
starting.value = false;
|
}
|
}
|
</script>
|
|
<template>
|
<div class="jnpf-content-wrapper">
|
<div class="jnpf-content-wrapper-center">
|
<div class="jnpf-content-wrapper-content tms-exam-detail-page">
|
<Spin :spinning="loading">
|
<div class="tms-exam-detail-header">
|
<div class="text-base font-medium">考试详情</div>
|
<a-space>
|
<a-button @click="goBack">返回列表</a-button>
|
<a-button
|
v-if="detail && detail.status !== 'submitted'"
|
type="primary"
|
:loading="starting"
|
@click="handleStart"
|
>
|
{{ detail?.status === 'doing' ? '继续考试' : '开始考试' }}
|
</a-button>
|
</a-space>
|
</div>
|
|
<ADescriptions v-if="detail" bordered :column="2" size="middle">
|
<ADescriptionsItem label="试卷名称" :span="2">{{ detail.paperName }}</ADescriptionsItem>
|
<ADescriptionsItem label="状态">
|
<span :style="{ color: colorOfMyPaperStatus(detail.status) }">
|
{{ labelOfMyPaperStatus(detail.status) }}
|
</span>
|
</ADescriptionsItem>
|
<ADescriptionsItem label="卷面总分">{{ detail.totalScore }}</ADescriptionsItem>
|
<ADescriptionsItem label="考试时间" :span="2">{{ detail.examTimeText || '-' }}</ADescriptionsItem>
|
<ADescriptionsItem label="考试时长">
|
{{ detail.durationMin != null ? `${detail.durationMin} 分钟` : '-' }}
|
</ADescriptionsItem>
|
<ADescriptionsItem label="合格分数">{{ detail.passScore ?? '-' }}</ADescriptionsItem>
|
<ADescriptionsItem label="开始时间">{{ detail.startTime || '-' }}</ADescriptionsItem>
|
<ADescriptionsItem label="交卷时间">{{ detail.submitTime || '-' }}</ADescriptionsItem>
|
<ADescriptionsItem label="得分">
|
{{ detail.gotScore != null ? detail.gotScore : '-' }}
|
</ADescriptionsItem>
|
<ADescriptionsItem label="是否合格">
|
<template v-if="detail.passFlag === '1'">合格</template>
|
<template v-else-if="detail.passFlag === '0'">不合格</template>
|
<template v-else>-</template>
|
</ADescriptionsItem>
|
</ADescriptions>
|
</Spin>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<style scoped>
|
.tms-exam-detail-page {
|
background: #fff;
|
padding: 20px 24px;
|
height: 100%;
|
overflow: auto;
|
}
|
|
.tms-exam-detail-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 20px;
|
padding-bottom: 12px;
|
border-bottom: 1px solid #f0f0f0;
|
}
|
</style>
|