|
|
|
|
@ -42,7 +42,7 @@
|
|
|
|
|
icon="el-icon-plus"
|
|
|
|
|
size="mini"
|
|
|
|
|
@click="handleAdd"
|
|
|
|
|
v-hasPermi="['course:student:add']"
|
|
|
|
|
v-hasPermi="['courses:student:add']"
|
|
|
|
|
>新增</el-button>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="1.5">
|
|
|
|
|
@ -53,7 +53,7 @@
|
|
|
|
|
size="mini"
|
|
|
|
|
:disabled="multiple"
|
|
|
|
|
@click="handleDelete"
|
|
|
|
|
v-hasPermi="['course:student:remove']"
|
|
|
|
|
v-hasPermi="['courses:student:remove']"
|
|
|
|
|
>删除</el-button>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="1.5">
|
|
|
|
|
@ -63,7 +63,7 @@
|
|
|
|
|
icon="el-icon-download"
|
|
|
|
|
size="mini"
|
|
|
|
|
@click="handleExport"
|
|
|
|
|
v-hasPermi="['course:student:export']"
|
|
|
|
|
v-hasPermi="['courses:student:export']"
|
|
|
|
|
>导出</el-button>
|
|
|
|
|
</el-col>
|
|
|
|
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
|
|
|
@ -76,15 +76,19 @@
|
|
|
|
|
<el-table-column label="姓名" align="center" prop="name" width="100" :show-overflow-tooltip="true" />
|
|
|
|
|
<el-table-column label="年级" align="center" prop="grade" width="80">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<el-tag size="small">{{ scope.row.grade }}</el-tag>
|
|
|
|
|
<el-tag size="small">{{ formatGrade(scope.row.grade) }}</el-tag>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="班级" align="center" prop="className" width="120" :show-overflow-tooltip="true" />
|
|
|
|
|
<el-table-column label="已选选修课" align="center" prop="selectedElectiveNames" min-width="250" :show-overflow-tooltip="true">
|
|
|
|
|
<el-table-column label="班级" align="center" prop="classId" width="120">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<div v-if="scope.row.selectedElectiveNames && scope.row.selectedElectiveNames !== '[]'">
|
|
|
|
|
{{ formatCourseNames(scope.row.selectedElectiveNames) }}
|
|
|
|
|
</div>
|
|
|
|
|
{{ getClassName(scope.row.classId) }}
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="已选选修课" align="center" min-width="250">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<span v-if="scope.row.selectedElectiveIds" class="text-gray">
|
|
|
|
|
{{ formatCourseNames(scope.row.selectedElectiveIds) }}
|
|
|
|
|
</span>
|
|
|
|
|
<span v-else class="text-gray">无选修课</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
@ -223,7 +227,7 @@
|
|
|
|
|
<script>
|
|
|
|
|
import { listStudent, getStudent, delStudent, addStudent, updateStudent, exportStudent } from "@/api/course/student"
|
|
|
|
|
import { listClazz } from "@/api/course/clazz"
|
|
|
|
|
import { listCourse } from "@/api/course/course"
|
|
|
|
|
import { listCourse } from "@/api/course/courses"
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: "Student",
|
|
|
|
|
@ -310,11 +314,12 @@ export default {
|
|
|
|
|
computed: {
|
|
|
|
|
// 计算属性:根据年级过滤班级
|
|
|
|
|
filteredClasses() {
|
|
|
|
|
if (!this.form.grade) return []
|
|
|
|
|
if (!this.form.grade || !Array.isArray(this.classList)) return []
|
|
|
|
|
return this.classList.filter(cls => cls.grade === this.form.grade)
|
|
|
|
|
},
|
|
|
|
|
// 计算属性:根据年级过滤选修课
|
|
|
|
|
filteredElectiveCourses() {
|
|
|
|
|
if (!Array.isArray(this.electiveCourses)) return []
|
|
|
|
|
if (!this.form.grade) return this.electiveCourses
|
|
|
|
|
|
|
|
|
|
// 返回当前年级的选修课和"全部"年级的选修课
|
|
|
|
|
@ -329,59 +334,151 @@ export default {
|
|
|
|
|
this.getCourseList()
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
|
|
|
|
|
/** 格式化年级显示 */
|
|
|
|
|
formatGrade(grade) {
|
|
|
|
|
const gradeMap = {
|
|
|
|
|
'FRESHMAN': '高一',
|
|
|
|
|
'SOPHOMORE': '高二',
|
|
|
|
|
'JUNIOR': '高三'
|
|
|
|
|
}
|
|
|
|
|
return gradeMap[grade] || grade
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** 根据班级ID获取班级名称 */
|
|
|
|
|
getClassName(classId) {
|
|
|
|
|
if (!this.classList.length) return `班级${classId}`
|
|
|
|
|
const cls = this.classList.find(c => c.id === classId)
|
|
|
|
|
return cls ? cls.className : `班级${classId}`
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** 格式化选修课名称显示 */
|
|
|
|
|
formatCourseNames(ids) {
|
|
|
|
|
if (!ids || !this.allCourses.length) return '无选修课'
|
|
|
|
|
|
|
|
|
|
// 如果 ids 是字符串,尝试解析
|
|
|
|
|
let idArray = []
|
|
|
|
|
try {
|
|
|
|
|
if (typeof ids === 'string') {
|
|
|
|
|
idArray = JSON.parse(ids)
|
|
|
|
|
} else if (Array.isArray(ids)) {
|
|
|
|
|
idArray = ids
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('解析选修课ID失败:', e)
|
|
|
|
|
return '选修课数据异常'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!idArray.length) return '无选修课'
|
|
|
|
|
|
|
|
|
|
const names = idArray.map(id => {
|
|
|
|
|
const course = this.allCourses.find(c => c.id === id)
|
|
|
|
|
return course ? course.courseName : `课程${id}`
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return names.join('、')
|
|
|
|
|
},
|
|
|
|
|
/** 查询学生列表 */
|
|
|
|
|
getList() {
|
|
|
|
|
this.loading = true
|
|
|
|
|
console.log('发送查询请求,参数:', this.queryParams)
|
|
|
|
|
|
|
|
|
|
listStudent(this.queryParams).then(response => {
|
|
|
|
|
this.studentList = response.rows
|
|
|
|
|
this.total = response.total
|
|
|
|
|
console.log('学生列表API返回:', response) // 查看完整响应
|
|
|
|
|
|
|
|
|
|
if (response.code === 200 || response.success) {
|
|
|
|
|
// 根据实际响应结构调整
|
|
|
|
|
// 数据在 response.data 中(这是一个数组)
|
|
|
|
|
this.studentList = response.rows
|
|
|
|
|
|
|
|
|
|
// 注意:响应中没有 total 字段,需要处理分页
|
|
|
|
|
// 如果没有分页信息,可以设置为数组长度
|
|
|
|
|
this.total = this.studentList.length
|
|
|
|
|
|
|
|
|
|
console.log('设置的学生数据:', this.studentList)
|
|
|
|
|
console.log('总数:', this.total)
|
|
|
|
|
} else {
|
|
|
|
|
this.$modal.msgError(response.msg || "获取学生列表失败")
|
|
|
|
|
this.studentList = []
|
|
|
|
|
this.total = 0
|
|
|
|
|
}
|
|
|
|
|
this.loading = false
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
console.error('获取学生列表失败:', error)
|
|
|
|
|
this.$modal.msgError("获取学生列表失败")
|
|
|
|
|
this.loading = false
|
|
|
|
|
this.studentList = []
|
|
|
|
|
this.total = 0
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** 获取班级列表 */
|
|
|
|
|
getClassList() {
|
|
|
|
|
this.classLoading = true
|
|
|
|
|
listClazz().then(response => {
|
|
|
|
|
this.classList = response || []
|
|
|
|
|
if (response.code === 200) {
|
|
|
|
|
// 根据实际API返回结构调整
|
|
|
|
|
// 可能是 response.data 或 response.rows
|
|
|
|
|
this.classList = response.data || response.rows || []
|
|
|
|
|
} else {
|
|
|
|
|
this.$modal.msgError(response.msg || "获取班级列表失败")
|
|
|
|
|
this.classList = []
|
|
|
|
|
}
|
|
|
|
|
this.classLoading = false
|
|
|
|
|
|
|
|
|
|
if (this.classList.length === 0) {
|
|
|
|
|
this.$modal.msgWarning("暂无班级数据,请先在班级管理中配置班级")
|
|
|
|
|
}
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
console.error('获取班级列表失败:', error)
|
|
|
|
|
this.classList = []
|
|
|
|
|
this.classLoading = false
|
|
|
|
|
this.$modal.msgWarning("获取班级列表失败,请联系管理员配置班级数据")
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
/** 获取选修课列表 */
|
|
|
|
|
|
|
|
|
|
/** 获取课程列表 */
|
|
|
|
|
getCourseList() {
|
|
|
|
|
this.courseLoading = true
|
|
|
|
|
listCourse().then(response => {
|
|
|
|
|
this.allCourses = response || []
|
|
|
|
|
// 过滤出选修课
|
|
|
|
|
this.electiveCourses = this.allCourses.filter(course => course.courseType === '选修') || []
|
|
|
|
|
if (response.code === 200) {
|
|
|
|
|
// 根据实际API返回结构调整
|
|
|
|
|
// 可能是 response.data 或 response.rows
|
|
|
|
|
this.allCourses = response.data || response.rows || []
|
|
|
|
|
// 过滤出选修课
|
|
|
|
|
this.electiveCourses = this.allCourses.filter(course =>
|
|
|
|
|
course.courseType === '选修'
|
|
|
|
|
) || []
|
|
|
|
|
} else {
|
|
|
|
|
this.$modal.msgError(response.msg || "获取课程列表失败")
|
|
|
|
|
this.allCourses = []
|
|
|
|
|
this.electiveCourses = []
|
|
|
|
|
}
|
|
|
|
|
this.courseLoading = false
|
|
|
|
|
|
|
|
|
|
if (this.electiveCourses.length === 0) {
|
|
|
|
|
this.$modal.msgWarning("暂无选修课数据,请先在课程管理中配置选修课")
|
|
|
|
|
}
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
console.error('获取课程列表失败:', error)
|
|
|
|
|
this.allCourses = []
|
|
|
|
|
this.electiveCourses = []
|
|
|
|
|
this.courseLoading = false
|
|
|
|
|
this.$modal.msgWarning("获取课程列表失败,请联系管理员配置课程数据")
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 年级变化时重置班级选择
|
|
|
|
|
handleGradeChange() {
|
|
|
|
|
this.form.classId = null
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 取消按钮
|
|
|
|
|
cancel() {
|
|
|
|
|
this.open = false
|
|
|
|
|
this.reset()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 表单重置
|
|
|
|
|
reset() {
|
|
|
|
|
this.form = {
|
|
|
|
|
@ -398,54 +495,73 @@ export default {
|
|
|
|
|
this.$refs.form.resetFields()
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** 搜索按钮操作 */
|
|
|
|
|
handleQuery() {
|
|
|
|
|
this.queryParams.pageNum = 1
|
|
|
|
|
this.getList()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** 重置按钮操作 */
|
|
|
|
|
resetQuery() {
|
|
|
|
|
this.resetForm("queryForm")
|
|
|
|
|
if (this.$refs.queryForm) {
|
|
|
|
|
this.$refs.queryForm.resetFields()
|
|
|
|
|
}
|
|
|
|
|
this.handleQuery()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 多选框选中数据
|
|
|
|
|
handleSelectionChange(selection) {
|
|
|
|
|
this.ids = selection.map(item => item.id)
|
|
|
|
|
this.single = selection.length !== 1
|
|
|
|
|
this.multiple = !selection.length
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** 新增按钮操作 */
|
|
|
|
|
handleAdd() {
|
|
|
|
|
this.reset()
|
|
|
|
|
this.open = true
|
|
|
|
|
this.title = "添加学生"
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** 修改按钮操作 */
|
|
|
|
|
handleUpdate(row) {
|
|
|
|
|
this.reset()
|
|
|
|
|
const id = row.id || this.ids
|
|
|
|
|
getStudent(id).then(response => {
|
|
|
|
|
const data = response.data
|
|
|
|
|
if (response.code === 200) {
|
|
|
|
|
const data = response.data || {}
|
|
|
|
|
|
|
|
|
|
// 解析选修课ID数组
|
|
|
|
|
let electiveIds = []
|
|
|
|
|
try {
|
|
|
|
|
if (data.selectedElectiveIds) {
|
|
|
|
|
electiveIds = JSON.parse(data.selectedElectiveIds)
|
|
|
|
|
// 解析选修课ID数组
|
|
|
|
|
let electiveIds = []
|
|
|
|
|
try {
|
|
|
|
|
if (data.selectedElectiveIds) {
|
|
|
|
|
if (typeof data.selectedElectiveIds === 'string') {
|
|
|
|
|
electiveIds = JSON.parse(data.selectedElectiveIds)
|
|
|
|
|
} else if (Array.isArray(data.selectedElectiveIds)) {
|
|
|
|
|
electiveIds = data.selectedElectiveIds
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('解析选修课ID失败:', e)
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('解析选修课ID失败:', e)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.form = {
|
|
|
|
|
...data,
|
|
|
|
|
selectedElectiveIds: electiveIds
|
|
|
|
|
}
|
|
|
|
|
this.form = {
|
|
|
|
|
...data,
|
|
|
|
|
selectedElectiveIds: electiveIds
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.open = true
|
|
|
|
|
this.title = "修改学生"
|
|
|
|
|
this.open = true
|
|
|
|
|
this.title = "修改学生"
|
|
|
|
|
} else {
|
|
|
|
|
this.$modal.msgError(response.msg || "获取学生信息失败")
|
|
|
|
|
}
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
console.error('获取学生信息失败:', error)
|
|
|
|
|
this.$modal.msgError("获取学生信息失败")
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** 提交按钮 */
|
|
|
|
|
submitForm() {
|
|
|
|
|
this.$refs["form"].validate(valid => {
|
|
|
|
|
@ -457,57 +573,110 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.form.id != null) {
|
|
|
|
|
// 修改学生
|
|
|
|
|
updateStudent(submitData).then(response => {
|
|
|
|
|
this.$modal.msgSuccess("修改成功")
|
|
|
|
|
this.open = false
|
|
|
|
|
this.getList()
|
|
|
|
|
if (response.code === 200) {
|
|
|
|
|
this.$modal.msgSuccess("修改成功")
|
|
|
|
|
this.open = false
|
|
|
|
|
this.getList()
|
|
|
|
|
} else {
|
|
|
|
|
this.$modal.msgError(response.msg || "修改失败")
|
|
|
|
|
}
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
console.error('修改失败:', error)
|
|
|
|
|
this.$modal.msgError("修改失败")
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
// 新增学生
|
|
|
|
|
addStudent(submitData).then(response => {
|
|
|
|
|
this.$modal.msgSuccess("新增成功")
|
|
|
|
|
this.open = false
|
|
|
|
|
this.getList()
|
|
|
|
|
if (response.code === 200) {
|
|
|
|
|
this.$modal.msgSuccess("新增成功")
|
|
|
|
|
this.open = false
|
|
|
|
|
this.getList()
|
|
|
|
|
} else {
|
|
|
|
|
this.$modal.msgError(response.msg || "新增失败")
|
|
|
|
|
}
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
console.error('新增失败:', error)
|
|
|
|
|
this.$modal.msgError("新增失败")
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** 删除按钮操作 */
|
|
|
|
|
handleDelete(row) {
|
|
|
|
|
const ids = row.id || this.ids
|
|
|
|
|
this.$modal.confirm('是否确认删除学生名称为"' + (row.name || ids) + '"的数据项?').then(() => {
|
|
|
|
|
return delStudent(ids)
|
|
|
|
|
}).then(() => {
|
|
|
|
|
this.getList()
|
|
|
|
|
this.$modal.msgSuccess("删除成功")
|
|
|
|
|
this.ids = []
|
|
|
|
|
}).catch(() => {})
|
|
|
|
|
}).then(response => {
|
|
|
|
|
if (response.code === 200) {
|
|
|
|
|
this.getList()
|
|
|
|
|
this.$modal.msgSuccess("删除成功")
|
|
|
|
|
this.ids = []
|
|
|
|
|
} else {
|
|
|
|
|
this.$modal.msgError(response.msg || "删除失败")
|
|
|
|
|
}
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
console.error('删除失败:', error)
|
|
|
|
|
this.$modal.msgError("删除失败")
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** 导出按钮操作 */
|
|
|
|
|
handleExport() {
|
|
|
|
|
this.$modal.confirm('是否确认导出所有学生数据项?').then(() => {
|
|
|
|
|
this.exportLoading = true
|
|
|
|
|
return exportStudent(this.queryParams)
|
|
|
|
|
}).then(response => {
|
|
|
|
|
this.$download.name(response, "学生数据.xlsx")
|
|
|
|
|
// 假设后端返回文件流,使用Blob下载
|
|
|
|
|
if (response instanceof Blob) {
|
|
|
|
|
const blob = new Blob([response], { type: 'application/vnd.ms-excel' })
|
|
|
|
|
const downloadElement = document.createElement('a')
|
|
|
|
|
const href = window.URL.createObjectURL(blob)
|
|
|
|
|
downloadElement.href = href
|
|
|
|
|
downloadElement.download = "学生数据.xlsx"
|
|
|
|
|
document.body.appendChild(downloadElement)
|
|
|
|
|
downloadElement.click()
|
|
|
|
|
document.body.removeChild(downloadElement)
|
|
|
|
|
window.URL.revokeObjectURL(href)
|
|
|
|
|
this.$modal.msgSuccess("导出成功")
|
|
|
|
|
} else {
|
|
|
|
|
this.$modal.msgError("导出失败,返回格式不正确")
|
|
|
|
|
}
|
|
|
|
|
this.exportLoading = false
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
console.error('导出失败:', error)
|
|
|
|
|
this.$modal.msgError("导出失败")
|
|
|
|
|
this.exportLoading = false
|
|
|
|
|
}).catch(() => {})
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
/** 格式化课程名称显示 */
|
|
|
|
|
formatCourseNames(idsStr) {
|
|
|
|
|
try {
|
|
|
|
|
const ids = JSON.parse(idsStr)
|
|
|
|
|
if (!ids || !ids.length) return '无选修课'
|
|
|
|
|
|
|
|
|
|
const names = ids.map(id => {
|
|
|
|
|
const course = this.allCourses.find(c => c.id === id)
|
|
|
|
|
return course ? course.courseName : `课程${id}`
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return names.join('、')
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return idsStr
|
|
|
|
|
|
|
|
|
|
/** 格式化时间 */
|
|
|
|
|
parseTime(time) {
|
|
|
|
|
if (!time) return ''
|
|
|
|
|
|
|
|
|
|
// 如果已经是字符串,直接返回
|
|
|
|
|
if (typeof time === 'string') {
|
|
|
|
|
return time
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是时间戳,转换为字符串
|
|
|
|
|
const date = new Date(time)
|
|
|
|
|
if (isNaN(date.getTime())) {
|
|
|
|
|
return time
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const year = date.getFullYear()
|
|
|
|
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
|
|
|
const day = String(date.getDate()).padStart(2, '0')
|
|
|
|
|
const hour = String(date.getHours()).padStart(2, '0')
|
|
|
|
|
const minute = String(date.getMinutes()).padStart(2, '0')
|
|
|
|
|
const second = String(date.getSeconds()).padStart(2, '0')
|
|
|
|
|
return `${year}-${month}-${day} ${hour}:${minute}:${second}`
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -529,4 +698,5 @@ export default {
|
|
|
|
|
padding: 20px;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
</style>
|
|
|
|
|
|