electron-vue-exam-single/src/views/user/EndView.vue
2025-08-12 22:35:36 +08:00

276 lines
8.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="end-container">
<el-container>
<Header />
<!-- 主要内容区域 -->
<el-main>
<div style="width: 100%; height: 100%;">
<div class="d-flex align-items-center justify-content-center p-4" style="width:100%">
<!-- 交卷结果卡片 -->
<div class="bg-white rounded-4 shadow-lg p-4 w-100 max-w-2xl border-2 border-primary/20">
<el-result icon="success" title="考试已完成" sub-title="您已成功提交试卷感谢您的参与">
<!--
<template #extra>
<p v-if="pdfPath">{{ pdfPath.filePath }}</p>
</template>
-->
</el-result>
<el-divider />
<div class="flex justify-between text-center mt-6 mb-4">
<h2 class="text-2xl font-bold text-primary">考生信息</h2>
</div>
<!-- 考生信息部分 -->
<el-descriptions class="margin-top" :column="3" :size="size" border>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon :style="iconStyle">
<User />
</el-icon>
姓名
</div>
</template>
{{ examinee?.examinee_name }}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon :style="iconStyle">
<Postcard />
</el-icon>
身份证号
</div>
</template>
{{ formatIdCard(examinee?.examinee_id_card) }}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon :style="iconStyle">
<Ticket />
</el-icon>
准考证号
</div>
</template>
{{ examinee?.examinee_admission_ticket }}
</el-descriptions-item>
</el-descriptions>
<el-divider />
<div class="flex justify-between text-center mt-6 mb-4">
<h2 class="text-2xl font-bold text-primary">考试信息</h2>
</div>
<!-- 试卷信息部分 -->
<el-descriptions class="margin-top" :column="2" :size="size" border>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon :style="iconStyle">
<Clock />
</el-icon>
开始时间
</div>
</template>
{{ formatDateTime(paper?.paper_start_time) }}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon :style="iconStyle">
<Clock />
</el-icon>
结束时间
</div>
</template>
{{ formatDateTime(paper?.paper_end_time) }}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<div class="cell-item">
<el-icon :style="iconStyle">
<Timer />
</el-icon>
总使用时间
</div>
</template>
{{ formatDuration(paper?.paper_start_time, paper?.paper_end_time) }}
</el-descriptions-item>
</el-descriptions>
</div>
</div>
</div>
</el-main>
<Footer />
</el-container>
</div>
</template>
<script setup>
// 导入组件
import Header from '@/components/common/Header.vue'
import Footer from '@/components/common/Footer.vue'
import { useRouter } from 'vue-router'
import { ref, computed, onMounted } from 'vue'
import { ElMessage, ElDescriptions, ElDescriptionsItem, ElIcon, ElResult } from 'element-plus'
import { User, Postcard, Ticket, Clock, Timer } from '@element-plus/icons-vue'
// 导入用户状态管理
import { useUserStore } from '@/store/userStore'
// 获取用户状态管理
const userStore = useUserStore()
// 响应式引用考生数据
const examinee = computed(() => userStore.state.examinee)
// 响应式引用试卷数据
const paper = computed(() => userStore.state.paper)
// 添加判卷状态变量
const isChecking = ref(false)
// 检查是否已登录
if (!userStore.state.isLoggedIn) {
// 如果未登录,重定向到欢迎页
router.push('/')
}
// 响应式数据
const router = useRouter()
const size = ref('default')
const pdfPath = ref('')
// 图标样式计算属性
const iconStyle = computed(() => {
const marginMap = {
large: '8px',
default: '6px',
small: '4px',
}
return {
marginRight: marginMap[size.value] || marginMap.default,
}
})
// 格式化身份证号第11-15位替换为*
const formatIdCard = (idCard) => {
if (!idCard || idCard.length !== 18) return idCard
return idCard.substring(0, 9) + '*****' + idCard.substring(14)
}
// 格式化日期时间
const formatDateTime = (dateTime) => {
if (!dateTime) return '未知'
const date = new Date(dateTime)
return date.toLocaleString()
}
// 计算考试持续时间
const formatDuration = (startTime, endTime) => {
if (!startTime || !endTime) return '未知'
const start = new Date(startTime)
const end = new Date(endTime)
const diff = end - start
const minutes = Math.floor(diff / (1000 * 60))
return `${minutes}分钟`
// const hours = Math.floor(minutes / 60)
// const mins = minutes % 60
// return `${hours}小时${mins}分钟`
}
// 返回首页
const goHome = () => {
router.push({ name: 'examinee-home' })
}
// 组件挂载时
onMounted(() => {
console.log('EndView初始化')
// 检查是否有试卷数据
if (!paper.value) {
ElMessage.warning('未找到试卷信息')
console.log('未找到试卷信息,准备跳转到首页')
// 延迟重定向到首页
setTimeout(() => {
goHome()
}, 2000)
} else {
// 有试卷数据,执行判卷
checkAnswers()
}
})
// 判卷函数
const checkAnswers = async () => {
try {
isChecking.value = true
console.log('开始判卷试卷ID:', paper.value.id)
// 调用检查答案接口
const result = await window.electronAPI.checkPaperAnswers(paper.value.id)
console.log('判卷接口返回结果:', result)
if (result.success) {
// 调用 generatePaperPdf 接口并传入 result.data
pdfPath.value = await window.electronAPI.generatePaperPdf(result.data)
console.log('生成的试卷PDF文件路径:', pdfPath.value)
// 更新store中的试卷数据
userStore.setPaper(JSON.parse(result.data))
console.log("paper.value: ", paper.value)
console.log('试卷数据已更新到store得分:', result.data.paper_score_real)
} else {
console.error('判卷失败:', result.message)
}
} catch (error) {
console.error('判卷过程发生错误:', error)
} finally {
isChecking.value = false
console.log('判卷完成')
}
}
</script>
<style scoped>
/* 自定义样式 */
.bg-primary {
background-color: #1E88E5 !important;
/* 蓝色主题与ExamineeHomeView保持一致 */
}
.text-primary {
color: #1E88E5 !important;
}
/* 确保容器占满高度 */
.end-container,
.el-container {
height: 100vh;
display: flex;
flex-direction: column;
}
/* 让主内容区自动扩展并居中 */
.el-main {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
/* 适配移动设备 */
@media (max-width: 640px) {
.max-w-2xl {
max-width: 100%;
}
}
.cell-item {
display: flex;
align-items: center;
}
.margin-top {
margin-top: 20px !important;
}
</style>