基于Spring+mybatis+amazeui+MySQL实现的毕业设计论文管理系统

到山东找蓝翔

发布日期: 2021-08-12 10:52:54 浏览量: 207
评分:
star star star star star star star star star star_border
*转载请注明来自write-bug.com

1.项目介绍

毕业设计是本科教育的最后一个环节,整个过程包括课题拟定与审核、师生双选、开题报告、文档审核、中期检查、毕业答辩等多个环节,是一项系统而复杂的工作。开发一个适合本校的毕业设计管理系统,不仅能够极大地减少教务管理人员的工作量,还能较大地提高学生和教师的效率。

毕业设计管理系统可以分为五个模块:登录模块,选题模块,信息管理模块,流程管理模块,文件管理模块。

该系统在技术上使用 Spring + SpringMVC + MyBatis 整合框架作为后台开发框架,AmazeUI 作为前端开发框架。并使用 Ehcache 作为项目的缓存,druid 作为项目的数据库连接池,使用 FreeMarker 实现 word 的导出,使用 Shiro 完成项目的登录认证,数据库使用的则是 MySQL。

该系统可以分为三类角色:学生,教师,教务管理员。

该系统前端界面使用纯 HTML 实现,与后台的交互则都是通过 Ajax 完成。

1.1 软件架构

系统的组织架构如图所示,三种用户根据自己不同的权限对课题、文档、成绩、公告、任务五种数据信息进行处理,不同用户角色再根据这些数据信息进行交互通过课题进行交互,并且围绕着文档进行数据的传递和处理等。

系统的功能模块如图所示,每个模块各有几个子功能模块。

本系统包含三种用户:学生、教师和管理员。通过本系统,学生可以获取指导教师和管理员发布的相关教学信息和教学资源;教师可以进行毕设进度的日常管理,发布任务、上传资料、审核文档等;管理员可以进行系统的管理和维护,并对教师、学生、课题和文档进行管理,确保系统的正常运行。

系统总共分为3个模块:

  • 1.学生模块
    学生登录系统后进入该模块,在该模块中,学生能够修改个人资料和登录密码,选择感兴趣的课题及导师,下载导师上传的相关参考资料,上传自己已经完成的文档,查看发布的公告、任务和自己的阶段成绩等

  • 2.教师模块
    教师登录系统后进入该模块,在该模块中,教师能够修改个人资料和登录密码,选择学生,上传拟好的课题题目给管理员审核,发布阶段任务,上传相关资料给学生参考,下载学生上传的阶段文档并审核和打分,查看公告及发布新公告等

  • 3.管理员模块
    管理员登录系统后进入该模块,在该模块中,管理员可以增删查改导师和学生的信息,审核教师上传的课题,发布公告,查看各种信息,查看各种数据分析的结果和图表

2.数据库设计

2.1 数据分析

本系统的主要数据表为存储学生、教师、文档、课题数据集的四个表。其余表大多作为外键关联用于完善四张表的信息。

概念设计:

数据库主要围绕学生、教师、 课题、文档4个实体进行数据处理。即系统只要处理好这4个实体的数据,就可以完成系统的绝大部分功能并让毕业设计管理的整个流程顺利进行下去。其余的数据表则是围绕这4个实体相应展开,进行一些扩展和补充,以完善整个数据库的结构并加快数据库对请求的响应速度。

数据库文档处理E-R图

数据库课题处理E-R图

2.2 表列表

数据库中一共设计了24张表,和学生相关的表有12张(包括学生信息、开题报告、文档成绩、毕设进度、学生疑问等),和教师相关的表有5张(包括教师信息、任务书、阶段任务、课题申报等),文档有2张表,课题涉及3张表,还有2张表属于公共信息表,用于进行一些补充以完善数据库。数据库的表清单如下。

管理员用户表

班级信息表

答辩信息表

部门科室表

字典表

下载信息表

年级表

公告表

综述表

论文表

盲审信息表

免答辩信息表

留言消息表

课题表

课题来源表

权限表

专业表

学生表

教师表

用户表

工作时间表

验收老师表

验收小组表

中期自查表

2.3 数据表关系图

2.4 功能模块的设计与实现

本系统依据学生、导师、管理员三种不同用户角色的需求,分为了三个大的功能模块,三种用户角色在各自的模块进行操作,可以通过课题进行与其他两种用户角色之间的交互,并且围绕着文档进行各种数据(用户信息、文档信息、课题信息)的传递和处理等,这就形成了系统的体系结构,管理员发布课题给学生,学生选择课题呈现给导师,导师自拟课题向管理员申报,如图所示。

同时三种用户可对五种数据信息进行不同的处理(增删查改的权限不同),表现在系统上就是拥有不同的功能模块,所以分为三个大的模块,每个模块有相应的小的功能模块,系统的功能结构如图。

3.项目实现

3.1 word文档工具类

  1. public class WordUtils {
  2. //配置信息,代码本身写的还是很可读的,就不过多注解了
  3. private static Configuration configuration = null;
  4. //这里注意的是利用WordUtils的类加载器动态获得模板文件的位置
  5. private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../").getPath()+"/templete/";
  6. static {
  7. configuration = new Configuration();
  8. configuration.setDefaultEncoding("utf-8");
  9. try {
  10. configuration.setDirectoryForTemplateLoading(new File(templateFolder));
  11. } catch (IOException e) {
  12. e.printStackTrace();
  13. }
  14. }
  15. private WordUtils() {
  16. throw new AssertionError();
  17. }
  18. public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response,
  19. Map map, String templeteName, String fileName) throws IOException {
  20. //Template freemarkerTemplate = configuration.getTemplate("开题报告.ftl");
  21. Template freemarkerTemplate = configuration.getTemplate(templeteName);
  22. File file = null;
  23. InputStream fin = null;
  24. ServletOutputStream out = null;
  25. try {
  26. // 调用工具类的createDoc方法生成Word文档
  27. file = createDoc(map,freemarkerTemplate);
  28. fin = new FileInputStream(file);
  29. // response.setCharacterEncoding("utf-8");
  30. response.setContentType("application/msword;charset=utf-8");
  31. // 设置浏览器以下载的方式处理该文件名
  32. // String fileName = "开题报告.doc";
  33. response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(Utils.filenameEncoding(fileName, request))));
  34. out = response.getOutputStream();
  35. byte[] buffer = new byte[512]; // 缓冲区
  36. int bytesToRead = -1;
  37. // 通过循环将读入的Word文件的内容输出到浏览器中
  38. while((bytesToRead = fin.read(buffer)) != -1) {
  39. out.write(buffer, 0, bytesToRead);
  40. }
  41. } finally {
  42. if(fin != null) fin.close();
  43. if(out != null) out.close();
  44. if(file != null) file.delete(); // 删除临时文件
  45. }
  46. }
  47. private static File createDoc(Map<?, ?> dataMap, Template template) {
  48. String name = "test.doc";
  49. File f = new File(name);
  50. Template t = template;
  51. try {
  52. // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
  53. Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
  54. t.process(dataMap, w);
  55. w.close();
  56. } catch (Exception ex) {
  57. ex.printStackTrace();
  58. throw new RuntimeException(ex);
  59. }
  60. return f;
  61. }
  62. }

3.2 登录拦截类

  1. public class LoginRealm extends AuthenticatingRealm{
  2. @Autowired
  3. private UserService userService;
  4. @Override
  5. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  6. System.out.println("doGetAuthenticationInfo1:"+token.hashCode());
  7. //1.将AuthenticationToken强转为UsernamePasswordToken
  8. UsernamePasswordToken uspaToken=(UsernamePasswordToken)token;
  9. //2.获得用户名,密码
  10. String userName=uspaToken.getUsername();
  11. String password=new String(uspaToken.getPassword());
  12. //3.查询数据库获得真实的用户名或密码(这里模拟)
  13. //若用户不存在,抛出UnknownAccountException
  14. User user = userService.login(userName, password);
  15. if(user==null) {
  16. throw new UnknownAccountException("用户不存在");
  17. }
  18. if(user.getUserRoles()==null||user.getUserRoles()==3){
  19. throw new LockedAccountException("用户被锁定");
  20. }
  21. //4.根据用户信息构建AuthenticationInfo,我们常用其子类:
  22. //1).principal 用户实体信息 可以是userName,也可以是数据表对应的实体类信息
  23. Object principal=userName;
  24. //2).credentials 密码
  25. Object credentials=password;
  26. //3).realmName 使用当前realName即可
  27. String realmName=this.getName();
  28. SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(principal, credentials, realmName);
  29. return info;
  30. }
  31. }

3.3 主要代码编写

UserController.java

  1. @Controller
  2. @RequestMapping("/userController")
  3. public class UserController {
  4. @Autowired
  5. private UserService userService;
  6. @ResponseBody
  7. @RequestMapping(value="/isuser",method=RequestMethod.POST)
  8. public boolean isUser(String account) {
  9. return userService.isUser(account);
  10. }
  11. @ResponseBody
  12. @RequestMapping(value="/ispassword",method=RequestMethod.POST)
  13. public boolean ispassword(@RequestParam("password")String password,HttpSession session) {
  14. User user = (User) session.getAttribute("user");
  15. if(user!=null) {
  16. return userService.ispassword(Utils.md5(password),user.getUserId());
  17. }
  18. return false;
  19. }
  20. @ResponseBody
  21. @RequestMapping(value="/login",method=RequestMethod.POST)
  22. public String login(HttpSession session,String randStr,String account,String password) {
  23. String randStr2=(String) session.getAttribute("randStr");
  24. if(randStr2!=null&&randStr2.equals(randStr)) {
  25. password=Utils.md5(password);
  26. Subject currentUser = SecurityUtils.getSubject();
  27. if (!currentUser.isAuthenticated()) {
  28. //把用户名和密码封装为UsernamePasswordToken
  29. UsernamePasswordToken token = new UsernamePasswordToken(account, password);
  30. try {
  31. //执行登录
  32. currentUser.login(token);
  33. return toUI(session,account,password);
  34. }
  35. //用户不存在
  36. catch (UnknownAccountException ae) {
  37. return "passwordError";
  38. }
  39. //用户被锁定
  40. catch (LockedAccountException e) {
  41. return "passwordError";
  42. }
  43. }else {
  44. return toUI(session,account,password);
  45. }
  46. }else {
  47. return "randStrError";
  48. }
  49. }
  50. private String toUI(HttpSession session,String account,String password) {
  51. User user = userService.login(account, password);
  52. if(user!=null) {
  53. if(2==user.getUserRoles()) {
  54. session.setAttribute("user", user);
  55. return "student/sindex.html";
  56. }
  57. if(1==user.getUserRoles()) {
  58. session.setAttribute("user", user);
  59. return "teacher/tindex.html";
  60. }
  61. }
  62. return "passwordError";
  63. @RequestMapping("/logout")
  64. public String logout(HttpSession session) {
  65. session.removeAttribute("user");
  66. return "redirect:http://localhost:8080/graduation/login.html";
  67. }
  68. @ResponseBody
  69. @RequestMapping(value="/updateInfo",method=RequestMethod.POST)
  70. public boolean updateStudentInfo(User user,
  71. @RequestParam(value="portrait",required=false)MultipartFile portrait,HttpServletRequest request) {
  72. if(portrait!=null&&portrait.getSize()>0) {
  73. if(portrait.getSize()>(10*1024*1024)) {
  74. return false;
  75. }
  76. String filename=portrait.getOriginalFilename();
  77. String dbPath=request.getServletContext().getContextPath()+"/portrait/"+user.getUserId();
  78. String basePath=request.getServletContext().getRealPath("/portrait/"+user.getUserId());
  79. new File(basePath).mkdir();
  80. File portraitFile=new File(basePath,filename);
  81. try {
  82. portrait.transferTo(portraitFile);
  83. user.setUserPortrait(dbPath+"/"+filename);
  84. return userService.updateUserInfo(user);
  85. } catch (Exception e) {
  86. e.printStackTrace();
  87. }
  88. }
  89. return userService.updateUserInfo(user);
  90. }
  91. @ResponseBody
  92. @RequestMapping(value="/updatePwd",method=RequestMethod.PUT)
  93. public boolean updateStudentPwd(User user,HttpSession session) {
  94. String password=user.getUserPassword();
  95. if(password!=null&&!password.isEmpty()) {
  96. user.setUserPassword(Utils.md5(password));
  97. boolean bool = userService.updateUserInfo(user);
  98. if(bool==true) {
  99. session.removeAttribute("user");
  100. return true;
  101. }
  102. }
  103. return false;
  104. }
  105. }

ProjectController.java

  1. @Controller
  2. @RequestMapping("/projectController")
  3. public class ProjectController {
  4. @Autowired
  5. private ProjectService projectService;
  6. @Autowired
  7. private TeacherService teacherService;
  8. @Autowired
  9. private StudentService studentService;
  10. @ResponseBody
  11. @RequestMapping(value="/getProjectListByTeacherId",method=RequestMethod.GET)
  12. public PageInfo<Project> getProjectListByTeacherId(@RequestParam(required=true)String teacherId,
  13. @RequestParam(defaultValue="1")int pageNum,@RequestParam(defaultValue="8")int pageSize) {
  14. PageHelper.startPage(pageNum, pageSize);
  15. List<Project> list = projectService.getProjectListByTeacherId(teacherId);
  16. return new PageInfo<>(list);
  17. }
  18. @ResponseBody
  19. @RequestMapping(value="/getCountProjectNum",method=RequestMethod.GET)
  20. public int getCountProjectNum() {
  21. return projectService.getCountProjectNum();
  22. }
  23. @ResponseBody
  24. @RequestMapping(value="/thisTeacherYesProjectNum",method=RequestMethod.GET)
  25. public int thisTeacherYesProjectNum(HttpSession session) {
  26. User user=(User) session.getAttribute("user");
  27. if(user!=null) {
  28. Teacher teacher = teacherService.findTeacherByUserId(user.getUserId());
  29. if(teacher!=null) {
  30. String teacherId = teacher.getTeacherId();
  31. return projectService.thisTeacherYesProjectNum(teacherId);
  32. }
  33. }
  34. return 0;
  35. }
  36. @ResponseBody
  37. @RequestMapping(value="/thisTeacherUndefinedStudentNum",method=RequestMethod.GET)
  38. public int thisTeacherUndefinedStudentNum(HttpSession session) {
  39. User user=(User) session.getAttribute("user");
  40. if(user!=null) {
  41. Teacher teacher = teacherService.findTeacherByUserId(user.getUserId());
  42. if(teacher!=null) {
  43. String teacherId = teacher.getTeacherId();
  44. return studentService.thisTeacherUndefinedStudentNum(teacherId);
  45. }
  46. }
  47. return 0;
  48. }
  49. /**
  50. * 添加与更新方法
  51. * @param project
  52. * @param session
  53. * @return
  54. */
  55. @ResponseBody
  56. @RequestMapping(value="/insertSelective",method=RequestMethod.POST)
  57. public boolean insertSelective(Project project,HttpSession session) {
  58. User user=(User) session.getAttribute("user");
  59. if(user!=null) {
  60. Teacher teacher = teacherService.findTeacherByUserId(user.getUserId());
  61. if(teacher!=null) {
  62. project.setTeacherId(teacher.getTeacherId());
  63. if(project.getProjectId()!=null) {
  64. return projectService.updateByPrimaryKeySelective(project);
  65. }else {
  66. return projectService.insertSelective(project,teacher.getTeacherId());
  67. }
  68. }
  69. }
  70. return false;
  71. }
  72. @ResponseBody
  73. @RequestMapping(value="/getProjectByTeacherId")
  74. public List<Project> getProjectByTeacherId(HttpSession session){
  75. User user=(User) session.getAttribute("user");
  76. if(user!=null) {
  77. Teacher teacher = teacherService.findTeacherByUserId(user.getUserId());
  78. if(teacher!=null) {
  79. return projectService.getProjectByTeacherId(teacher.getTeacherId());
  80. }
  81. }
  82. return null;
  83. }
  84. }

4.项目展示

4.1 学生模块部分页面

主页(主页可以看到一些内容概要与相关提示)

登陆后

选择课题模块图

填写报告界面

下载资源

4.2 教师模块部分页面

上传的附件 cloud_download 开发文档.pdf ( 3.18mb, 2次下载 ) cloud_download graduation-master.zip ( 3.88mb, 2次下载 )
error_outline 下载需要13点积分

发送私信

会冒泡的可乐

111
文章数
12
评论数
最近文章
eject