forked from liweijie/education
1. 机关教学日志2.新增全局表格横向拖拽滚动指令3.学员模块
This commit is contained in:
@@ -1,15 +1,249 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<placeholder-page title="学员成绩管理" icon="form"
|
||||
description="用于管理学员各课程的考核成绩,支持录入、查询、统计与导出。" />
|
||||
<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>
|
||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||
<el-table-column prop="xybh" label="学员编号" width="110" show-overflow-tooltip />
|
||||
<el-table-column prop="kmbh" label="科目编号" width="110" show-overflow-tooltip />
|
||||
<el-table-column prop="klx" label="课类型" width="90" align="center" />
|
||||
<el-table-column prop="kscj" label="考试成绩" width="90" align="center" />
|
||||
<el-table-column prop="pscj" label="平时成绩" width="90" align="center" />
|
||||
<el-table-column prop="zzcj" label="最终成绩" width="90" align="center" />
|
||||
<el-table-column prop="bkcj" label="补考成绩" width="90" align="center" />
|
||||
<el-table-column prop="bkcs" label="补考次数" width="90" align="center" />
|
||||
<el-table-column prop="ksqk" label="考试情况" width="90" align="center" />
|
||||
<el-table-column prop="qwxf" label="期望学分" width="90" align="center" />
|
||||
<el-table-column prop="ytg" label="已通过" width="80" align="center" />
|
||||
<el-table-column prop="nd" label="年度" 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>
|
||||
<el-table-column type="index" label="序号" width="55" align="center" />
|
||||
<el-table-column prop="xybh" label="学员编号" width="110" show-overflow-tooltip />
|
||||
<el-table-column prop="kmbh" label="科目编号" width="110" show-overflow-tooltip />
|
||||
<el-table-column prop="klx" label="课类型" width="90" align="center" />
|
||||
<el-table-column prop="yscj" label="原始成绩" width="90" align="center" />
|
||||
<el-table-column prop="zzcj" label="最终成绩" width="90" align="center" />
|
||||
<el-table-column prop="bkcj1" label="补考1" width="80" align="center" />
|
||||
<el-table-column prop="bkcj2" label="补考2" width="80" align="center" />
|
||||
<el-table-column prop="bkcj3" label="补考3" width="80" align="center" />
|
||||
<el-table-column prop="ksqk" label="考试情况" width="90" align="center" />
|
||||
<el-table-column prop="nd" label="年度" 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 PlaceholderPage from "@/components/PlaceholderPage"
|
||||
import {
|
||||
listStudentGrades,
|
||||
listStudentProcessGrades,
|
||||
exportStudentGrades,
|
||||
exportStudentProcessGrades
|
||||
} from "@/api/studentRecords/studentRecords"
|
||||
|
||||
export default {
|
||||
name: "Score",
|
||||
components: { PlaceholderPage }
|
||||
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>
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.score-page {
|
||||
padding: 20px;
|
||||
|
||||
.search-card {
|
||||
margin-bottom: 16px;
|
||||
|
||||
.search-form {
|
||||
.el-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.table-card {
|
||||
.el-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user