项目介绍 :
Spring Boot + SpringMVC + MyBatis+ Mysql + druid + Vue 开发的前后端分离的学生成绩管理系统
环境需要:
- 运行环境: 最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。
- IDE环境:Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以
- 数据库:MySql 5.7
- Maven:3.3以上
技术栈
前端
Vue、Axios、ElementUI、Vue-Router、Vuex、ECharts
后端
Spring Boot、JWT、MyBatis-Plus、MySQL、Hutool
功能结构
管理员角色:
- 首页
- 权限管理
- 班主任信息管理
- 教师信息管理
- 学生信息管理
- 基础信息管理
- 成绩信息管理
- 修改密码
班主任角色
学生信息管理
考试列表
学生角色
信息管理
考试成绩列表
项目预览
登录页
管理员首页
学生信息
考试列表
成绩列表
基本信息和成绩信息可支持表格的导入导出
部分代码
package com.ljxy.score.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ljxy.score.common.Result;
import com.ljxy.score.entity.User;
import com.ljxy.score.entity.Vo.UserVo;
import com.ljxy.score.service.UserService;
import com.ljxy.score.util.MD5Util;
import com.ljxy.score.util.TokenUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@Api(tags = "用户模块")
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
UserService userService;
@ApiOperation("用户登录")
@PostMapping("/login")
public Result<?> login(@RequestBody UserVo user, @RequestParam("code") String code, HttpServletRequest request) {
System.out.println(code);
System.out.println(user.getAccount());
System.out.println("原密码"+user.getPassword());
// 对密码进行加密比较
String pwd = MD5Util.string2MD5(user.getPassword());
System.out.println("加密密码"+pwd);
user.setPassword(pwd);
// 根据账号和密码查询数据
User res = userService.getOne(Wrappers.<User>lambdaQuery().eq(User::getAccount, user.getAccount())
.eq(User::getPassword, user.getPassword()));
if (res == null) return Result.error("-1", "用户名或密码错误");
// 获取生成图形验证码的结果
String captcha = (String) request.getSession().getAttribute("captcha");
System.out.println("captcha=" + captcha);
// 判断验证码是否为空和正确
if (StrUtil.isEmpty(code) || !captcha.equalsIgnoreCase(code)) return Result.error("-2", "验证码错误");
user.setName(res.getName());
user.setType(res.getType());
// 生成token
String token = TokenUtils.getToken(user.getAccount(), user.getPassword());
user.setToken(token);
return Result.success(user);
}
@ApiOperation("添加用户")
@PostMapping("/add")
public Result<?> addUser(@RequestBody User user) {
User res = userService.getOne(Wrappers.<User>lambdaQuery().eq(User::getAccount, user.getAccount()));
if (res != null) return Result.error("-1", "账号已存在");
String pwd = MD5Util.string2MD5(user.getPassword());
user.setPassword(pwd);
userService.save(user);
return Result.success(user);
}
@ApiOperation(value = "修改用户信息")
@PutMapping("/update")
public Result<?> updateUser(@RequestBody User user) {
String pwd = MD5Util.string2MD5(user.getPassword());
user.setPassword(pwd);
if (userService.updateById(user)){
return Result.success();
}
return Result.error("-1","修改失败");
}
@ApiOperation(value = "修改密码")
@PutMapping("/resetpwd")
public Result<?>resetPwd(@RequestBody User user){
Integer id = userService.getOne(Wrappers.<User>lambdaQuery().eq(User::getAccount, user.getAccount())).getId();
user.setId(id);
String pwd = MD5Util.string2MD5(user.getPassword());
user.setPassword(pwd);
if (userService.updateById(user)){
return Result.success();
}
return Result.error("-1","修改失败");
}
@ApiOperation(value = "删除班级")
@ApiImplicitParam(name = "id", value = "用户id", required = true)
@DeleteMapping("/delete/{id}")
public Result<?> deleteUser(@PathVariable Long id) {
if (userService.removeById(id)){
return Result.success();
}
return Result.error("-1","删除失败");
}
@ApiOperation(value = "多条件查询")
@GetMapping("/userQuery")
public Result<?> studentQuery(@RequestParam(defaultValue = "1") Integer PageNum, @RequestParam(defaultValue = "10") Integer PageSize, String account, Integer type) {
Page<User> userPage = userService.findPage(new Page<>(PageNum, PageSize), account, type);
return Result.success(userPage);
}
@ApiOperation(value = "重置密码")
@PutMapping("updatepwd")
public Result<?> updatePwd(Integer id){
if (userService.updatePwd("e10adc3949ba59abbe56e057f20f883e",id)) {
return Result.success();
}
return Result.error("-1","重置失败");
}
}
<template>
<div style="padding: 10px; width: 100%">
<div style="margin: 10px 0">
<el-input
placeholder="请输入教师姓名"
v-model="search"
style="width: 200px"
>
<template #append>
<el-button icon="el-icon-search" @click="load"></el-button>
</template>
</el-input>
<span style="margin-left: 20px">年级:</span>
<el-select
v-model="grade"
placeholder="请选择"
style="width: 100px"
clearable
@change="selectGrade($event)"
>
<el-option
v-for="item in gradeInfo"
:key="item.value"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
<span style="margin-left: 20px">班级:</span>
<el-select
v-model="clazz"
placeholder="请选择"
style="width: 100px"
clearable
@change="load"
>
<el-option
v-for="items in clazzInfo"
:key="items.value"
:label="items.name"
:value="items.id"
>
</el-option>
</el-select>
<span style="margin-left: 20px">课程:</span>
<el-select
v-model="course"
size="mini"
placeholder="请选择"
style="width: 100px"
@change="load"
clearable
>
<el-option
v-for="item in courseInfo"
:key="item.value"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
<el-button
type="warning"
style="margin-left: 20px; float: right; margin-right: 20px"
@click="deleteBatch"
icon="el-icon-delete"
>批量删除</el-button
>
<el-button
type="primary"
style="margin-left: 20px; float: right"
@click="add"
>添加</el-button
>
</div>
<!-- 表格-->
<el-table
:data="tableData"
border
stripe
style="width: 99%"
@selection-change="handleSelectionChange"
height="76vh"
>
<el-table-column type="selection" width="55" />
<el-table-column prop="tid" label="教工号"> </el-table-column>
<el-table-column prop="tname" label="姓名"> </el-table-column>
<el-table-column prop="sex" label="性别"> </el-table-column>
<el-table-column prop="phone" label="电话"> </el-table-column>
<el-table-column label="课程" width="400px" :show-overflow-tooltip="true">
<template #default="scope">
<div class="name-wrapper">
<el-button
style="margin-left: 10px"
class="button-new-tag"
size="mini"
@click="showInput(scope.row)"
>+ 添加课程</el-button
>
<el-tag
closable
@close="handleClose(item, scope.row.id)"
type="success"
style="margin-left: 10px"
v-for="item in scope.row.clazzList"
:key="item.id"
>
{{ item.gradeList.name }} {{ item.name }}
{{ item.gradeList.courseList[0].name }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button
@click="handleEdit(scope.row)"
size="mini"
type="primary"
plain
>编辑</el-button
>
<el-button
@click="handleDelete(scope.row.id)"
type="danger"
size="mini"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div style="margin: 10px 0">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[5, 10, 20,100]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
</div>
<el-dialog
title="添加教师信息"
v-model="dialogVisible"
width="30%"
:before-close="dialogClose"
>
<el-form :model="form" label-width="120px" :rules="rules" ref="form">
<el-form-item label="教工号" style="width: 80%" prop="tid">
<el-input v-model.number="form.tid"></el-input>
</el-form-item>
<el-form-item label="姓名" style="width: 80%" prop="tname">
<el-input v-model="form.tname"></el-input>
</el-form-item>
<el-form-item label="性别" style="width: 80%" prop="sex">
<el-radio v-model="form.sex" label="男">男</el-radio>
<el-radio v-model="form.sex" label="女">女</el-radio>
</el-form-item>
<el-form-item label="电话" style="width: 80%" prop="phone">
<el-input v-model="form.phone"></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogClose">取 消</el-button>
<el-button type="primary" @click="save">确 定</el-button>
</span>
</template>
</el-dialog>
<!-- 更新学生信息-->
<el-dialog title="编辑信息" v-model="dialogVisible1" width="30%">
<el-form :model="form" label-width="120px" :rules="rules" ref="form">
<el-form-item label="教工号" style="width: 80%" prop="tid">
<el-input v-model.number="form.tid"></el-input>
</el-form-item>
<el-form-item label="姓名" style="width: 80%" prop="tname">
<el-input v-model="form.tname"></el-input>
</el-form-item>
<el-form-item label="性别" style="width: 80%" prop="sex">
<el-radio v-model="form.sex" label="男">男</el-radio>
<el-radio v-model="form.sex" label="女">女</el-radio>
</el-form-item>
<el-form-item label="电话" style="width: 80%" prop="phone">
<el-input v-model="form.phone"></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible1 = false">取 消</el-button>
<el-button type="primary" @click="update">确 定</el-button>
</span>
</template>
</el-dialog>
<!-- 添加课程 -->
<el-dialog title="添加课程" v-model="addVisible" width="30%">
<el-form
:model="courseForm"
label-width="120px"
:rules="rules"
ref="courseForm"
>
<el-form-item label="教工号" style="width: 80%" prop="tid">
<el-input v-model="courseForm.tid" :disabled="true"></el-input>
</el-form-item>
<el-form-item label="姓名" style="width: 80%" prop="tname">
<el-input v-model="courseForm.tname" :disabled="true"></el-input>
</el-form-item>
<el-form-item label="年级" style="width: 80%" prop="gradeId">
<el-select
v-model="gradeId"
size="mini"
placeholder="请选择"
@change="selectGrade($event)"
>
<el-option
v-for="item in gradeInfo"
:key="item.value"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="班级" style="width: 80%" prop="clazzId">
<el-select v-model="clazzId" size="mini" placeholder="请选择">
<el-option
v-for="item in clazzInfo"
:key="item.value"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="课程" style="width: 80%" prop="courseId">
<el-select v-model="courseId" size="mini" placeholder="请选择">
<el-option
v-for="item in courseInfo"
:key="item.value"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="addVisible = false">取 消</el-button>
<el-button type="primary" @click="addCourse(gradeId)"
>确 定</el-button
>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
import request from "../../utils/request";
export default {
name: "Teacher",
components: {},
data() {
return {
rules: {
tid: [{ required: true, message: "请输入教工号", trigger: "blur" }],
tname: [{ required: true, message: "请输入姓名", trigger: "blur" }],
phone: [
{ required: true, trigger: "blur", validator: this.phoneValidator },
],
sex: [{ required: true, message: "请选择性别", trigger: "blur" }],
},
//当前页
currentPage: 1,
// 页大小
pageSize: 20,
// 总条数
total: 0,
//弹窗默认关闭
dialogVisible: false,
dialogVisible1: false,
addVisible: false,
// 老师姓名
search: "",
// 新增,更新
form: {},
// 表格
tableData: [],
// 批量删除数组
ids: [],
// 中间表的id
gctId: "",
// 添加课程表单
courseForm: {},
// 年级下拉数据
gradeInfo: [],
// 班级下拉数据
clazzInfo: [],
// 课程下拉数据
courseInfo: [],
// 年级下拉值
gradeId: "",
// 班级下拉值
clazzId: "",
// 课程下拉值
courseId: "",
// 添加课程传后端的对象
resForm: {},
grade: "",
clazz: "",
course: "",
};
},
created() {
this.findGradeInfo();
this.load();
},
//定义函数
methods: {
// 添加课程
addCourse(gradeId) {
console.log("gradeId=================");
console.log(this.gradeId);
console.log("clazzId=================");
console.log(this.clazzId);
console.log("courseId=================");
console.log(this.courseId);
console.log("courseForm.id=================");
console.log(this.courseForm.id);
this.resForm.gradeId = this.gradeId;
this.resForm.clazzId = this.clazzId;
this.resForm.courseId = this.courseId;
this.resForm.teacherId = this.courseForm.id;
console.log("res==============");
console.log(this.resForm);
request.post("/clazz/course/teacher/add", this.resForm).then((res) => {
console.log(res);
if (res.code === "0") {
this.$message({
type: "success",
message: "添加成功",
});
this.load();
this.addVisible = false;
} else {
this.$message({
type: "error",
message: res.msg,
});
}
});
},
// 查询年级信息
findGradeInfo() {
request.get("/grade/all", {}).then((res) => {
console.log(res);
this.gradeInfo = res.data;
});
},
// 年级下拉事件
selectGrade($event) {
this.load();
this.clazzId = null;
this.courseId = null;
console.log("年级ID================");
console.log($event);
let gradeId = $event;
// 查询年级下的班级
request
.get("/clazz/findClazzByGid", {
params: {
gradeId: gradeId,
},
})
.then((res) => {
console.log(res);
this.clazzInfo = res.data;
});
// 查询年级下的课程
request
.get("/grade/list", {
params: {
id: gradeId,
},
})
.then((res) => {
console.log(res);
this.courseInfo = res.data[0].courseList;
});
},
// 打开添加课程弹框
showInput(row) {
this.courseForm = JSON.parse(JSON.stringify(row));
this.gradeId = null;
this.clazzId = null;
this.courseId = null;
this.findGradeInfo();
this.addVisible = true;
},
// 删除教师课程信息
handleClose(item, id) {
console.log("年级ID");
console.log(item.gradeList.id);
console.log(item);
console.log("课程ID");
console.log(item.gradeList.courseList[0].id);
console.log("老师ID");
console.log(id);
console.log("班级Id");
console.log(item.id);
request
.get("/clazz/course/teacher/list", {
params: {
gradeId: item.gradeList.id,
courseId: item.gradeList.courseList[0].id,
clazzId: item.id,
teacherId: id,
},
})
.then((res) => {
console.log("id====================");
console.log(res);
console.log(res.data[0].id);
this.gctId = res.data[0].id;
});
this.$confirm("是否删除该课程信息?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
request
.delete("/clazz/course/teacher/delete/" + this.gctId)
.then((res) => {
if (res.code === "0") {
this.$message({
type: "success",
message: "删除成功",
});
} else {
this.$message({
type: "error",
message: res.msg(),
});
}
this.load();
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},
handleSelectionChange(val) {
this.ids = val.map((v) => v.id);
},
// 批量删除
deleteBatch() {
if (!this.ids.length) {
this.$message.warning("请选择数据");
return;
}else{
this.$confirm("是否删除选中教师信息?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
request.post("/teacher/deleteBatch", this.ids).then((res) => {
if (res.code === "0") {
this.$message({
type: "success",
message: "批量删除成功",
});
} else {
this.$message({
type: "error",
message: res.msg(),
});
}
this.load();
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
}
},
// 分页查询
load() {
request
.get("/teacher/page", {
params: {
PageNum: this.currentPage,
PageSize: this.pageSize,
search: this.search,
gradeId: this.grade,
clazzId: this.clazz,
courseId: this.course,
},
})
.then((res) => {
console.log(res);
this.tableData = res.data.records;
this.total = res.data.total;
console.log(res.data.records);
});
},
//新增老师信息
save() {
this.$refs.form.validate((valid) => {
if (valid) {
request.post("/teacher/add", this.form).then((res) => {
if (res.code === "0") {
this.$message({
type: "success",
message: "添加成功",
});
this.dialogVisible = false;
} else {
this.$message({
type: "error",
message: res.msg,
});
}
this.load();
});
}
});
},
//更新老师信息
update() {
request.put("/teacher/update", this.form).then((res) => {
console.log(res);
if (res.code === "0") {
this.$message({
type: "success",
message: "更新成功",
});
} else {
this.$message({
type: "error",
message: "更新失败",
});
}
this.load();
this.dialogVisible1 = false;
});
},
//删除老师信息
handleDelete(id) {
console.log(id);
this.$confirm("是否删除该教师?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
request.delete("/teacher/delete/" + id).then((res) => {
if (res.code === "0") {
this.$message({
type: "success",
message: "删除成功",
});
} else {
this.$message({
type: "error",
message: res.msg(),
});
}
this.load();
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},
//改变当前每页的个数触发
handleSizeChange(pageSize) {
this.pageSize = pageSize;
this.load();
},
//改变当前页码触发
handleCurrentChange(pageNum) {
this.currentPage = pageNum;
this.load();
},
//打开dialogVisible弹窗
add() {
this.dialogVisible = true;
//清空弹窗的内容
this.form = {};
},
//打开编辑弹框
handleEdit(row) {
this.form = JSON.parse(JSON.stringify(row));
this.dialogVisible1 = true;
},
// 关闭弹窗事件
dialogClose() {
//清空表单验证信息
this.$refs.form.resetFields();
this.dialogVisible = false;
},
// 自定义校验规则
phoneValidator(rule, value, callback) {
const phoneReg =
/^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[189])\d{8}$/;
if (!value) {
callback(new Error("不能为空"));
} else {
// 正则表达式判断是否符合格式
if (phoneReg.test(value)) {
// 如果符合
callback();
} else {
callback(new Error("手机号码格式错误"));
console.log("手机号码格式错误");
}
}
},
},
};
</script>
创作不易,源码非无偿提供,需要获取源码的私信博主