Files
education/frontend/src/views/student/score/index.vue
T
2026-08-24 14:48:08 +08:00

231 lines
8.4 KiB
Vue

<template>
<div class="app-container score-page">
<!-- ==================== 1. 查询条件区域 ==================== -->
<el-card shadow="never" class="search-card">
<el-form :model="queryForm" label-width="90px" inline class="search-form">
<el-form-item label="学员编号">
<el-input v-model="queryForm.xybh" placeholder="请输入学员编号" clearable style="width: 200px" />
</el-form-item>
<el-form-item label="年度">
<el-input v-model="queryForm.nd" placeholder="如 2026" clearable style="width: 140px" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch">查询</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- ==================== 2. 成绩列表区域 ==================== -->
<div class="toolbar">
<el-button type="primary" :loading="exportLoading" @click="handleExportGrades">导出课程成绩</el-button>
<el-button type="primary" :loading="exportLoading" @click="handleExportProcessGrades">导出课程过程成绩</el-button>
</div>
<el-card shadow="never" class="table-card">
<el-tabs v-model="activeTab">
<!-- 课程成绩 -->
<el-tab-pane label="课程成绩" name="grades">
<el-table v-loading="loading" :data="gradesData" stripe border style="width: 100%">
<el-table-column type="index" label="序号" width="55" align="center" />
<el-table-column prop="xybh" label="学员编号" min-width="110" show-overflow-tooltip />
<el-table-column prop="kmbh" label="科目编号" min-width="110" show-overflow-tooltip />
<el-table-column prop="klx" label="课类型" min-width="90" align="center" />
<el-table-column prop="kscj" label="考试成绩" min-width="90" align="center" />
<el-table-column prop="pscj" label="平时成绩" min-width="90" align="center" />
<el-table-column prop="zzcj" label="最终成绩" min-width="90" align="center" />
<el-table-column prop="bkcj" label="补考成绩" min-width="90" align="center" />
<el-table-column prop="bkcs" label="补考次数" min-width="90" align="center" />
<el-table-column prop="ksqk" label="考试情况" min-width="90" align="center" />
<el-table-column prop="qwxf" label="期望学分" min-width="90" align="center" />
<el-table-column prop="ytg" label="已通过" min-width="80" align="center" />
<el-table-column prop="nd" label="年度" min-width="80" align="center" />
</el-table>
<el-empty v-if="!loading && gradesData.length === 0" description="暂无课程成绩数据" :image-size="60" />
</el-tab-pane>
<!-- 课程过程成绩 -->
<el-tab-pane label="课程过程成绩" name="process">
<el-table v-loading="loading" :data="processGradesData" stripe border style="width: 100%">
<el-table-column type="index" label="序号" width="55" align="center" />
<el-table-column prop="xybh" label="学员编号" min-width="110" show-overflow-tooltip />
<el-table-column prop="kmbh" label="科目编号" min-width="110" show-overflow-tooltip />
<el-table-column prop="klx" label="课类型" min-width="90" align="center" />
<el-table-column prop="yscj" label="原始成绩" min-width="90" align="center" />
<el-table-column prop="zzcj" label="最终成绩" min-width="90" align="center" />
<el-table-column prop="bkcj1" label="补考1" min-width="80" align="center" />
<el-table-column prop="bkcj2" label="补考2" min-width="80" align="center" />
<el-table-column prop="bkcj3" label="补考3" min-width="80" align="center" />
<el-table-column prop="ksqk" label="考试情况" min-width="90" align="center" />
<el-table-column prop="nd" label="年度" min-width="80" align="center" />
</el-table>
<el-empty v-if="!loading && processGradesData.length === 0" description="暂无课程过程成绩数据" :image-size="60" />
</el-tab-pane>
</el-tabs>
<div class="pagination">
<el-pagination
:current-page="pagination.pageNum"
:page-size="pagination.pageSize"
:total="pagination.total"
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
background
@size-change="handleSizeChange"
@current-change="handlePageChange"
/>
</div>
</el-card>
</div>
</template>
<script>
import {
listStudentGrades,
listStudentProcessGrades,
exportStudentGrades,
exportStudentProcessGrades
} from "@/api/studentRecords/studentRecords"
export default {
name: 'ScoreIndex',
data() {
return {
// ==================== 查询条件 ====================
queryForm: {
xybh: '',
nd: ''
},
// ==================== 数据表格 ====================
// 数据来源:grades 课程成绩 / process 课程过程成绩
activeTab: 'grades',
loading: false,
gradesData: [],
processGradesData: [],
pagination: { pageNum: 1, pageSize: 20, total: 0 },
// ==================== 导出 ====================
exportLoading: false
}
},
watch: {
activeTab() {
this.handleSearch()
}
},
mounted() {
this.loadData()
},
methods: {
/** 组装查询参数,仅传非空值 */
buildQueryParams(params) {
const xybh = this.queryForm.xybh && this.queryForm.xybh.trim()
const nd = this.queryForm.nd && this.queryForm.nd.trim()
if (xybh) params.xybh = xybh
if (nd) params.nd = nd
},
loadData() {
this.loading = true
const params = {
pageNum: this.pagination.pageNum,
pageSize: this.pagination.pageSize
}
this.buildQueryParams(params)
const request = this.activeTab === 'grades' ? listStudentGrades(params) : listStudentProcessGrades(params)
request.then(res => {
const data = res.data || {}
const records = data.records || []
if (this.activeTab === 'grades') {
this.gradesData = records
} else {
this.processGradesData = records
}
this.pagination.total = data.total || 0
this.loading = false
}).catch(() => {
if (this.activeTab === 'grades') {
this.gradesData = []
} else {
this.processGradesData = []
}
this.pagination.total = 0
this.loading = false
})
},
handleSearch() {
this.pagination.pageNum = 1
this.loadData()
},
handlePageChange(page) {
this.pagination.pageNum = page
this.loadData()
},
handleSizeChange(size) {
this.pagination.pageSize = size
this.pagination.pageNum = 1
this.loadData()
},
/** 通用 blob 下载 */
downloadBlob(blob, filename) {
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = filename
link.click()
URL.revokeObjectURL(link.href)
},
/** 校验导出所需学员编号 */
requireXybh(exportName) {
const xybh = this.queryForm.xybh && this.queryForm.xybh.trim()
if (!xybh) {
this.$message.warning('导出' + exportName + '前请先输入学员编号')
return null
}
return xybh
},
/** 导出课程成绩 Excel */
handleExportGrades() {
const xybh = this.requireXybh('课程成绩')
if (!xybh) return
this.exportLoading = true
exportStudentGrades(xybh).then(res => {
this.downloadBlob(res, `课程成绩_${xybh}.xls`)
this.$message.success('课程成绩导出成功')
}).catch(() => {}).finally(() => {
this.exportLoading = false
})
},
/** 导出课程过程成绩 Excel */
handleExportProcessGrades() {
const xybh = this.requireXybh('课程过程成绩')
if (!xybh) return
this.exportLoading = true
exportStudentProcessGrades(xybh).then(res => {
this.downloadBlob(res, `课程过程成绩_${xybh}.xls`)
this.$message.success('课程过程成绩导出成功')
}).catch(() => {}).finally(() => {
this.exportLoading = false
})
}
}
}
</script>
<style scoped lang="scss">
.score-page {
.toolbar {
margin-bottom: 16px;
}
.table-card {
.el-table {
width: 100%;
}
}
}
</style>