摘要
从20年代开始,计算机疯狂的出现在人们的生活以及工作当中,成为人们生活、工作的好帮手,计算机深入到每家每户当中,网络办公,网络教学更是替换了传统手工记录管理的方式,使用计算机办公可以不必局限于固定的时间和固定的地点,通过计算机系统可以轻松实现跨区域的交流。随着高等教育的普及,学生的数量也在持续的增加,最近又由于疫情的影响,使得传统的学生信息的查询管理越来越不方便,而且手工查询管理也降低了工作效率,增加了老师和学校的工作量,而且也不方便学生进行查询,因此开发本了学生信息管理系统。
本系统以实际运用为开发背景,通过系统管理员可以对所有的学生和教师等人员以及学生相关联的一些学生管理、分配任务、完成任务、打卡签到、师生交流等数据信息进行统一的管理,方便资料的保留。教师和学生可以通过注册,然后登录到系统当中,对分配任务、完成任务、打卡签到以及师生交流这些信息进行查询管理。总的来说,系统的前台是通过Java页面展示,后台使用SSM这个框架,数据库采用目前流行的开源关系型数据库MYSQL。这一系统在前台的技术使用上,使用了目前流行的vue.js,让页面展现得更加的整齐漂亮。
关键词:学生信息管理;Java;SSM;MYSQL
- 4 章 关键模块的设计与实现
- 登录模块
管理员、教师和学生在登录界面输入账号+密码,点击“登录”按钮,系统在用户数据库表中会对管理员、教师和学生的账号进行匹配,账号+密码正确的话,就会登录到系统中各个用户的主管理界面,否则提示对应的信息,返回到登录的界面,其主界面展示如下图4.1所示。
图4.1 登录界面图
登录关键代码如下所示。
/**
* 登录
* @param data
* @param httpServletRequest
* @return
*/
@PostMapping("login")
public Map<String, Object> login(@RequestBody Map<String, String> data, HttpServletRequest httpServletRequest) {
log.info("[执行登录接口]");
String username = data.get("username");
String email = data.get("email");
String phone = data.get("phone");
String password = data.get("password");
List resultList = null;
QueryWrapper wrapper = new QueryWrapper<User>();
Map<String, String> map = new HashMap<>();
if(username != null && "".equals(username) == false){
map.put("username", username);
resultList = service.selectBaseList(service.select(map, new HashMap<>()));
}
else if(email != null && "".equals(email) == false){
map.put("email", email);
resultList = service.selectBaseList(service.select(map, new HashMap<>()));
}
else if(phone != null && "".equals(phone) == false){
map.put("phone", phone);
resultList = service.selectBaseList(service.select(map, new HashMap<>()));
}else{
return error(30000, "账号或密码不能为空");
}
if (resultList == null || password == null) {
return error(30000, "账号或密码不能为空");
}
//判断是否有这个用户
if (resultList.size()<=0){
return error(30000,"用户不存在");
}
User byUsername = (User) resultList.get(0);
Map<String, String> groupMap = new HashMap<>();
groupMap.put("name",byUsername.getUserGroup());
List groupList = userGroupService.selectBaseList(userGroupService.select(groupMap, new HashMap<>()));
if (groupList.size()<1){
return error(30000,"用户组不存在");
}
UserGroup userGroup = (UserGroup) groupList.get(0);
//查询用户审核状态
if (!StringUtils.isEmpty(userGroup.getSourceTable())){
String res = service.selectExamineState(userGroup.getSourceTable(),byUsername.getUserId());
if (res==null){
return error(30000,"用户不存在");
}
if (!res.equals("已通过")){
return error(30000,"该用户审核未通过");
}
}
//查询用户状态
if (byUsername.getState()!=1){
return error(30000,"用户非可用状态,不能登录");
}
String md5password = service.encryption(password);
if (byUsername.getPassword().equals(md5password)) {
// 存储Token到数据库
AccessToken accessToken = new AccessToken();
accessToken.setToken(UUID.randomUUID().toString().replaceAll("-", ""));
accessToken.setUser_id(byUsername.getUserId());
tokenService.save(accessToken);
// 返回用户信息
JSONObject user = JSONObject.parseObject(JSONObject.toJSONString(byUsername));
user.put("token", accessToken.getToken());
JSONObject ret = new JSONObject();
ret.put("obj",user);
return success(ret);
} else {
return error(30000, "账号或密码不正确");
}
}
public String select(Map<String,String> query,Map<String,String> config){
StringBuffer sql = new StringBuffer("select ");
sql.append(config.get(FindConfig.FIELD) == null || "".equals(config.get(FindConfig.FIELD)) ? "*" : config.get(FindConfig.FIELD)).append(" ");
sql.append("from ").append("`").append(table).append("`").append(toWhereSql(query, "0".equals(config.get(FindConfig.LIKE))));
if (config.get(FindConfig.GROUP_BY) != null && !"".equals(config.get(FindConfig.GROUP_BY))){
sql.append("group by ").append(config.get(FindConfig.GROUP_BY)).append(" ");
}
if (config.get(FindConfig.ORDER_BY) != null && !"".equals(config.get(FindConfig.ORDER_BY))){
sql.append("order by ").append(config.get(FindConfig.ORDER_BY)).append(" ");
}
if (config.get(FindConfig.PAGE) != null && !"".equals(config.get(FindConfig.PAGE))){
int page = config.get(FindConfig.PAGE) != null && !"".equals(config.get(FindConfig.PAGE)) ? Integer.parseInt(config.get(FindConfig.PAGE)) : 1;
int limit = config.get(FindConfig.SIZE) != null && !"".equals(config.get(FindConfig.SIZE)) ? Integer.parseInt(config.get(FindConfig.SIZE)) : 10;
sql.append(" limit ").append( (page-1)*limit ).append(" , ").append(limit);
}
log.info("[{}] - 查询操作,sql: {}",table,sql);
return sql.toString();
}
public List selectBaseList(String select) {
List<Map<String,Object>> mapList = baseMapper.selectBaseList(select);
List<E> list = new ArrayList<>();
for (Map<String,Object> map:mapList) {
list.add(JSON.parseObject(JSON.toJSONString(map),eClass));
}
return list;
}
-
- 注册模块
注册模块满足教师和学生两部分,当学生和教师想要进行学生相关信息的查询管理的时候,就必须进行登录,如果没有账号的话,在登录界面,点击“注册”按钮就会跳转到注册的界面,根据提示填写好注册信息,添加提交,注册的信息在数据库中就添加完成了,然后再输入填写好的账号和密码进行登录,其主界面展示如下图4.1所示。
图4.2 注册界面图
注册关键代码如下所示。
/**
* 注册
* @return
*/
@PostMapping("register")
public Map<String, Object> signUp(HttpServletRequest request) throws IOException {
// 查询用户
Map<String, String> query = new HashMap<>();
Map<String,Object> map = service.readBody(request.getReader());
query.put("username",String.valueOf(map.get("username")));
List list = service.selectBaseList(service.select(query, new HashMap<>()));
if (list.size()>0){
return error(30000, "用户已存在");
}
map.put("password",service.encryption(String.valueOf(map.get("password"))));
service.insert(map);
return success(1);
}
public Map<String,Object> readBody(BufferedReader reader){
BufferedReader br = null;
StringBuilder sb = new StringBuilder("");
try{
br = reader;
String str;
while ((str = br.readLine()) != null){
sb.append(str);
}
br.close();
String json = sb.toString();
return JSONObject.parseObject(json, Map.class);
}catch (IOException e){
e.printStackTrace();
}finally{
if (null != br){
try{
br.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
return null;
}
public void insert(Map<String,Object> body){
E entity = JSON.parseObject(JSON.toJSONString(body),eClass);
baseMapper.insert(entity);
log.info("[{}] - 插入操作:{}",entity);
}
-
- 用户管理模块
管理员可以对系统中所有的用户角色进行管控,包含了管理员、学生以及教师这三种角色,如果需要添加新的用户,点击页面中的“添加”按钮根据提示输入上用户信息,点击“提交”以后在对应的用户界面就可以查看到了,可以点击用户后面的“删除”按钮直接删除某一用户,这里以教师用户为例。界面如下图4.3所示。
图4.3 用户管理界面图
用户管理关键代码如下所示。
/**
* 用户组:用于用户前端身份和鉴权(UserGroup)表实体类
*
* @author xxx
*@since 202X-XX-XX
*/
@TableName("user_group")
@Data
@EqualsAndHashCode(callSuper = false)
public class UserGroup implements Serializable {
private static final long serialVersionUID = 968356951391304707L;
/**
* 用户组ID:[0,8388607]
*/
@TableId(value = "group_id", type = IdType.AUTO)
private Integer groupId;
/**
* 显示顺序:[0,1000]
*/
@TableField(value = "display")
private Integer display;
/**
* 名称:[0,16]
*/
@TableField(value = "name")
private String name;
/**
* 描述:[0,255]描述该用户组的特点或权限范围
*/
@TableField(value = "description")
private String description;
/**
* 来源表:
*/
@TableField(value = "source_table")
private String sourceTable;
/**
* 来源字段:
*/
@TableField(value = "source_field")
private String sourceField;
/**
* 注册位置:
*/
@TableField(value = "register")
private String register;
/**
* 创建时间:
*/
@TableField(value = "create_time")
private Timestamp createTime;
/**
* 更新时间:
*/
@TableField(value = "update_time")
private Timestamp updateTime;
}
/**
* 所在用户组:[0,32767]决定用户身份和权限
*/
@TableField(value = "user_group")
private String userGroup;
/**
* 用户组:用于用户前端身份和鉴权(UserGroup)表控制层
*
*/
@RestController
@RequestMapping("user_group")
public class UserGroupController extends BaseController<UserGroup, UserGroupService> {
/**
* 服务对象
*/
@Autowired
public UserGroupController(UserGroupService service) {
setService(service);
}
}
-
- 学生管理模块
管理员和学生点击“学生信息”这个按钮可以查看到系统中的学生信息,支持通过学生姓名或者班级名称或者学生档案进行查询学生信息,如果想要添加新的学生信息,点击“添加”按钮然后根据提示输入学生信息,点击“提交”后,在学生管理界面就会显示新增的学生信息,可以点击某一学生信息查看学生信息的详情,也可以直接点击“删除”进行删除学生信息。界面如下图4.4所示。
图4.4 学生管理界面图
学生管理关键代码如下所示。
@RequestMapping("/get_list")
public Map<String, Object> getList(HttpServletRequest request) {
Map<String, Object> map = service.selectToPage(service.readQuery(request), service.readConfig(request));
return success(map);
}
-
- 分配任务模块
点击“分配任务”这个菜单,可以查看到系统中所有查询的分配任务信息,支持通过任务编号对任务信息进行查询,如果想要了解某一任务的详细信息,点击后面的“详情”会进入详情界面,学生和管理员如果想要选择某一分配任务,点击“任务”按钮,根据提示填写对应的信息,点击“提交”按钮,信息没有错误在数据库就会提交成功。界面如下图4.5所示。
图4.5 分配任务界面图
分配任务管理关键代码如下所示。
@PostMapping("/set")
@Transactional
public Map<String, Object> set(HttpServletRequest request) throws IOException {
service.update(service.readQuery(request), service.readConfig(request), service.readBody(request.getReader()));
return success(1);
}
-
- 完成任务模块
学生点击“完成任务信息”这个按钮可以查看到自己提交的完成任务信息,支持通过班级名称或者学生姓名进行查询完成任务信息,如果想要了解某一完成任务的详细信息,点击后面的“查看”会进入详情界面,也支持对自己选择的完成任务进行删除;教师和管理员可以对学生提交的完成任务进行查询,选择某一完成任务,点击后面的“任务”按钮,根据提示输入对应的信息,点击“提交”后,完成任务就录入成功了。界面如下图4.6所示。
图4.6 完成任务界面图
-
- 打卡签到模块
学生点击“打卡签到”这个按钮可以查看到自己所有打卡签到信息,支持通过班级名称或者学生姓名进行查询打卡签到信息,管理员和教师可以对所打卡签到信息进行删除。界面如下图4.7所示。
图4.7 打卡签到界面图
打卡签到管理关键代码:
@RequestMapping("/get_obj")
public Map<String, Object> obj(HttpServletRequest request) {
List resultList = service.selectBaseList(service.select(service.readQuery(request), service.readConfig(request)));
if (resultList.size() > 0) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("obj",resultList.get(0));
return success(jsonObject);
} else {
return success(null);
}
}
-
- 师生交流管理模块
点击“师生交流”这个菜单,可以查看到系统中所有添加的师生交流信息,支持通过标题对师生交流信息进行查询,只有管理员用户可以添加新的师生交流内容,点击“添加”按钮,根据提示输入师生交流信息,点击“提交”按钮,新的师生交流信息就在系统中显示出来了,也可以对添加的师生交流信息进行删除。界面如下图4.8所示。
图4.8 师生交流界面图
- 5 章 系统实验与结果分析
- 测试的目的
通过前面章节的介绍,我们可以看到本学生信息管理系统已经完成了,但是能不能投入使用还是未知,因为在每个项目正式使用之前必须对开发的项目进行测试,如果不进行测试一旦投入使用可能会出现很多未可知的问题,比如使用人数太多导致系统瘫痪,比如某一功能存在bug信息填写错误等等,这些错误将给使用者带来很多的困扰,甚至造成更大的损失,因此测试是项目投入使用的最后一步,为用户提供一个运行顺畅、完美的项目也就是我们进行最后测试的目的。
-
- 系统部分测试
用户登录功能测试:
表5.1 用户登录功能测试表
测试名称 | 测试功能 | 操作过程 | 预期结果 | 测试结果 |
用户登录模块测试 | 用户登录成功的情况 | 点击前登录界面输入账号和密码分别输入admin和admin后点击“登录”按钮。 | 登录成功并调整到用户界面 | 正确 |
学生信息添加功能测试:
表5.2 学生信息添加功能测试表
测试名称 | 测试功能 | 操作过程 | 预期结果 | 测试结果 |
学生添加模块测试 | 学生添加成功的情况 | 在学生的页面中将点击添加,输入学生关信息,输入正确的信息后然后点击“提交”按钮。 | 提示添加成功 | 正确 |
学生添加模块测试 | 学生添加失败的情况 | 在学生页面中不填写的体温、健康码信息,其他信息正常输入“提交”按钮。 | 提示“添加失败,信息不能为空” | 正确 |
查询打卡签到信息功能模块测试:
表5.3 查询打卡签到信息功能测试表
测试名称 | 测试功能 | 操作过程 | 预期结果 | 测试结果 |
查询打卡签到信息功能测试 | 查询成功的情况 | 在打卡签到界面输入班级名称或者学生姓名进行查询 | 查询成功 | 正确 |
师生交流信息添加功能测试:
表5.4 师生交流添加功能测试表
测试名称 | 测试功能 | 操作过程 | 预期结果 | 测试结果 |
师生交流添加模块测试 | 师生交流添加成功的情况 | 在师生交流的页面中将点击添加,输入课程相关信息,输入正确的信息后然后点击“提交”按钮。 | 提示添加成功 | 正确 |
师生交流添加模块测试 | 师生交流添加失败的情况 | 在师生交流页面中不填写的请假时间,其他信息正常输入“提交”按钮。 | 提示“添加失败,信息不能为空” | 正确 |
-
- 系统测试结果
通过编写学生信息管理系统的测试用例,已经检测完毕用户的登录模块、学生信息添加模块、查询打卡签到模块、师生交流添加模块的功能测试,在对以上功能得测试过程中,发现了系统中的很多漏送并进行了完善,经过多人在线进行测试,系统完全可以正常运行,当然在后期的维护中系统将不断完善。
- 6 章 结论
在开发本学生信息管理系统之前我胸有成竹,觉得很简单,但在实际的开发中我发现了自身的很多问题,许多编程思想和方法都还没有掌握牢靠,比如Bootsatrp、Jquery、AJAX 、Spring、SpringMVC、mybeatis等许多Java Web开发技术,通过开发这个学生信息管理系统我成长了很多,懂得了做什么事情都要脚踏实地,不能眼高手低,在本次学生信息管理系统的开发中我逐渐掌握逐渐熟悉的技术。
本次学生信息管理系统的开发中我还学会了例如良好的编程思想和完善的规划思想。在着手编程之前需要罗列出程序框架的大概,脑海中构建出程序的主题框架。做好这一步我们才能胸有成竹的经行开发项目。当设计框架了熟于心之后,需要思考本次编程所需的主要知识点和技术点,并充分学习。如此一来项目的开发才能循序渐进、如丝般顺滑,长久以往就能养成良好的开发习惯。一个程序好不好还要看出的bug多不多,如果在项目完成前做好bug的查验与预防可能发生的事故才能保证程序的稳定长久性运行。如果项目在完工后出现各种问题自己,那么在进入社会后,不仅会给公司团队带来麻烦和增加不必要的工作,还会导致客户流失,公司对自己的评价下降。
在本次项目中我也暴露了诸多问题。对于Java的编程知识有所欠缺,环境配置和算法上出现诸多问题,时常导致项目运行出错,或者目标的实现有问题。或者实现想法时算法未优化,使得代码冗长,程序运行不顺畅。
源码获取