feat(exam): 增加试卷结果分页查询接口及前端显示功能

- 新增ExamWordsResultReqVO和ExamWordsResultRspVO用于请求与响应封装
- ExamWordsController新增getExamWordsResult方法支持分页查询试卷结果
- ExamWordsJudgeService接口及实现中添加分页获取试卷结果方法及统计总数
- Mapper层添加分页查询和统计的SQL语句支持
- Vue前端uploadpng页面优化为两列布局,新增结果集表格与分页控件
- 上传功能改用自定义http-request,上传后自动刷新结果列表
- Class页面调整布局增加额外展示内容
- 删除未使用接口ExamWordsJudge接口及相关引用
- 重命名ExamWordsJudge相关类和测试类以统一命名规范
This commit is contained in:
lbw
2025-12-14 12:49:53 +08:00
parent 9a11a7c094
commit c1b3c92244
24 changed files with 904 additions and 38 deletions

View File

@@ -0,0 +1,113 @@
<template>
<div class="common-layout">
<el-container>
<el-header>
<Header></Header>
</el-header>
<el-main class="p-4">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
<div class="text-lg font-semibold mb-4">上传图片</div>
<el-upload
:show-file-list="false"
:http-request="doUpload"
accept="image/*"
>
<el-button type="primary">选择图片并上传</el-button>
</el-upload>
</div>
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6">
<div class="text-lg font-semibold mb-4">结果集</div>
<el-table
:data="list"
border
class="w-full"
v-loading="loading"
>
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="studentId" label="学生ID" width="100" />
<el-table-column prop="examWordsId" label="试题ID" width="100" />
<el-table-column prop="correctWordCount" label="正确词数" width="110" />
<el-table-column prop="wrongWordCount" label="错误词数" width="110" />
<el-table-column label="完成状态" width="110">
<template #default="{ row }">
<el-tag :type="row.isFinished === 1 ? 'success' : 'info'">
{{ row.isFinished === 1 ? '已完成' : '未完成' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="startDate" label="开始时间" min-width="160" />
<el-table-column prop="errorMsg" label="错误信息" min-width="160" />
</el-table>
<div class="mt-4 flex justify-end">
<el-pagination
background
layout="prev, pager, next, sizes, total"
:total="totalCount"
:page-size="pageSize"
:current-page="pageNo"
@current-change="handlePageChange"
@size-change="handleSizeChange"
/>
</div>
</div>
</div>
</el-main>
</el-container>
</div>
</template>
<script setup>
import Header from '@/layouts/components/Header.vue'
import { ref, onMounted } from 'vue'
import { uploadExamWordsPng, getExamWordsResult } from '@/api/exam'
const list = ref([])
const pageNo = ref(1)
const pageSize = ref(10)
const totalCount = ref(0)
const loading = ref(false)
async function fetchList() {
loading.value = true
try {
const res = await getExamWordsResult(pageNo.value, pageSize.value)
const d = res.data
list.value = Array.isArray(d.data) ? d.data : []
totalCount.value = d.totalCount || 0
pageNo.value = d.pageNo || pageNo.value
pageSize.value = d.pageSize || pageSize.value
} finally {
loading.value = false
}
}
function handlePageChange(p) {
pageNo.value = p
fetchList()
}
function handleSizeChange(s) {
pageSize.value = s
pageNo.value = 1
fetchList()
}
async function doUpload(options) {
const file = options.file
const formData = new FormData()
formData.append('file', file)
await uploadExamWordsPng(formData)
ElMessage.success('上传成功,已开始生成结果')
fetchList()
}
onMounted(() => {
fetchList()
})
</script>
<style scoped>
</style>