学生信息管理系统学籍信息管理

Brief Introduction
这个项目是一个大学生信息管理系统,提供用户级别的登录注册资料管理,信息查询,信息修改(管理员权利),简单的数据可视化分析等功能,也有基本的安全性保障

代码已经上传github

https://github.com/21503882/studentinfossh
Release Notes
v1.0.0 - 2019.5.19
StuInfoAdmin-v1.0.0 的一切准备工作似乎都已到位。发布之弦,一触即发。 不枉近百个日日夜夜与之为伴。因小而大,因弱而强。
无论它能走多远,抑或如何支撑?至少我曾倾注全心,无怨无悔


v1.1.0 - 2019.7.27
版本1.1.0,更新如下内容 :
优化数据表结构,对原有的表的部分字段进行了修改,并增加了title和grade两个表
优化sql语句效率
优化前端查询界面及查询方式,使其更加全面,对用户友好
更新登录界面记住密码的cookie设置
更新邮箱验证码服务,增加了验证码有效时间
优化源代码结构,增强了规范性和可拓展性
v1.2.0 - 2019.9.12 (Current Version)
目前版本为v1.2.0,更新如下内容 :
修复了前端编辑添加弹窗在不同分辨率客户机上的显示大小问题
新增Redis技术,用以缓存用户名密码,用户错误登录次数限制,邮箱验证码等等
新增连续输错用户名密码超过一定次数后的限制时间
更改了邮箱验证码有效时间的实现方式,由服务端java实现改为redis过期时间实现
提升了服务端的安全性和新增异常处理机制,用aop实现入参的校验,对不合法的请求及其参数值用日志记录,并抛出异常
优化了util包等源代码的结构,增强了可拓展性
对Redis和SpringAOP不太熟的同学,下载v1.1.0版本足够学习或完成课设了~
v2.0.0 (//TODO)
使用SpringBoot重构SSM,Thymeleaf重构JSP,提高项目的实用性及扩展性,尽情期待哟~


Technologies Used
前端
前端框架 : layui
数据可视化框架 : echarts
后端
IOC容器 : Spring
MVC框架 : SpringMVC
ORM框架 : Mybatis
缓存技术:Redis
数据库:Mysql
日志框架 : Log4j
安全框架 : Shiro
Project Structure
├─database                          // 数据库相关文件
│  ├─design                                  // 数据库设计
│  │  └─1
│  └─sql                            // 数据库初始化脚本文件
├─git_screenshot                    // 存放README.md 中的图片
├─src                               // 项目源代码目录
│  ├─main                           //源代码目录
│  │  ├─java
│  │  │  └─com
│  │  │      └─jzy          // java代码目录
│  │  │          ├─controller       // 控制层
│  │  │          ├─dao              // 持久层
│  │  │          ├─dto              // 传输对象
│  │  │          ├─entity           // 实体类
│  │  │          ├─interceptor      // 拦截器
│  │  │          ├─log              // 日志管理
│  │  │          ├─service          // 服务层
│  │  │          │  └─impl          // 服务层接口实现
│  │  │          └─util             // 工具方法
│  │  ├─resources                   // 资源文件目录
│  │  │  └─com
│  │  │      └─jzy
│  │  │          └─mapper           // mybatis对dao接口的xml实现
│  │  └─webapp                      // tomcat前端文件目录
│  │      ├─static                  // 静态资源
│  │      │  ├─custom               // 自定义静态资源
│  │      │  └─plugins              // 插件类静态资源
│  │      └─WEB-INF
│  │          └─page                // jsp页面目录 
│  └─test                           // 测试代码目录
├─README.md                         // help
└─pom.xml                           // maven依赖
Quick Start
1 : 项目开发环境
IDE : IntelliJ IDEA 2018.1.7
项目构建工具 : Maven 3.x
数据库 : Mysql 8.0.13
Redis:Redis server 3.2.100
JDK版本 : jdk 1.8
Tomcat版本 : Tomcat 8.x
2 : 项目的初始构建
在你的Mysql中,运行我提供的database/sql/init.sql 文件(注意mysql版本与sql脚本中部分代码的兼容性), 成功会创建名为mydatabase2的数据库,以及user、student、teacher、class、major、college、title、grade八个表
数据库物理模型如下 :

Snipaste_2019-07-17_09-48-36

进入src/main/resources修改dbconfig.properties配置文件,把数据库主机、端口、用户名和密码,改为你本地的
进入src/main/resources修改redis.properties配置文件,把数据库主机、端口、用户名和密码,改为你本地的
进入src/main/resources查看log4j.properties,如果有必要可以修改日志输出路径,目前在D盘下,你可选择不修改跳过此步
使用 IntelliJ IDEA 导入项目,选择Maven项目选项,一路点击next,即可将项目所需依赖导入。若有无法引入的依赖,可能是因为maven版本不同或是该依赖已过时不存在于现有maven仓库中,请前往maven官网映入最新的该类型依赖
Snipaste_2019-07-17_08-47-37

Snipaste_2019-07-17_08-49-48

在 IntelliJ IDEA 中,配置我们的 Tomcat, 然后把使用Maven构建好的项目添加到Tomcat中,操作比较简单,相关方法可以参考百度

运行项目,进入用户登录页面

Snipaste_2019-05-04_08-02-50

登录账户/密码(你也可以自行注册一个账户登录哟)
管理员账户:000000000000/admin1
学生账户:516030910429/123456
教师账户:1000000001/123456
Detailed Functions
用户服务
登录:如上文图所示

注册

Snipaste_2019-05-04_08-11-21

忘记密码后的重置密码(含发送邮箱验证码)

Snipaste_2019-05-04_08-12-27

登录进入主页

Snipaste_2019-09-12_10-35-03

修改基本资料

Snipaste_2019-07-04_08-19-12

修改密码

Snipaste_2019-07-17_09-23-03

修改绑定邮箱

Snipaste_2019-07-17_09-30-38

信息查询
学生信息查询

查询所有信息

Snipaste_2019-07-17_09-31-05

根据登录用户的用户名(应以学号注册)查询当前个人的学籍信息,若注册时未以真实学号注册,则无法查询到。

Snipaste_2019-07-17_09-32-12

模糊查询搜索

Snipaste_2019-07-17_09-32-47

教师信息查询:类似学生信息查询,图略

班级信息查询:类似学生信息查询,图略

专业&学院信息查询:类似学生信息查询,图略

信息修改
学生信息修改

此功能必须以管理员用户身份登录,否则会跳转至异常页面

Snipaste_2019-05-04_08-32-13

编辑信息

Snipaste_2019-07-17_09-33-51

添加

Snipaste_2019-07-17_09-34-24

单条、多条删除

Snipaste_2019-07-17_09-34-56

教师信息修改:类似学生信息修改,图略

班级信息修改:类似学生信息修改,图略

专业&学院信息修改:类似学生信息修改,图略

拓展功能
学生男女比可视化
Snipaste_2019-07-17_09-36-37

学生人数比可视化
Snipaste_2019-07-17_09-37-17

Snipaste_2019-07-26_17-10-43

师资力量可视化

package com.springmvc.controller;

import com.springmvc.dto.other.EmailVerifyCode;
import com.springmvc.dto.other.senior.StudentPercentBySex;
import com.springmvc.entity.College;
import com.springmvc.entity.User;
import com.springmvc.interceptor.Token;
import com.springmvc.util.Constants;
import com.springmvc.util.SetCookie;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author JinZhiyun
 * @ClassName OtherController
 * @Description 其他一些请求的控制类
 * @Date 2019/6/6 13:09
 * @Version 1.0
 **/
@Controller
public class OtherController extends BaseController {
    /**
     * @author JinZhiyun
     * @Description 定向到主页index.jsp,并返回用户model
     * @Date 16:48 2019/7/25
     * @Param []
     * @return org.springframework.web.servlet.ModelAndView
     **/
    @RequestMapping("/index")
    public ModelAndView index() {
        User user = userService.updateUserSession(session);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject(Constants.USER_MODEL, user);
        modelAndView.setViewName("index");
        return modelAndView;
    }

    /**
     * @return java.lang.String
     * @Author JinZhiyun
     * @Description 定向到登录页面login.jsp
     * @Date 9:25 2019/4/19
     * @Param []
     **/
    @RequestMapping("/login")
    public String login() {
        return "user/login";
    }

    /**
     * @return java.lang.String
     * @Author JinZhiyun
     * @Description 注销并定向到登录页面login.jsp
     * @Date 9:36 2019/4/19
     * @Param []
     **/
    @RequestMapping("/logout")
    public String logout() {
        userService.deleteUserSession(session);
        return "user/login";
    }

    /**
     * @author JinZhiyun
     * @Description 测试登录成功与否的ajax交互
     * @Date 16:49 2019/7/25
     * @Param [user, remember]
     * @return java.util.Map<java.lang.String,java.lang.Object>
     **/
    @RequestMapping("/loginTest")
    @ResponseBody //直接返回 json 数据
    public Map<String, Object> loginTest(User user, @RequestParam(value = "remember", required = false) String remember) {
        Map<String, Object> map = new HashMap();
        User userSessionInfo = userService.selectUserByNameAndPassword(user.getUserName(), user.getUserPassword());
        if (userSessionInfo == null) {
            map.put("data", "resultFail");
        } else {
            map.put("data", "resultSuccess");
            //登录成功设置session
            session.setAttribute(Constants.USERINFO_SESSION, userSessionInfo);
            //记住密码存cookie
            SetCookie.setUserLoginCookie(user.getUserName(), user.getUserPassword(), remember, request, response);
        }
        return map;
    }

    /**
     * @return java.lang.String
     * @Author JinZhiyun
     * @Description 定向到注册页面reg.jsp
     * @Date 9:37 2019/4/19
     * @Param []
     **/
    @RequestMapping("/reg")
    public String reg() {
        return "user/reg";
    }

    /**
     * @return java.util.Map<java.lang.String                               ,                               java.lang.Object>
     * @Author JinZhiyun
     * @Description 判断注册成功与否的ajax交互
     * @Date 9:39 2019/4/19
     * @Param [user]
     **/
    @RequestMapping("/regTest")
    @ResponseBody
    public Map<String, Object> regTest(User user) {
        Map<String, Object> map = new HashMap();
        map.put("data", userService.insertUserRegInfo(user));
        return map;
    }

    /**
     * @return java.lang.String
     * @Author JinZhiyun
     * @Description 定向到忘记密码页面forget.jsp
     * @Date 9:37 2019/4/19
     * @Param []
     **/
    @RequestMapping("/forget")
    @Token(save = true)
    public String forget() {
        return "user/forget";
    }

    /**
     * @return java.util.Map<java.lang.String       ,       java.lang.Object>
     * @author JinZhiyun
     * @Description 发送验证码的ajax交互
     * @Date 8:46 2019/6/6
     * @Param [user]
     **/
    @RequestMapping("/sendVerifyCodeToEmail")
    @ResponseBody
    public Map<String, Object> sendVerifyCodeToEmail(User user) {
        Map<String, Object> map = new HashMap();
        EmailVerifyCode emailVerifyCode = otherService.sendVerifyCodeToEmail(user.getUserEmail());
        session.setAttribute(Constants.EMAILVERIFYCODE_SESSION, emailVerifyCode);
        map.put("msg", "sendSuccess");
        return map;
    }

    /**
     * @return java.util.Map<java.lang.String       ,       java.lang.Object>
     * @author JinZhiyun
     * @Description 检测验证码是否正确的ajax交互
     * @Date 8:58 2019/6/6
     * @Param [emailVerifyCode, user]
     **/
    @RequestMapping("/emailVerifyCodeTest")
    @ResponseBody
    public Map<String, Object> emailVerifyCodeTest(@RequestParam("emailVerifyCode") String emailVerifyCode, User user) {
        Map<String, Object> map = new HashMap();

        if (userService.selectUserByEmail(user.getUserEmail()) == null) {
            map.put("data", "emailUnregistered");
        } else if (!otherService.ifValidEmailVerifyCode(emailVerifyCode, session)) {
            map.put("data", "verifyCodeWrong");
        } else {
            session.setAttribute(Constants.USEREMAIL_SESSION, user.getUserEmail());
            map.put("data", "verifyCodeCorrect");
        }

        return map;
    }

    /**
     * @return java.util.Map<java.lang.String                               ,                               java.lang.Object>
     * @Author JinZhiyun
     * @Description 重置密码的ajax交互
     * @Date 9:46 2019/4/19
     * @Param [user]
     **/
    @RequestMapping("/resetPassword")
    @Token(remove = true)
    @ResponseBody
    public Map<String, Object> resetPassword(User user) {
        Map<String, Object> map = new HashMap();

        String userEmail = (String) session.getAttribute(Constants.USEREMAIL_SESSION);
        if (userEmail != null && userEmail != "") {
            userService.updateResetPasswordByEmail(userEmail, user.getUserPassword());
            map.put("data", "resetPasswordSuccess");
        }

        return map;
    }

    /*=================以上为非登录下的请求,在LoginInterceptor中应该排除==================*/

    /**
     * @return java.lang.String
     * @Author JinZhiyun
     * @Description 定向到无修改权限提示页面error.jsp
     * @Date 13:17 2019/5/3
     * @Param []
     **/
    @RequestMapping("/error")
    public String error() {
        return "tips/error";
    }

    /**
     * @return java.lang.String
     * @Author JinZhiyun
     * @Description 定向到控制台console.jsp
     * @Date 9:58 2019/5/3
     * @Param []
     **/
    @RequestMapping("/console")
    public String console() {
        return "home/console";
    }

    /**
     * @return java.util.Map<java.lang.String               ,               java.lang.Object>
     * @Author JinZhiyun
     * @Description 性别比可视化ajax
     * @Date 18:54 2019/5/5
     * @Param [stuCollegeName, stuMajorName, stuClassName]
     **/
    @RequestMapping("/findSexPercent")
    @ResponseBody
    public Map<String, Object> findSexPercent(@RequestParam(value = "college", required = false) String stuCollegeName
            , @RequestParam(value = "major", required = false) String stuMajorName
            , @RequestParam(value = "class", required = false) String stuClassName) {
        Map<String, Object> map = new HashMap<>();
        StudentPercentBySex studentPercent = otherService.selectStuTotalBySex(stuCollegeName, stuMajorName, stuClassName);
        map.put(Constants.STUDENT_PERCENT_BY_SEX, studentPercent);
        return map;
    }

    /**
     * @return java.lang.String
     * @Author JinZhiyun
     * @Description 重定向到echarts可视化性别比饼图
     * @Date 12:18 2019/5/5
     * @Param []
     **/
    @RequestMapping("/senior/stuSex")
    public String sex() {
        return "senior/student/stuSex";
    }

    /**
     * @return java.lang.String
     * @Author JinZhiyun
     * @Description 重定向到echarts可视化学生数柱状图
     * @Date 19:37 2019/5/5
     * @Param []
     **/
    @RequestMapping("/senior/stuNum")
    public String stuNum() {
        return "senior/student/stuNum";
    }

    /**
     * @return java.util.Map<java.lang.String   ,   java.lang.Object>
     * @author JinZhiyun
     * @Description 学生人数比可视化ajax
     * @Date 19:00 2019/7/21
     * @Param [collegeName, majorName, type]
     **/
    @RequestMapping("/findPersonTotalPercentByCommonName")
    @ResponseBody
    public Map<String, Object> findPersonTotalPercentByCommonName(@RequestParam(value = "college", required = false) String collegeName
            , @RequestParam(value = "major", required = false) String majorName, @RequestParam(value = "type", required = false) String type) {
        Map<String, Object> map = new HashMap<>();
        List<List<Object>> list = otherService.proSelectStuTotalByCollegeOrMajorName(type, collegeName, majorName);
        map.put("commonName", list.get(0));
        map.put("total", list.get(1));
        return map;
    }

    /**
     * @author JinZhiyun
     * @Description 本硕博比可视化ajax
     * @Date 17:40 2019/7/23
     * @Param [collegeName, type]
     * @return java.util.Map<java.lang.String,java.lang.Object>
     **/
    @RequestMapping("/findStuTotalByDegreeAndCollege")
    @ResponseBody
    public Map<String, Object> findStuTotalByDegreeAndCollege(@RequestParam(value = "college", required = false) String collegeName, @RequestParam(value = "type", required = false) String type) {
        Map<String, Object> map = new HashMap<>();
        map.put("dimensions", new ArrayList<Object>() {//这个大括号 就相当于我们  new 接口
                    {//这个大括号 就是 构造代码块 会在构造函数前 调用
                        this.add("product");
                        this.addAll(Constants.stuDegrees);
                    }
                }
        );
        List<Map<String, Object>> list = otherService.transferStuTotalToValidJSON(type,collegeName);
        map.put("source", list);
        return map;
    }

    /**
     * @author JinZhiyun
     * @Description 重定向到师资力量echarts可视化
     * @Date 17:42 2019/7/23
     * @Param []
     * @return java.lang.String
     **/
    @RequestMapping("/senior/teaPower")
    public String teaPower() {
        return "senior/teacher/teaPower";
    }

    /**
     * @author JinZhiyun
     * @Description 师资力量可视化ajax
     * @Date 18:45 2019/7/24
     * @Param [collegeName, majorName, type]
     * @return java.util.Map<java.lang.String,java.lang.Object>
     **/
    @RequestMapping("/findTeaTotalGroupByTitle")
    @ResponseBody
    public Map<String, Object> findTeaTotalGroupByTitle(@RequestParam(value = "college", required = false) String collegeName
            , @RequestParam(value = "major", required = false) String majorName,@RequestParam(value = "type", required = false) String type) {
        return otherService.transTeaTotalToValidJSON(type,collegeName,majorName);
    }
}
代码已经上传github,下载地址: https://github.com/21503882/studentinfossh
————————————————
 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值