feat(grade): 实现年级管理的新增与删除功能

- 后端新增AddGradeReqVO和DeleteGradeReqVO请求对象
- GradeController添加新增和删除年级两个接口
- GradeService及其实现类实现新增和删除年级逻辑
- MyBatis映射新增插入和删除SQL语句
- 前端API新增addGrade和deleteGrade方法
- class.vue新增年级列表操作列及相关事件处理
- 新增AddGradeDialog组件用于输入新增年级名称
- 增加页面新增按钮及弹窗显示控制
- 实现删除年级的API调用与界面删除操作反馈
This commit is contained in:
lbw
2025-12-15 14:59:40 +08:00
parent e3b993dd27
commit 84239d0199
10 changed files with 168 additions and 2 deletions

View File

@@ -5,4 +5,16 @@ export function getGradeList(page, size) {
page: page,
pageSize: size
})
}
}
export function addGrade(name) {
return axios.post('/grade/add', {
title: name
})
}
export function deleteGrade(id) {
return axios.post('/grade/delete', {
id: id
})
}

View File

@@ -0,0 +1,54 @@
<template>
<el-dialog v-model="visible" title="新增年级" width="420px" :close-on-click-modal="false">
<div class="space-y-4" v-loading="loading">
<el-input v-model="name" placeholder="请输入年级名称,如:一年级" clearable />
</div>
<template #footer>
<div class="flex justify-end gap-2">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" :disabled="!canSubmit" @click="handleSubmit">确定</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, computed, watch } from 'vue'
import { addGrade } from '@/api/grade'
const props = defineProps({
modelValue: { type: Boolean, default: false }
})
const emit = defineEmits(['update:modelValue', 'success'])
const visible = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val)
})
const loading = ref(false)
const name = ref('')
const canSubmit = computed(() => name.value.trim().length > 0)
async function handleSubmit() {
if (!canSubmit.value) return
loading.value = true
try {
await addGrade(name.value.trim())
ElMessage.success('新增年级成功')
emit('success')
visible.value = false
} finally {
loading.value = false
}
}
watch(
() => props.modelValue,
(v) => {
if (v) name.value = ''
}
)
</script>
<style scoped></style>

View File

@@ -71,12 +71,21 @@
:current-row-key="selectedGradeId" @row-click="onGradeRowClick">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="title" label="年级名称" min-width="160" />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button type="danger" size="small" @click.stop="onDeleteGrade(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="mt-4 flex justify-end">
<el-pagination background layout="prev, pager, next, sizes, total" :total="gradeTotalCount"
:page-size="gradePageSize" :current-page="gradePageNo"
@current-change="handleGradePageChange" @size-change="handleGradeSizeChange" />
</div>
<div class="mt-3 flex justify-end">
<el-button type="primary" @click="showAddGradeDialog = true">新增年级</el-button>
</div>
<AddGradeDialog v-model="showAddGradeDialog" @success="fetchGrades" />
</div>
</div>
@@ -90,9 +99,10 @@
import Header from '@/layouts/components/Header.vue'
import { ref, onMounted } from 'vue'
import { getClassList } from '@/api/class'
import { getGradeList } from '@/api/grade'
import { getGradeList, deleteGrade } from '@/api/grade'
import { getStudentList } from '@/api/student'
import ExamGenerateDialog from '@/layouts/components/ExamGenerateDialog.vue'
import AddGradeDialog from '@/layouts/components/AddGradeDialog.vue'
const classes = ref([])
const pageNo = ref(1)
@@ -111,6 +121,7 @@ const gradeLoading = ref(false)
const gradeTableRef = ref(null)
const selectedGradeId = ref(null)
const selectedGradeTitle = ref('')
const showAddGradeDialog = ref(false)
const students = ref([])
const studentPageNo = ref(1)
@@ -229,6 +240,21 @@ function resetStudentFilters() {
fetchStudents()
}
async function onDeleteGrade(row) {
try {
await deleteGrade(row.id)
ElMessage.success('删除成功')
if (selectedGradeId.value === row.id) {
selectedGradeId.value = null
selectedGradeTitle.value = ''
gradeTableRef.value?.setCurrentRow()
}
await fetchGrades()
} catch (e) {
ElMessage.error('删除失败')
}
}
onMounted(() => {
fetchClasses()
fetchGrades()