├── .settings ├── org.eclipse.wst.jsdt.ui.superType.name ├── org.eclipse.wst.jsdt.ui.superType.container ├── org.eclipse.wst.validation.prefs ├── org.eclipse.m2e.core.prefs ├── org.eclipse.jpt.core.prefs ├── org.eclipse.core.resources.prefs ├── org.eclipse.wst.common.project.facet.core.xml ├── org.eclipse.wst.common.project.facet.core.prefs.xml ├── .jsdtscope ├── org.eclipse.jdt.core.prefs ├── org.eclipse.wst.common.component └── .rebel.xml.bak ├── 文档 ├── ER.png ├── 错题管理.png ├── 在线考试系统.png ├── 开始考试用例图.png ├── 界面 │ ├── 上传资源.png │ ├── 登陆页面.png │ ├── 考试页面.png │ ├── 资源详情.png │ ├── 题目讨论.png │ └── 考试结果图.png ├── 考试模块类图.png ├── 表结构 │ ├── 无标题.htm │ ├── 无标题.xlsx │ ├── 无标题.files │ │ ├── sheet001.htm │ │ ├── tabstrip.htm │ │ ├── stylesheet.css │ │ └── filelist.xml │ └── 所有表.txt ├── 试卷管理类图.png ├── 资源管理类图.png ├── 时序图 │ ├── 交卷时序图.png │ ├── 下载资源时序图.png │ └── 试卷导入时序图.png └── 用例图 │ ├── 考试管理.png │ ├── 试卷管理.png │ └── 资源管理.png ├── 题库 ├── 待新增试题.xlsx ├── 软件工程考试题库.pdf ├── 2015软件工程考试.xlsx ├── 2016年软件工程考试全单选.xlsx ├── 2017年软件测试工程师考试.xlsx ├── 2018年软件工程练习题.xlsx └── 2016年软件工程考试全单选新.xlsx ├── src └── main │ ├── webapp │ ├── index.jsp │ ├── WEB-INF │ │ ├── views │ │ │ ├── index.jsp │ │ │ ├── exception │ │ │ │ └── 403.jsp │ │ │ ├── manager-templet.jsp │ │ │ ├── sys │ │ │ │ ├── exampaper-list.jsp │ │ │ │ ├── user-list.jsp │ │ │ │ └── user-input.jsp │ │ │ ├── question-list.jsp │ │ │ ├── exam-result-list.jsp │ │ │ ├── exam-list.jsp │ │ │ ├── exampaper-input.jsp │ │ │ ├── exam-result-input.jsp │ │ │ ├── exampaper-list.jsp │ │ │ ├── resource-list.jsp │ │ │ ├── exam-result-show.jsp │ │ │ ├── resource-input.jsp │ │ │ ├── exam-input.jsp │ │ │ ├── exam-show.jsp │ │ │ ├── uploadfile-input.jsp │ │ │ ├── login.jsp │ │ │ ├── wrong-question-show.jsp │ │ │ ├── register.jsp │ │ │ ├── question-show.jsp │ │ │ ├── resource-show.jsp │ │ │ ├── exam-result.jsp │ │ │ ├── question-input.jsp │ │ │ ├── exam.jsp │ │ │ └── resource-all.jsp │ │ └── web.xml │ ├── static │ │ ├── img │ │ │ ├── logo.png │ │ │ └── touxiang.jpg │ │ ├── uploadFive │ │ │ ├── uploadifive-cancel.png │ │ │ └── uploadifive.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ ├── css │ │ │ └── my-css.css │ │ └── js │ │ │ ├── npm.js │ │ │ ├── my-js.js │ │ │ └── jquery.cookie.js │ ├── test.html │ ├── common │ │ ├── taglibs.jsp │ │ ├── show-message.jsp │ │ ├── head.jsp │ │ ├── left-bar.jsp │ │ ├── header.jsp │ │ └── page.jsp │ └── home.html │ ├── java │ ├── pers │ │ └── corvey │ │ │ └── exam │ │ │ ├── dao │ │ │ ├── ChoiceDAO.java │ │ │ ├── QuestionDAO.java │ │ │ ├── SysModifyLogDAO.java │ │ │ ├── SysAuthorityDAO.java │ │ │ ├── QuestionCommentDAO.java │ │ │ ├── ResourceCommentDAO.java │ │ │ ├── ExamDAO.java │ │ │ ├── ExamPaperDAO.java │ │ │ ├── ResourceDAO.java │ │ │ ├── SysUserDAO.java │ │ │ ├── BuyLogDAO.java │ │ │ ├── ChooseLogDAO.java │ │ │ └── ExamResultDAO.java │ │ │ ├── controller │ │ │ ├── sys │ │ │ │ ├── ExceptionController.java │ │ │ │ ├── CaptchaController.java │ │ │ │ └── SysUserController.java │ │ │ ├── IndexController.java │ │ │ ├── common │ │ │ │ ├── BaseController.java │ │ │ │ └── BaseControllerImpl.java │ │ │ ├── QuestionCommentController.java │ │ │ ├── ResourceCommentController.java │ │ │ ├── QuestionController.java │ │ │ ├── ExamResultController.java │ │ │ └── ExamPaperController.java │ │ │ ├── other │ │ │ ├── security │ │ │ │ ├── CaptchaException.java │ │ │ │ ├── UserDetailsServiceImpl.java │ │ │ │ └── CaptchaUsernamePasswordAuthenticationFilter.java │ │ │ └── hibernate │ │ │ │ ├── MyImplicitNamingStrategy.java │ │ │ │ └── MyPhysicalNamingStrategy.java │ │ │ ├── entity │ │ │ ├── QuestionComment.java │ │ │ ├── common │ │ │ │ ├── IdEntity.java │ │ │ │ ├── BaseComment.java │ │ │ │ ├── BaseEntity.java │ │ │ │ ├── BaseEntityImpl.java │ │ │ │ └── SysModifyLog.java │ │ │ ├── ResourceComment.java │ │ │ ├── BuyLog.java │ │ │ ├── Choice.java │ │ │ ├── sys │ │ │ │ ├── SysAuthority.java │ │ │ │ └── SysUser.java │ │ │ ├── Exam.java │ │ │ ├── ExamPaper.java │ │ │ ├── ChooseLog.java │ │ │ ├── ExamResult.java │ │ │ ├── ui │ │ │ │ └── CallBackMessage.java │ │ │ ├── Resource.java │ │ │ └── Question.java │ │ │ ├── service │ │ │ ├── ExamService.java │ │ │ ├── ChoiceService.java │ │ │ ├── ResourceService.java │ │ │ ├── ExamPaperService.java │ │ │ ├── common │ │ │ │ ├── BaseService.java │ │ │ │ └── BaseServiceImpl.java │ │ │ ├── QuestionCommentService.java │ │ │ ├── ResourceCommentService.java │ │ │ ├── sys │ │ │ │ ├── SysUserService.java │ │ │ │ └── SysAuthorityService.java │ │ │ ├── ExamResultService.java │ │ │ ├── QuestionService.java │ │ │ ├── BuyLogService.java │ │ │ └── ChooseLogService.java │ │ │ ├── exception │ │ │ └── FileNotPermitException.java │ │ │ ├── util │ │ │ ├── CurrentUtils.java │ │ │ └── MyFileUtils.java │ │ │ └── helper │ │ │ └── form │ │ │ ├── ChooseFormHelper.java │ │ │ └── QuestionFormHelper.java │ └── META-INF │ │ └── persistence.xml │ └── resources │ ├── config.properties │ ├── rebel.xml │ └── spring-security.xml ├── .gitignore ├── README.md ├── .classpath └── .project /.settings/org.eclipse.wst.jsdt.ui.superType.name: -------------------------------------------------------------------------------- 1 | Window -------------------------------------------------------------------------------- /文档/ER.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/ER.png -------------------------------------------------------------------------------- /文档/错题管理.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/错题管理.png -------------------------------------------------------------------------------- /文档/在线考试系统.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/在线考试系统.png -------------------------------------------------------------------------------- /文档/开始考试用例图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/开始考试用例图.png -------------------------------------------------------------------------------- /文档/界面/上传资源.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/界面/上传资源.png -------------------------------------------------------------------------------- /文档/界面/登陆页面.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/界面/登陆页面.png -------------------------------------------------------------------------------- /文档/界面/考试页面.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/界面/考试页面.png -------------------------------------------------------------------------------- /文档/界面/资源详情.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/界面/资源详情.png -------------------------------------------------------------------------------- /文档/界面/题目讨论.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/界面/题目讨论.png -------------------------------------------------------------------------------- /文档/考试模块类图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/考试模块类图.png -------------------------------------------------------------------------------- /文档/表结构/无标题.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/表结构/无标题.htm -------------------------------------------------------------------------------- /文档/试卷管理类图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/试卷管理类图.png -------------------------------------------------------------------------------- /文档/资源管理类图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/资源管理类图.png -------------------------------------------------------------------------------- /题库/待新增试题.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/题库/待新增试题.xlsx -------------------------------------------------------------------------------- /文档/时序图/交卷时序图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/时序图/交卷时序图.png -------------------------------------------------------------------------------- /文档/用例图/考试管理.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/用例图/考试管理.png -------------------------------------------------------------------------------- /文档/用例图/试卷管理.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/用例图/试卷管理.png -------------------------------------------------------------------------------- /文档/用例图/资源管理.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/用例图/资源管理.png -------------------------------------------------------------------------------- /文档/界面/考试结果图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/界面/考试结果图.png -------------------------------------------------------------------------------- /文档/表结构/无标题.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/表结构/无标题.xlsx -------------------------------------------------------------------------------- /题库/软件工程考试题库.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/题库/软件工程考试题库.pdf -------------------------------------------------------------------------------- /文档/时序图/下载资源时序图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/时序图/下载资源时序图.png -------------------------------------------------------------------------------- /文档/时序图/试卷导入时序图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/时序图/试卷导入时序图.png -------------------------------------------------------------------------------- /题库/2015软件工程考试.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/题库/2015软件工程考试.xlsx -------------------------------------------------------------------------------- /src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Hello World!

4 | 5 | 6 | -------------------------------------------------------------------------------- /题库/2016年软件工程考试全单选.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/题库/2016年软件工程考试全单选.xlsx -------------------------------------------------------------------------------- /题库/2017年软件测试工程师考试.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/题库/2017年软件测试工程师考试.xlsx -------------------------------------------------------------------------------- /题库/2018年软件工程练习题.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/题库/2018年软件工程练习题.xlsx -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.jsdt.ui.superType.container: -------------------------------------------------------------------------------- 1 | org.eclipse.wst.jsdt.launching.baseBrowserLibrary -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.validation.prefs: -------------------------------------------------------------------------------- 1 | disabled=06target 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /题库/2016年软件工程考试全单选新.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/题库/2016年软件工程考试全单选新.xlsx -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/index.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Hello World!

4 | 5 | 6 | -------------------------------------------------------------------------------- /文档/表结构/无标题.files/sheet001.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/表结构/无标题.files/sheet001.htm -------------------------------------------------------------------------------- /文档/表结构/无标题.files/tabstrip.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/表结构/无标题.files/tabstrip.htm -------------------------------------------------------------------------------- /文档/表结构/无标题.files/stylesheet.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/文档/表结构/无标题.files/stylesheet.css -------------------------------------------------------------------------------- /src/main/webapp/static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/src/main/webapp/static/img/logo.png -------------------------------------------------------------------------------- /src/main/webapp/static/img/touxiang.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/src/main/webapp/static/img/touxiang.jpg -------------------------------------------------------------------------------- /.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /文档/表结构/所有表.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 选择记录 - 选项关系表 5 | 6 | 试卷 - 题目关系表 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 用户 - 权限角色关系表 15 | -------------------------------------------------------------------------------- /src/main/webapp/static/uploadFive/uploadifive-cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/src/main/webapp/static/uploadFive/uploadifive-cancel.png -------------------------------------------------------------------------------- /src/main/webapp/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/src/main/webapp/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /src/main/webapp/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/src/main/webapp/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /src/main/webapp/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/src/main/webapp/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /.settings/org.eclipse.jpt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jpt.core.platform=eclipselink2_5 3 | org.eclipse.jpt.jpa.core.discoverAnnotatedClasses=false 4 | -------------------------------------------------------------------------------- /src/main/webapp/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corvey/Exam-Online/HEAD/src/main/webapp/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Operating System Files 2 | 3 | *.DS_Store 4 | Thumbs.db 5 | *.sw? 6 | .#* 7 | *# 8 | *~ 9 | *.sublime-* 10 | 11 | # Build Artifacts 12 | 13 | .gradle/ 14 | build/ 15 | target/ 16 | bin/ 17 | dependency-reduced-pom.xml 18 | 19 | # My 20 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/main/resources/config.properties=UTF-8 5 | encoding//src/test/java=UTF-8 6 | encoding/=UTF-8 7 | -------------------------------------------------------------------------------- /文档/表结构/无标题.files/filelist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/dao/ChoiceDAO.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.dao; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import pers.corvey.exam.entity.Choice; 6 | 7 | public interface ChoiceDAO extends CrudRepository { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/dao/QuestionDAO.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.dao; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import pers.corvey.exam.entity.Question; 6 | 7 | public interface QuestionDAO extends CrudRepository { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/dao/SysModifyLogDAO.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.dao; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import pers.corvey.exam.entity.common.SysModifyLog; 6 | 7 | public interface SysModifyLogDAO extends CrudRepository { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/dao/SysAuthorityDAO.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.dao; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import pers.corvey.exam.entity.sys.SysAuthority; 6 | 7 | public interface SysAuthorityDAO extends CrudRepository { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/dao/QuestionCommentDAO.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.dao; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import pers.corvey.exam.entity.QuestionComment; 6 | 7 | public interface QuestionCommentDAO extends CrudRepository { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/dao/ResourceCommentDAO.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.dao; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import pers.corvey.exam.entity.ResourceComment; 6 | 7 | public interface ResourceCommentDAO extends CrudRepository { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/exception/403.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp" %> 3 | 4 | 5 | 6 | <%@include file="/common/head.jsp" %> 7 | 8 | 9 | 10 |

您没有足够的权限!

11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/dao/ExamDAO.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.dao; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import pers.corvey.exam.entity.Exam; 6 | 7 | public interface ExamDAO extends CrudRepository { 8 | 9 | Iterable findByNameStartingWith(String keyword); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/dao/ExamPaperDAO.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.dao; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import pers.corvey.exam.entity.ExamPaper; 6 | 7 | public interface ExamPaperDAO extends CrudRepository { 8 | 9 | Iterable findByNameStartingWith(String keyword); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/dao/ResourceDAO.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.dao; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import pers.corvey.exam.entity.Resource; 6 | 7 | public interface ResourceDAO extends CrudRepository { 8 | 9 | Iterable findByNameStartingWith(String keyword); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/webapp/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | asdf 4 | 5 | 6 |
7 | 8 | 9 |
10 |
11 | 12 | 13 |
14 | 15 | -------------------------------------------------------------------------------- /src/main/webapp/common/taglibs.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%-- 标签 --%> 3 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 4 | <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> 5 | <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> 6 | 7 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/dao/SysUserDAO.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.dao; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import pers.corvey.exam.entity.sys.SysUser; 6 | 7 | public interface SysUserDAO extends CrudRepository { 8 | 9 | SysUser findByUsername(String username); 10 | Iterable findByNameStartingWith(String keyword); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/webapp/common/show-message.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | 3 | 4 |
5 | 8 | 9 |
10 |
11 | <%session.removeAttribute("message");%> -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.common.project.facet.core.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/webapp/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 在线考试系统 5 | 6 | 7 | 8 |
9 | 1:
10 | 2:
11 | 3:
12 | 4:
13 | 14 |
15 | 16 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | org.hibernate.jpa.HibernatePersistenceProvider 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/controller/sys/ExceptionController.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.controller.sys; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | 7 | @Controller 8 | @RequestMapping("/exception") 9 | public class ExceptionController { 10 | 11 | @GetMapping("/403") 12 | public String show403Page() { 13 | return "exception/403"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/manager-templet.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 | 5 | 6 | <%@include file="/common/head.jsp" %> 7 | 8 | 9 | 10 | <%@include file="/common/header.jsp" %> 11 |
12 |
13 | <%@include file="/common/left-bar.jsp" %> 14 | 15 |
16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/other/security/CaptchaException.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.other.security; 2 | 3 | import org.springframework.security.core.AuthenticationException; 4 | 5 | public class CaptchaException extends AuthenticationException { 6 | 7 | private static final long serialVersionUID = 3974591721255959567L; 8 | 9 | public CaptchaException(String msg, Throwable t) { 10 | super(msg, t); 11 | } 12 | 13 | public CaptchaException(String msg) { 14 | super(msg); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.common.project.facet.core.prefs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main/webapp/static/css/my-css.css: -------------------------------------------------------------------------------- 1 | nav { 2 | font-size: 16px; 3 | font-family: "微软雅黑"; 4 | } 5 | #header { 6 | background-color: white; 7 | border-bottom: 2px solid #EEE; 8 | margin-bottom: 20px; 9 | } 10 | #header > nav{margin-bottom: 0;} 11 | body {background-color: #F9F9F9;} 12 | a {color: #666;} 13 | a:active, a:visited {text-decoration: none;} 14 | a:hover { 15 | color: lightseagreen; 16 | text-decoration: none; 17 | } 18 | .nav > li > a:hover {background-color: inherit;} 19 | button {outline: none;} -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/dao/BuyLogDAO.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.dao; 2 | 3 | import org.springframework.data.jpa.repository.Query; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | import pers.corvey.exam.entity.BuyLog; 7 | 8 | public interface BuyLogDAO extends CrudRepository { 9 | 10 | @Query(value = "select * from buy_log where sys_user_id = ?1 and resource_id = ?2", 11 | nativeQuery = true) 12 | BuyLog findByUserIdAndResourceId(Long userId, Long resourceId); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/webapp/common/head.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 在线考试系统 -------------------------------------------------------------------------------- /src/main/webapp/static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/QuestionComment.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.FetchType; 5 | import javax.persistence.ManyToOne; 6 | 7 | import pers.corvey.exam.entity.common.BaseComment; 8 | 9 | @Entity 10 | public class QuestionComment extends BaseComment { 11 | 12 | private Question question; 13 | 14 | @ManyToOne(fetch=FetchType.LAZY) 15 | public Question getQuestion() { 16 | return question; 17 | } 18 | public void setQuestion(Question question) { 19 | this.question = question; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/common/IdEntity.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity.common; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public interface IdEntity extends Serializable { 8 | 9 | ID getId(); 10 | void setId(ID id); 11 | 12 | static List getCollectionIds(Iterable> entities) { 13 | List ids = new ArrayList<>(); 14 | if (entities != null) { 15 | entities.forEach(e -> ids.add(e.getId())); 16 | } 17 | return ids; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/ResourceComment.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.FetchType; 5 | import javax.persistence.ManyToOne; 6 | 7 | import pers.corvey.exam.entity.common.BaseComment; 8 | 9 | @Entity 10 | public class ResourceComment extends BaseComment { 11 | 12 | private Resource resource; 13 | 14 | @ManyToOne(fetch=FetchType.LAZY) 15 | public Resource getResource() { 16 | return resource; 17 | } 18 | 19 | public void setResource(Resource resource) { 20 | this.resource = resource; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/ExamService.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | import pers.corvey.exam.dao.ExamDAO; 6 | import pers.corvey.exam.entity.Exam; 7 | import pers.corvey.exam.service.common.BaseServiceImpl; 8 | 9 | @Service 10 | public class ExamService extends BaseServiceImpl { 11 | 12 | private final ExamDAO dao; 13 | 14 | public ExamService(ExamDAO dao) { 15 | super(dao); 16 | this.dao = dao; 17 | } 18 | 19 | public Iterable search(String keyword) { 20 | return dao.findByNameStartingWith(keyword); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/ChoiceService.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | 6 | import pers.corvey.exam.dao.ChoiceDAO; 7 | import pers.corvey.exam.entity.Choice; 8 | import pers.corvey.exam.service.common.BaseServiceImpl; 9 | 10 | @Service 11 | public class ChoiceService extends BaseServiceImpl { 12 | 13 | private final ChoiceDAO choiceDAO; 14 | 15 | @Autowired 16 | public ChoiceService(ChoiceDAO choiceDAO) { 17 | super(choiceDAO); 18 | this.choiceDAO = choiceDAO; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/exception/FileNotPermitException.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.exception; 2 | 3 | public class FileNotPermitException extends Exception { 4 | 5 | private static final long serialVersionUID = -1597286590998413678L; 6 | 7 | public FileNotPermitException() { 8 | super(); 9 | } 10 | 11 | public FileNotPermitException(String message) { 12 | super(message); 13 | } 14 | 15 | public FileNotPermitException(String message, Throwable cause) { 16 | super(message, cause); 17 | } 18 | 19 | public FileNotPermitException(Throwable cause) { 20 | super(cause); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.settings/.jsdtscope: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/ResourceService.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | 6 | import pers.corvey.exam.dao.ResourceDAO; 7 | import pers.corvey.exam.entity.Resource; 8 | import pers.corvey.exam.service.common.BaseServiceImpl; 9 | 10 | @Service 11 | public class ResourceService extends BaseServiceImpl { 12 | 13 | private final ResourceDAO dao; 14 | 15 | @Autowired 16 | public ResourceService(ResourceDAO dao) { 17 | super(dao); 18 | this.dao = dao; 19 | } 20 | 21 | public Iterable search(String keyword) { 22 | return dao.findByNameStartingWith(keyword); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/dao/ChooseLogDAO.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.dao; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.Query; 6 | import org.springframework.data.repository.CrudRepository; 7 | 8 | import pers.corvey.exam.entity.ChooseLog; 9 | 10 | public interface ChooseLogDAO extends CrudRepository { 11 | 12 | @Query(value = "select * from choose_log where sys_user_id = ?2 and exam_id = ?1", 13 | nativeQuery = true) 14 | List findByExamIdAndUserId(Long examId, Long userId); 15 | 16 | @Query(value = "select * from choose_log where sys_user_id = ?1 " 17 | + "and display = 1 and correct = 0", nativeQuery = true) 18 | List findWrongByUserId(Long userId); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/resources/config.properties: -------------------------------------------------------------------------------- 1 | # 数据库配置 2 | db.driver=com.mysql.jdbc.Driver 3 | db.url=jdbc:mysql://localhost:3306/exam?useSSL=false 4 | db.username=root 5 | db.password=123456 6 | 7 | # hibernate配置 8 | hibernate.current_session_context_class=thread 9 | hibernate.hbm2ddl.auto=update 10 | hibernate.show_sql=true 11 | hibernate.format_sql=true 12 | hibernate.enable_lazy_load_no_trans=true 13 | 14 | # 日志配置 15 | log4j.logger.com.ibatis=DEBUG 16 | log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG 17 | log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG 18 | log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG 19 | log4j.logger.Java.sql.Connection=DEBUG 20 | log4j.logger.java.sql.Statement=DEBUG 21 | log4j.logger.java.sql.PreparedStatement=DEBUG -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.8 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 13 | org.eclipse.jdt.core.compiler.source=1.8 14 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.common.component: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/ExamPaperService.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | 6 | import pers.corvey.exam.dao.ExamPaperDAO; 7 | import pers.corvey.exam.entity.ExamPaper; 8 | import pers.corvey.exam.service.common.BaseServiceImpl; 9 | 10 | @Service 11 | public class ExamPaperService extends BaseServiceImpl { 12 | 13 | private final ExamPaperDAO examPaperDAO; 14 | 15 | @Autowired 16 | public ExamPaperService(ExamPaperDAO examPaperDAO) { 17 | super(examPaperDAO); 18 | this.examPaperDAO = examPaperDAO; 19 | } 20 | 21 | public Iterable search(String keyword) { 22 | return examPaperDAO.findByNameStartingWith(keyword); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/webapp/common/left-bar.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | 3 |
4 |
5 |
6 |

7 |  信息管理 8 |

9 |
10 | 18 |
19 |
20 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/controller/IndexController.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.ResponseBody; 6 | 7 | import pers.corvey.exam.entity.sys.SysUser; 8 | import pers.corvey.exam.util.CurrentUtils; 9 | 10 | @Controller 11 | public class IndexController { 12 | 13 | @GetMapping("/login") 14 | public String showLoginPage() { 15 | return "login"; 16 | } 17 | 18 | @GetMapping("/register") 19 | public String showRegisterPage() { 20 | return "register"; 21 | } 22 | 23 | @GetMapping("/index") 24 | public String index() { 25 | return "index"; 26 | } 27 | 28 | @GetMapping("/isadmin") 29 | @ResponseBody 30 | public Boolean test() { 31 | SysUser user = CurrentUtils.getCurrentUser(); 32 | return user.getAdmin(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/common/BaseComment.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity.common; 2 | 3 | import javax.persistence.FetchType; 4 | import javax.persistence.ManyToOne; 5 | import javax.persistence.MappedSuperclass; 6 | 7 | import pers.corvey.exam.entity.sys.SysUser; 8 | 9 | @MappedSuperclass 10 | public class BaseComment extends BaseEntityImpl { 11 | 12 | private SysUser user; 13 | private String content; 14 | private Integer good = 0; 15 | 16 | @ManyToOne(fetch=FetchType.EAGER) 17 | public SysUser getUser() { 18 | return user; 19 | } 20 | public void setUser(SysUser user) { 21 | this.user = user; 22 | } 23 | public String getContent() { 24 | return content; 25 | } 26 | public void setContent(String content) { 27 | this.content = content; 28 | } 29 | public Integer getGood() { 30 | return good; 31 | } 32 | public void setGood(Integer good) { 33 | this.good = good; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/dao/ExamResultDAO.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.dao; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.Query; 6 | import org.springframework.data.repository.CrudRepository; 7 | 8 | import pers.corvey.exam.entity.ExamResult; 9 | import pers.corvey.exam.entity.sys.SysUser; 10 | 11 | public interface ExamResultDAO extends CrudRepository { 12 | 13 | @Query(value = "select * from exam_result where sys_user_id = ?2 and exam_id = ?1 order by id desc limit 1", 14 | nativeQuery = true) 15 | ExamResult findByExamIdAndUserId(Long examId, Long userId); 16 | 17 | @Query(value = "select count(*) from exam_result where sys_user_id = ?2 and exam_id = ?1", 18 | nativeQuery = true) 19 | Integer countByExamIdAndUserId(Long examId, Long userId); 20 | 21 | @Query(value = "select * from exam_result where sys_user_id = ?1", nativeQuery = true) 22 | List findByUserId(Long userId); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/common/BaseEntity.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity.common; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | import pers.corvey.exam.entity.sys.SysUser; 7 | import pers.corvey.exam.util.CurrentUtils; 8 | 9 | public interface BaseEntity extends IdEntity { 10 | 11 | SysModifyLog getSysModifyLog(); 12 | void setSysModifyLog(SysModifyLog sysModifyLog); 13 | 14 | /** 15 | * 更新修改记录 16 | * @param entity 17 | */ 18 | default void updateSysModifyLog() { 19 | SysUser currentUser = CurrentUtils.getCurrentUser(); 20 | Date nowDate = new Date(); 21 | SysModifyLog modifyLog = getSysModifyLog(); 22 | if (modifyLog == null) { // modifyLog为空,即新增操作 23 | modifyLog = new SysModifyLog(); 24 | modifyLog.setCreateDate(nowDate); 25 | modifyLog.setCreator(currentUser); 26 | setSysModifyLog(modifyLog); 27 | } else { // modifyLog不为空,即更新操作 28 | modifyLog.setModifiedDate(nowDate); 29 | modifyLog.setModifier(currentUser); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/BuyLog.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.FetchType; 5 | import javax.persistence.ManyToOne; 6 | 7 | import pers.corvey.exam.entity.common.BaseEntityImpl; 8 | import pers.corvey.exam.entity.sys.SysUser; 9 | 10 | @Entity 11 | public class BuyLog extends BaseEntityImpl { 12 | 13 | private Resource resource; 14 | private SysUser user; 15 | private Integer spending; 16 | 17 | @ManyToOne(fetch=FetchType.LAZY) 18 | public Resource getResource() { 19 | return resource; 20 | } 21 | 22 | public void setResource(Resource resource) { 23 | this.resource = resource; 24 | } 25 | 26 | @ManyToOne(fetch=FetchType.LAZY) 27 | public SysUser getUser() { 28 | return user; 29 | } 30 | 31 | public void setUser(SysUser user) { 32 | this.user = user; 33 | } 34 | 35 | public Integer getSpending() { 36 | return spending; 37 | } 38 | 39 | public void setSpending(Integer spending) { 40 | this.spending = spending; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /.settings/.rebel.xml.bak: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/main/resources/rebel.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/other/security/UserDetailsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.other.security; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.security.core.userdetails.UserDetails; 5 | import org.springframework.security.core.userdetails.UserDetailsService; 6 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | import pers.corvey.exam.dao.SysUserDAO; 11 | import pers.corvey.exam.entity.sys.SysUser; 12 | 13 | @Service 14 | @Transactional 15 | public class UserDetailsServiceImpl implements UserDetailsService { 16 | 17 | @Autowired 18 | private SysUserDAO sysUserDAO; 19 | 20 | @Override 21 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 22 | SysUser user = sysUserDAO.findByUsername(username); 23 | if (user == null) { 24 | throw new UsernameNotFoundException("不存在此用户"); 25 | } 26 | user.getAuthorities(); // 触发懒加载 27 | return user; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/Choice.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.FetchType; 5 | import javax.persistence.ManyToOne; 6 | 7 | import pers.corvey.exam.entity.common.BaseEntityImpl; 8 | 9 | @Entity 10 | public class Choice extends BaseEntityImpl { 11 | 12 | private String content; 13 | private Boolean answer; 14 | private Question question; 15 | 16 | public Choice() {} 17 | 18 | public String getContent() { 19 | return content; 20 | } 21 | 22 | public void setContent(String content) { 23 | this.content = content; 24 | } 25 | 26 | public Boolean getAnswer() { 27 | return answer; 28 | } 29 | 30 | public void setAnswer(Boolean answer) { 31 | this.answer = answer; 32 | } 33 | 34 | @ManyToOne(fetch = FetchType.LAZY) 35 | public Question getQuestion() { 36 | return question; 37 | } 38 | 39 | public void setQuestion(Question question) { 40 | this.question = question; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return String.format("Choice[content: %s, answer: %s]\n", content, answer); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 计算机专业认证在线考试系统 2 | 3 | 毕业设计,个人独立完成 4 | 5 | ## 功能模块图 6 | 7 | ![功能模块图](文档/在线考试系统.png) 8 | 9 | ## 技术选型 10 | 11 | * 前端 12 | * Html/Css/JavaScript 13 | * Bootstrap 14 | * jQuery 15 | * UploadFive 16 | * 后端 17 | * Spring/SpringMVC/Hibernate 18 | * Spring Security 19 | * slf4j/log4j 20 | * Gson 21 | * POI 22 | * Druid 23 | * 数据库 24 | * MySQL 25 | 26 | ## 界面展示 27 | 28 | ![pic](文档/界面/登陆页面.png) 29 | ![pic](文档/界面/考试页面.png) 30 | ![pic](文档/界面/考试结果图.png) 31 | ![pic](文档/界面/题目讨论.png) 32 | ![pic](文档/界面/资源详情.png) 33 | ![pic](文档/界面/上传资源.png) 34 | 35 | ## ER图 36 | 37 | ![pic](文档/ER.png) 38 | 39 | ## 项目包结构 40 | 41 | * src.main 42 | * java 43 | * pers.corvey.exam 44 | * controller 45 | * common 46 | * sys 47 | * service 48 | * common 49 | * sys 50 | * dao 51 | * entity 52 | * common 53 | * sys 54 | * ui 55 | * support 56 | * form 57 | * hibernate 58 | * security 59 | * exception 60 | * utils 61 | * resources 62 | * webapp 63 | * common 64 | * static 65 | * css 66 | * fonts 67 | * img 68 | * js 69 | * WEB-INF 70 | * views 71 | * sys 72 | * exception 73 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/common/BaseService.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service.common; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import pers.corvey.exam.entity.common.BaseEntity; 8 | 9 | public interface BaseService, ID extends Serializable> { 10 | 11 | T createEntity(); 12 | T save(T entity); 13 | 14 | T findByID(ID id); 15 | Iterable findAll(); 16 | Iterable findAll(Iterable ids); 17 | void delete(ID id); 18 | 19 | default void delete(Iterable ids) { 20 | ids.forEach(this::delete); 21 | } 22 | 23 | default Iterable saveAll(Iterable entities) { 24 | List ret = new ArrayList<>(); 25 | entities.forEach(e -> { 26 | ret.add(save(e)); 27 | }); 28 | return ret; 29 | } 30 | 31 | /** 32 | * 将iterable类型的对象转换为list类型的对象 33 | * @param entities 34 | * @return 35 | */ 36 | static List iterableTolist(Iterable entities) { 37 | if (entities instanceof List) { 38 | return (List) entities; 39 | } 40 | List list = new ArrayList<>(); 41 | if (entities != null) { 42 | entities.forEach(e -> list.add(e)); 43 | } 44 | return list; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/common/BaseEntityImpl.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity.common; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.persistence.CascadeType; 6 | import javax.persistence.FetchType; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import javax.persistence.MappedSuperclass; 11 | import javax.persistence.OneToOne; 12 | 13 | 14 | /** 15 | * 注意:子类必须要有空的构造方法 16 | * @author Corvey 17 | * @param 18 | */ 19 | @MappedSuperclass 20 | public abstract class BaseEntityImpl implements BaseEntity { 21 | 22 | private static final long serialVersionUID = -290755885790882631L; 23 | 24 | protected ID id; 25 | protected SysModifyLog sysModifyLog; 26 | 27 | @Id 28 | @GeneratedValue(strategy=GenerationType.IDENTITY) 29 | @Override 30 | public ID getId() { 31 | return id; 32 | } 33 | 34 | @Override 35 | public void setId(ID id) { 36 | this.id = id; 37 | } 38 | 39 | @OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL) 40 | @Override 41 | public SysModifyLog getSysModifyLog() { 42 | return sysModifyLog; 43 | } 44 | 45 | @Override 46 | public void setSysModifyLog(SysModifyLog sysModifyLog) { 47 | this.sysModifyLog = sysModifyLog; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/sys/SysAuthority.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity.sys; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Entity; 5 | import javax.persistence.GeneratedValue; 6 | import javax.persistence.GenerationType; 7 | import javax.persistence.Id; 8 | 9 | import org.springframework.security.core.GrantedAuthority; 10 | 11 | import pers.corvey.exam.entity.common.IdEntity; 12 | 13 | @Entity 14 | public class SysAuthority implements GrantedAuthority, IdEntity { 15 | 16 | private static final long serialVersionUID = -59397517996869520L; 17 | 18 | private Byte id; 19 | private String authority; 20 | 21 | public SysAuthority() {} 22 | 23 | @Override 24 | public String toString() { 25 | return String.format("SysAuthority[id=%d, authority=%s]", id, authority); 26 | } 27 | 28 | @Id 29 | @GeneratedValue(strategy=GenerationType.IDENTITY) 30 | @Override 31 | public Byte getId() { 32 | return id; 33 | } 34 | 35 | @Override 36 | public void setId(Byte id) { 37 | this.id = id; 38 | } 39 | 40 | @Override 41 | @Column(length = 20, unique = true) 42 | public String getAuthority() { 43 | return authority; 44 | } 45 | 46 | public void setAuthority(String authority) { 47 | this.authority = authority; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/Exam.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.FetchType; 5 | import javax.persistence.ManyToOne; 6 | import javax.persistence.Transient; 7 | 8 | import pers.corvey.exam.entity.common.BaseEntityImpl; 9 | 10 | @Entity 11 | public class Exam extends BaseEntityImpl { 12 | 13 | private String name; 14 | private String description; 15 | private Integer time; 16 | private ExamPaper exampaper; 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | public void setName(String name) { 22 | this.name = name; 23 | } 24 | public String getDescription() { 25 | return description; 26 | } 27 | public void setDescription(String description) { 28 | this.description = description; 29 | } 30 | public Integer getTime() { 31 | return time; 32 | } 33 | public void setTime(Integer time) { 34 | this.time = time; 35 | } 36 | 37 | @ManyToOne(fetch=FetchType.LAZY) 38 | public ExamPaper getExampaper() { 39 | return exampaper; 40 | } 41 | public void setExampaper(ExamPaper exampaper) { 42 | this.exampaper = exampaper; 43 | } 44 | 45 | // JSP用到的方法 46 | @Transient 47 | public Long getExampaperId() { 48 | return exampaper == null ? null : exampaper.getId(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/ExamPaper.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity; 2 | 3 | import java.util.List; 4 | 5 | import javax.persistence.CascadeType; 6 | import javax.persistence.Entity; 7 | import javax.persistence.FetchType; 8 | import javax.persistence.JoinTable; 9 | import javax.persistence.ManyToMany; 10 | import javax.persistence.OrderBy; 11 | import javax.persistence.Table; 12 | 13 | import pers.corvey.exam.entity.common.BaseEntityImpl; 14 | 15 | @Entity 16 | @Table(name = "exampaper") 17 | public class ExamPaper extends BaseEntityImpl { 18 | 19 | private String name; 20 | private String description; 21 | private List questions; 22 | 23 | public ExamPaper() {} 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | public void setName(String name) { 30 | this.name = name; 31 | } 32 | 33 | public String getDescription() { 34 | return description; 35 | } 36 | 37 | public void setDescription(String description) { 38 | this.description = description; 39 | } 40 | 41 | @ManyToMany(fetch = FetchType.LAZY, cascade=CascadeType.PERSIST) 42 | @JoinTable(name="exampaper_question") 43 | @OrderBy("type") 44 | public List getQuestions() { 45 | return questions; 46 | } 47 | 48 | public void setQuestions(List questions) { 49 | this.questions = questions; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/QuestionCommentService.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | 6 | import pers.corvey.exam.dao.QuestionCommentDAO; 7 | import pers.corvey.exam.dao.SysUserDAO; 8 | import pers.corvey.exam.entity.QuestionComment; 9 | import pers.corvey.exam.entity.sys.SysUser; 10 | import pers.corvey.exam.service.common.BaseServiceImpl; 11 | import pers.corvey.exam.util.CurrentUtils; 12 | 13 | @Service 14 | public class QuestionCommentService extends BaseServiceImpl { 15 | 16 | private final QuestionCommentDAO dao; 17 | private final SysUserDAO userDAO; 18 | 19 | @Autowired 20 | public QuestionCommentService(QuestionCommentDAO dao, SysUserDAO userDAO) { 21 | super(dao); 22 | this.dao = dao; 23 | this.userDAO = userDAO; 24 | } 25 | 26 | public int thumbsUp(Long id) { 27 | QuestionComment comment = dao.findOne(id); 28 | SysUser nowUser = CurrentUtils.getCurrentUser(); 29 | SysUser commentUser = comment.getUser(); 30 | if (nowUser.getId() != commentUser.getId()) { 31 | comment.setGood(comment.getGood() + 1); 32 | dao.save(comment); 33 | commentUser.setMoney(commentUser.getMoney() + 1); 34 | userDAO.save(commentUser); 35 | } 36 | return comment.getGood(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/ResourceCommentService.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | 6 | import pers.corvey.exam.dao.ResourceCommentDAO; 7 | import pers.corvey.exam.dao.SysUserDAO; 8 | import pers.corvey.exam.entity.ResourceComment; 9 | import pers.corvey.exam.entity.sys.SysUser; 10 | import pers.corvey.exam.service.common.BaseServiceImpl; 11 | import pers.corvey.exam.util.CurrentUtils; 12 | 13 | @Service 14 | public class ResourceCommentService extends BaseServiceImpl { 15 | 16 | private final ResourceCommentDAO dao; 17 | private final SysUserDAO userDAO; 18 | 19 | @Autowired 20 | public ResourceCommentService(ResourceCommentDAO dao, SysUserDAO userDAO) { 21 | super(dao); 22 | this.dao = dao; 23 | this.userDAO = userDAO; 24 | } 25 | 26 | public int thumbsUp(Long id) { 27 | ResourceComment comment = dao.findOne(id); 28 | SysUser nowUser = CurrentUtils.getCurrentUser(); 29 | SysUser commentUser = comment.getUser(); 30 | if (nowUser.getId() != commentUser.getId()) { 31 | comment.setGood(comment.getGood() + 1); 32 | dao.save(comment); 33 | commentUser.setMoney(commentUser.getMoney() + 1); 34 | userDAO.save(commentUser); 35 | } 36 | return comment.getGood(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/controller/common/BaseController.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.controller.common; 2 | 3 | import java.io.Serializable; 4 | 5 | import org.springframework.ui.Model; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | 8 | import pers.corvey.exam.entity.common.BaseEntity; 9 | 10 | public interface BaseController, ID extends Serializable> { 11 | 12 | /** 13 | * 列表页面地址 14 | */ 15 | String LIST_PATH = "/list"; 16 | 17 | /** 18 | * 详细信息页面地址 19 | */ 20 | String DETAIL_PATH = "/detail"; 21 | 22 | /** 23 | * 新增或修改页面地址 24 | */ 25 | String INPUT_PATH = "/input"; 26 | 27 | /** 28 | * 删除地址 29 | */ 30 | String DELETE_PATH = "/delete"; 31 | 32 | /** 33 | * 保存地址 34 | */ 35 | String SAVE_PATH = "/save"; 36 | 37 | /** 38 | * 显示列表页面 39 | * @param model 40 | * @return 41 | */ 42 | @RequestMapping(LIST_PATH) 43 | String showListView(Model model); 44 | 45 | /** 46 | * 显示详细信息页面 47 | * @param id 48 | * @param model 49 | * @return 50 | */ 51 | @RequestMapping(DETAIL_PATH) 52 | String showDetailView(Model model, T entity); 53 | 54 | /** 55 | * 显示新增或修改信息页面 56 | * @param id 57 | * @param model 58 | * @return 59 | */ 60 | @RequestMapping(INPUT_PATH) 61 | String showInputView(Model model, T entity); 62 | 63 | /** 64 | * 通过id删除实体 65 | * @param id 66 | * @return 67 | */ 68 | @RequestMapping(DELETE_PATH) 69 | String deleteById(ID id); 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/sys/SysUserService.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service.sys; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.security.authentication.encoding.Md5PasswordEncoder; 6 | import org.springframework.stereotype.Service; 7 | 8 | import pers.corvey.exam.dao.SysUserDAO; 9 | import pers.corvey.exam.entity.sys.SysUser; 10 | import pers.corvey.exam.service.common.BaseServiceImpl; 11 | 12 | @Service 13 | public class SysUserService extends BaseServiceImpl { 14 | 15 | private static final Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder(); 16 | 17 | private final SysUserDAO sysUserDAO; 18 | 19 | @Autowired 20 | public SysUserService(SysUserDAO sysUserDAO) { 21 | super(sysUserDAO); 22 | this.sysUserDAO = sysUserDAO; 23 | } 24 | 25 | @Override 26 | public SysUser save(SysUser entity) { 27 | if (StringUtils.isNotBlank(entity.getPassword())) { 28 | // 密码不为空时,加密 29 | String password = md5PasswordEncoder.encodePassword(entity.getPassword(), entity.getUsername()); 30 | entity.setPassword(password); 31 | } else if (entity.getId() != null) { 32 | // 当id不为空而密码为空时即更新操作,找到旧密码放入避免更新成空值 33 | SysUser user = sysUserDAO.findOne(entity.getId()); 34 | entity.setPassword(user.getPassword()); 35 | } 36 | return super.save(entity); 37 | } 38 | 39 | public Iterable search(String keyword) { 40 | return sysUserDAO.findByNameStartingWith(keyword); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/webapp/static/js/my-js.js: -------------------------------------------------------------------------------- 1 | function showMessage(message) { 2 | var messageBlock = $("#message"); 3 | messageBlock.css("visibility", "visible"); 4 | messageBlock.text(message); 5 | } 6 | function myAjax(obj, finalDo) { 7 | var ajaxArgs = { 8 | cache: false, 9 | dataType: "json", 10 | timeout: 5000, 11 | error: function(XMLHttpRequest, textStatus, errorThrown) { 12 | showMessage(XMLHttpRequest.responseJSON.message); 13 | if (typeof finalDo === 'function') { 14 | finalDo(); 15 | } 16 | }, 17 | complete: function(XMLHttpRequest, status) { 18 | if(status === "timeout") { 19 | ajaxTask.abort(); 20 | showMessage("请求超时!请重试!"); 21 | if (typeof finalDo === 'function') { 22 | finalDo(); 23 | } 24 | } 25 | } 26 | }; 27 | $.ajax($.extend(ajaxArgs, obj)); 28 | } 29 | function moralLoad(obj, url) { 30 | $(obj).load(url); 31 | } 32 | function checkLength(str, min, max) { 33 | if (str != null && str.length >= min && str.length <= max) { 34 | return true; 35 | } 36 | return false; 37 | } 38 | function updateCaptcha() { 39 | $("#captchaImg").attr("src", "captcha?" + Math.ceil(Math.random()*100000)); 40 | $("input[name='captcha']").val(''); 41 | } 42 | function getQueryString(name) { 43 | var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); 44 | var r = window.location.search.substr(1).match(reg); 45 | if (r != null) 46 | return r[2]; 47 | return null; 48 | } -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/other/security/CaptchaUsernamePasswordAuthenticationFilter.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.other.security; 2 | 3 | import java.util.Objects; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | import javax.servlet.http.HttpServletResponse; 7 | import javax.servlet.http.HttpSession; 8 | 9 | import org.springframework.security.core.Authentication; 10 | import org.springframework.security.core.AuthenticationException; 11 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 12 | 13 | public class CaptchaUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{ 14 | 15 | public static final String SPRING_SECURITY_FORM_CAPTCHA_KEY = "captcha"; 16 | 17 | private String captchaParameter = SPRING_SECURITY_FORM_CAPTCHA_KEY; 18 | 19 | @Override 20 | public Authentication attemptAuthentication(HttpServletRequest request, 21 | HttpServletResponse response) throws AuthenticationException { 22 | System.out.println("---------------------captcha filter"); 23 | HttpSession session = request.getSession(); 24 | String captcha = (String) session.getAttribute(captchaParameter); 25 | if (captcha == null) { 26 | throw new CaptchaException("验证码已失效,请重试!"); 27 | } 28 | session.removeAttribute(captchaParameter); 29 | String inputCaptcha = request.getParameter(captchaParameter); 30 | if (inputCaptcha == null || !Objects.equals(captcha.toLowerCase(), inputCaptcha.toLowerCase())) { 31 | throw new CaptchaException("输入验证码有误,请重试!"); 32 | } 33 | return super.attemptAuthentication(request, response); 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/other/hibernate/MyImplicitNamingStrategy.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.other.hibernate; 2 | 3 | import org.hibernate.boot.model.naming.Identifier; 4 | import org.hibernate.boot.model.naming.ImplicitBasicColumnNameSource; 5 | import org.hibernate.boot.model.naming.ImplicitEntityNameSource; 6 | import org.hibernate.boot.model.naming.ImplicitJoinColumnNameSource; 7 | import org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl; 8 | 9 | public class MyImplicitNamingStrategy extends ImplicitNamingStrategyLegacyHbmImpl { 10 | 11 | private static final long serialVersionUID = 8039490212591227210L; 12 | 13 | private static final String REGEXP = "([a-z])([A-Z])"; 14 | private static final String REPLACEMENT = "$1_$2"; 15 | 16 | @Override 17 | public Identifier determinePrimaryTableName(ImplicitEntityNameSource source) { 18 | Identifier identifier = super.determinePrimaryTableName(source); 19 | return toIdentifier(convert(identifier.getText()), source.getBuildingContext()); 20 | } 21 | 22 | @Override 23 | public Identifier determineBasicColumnName(ImplicitBasicColumnNameSource source) { 24 | Identifier identifier = super.determineBasicColumnName(source); 25 | return toIdentifier(convert(identifier.getText()), source.getBuildingContext()); 26 | } 27 | 28 | @Override 29 | public Identifier determineJoinColumnName(ImplicitJoinColumnNameSource source) { 30 | String name = source.getReferencedTableName() + "_" + source.getReferencedColumnName(); 31 | return toIdentifier(name, source.getBuildingContext()); 32 | } 33 | 34 | private String convert(String str) { 35 | if (str == null) { 36 | return null; 37 | } 38 | return str.replaceAll(REGEXP, REPLACEMENT).toLowerCase(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/sys/exampaper-list.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 |
5 |
6 |
7 |

8 | 9 |  试卷信息管理 10 |

11 |
12 |
13 | <%@include file="/common/show-message.jsp" %> 14 |
15 | 新增 16 | 17 |
18 | 19 |
20 | 21 |
22 |
23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 41 | 42 | 43 |
试卷名称试卷描述出题人操作
37 | 查看 38 | 修改 39 | 删除 40 |
44 |
45 |
46 |
47 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/question-list.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 |
5 |
6 |
7 |

8 | 9 |  题目信息管理 10 |

11 |
12 |
13 | <%@include file="/common/show-message.jsp" %> 14 |
15 | 新增 16 |
17 |
18 | 19 |
20 | 21 |
22 |
23 |
24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 40 | 41 | 42 |
题目类型题干操作
36 | 查看 37 | 修改 38 | 删除 39 |
43 |
44 |
45 |
46 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/exam-result-list.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 |
5 |
6 |
7 |

8 | 9 |  成绩管理 10 |

11 |
12 |
13 | <%@include file="/common/show-message.jsp" %> 14 |
15 | 新增 16 | 17 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 41 | 42 | 43 |
考试名称考试用户成绩操作
37 | 查看 38 | 修改 39 | 删除 40 |
44 |
45 |
46 |
47 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/util/CurrentUtils.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.util; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | import javax.servlet.http.HttpSession; 6 | 7 | import org.springframework.security.core.context.SecurityContextHolder; 8 | import org.springframework.web.context.request.RequestContextHolder; 9 | import org.springframework.web.context.request.ServletRequestAttributes; 10 | 11 | import pers.corvey.exam.entity.sys.SysUser; 12 | 13 | public class CurrentUtils { 14 | 15 | public static SysUser getCurrentUser() { 16 | Object obj = SecurityContextHolder.getContext() 17 | .getAuthentication() 18 | .getPrincipal(); 19 | if (!(obj instanceof SysUser)) { 20 | return null; 21 | } 22 | SysUser user = (SysUser) obj; 23 | return user; 24 | } 25 | 26 | public static HttpServletRequest getCurrentRequest() { 27 | HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder 28 | .getRequestAttributes()).getRequest(); 29 | return request; 30 | } 31 | 32 | public static HttpServletResponse getCurrentResponse() { 33 | HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder 34 | .getRequestAttributes()).getResponse(); 35 | return response; 36 | } 37 | 38 | public static HttpSession getCurrentSession() { 39 | return getCurrentRequest().getSession(); 40 | } 41 | 42 | public static void addAttributeToRequest(String name, Object obj) { 43 | HttpServletRequest request = getCurrentRequest(); 44 | request.setAttribute(name, obj); 45 | } 46 | 47 | public static void addAttributeToSession(String name, Object obj) { 48 | HttpSession session = getCurrentSession(); 49 | session.setAttribute(name, obj); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/ExamResultService.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import pers.corvey.exam.dao.ExamResultDAO; 9 | import pers.corvey.exam.entity.ChooseLog; 10 | import pers.corvey.exam.entity.ExamResult; 11 | import pers.corvey.exam.entity.sys.SysUser; 12 | import pers.corvey.exam.service.common.BaseServiceImpl; 13 | 14 | @Service 15 | public class ExamResultService extends BaseServiceImpl { 16 | 17 | private final ExamResultDAO dao; 18 | 19 | @Autowired 20 | public ExamResultService(ExamResultDAO dao) { 21 | super(dao); 22 | this.dao = dao; 23 | } 24 | 25 | public ExamResult findByExamIdAndUserId(Long examId, Long userId) { 26 | return dao.findByExamIdAndUserId(examId, userId); 27 | } 28 | 29 | public Integer countByExamIdAndUserId(Long examId, Long userId) { 30 | return dao.countByExamIdAndUserId(examId, userId); 31 | } 32 | 33 | public List findByUserId(Long userId) { 34 | return dao.findByUserId(userId); 35 | } 36 | 37 | public ExamResult chooseToExamResult(List chooseLogs) { 38 | int count = chooseLogs.size(); 39 | int rightCount = 0; 40 | for (ChooseLog log : chooseLogs) { 41 | if (log.getCorrect()) { 42 | ++rightCount; 43 | } 44 | } 45 | int grade = 100 * rightCount / count; 46 | 47 | ExamResult examResult = new ExamResult(); 48 | examResult.setExam(chooseLogs.get(0).getExam()); 49 | examResult.setUser(chooseLogs.get(0).getUser()); 50 | examResult.setAllCount(count); 51 | examResult.setWrongCount(count - rightCount); 52 | examResult.setGrade(grade); 53 | return save(examResult); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | exam Maven Webapp 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.wst.common.project.facet.core.builder 15 | 16 | 17 | 18 | 19 | org.eclipse.wst.validation.validationbuilder 20 | 21 | 22 | 23 | 24 | com.genuitec.eclipse.j2eedt.core.DeploymentDescriptorValidator 25 | 26 | 27 | 28 | 29 | com.genuitec.eclipse.springframework.springbuilder 30 | 31 | 32 | 33 | 34 | org.eclipse.m2e.core.maven2Builder 35 | 36 | 37 | 38 | 39 | org.zeroturnaround.eclipse.rebelXmlBuilder 40 | 41 | 42 | 43 | 44 | 45 | com.genuitec.eclipse.springframework.springnature 46 | org.eclipse.jem.workbench.JavaEMFNature 47 | org.eclipse.wst.common.modulecore.ModuleCoreNature 48 | org.eclipse.jdt.core.javanature 49 | org.eclipse.m2e.core.maven2Nature 50 | org.eclipse.wst.common.project.facet.core.nature 51 | org.eclipse.wst.jsdt.core.jsNature 52 | org.zeroturnaround.eclipse.jrebelNature 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/ChooseLog.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity; 2 | 3 | import java.util.List; 4 | 5 | import javax.persistence.Entity; 6 | import javax.persistence.FetchType; 7 | import javax.persistence.JoinTable; 8 | import javax.persistence.ManyToMany; 9 | import javax.persistence.ManyToOne; 10 | 11 | import pers.corvey.exam.entity.common.BaseEntityImpl; 12 | import pers.corvey.exam.entity.sys.SysUser; 13 | 14 | @Entity 15 | public class ChooseLog extends BaseEntityImpl { 16 | 17 | private Exam exam; 18 | private Question question; 19 | private List choose; 20 | private Boolean correct; 21 | private SysUser user; 22 | private Boolean display = true; 23 | 24 | @ManyToOne(fetch=FetchType.LAZY) 25 | public Exam getExam() { 26 | return exam; 27 | } 28 | public void setExam(Exam exam) { 29 | this.exam = exam; 30 | } 31 | 32 | @ManyToOne(fetch=FetchType.LAZY) 33 | public Question getQuestion() { 34 | return question; 35 | } 36 | public void setQuestion(Question question) { 37 | this.question = question; 38 | } 39 | 40 | @ManyToMany(fetch=FetchType.LAZY) 41 | @JoinTable(name = "choose_log_choice") 42 | public List getChoose() { 43 | return choose; 44 | } 45 | public void setChoose(List choose) { 46 | this.choose = choose; 47 | } 48 | public Boolean getCorrect() { 49 | return correct; 50 | } 51 | public void setCorrect(Boolean correct) { 52 | this.correct = correct; 53 | } 54 | 55 | @ManyToOne(fetch=FetchType.LAZY) 56 | public SysUser getUser() { 57 | return user; 58 | } 59 | public void setUser(SysUser user) { 60 | this.user = user; 61 | } 62 | 63 | public Boolean getDisplay() { 64 | return display; 65 | } 66 | public void setDisplay(Boolean display) { 67 | this.display = display; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/exam-list.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 |
5 |
6 |
7 |

8 | 9 |  考试管理 10 |

11 |
12 |
13 | <%@include file="/common/show-message.jsp" %> 14 |
15 | 新增 16 |
17 |
18 | 19 |
20 | 21 |
22 |
23 |
24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 42 | 43 | 44 |
考试名称考试试卷发布者操作
38 | 查看 39 | 修改 40 | 删除 41 |
45 |
46 |
47 |
48 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/exampaper-input.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 |
5 |
6 |
7 |

8 |  试卷信息管理 9 |

10 |
11 |
12 | 14 | 15 |
16 | 17 |
18 | 19 |
20 |
21 |
22 | 23 |
24 | 25 |
26 |
27 |
28 | 29 |
30 | 32 |
33 |
34 |
35 | 36 |      37 | 返回 38 |
39 |
40 |
41 |
42 |
-------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/sys/user-list.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 |
5 |
6 |
7 |

8 | 9 |  用户信息管理 10 |

11 |
12 |
13 | <%@include file="/common/show-message.jsp" %> 14 |
15 | 新增 16 |
17 |
18 | 19 |
20 | 21 |
22 |
23 |
24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 42 | 43 | 44 |
昵称用户名用户角色操作
38 | 查看 39 | 修改 40 | 删除 41 |
45 |
46 |
47 |
48 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/ExamResult.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.FetchType; 5 | import javax.persistence.ManyToOne; 6 | import javax.persistence.Transient; 7 | 8 | import pers.corvey.exam.entity.common.BaseEntityImpl; 9 | import pers.corvey.exam.entity.sys.SysUser; 10 | 11 | @Entity 12 | public class ExamResult extends BaseEntityImpl { 13 | 14 | private Exam exam; 15 | private SysUser user; 16 | private Integer allCount; 17 | private Integer wrongCount; 18 | private Integer grade; 19 | private Integer rank; 20 | 21 | @ManyToOne(fetch = FetchType.LAZY) 22 | public Exam getExam() { 23 | return exam; 24 | } 25 | public void setExam(Exam exam) { 26 | this.exam = exam; 27 | } 28 | 29 | @ManyToOne(fetch = FetchType.LAZY) 30 | public SysUser getUser() { 31 | return user; 32 | } 33 | public void setUser(SysUser user) { 34 | this.user = user; 35 | } 36 | public Integer getWrongCount() { 37 | return wrongCount; 38 | } 39 | public void setWrongCount(Integer wrongCount) { 40 | this.wrongCount = wrongCount; 41 | } 42 | public Integer getAllCount() { 43 | return allCount; 44 | } 45 | public void setAllCount(Integer allCount) { 46 | this.allCount = allCount; 47 | } 48 | public Integer getGrade() { 49 | return grade; 50 | } 51 | public void setGrade(Integer grade) { 52 | this.grade = grade; 53 | } 54 | 55 | @Transient 56 | public Integer getRank() { 57 | return rank; 58 | } 59 | public void setRank(Integer rank) { 60 | this.rank = rank; 61 | } 62 | 63 | // JSP用到的方法 64 | @Transient 65 | public Long getUserId() { 66 | return user == null ? (long)1 : user.getId(); 67 | } 68 | 69 | @Transient 70 | public Long getExamId() { 71 | return exam == null ? (long)1 : exam.getId(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/exam-result-input.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 |
5 |
6 |
7 |

8 |  成绩管理 9 |

10 |
11 |
12 | 14 | 15 |
16 | 17 |
18 | 20 |
21 |
22 |
23 | 24 |
25 | 27 |
28 |
29 |
30 | 31 |
32 | 33 |
34 |
35 |
36 | 37 |      38 | 返回 39 |
40 |
41 |
42 |
43 |
-------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/helper/form/ChooseFormHelper.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.helper.form; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import pers.corvey.exam.entity.Choice; 7 | import pers.corvey.exam.entity.ChooseLog; 8 | import pers.corvey.exam.entity.Exam; 9 | import pers.corvey.exam.entity.Question; 10 | 11 | public class ChooseFormHelper { 12 | 13 | private Long examId; 14 | private List questionIds; 15 | private List> chooses; 16 | 17 | public Long getExamId() { 18 | return examId; 19 | } 20 | public void setExamId(Long examId) { 21 | this.examId = examId; 22 | } 23 | public List getQuestionIds() { 24 | return questionIds; 25 | } 26 | public void setQuestionIds(List questionIds) { 27 | this.questionIds = questionIds; 28 | } 29 | public List> getChooses() { 30 | return chooses; 31 | } 32 | public void setChooses(List> chooses) { 33 | this.chooses = chooses; 34 | } 35 | 36 | public List generateChooseLog() { 37 | List logs = new ArrayList<>(); 38 | for (int i=0; i choices = new ArrayList<>(); 50 | List choiceIds = chooses.get(i); 51 | if (choiceIds != null && choiceIds.size() > 0) { 52 | for (Long id : choiceIds) { 53 | if (id != null) { 54 | Choice choice = new Choice(); 55 | choice.setId(id); 56 | choices.add(choice); 57 | } 58 | } 59 | } 60 | log.setChoose(choices); 61 | logs.add(log); 62 | } 63 | return logs; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/other/hibernate/MyPhysicalNamingStrategy.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.other.hibernate; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.hibernate.boot.model.naming.Identifier; 5 | import org.hibernate.boot.model.naming.PhysicalNamingStrategy; 6 | import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; 7 | 8 | public class MyPhysicalNamingStrategy implements PhysicalNamingStrategy { 9 | 10 | private static final String REGEX = "([a-z])([A-Z])"; 11 | private static final String REPLACEMENT = "$1_$2"; 12 | 13 | @Override 14 | public Identifier toPhysicalCatalogName(Identifier identifier, JdbcEnvironment jdbcEnv) { 15 | return convert(identifier); 16 | } 17 | 18 | @Override 19 | public Identifier toPhysicalColumnName(Identifier identifier, JdbcEnvironment jdbcEnv) { 20 | return convert(identifier); 21 | } 22 | 23 | @Override 24 | public Identifier toPhysicalSchemaName(Identifier identifier, JdbcEnvironment jdbcEnv) { 25 | return convert(identifier); 26 | } 27 | 28 | @Override 29 | public Identifier toPhysicalSequenceName(Identifier identifier, JdbcEnvironment jdbcEnv) { 30 | return convert(identifier); 31 | } 32 | 33 | @Override 34 | public Identifier toPhysicalTableName(Identifier identifier, JdbcEnvironment jdbcEnv) { 35 | return convert(identifier); 36 | } 37 | 38 | private Identifier convert(Identifier identifier) { 39 | if (identifier == null || StringUtils.isBlank(identifier.getText())) { 40 | return identifier; 41 | } 42 | return Identifier.toIdentifier(convert(identifier.getText())); 43 | } 44 | 45 | private String convert(String str) { 46 | if (str == null) { 47 | return null; 48 | } 49 | String newStr = str.replaceAll(REGEX, REPLACEMENT).toLowerCase(); 50 | return newStr; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/exampaper-list.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 |
5 |
6 |
7 |

8 | 9 |  试卷信息管理 10 |

11 |
12 |
13 | <%@include file="/common/show-message.jsp" %> 14 |
15 | 新增 16 |
17 |
18 | 19 |
20 | 21 |
22 |
23 |
24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 42 | 43 | 44 |
试卷名称试卷描述出题人操作
38 | 查看 39 | 修改 40 | 删除 41 |
45 |
46 |
47 |
48 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/resource-list.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 |
5 |
6 |
7 |

8 | 9 |  资源信息管理 10 |

11 |
12 |
13 | <%@include file="/common/show-message.jsp" %> 14 |
15 | 新增 16 |
17 |
18 | 19 |
20 | 21 |
22 |
23 |
24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 46 |
资源名称原文件名资源大小(字节)所需积分操作
40 | 查看 41 | 修改 42 | 删除 43 |
47 |
48 |
49 |
50 | -------------------------------------------------------------------------------- /src/main/webapp/common/header.jsp: -------------------------------------------------------------------------------- 1 | <%@page import="pers.corvey.exam.util.CurrentUtils"%> 2 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 3 | <% 4 | request.setAttribute("user", CurrentUtils.getCurrentUser()); 5 | %> 6 | 44 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/exam-result-show.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 | 5 | 6 | <%@include file="/common/head.jsp"%> 7 | 8 | 9 | 10 | <%@include file="/common/header.jsp"%> 11 |
12 |
13 |
14 |
15 |
16 |

17 |  我的成绩 18 |

19 |
20 |
21 | <%@include file="/common/show-message.jsp"%> 22 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
考试名称考试试卷考试日期成绩
46 |
47 |
48 |
49 |
50 |
51 | 52 | 54 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/controller/QuestionCommentController.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.web.bind.annotation.PostMapping; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | import org.springframework.web.bind.annotation.ResponseBody; 9 | 10 | import pers.corvey.exam.entity.Question; 11 | import pers.corvey.exam.entity.QuestionComment; 12 | import pers.corvey.exam.entity.sys.SysUser; 13 | import pers.corvey.exam.entity.ui.CallBackMessage; 14 | import pers.corvey.exam.service.QuestionCommentService; 15 | import pers.corvey.exam.service.QuestionService; 16 | import pers.corvey.exam.util.CurrentUtils; 17 | 18 | @Controller 19 | @RequestMapping("/questionComment") 20 | public class QuestionCommentController { 21 | 22 | private final QuestionCommentService service; 23 | private final QuestionService questionService; 24 | 25 | @Autowired 26 | public QuestionCommentController(QuestionCommentService service, 27 | QuestionService questionService) { 28 | this.service = service; 29 | this.questionService = questionService; 30 | } 31 | 32 | @RequestMapping("/good") 33 | @ResponseBody 34 | public int thumbsUp(@RequestParam("id") Long commentId) { 35 | return service.thumbsUp(commentId); 36 | } 37 | 38 | @PostMapping("/save") 39 | public String save(QuestionComment entity, 40 | @RequestParam("questionId") Long questionId) { 41 | SysUser user = CurrentUtils.getCurrentUser(); 42 | Question question = questionService.findByID(questionId); 43 | entity.setUser(user); 44 | entity.setQuestion(question); 45 | CallBackMessage msg = CallBackMessage.createMsgAfterFunction( 46 | () -> service.save(entity), "回复成功!", "回复失败!请重试!"); 47 | msg.addToCurrentSession(); 48 | return "redirect:/question/" + questionId; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/controller/ResourceCommentController.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.web.bind.annotation.PostMapping; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | import org.springframework.web.bind.annotation.ResponseBody; 9 | 10 | import pers.corvey.exam.entity.Resource; 11 | import pers.corvey.exam.entity.ResourceComment; 12 | import pers.corvey.exam.entity.sys.SysUser; 13 | import pers.corvey.exam.entity.ui.CallBackMessage; 14 | import pers.corvey.exam.service.ResourceCommentService; 15 | import pers.corvey.exam.service.ResourceService; 16 | import pers.corvey.exam.util.CurrentUtils; 17 | 18 | @Controller 19 | @RequestMapping("/resourceComment") 20 | public class ResourceCommentController { 21 | 22 | private final ResourceCommentService service; 23 | private final ResourceService resourceService; 24 | 25 | @Autowired 26 | public ResourceCommentController(ResourceCommentService service, 27 | ResourceService resourceService) { 28 | this.service = service; 29 | this.resourceService = resourceService; 30 | } 31 | 32 | @RequestMapping("/good") 33 | @ResponseBody 34 | public int thumbsUp(@RequestParam("id") Long commentId) { 35 | return service.thumbsUp(commentId); 36 | } 37 | 38 | @PostMapping("/save") 39 | public String save(ResourceComment entity, 40 | @RequestParam("resourceId") Long resourceId) { 41 | SysUser user = CurrentUtils.getCurrentUser(); 42 | Resource Resource = resourceService.findByID(resourceId); 43 | entity.setUser(user); 44 | entity.setResource(Resource); 45 | CallBackMessage msg = CallBackMessage.createMsgAfterFunction( 46 | () -> service.save(entity), "回复成功!", "回复失败!请重试!"); 47 | msg.addToCurrentSession(); 48 | return "redirect:/resource/" + resourceId; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/resource-input.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 |
4 |
5 |
6 |

7 | 8 |  资源信息管理 9 |

10 |
11 |
12 | 14 | 15 |
16 | 17 |
18 | 19 |
20 |
21 |
22 | 23 |
24 | 25 |
26 |
27 |
28 | 29 |
30 | 31 |
32 |
33 |
34 | 35 |
36 | 37 |
38 |
39 |

40 | 41 |      42 | 返回 43 |
44 |
45 |
46 |
47 |
48 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/exam-input.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 |
5 |
6 |
7 |

8 |  考试管理 9 |

10 |
11 |
12 | 14 | 15 |
16 | 17 |
18 | 19 |
20 |
21 |
22 | 23 |
24 | 25 |
26 |
27 |
28 | 29 |
30 | 31 |
32 |
33 |
34 | 35 |
36 | 38 |
39 |
40 |
41 | 42 |      43 | 返回 44 |
45 |
46 |
47 |
48 |
-------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/sys/SysAuthorityService.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service.sys; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.Set; 9 | 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Service; 12 | import org.springframework.transaction.annotation.Transactional; 13 | import org.springframework.util.Assert; 14 | 15 | import pers.corvey.exam.dao.SysAuthorityDAO; 16 | import pers.corvey.exam.entity.sys.SysAuthority; 17 | 18 | @Service 19 | @Transactional 20 | public class SysAuthorityService { 21 | 22 | private static List ALL_SYS_AUTHORITY = new ArrayList<>(); 23 | private static Map ID_TO_SYS_AUTHORITY = new HashMap<>(); 24 | private static Map NAME_TO_SYS_AUTHORITY = new HashMap<>(); 25 | private static SysAuthority DEFAULT_SYS_AUTHORITY; 26 | 27 | private final SysAuthorityDAO dao; 28 | 29 | @Autowired 30 | public SysAuthorityService(SysAuthorityDAO dao) { 31 | this.dao = dao; 32 | Iterable authorities = dao.findAll(); 33 | Assert.notNull(authorities, "权限表没数据?"); 34 | authorities.forEach(e -> { 35 | ALL_SYS_AUTHORITY.add(e); 36 | ID_TO_SYS_AUTHORITY.put(e.getId(), e); 37 | NAME_TO_SYS_AUTHORITY.put(e.getAuthority(), e); 38 | }); 39 | DEFAULT_SYS_AUTHORITY = NAME_TO_SYS_AUTHORITY.get("ROLE_USER"); 40 | } 41 | 42 | public List findAll() { 43 | return ALL_SYS_AUTHORITY; 44 | } 45 | 46 | public Set findAll(Iterable ids) { 47 | Set authorities = new HashSet<>(); 48 | if (ids != null) { 49 | ids.forEach(id -> { 50 | SysAuthority authority = ID_TO_SYS_AUTHORITY.get(id); 51 | if (id != null) { 52 | authorities.add(authority); 53 | } 54 | }); 55 | } 56 | return authorities; 57 | } 58 | 59 | public SysAuthority getDefaultAuthority() { 60 | return DEFAULT_SYS_AUTHORITY; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/sys/user-input.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 |
5 |
6 |
7 |

8 |  用户信息管理 9 |

10 |
11 |
12 | 14 | 15 |
16 | 17 |
18 | 20 |
21 |
22 |
23 | 24 |
25 | 26 |
27 |
28 |
29 | 30 |
31 | 32 |
33 |
34 |
35 | 36 |
37 | 39 |
40 |
41 |
42 | 43 |      44 | 返回 45 |
46 |
47 |
48 |
49 |
-------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/util/MyFileUtils.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.util; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | import java.util.UUID; 8 | 9 | import org.springframework.web.multipart.MultipartFile; 10 | 11 | import pers.corvey.exam.exception.FileNotPermitException; 12 | 13 | public class MyFileUtils { 14 | 15 | private static final String UPLOAD_FILE_PATH = "E://uploadFile"; 16 | private static final String DATE_FORMAT = "YYYY-MM-dd"; 17 | private static final String[] PERMIT_FILENAME_EXTENSION = { 18 | ".txt", ".doc", ".docx", ".xls", "xlsx", ".pdf" 19 | }; 20 | 21 | public static File saveFile(MultipartFile file) throws IOException, 22 | FileNotPermitException { 23 | 24 | String filenameExtension = getFilenameExtension(file.getOriginalFilename()); 25 | if (!isPermit(filenameExtension)) { 26 | throw new FileNotPermitException("服务器不允许上传类型为'" 27 | + filenameExtension + "'的文件"); 28 | } 29 | String dateStr = getYearMonthDayString(); 30 | File dir = new File(UPLOAD_FILE_PATH, dateStr); 31 | String fileName = createFileName(); 32 | File dest = new File(dir, fileName + filenameExtension); 33 | org.apache.commons.io.FileUtils 34 | .copyInputStreamToFile(file.getInputStream(), dest); 35 | return dest; 36 | } 37 | 38 | public static boolean isPermit(String filename) { 39 | String filenameExtension = getFilenameExtension(filename); 40 | for (String permitExtension : PERMIT_FILENAME_EXTENSION) { 41 | if (permitExtension.equals(filenameExtension)) { 42 | return true; 43 | } 44 | } 45 | return false; 46 | } 47 | 48 | private static String createFileName() { 49 | return UUID.randomUUID().toString().replace("-", ""); 50 | } 51 | 52 | // XXX 无扩展名时未处理 53 | private static String getFilenameExtension(String filename) { 54 | int index = filename.lastIndexOf("."); 55 | return filename.substring(index); 56 | } 57 | 58 | private static String getYearMonthDayString() { 59 | SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); 60 | return sdf.format(new Date()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/exam-show.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 | 5 | 6 | <%@include file="/common/head.jsp"%> 7 | 8 | 9 | 10 | <%@include file="/common/header.jsp"%> 11 |
12 |
13 |
14 |
15 |
16 |

17 |  所有考试 18 |

19 |
20 |
21 | <%@include file="/common/show-message.jsp"%> 22 |
23 |
24 |
25 | 27 |
28 | 29 |
30 |
31 |
32 |
33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 47 | 48 | 49 |
考试名称考试试卷考试时间(分钟)操作
参加考试
50 |
51 |
52 |
53 |
54 |
55 | 56 | 58 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/QuestionService.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import pers.corvey.exam.dao.ChoiceDAO; 9 | import pers.corvey.exam.dao.ExamPaperDAO; 10 | import pers.corvey.exam.dao.QuestionDAO; 11 | import pers.corvey.exam.entity.Choice; 12 | import pers.corvey.exam.entity.ExamPaper; 13 | import pers.corvey.exam.entity.Question; 14 | import pers.corvey.exam.entity.common.IdEntity; 15 | import pers.corvey.exam.service.common.BaseService; 16 | import pers.corvey.exam.service.common.BaseServiceImpl; 17 | 18 | @Service 19 | public class QuestionService extends BaseServiceImpl { 20 | 21 | private final QuestionDAO questionDAO; 22 | private final ChoiceDAO choiceDAO; 23 | private final ExamPaperDAO examPaperDAO; 24 | 25 | @Autowired 26 | public QuestionService(QuestionDAO questionDAO, ChoiceDAO choiceDAO, 27 | ExamPaperDAO examPaperDAO) { 28 | 29 | super(questionDAO); 30 | this.questionDAO = questionDAO; 31 | this.choiceDAO = choiceDAO; 32 | this.examPaperDAO = examPaperDAO; 33 | System.out.println(examPaperDAO); 34 | } 35 | 36 | @Override 37 | public Question save(Question entity) { 38 | List exampaperIds = entity.getExampaperIds(); 39 | Iterable exampapers = examPaperDAO.findAll(exampaperIds); 40 | entity.setExampapers(BaseService.iterableTolist(exampapers)); 41 | return super.save(entity); 42 | } 43 | 44 | // 增加注解使得hibernate自动删除无关联的数据 45 | // /** 46 | // * 删除掉更新后不存在的旧的选项 47 | // * @param newQuestion 48 | // */ 49 | // private void deleteRemovedChoices(Question newQuestion) { 50 | // Question oldQuestion = findByID(newQuestion.getId()); 51 | // if (oldQuestion != null) { 52 | // List newChoiceIds = IdEntity.getCollectionIds(newQuestion.getChoices()); 53 | // oldQuestion.getChoices().forEach(e -> { 54 | // Long id = e.getId(); 55 | // if (!newChoiceIds.contains(id)) { 56 | // System.out.println("执行删除" + id); 57 | // choiceDAO.delete(id); 58 | // } 59 | // }); 60 | // } 61 | // } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/helper/form/QuestionFormHelper.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.helper.form; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | import java.util.Optional; 7 | 8 | import pers.corvey.exam.entity.Choice; 9 | import pers.corvey.exam.entity.ExamPaper; 10 | import pers.corvey.exam.entity.Question; 11 | 12 | public class QuestionFormHelper { 13 | 14 | private List newChoices; 15 | private List deleteChoiceIds; 16 | private List exampaperIds; 17 | 18 | public void updateToQuestion(Question question) { 19 | List choices = Optional.ofNullable(question.getChoices()).orElse(new ArrayList<>()); 20 | System.out.println("----------------------"); 21 | if (deleteChoiceIds != null) { // 删除选项 22 | for (Iterator iter = choices.iterator(); iter.hasNext(); ) { 23 | Choice choice = iter.next(); 24 | if (deleteChoiceIds.contains(choice.getId())) { 25 | iter.remove(); 26 | } 27 | } 28 | } 29 | if (newChoices != null) { // 增加新选项 30 | newChoices.forEach(e -> { 31 | if (e.getAnswer() != null) { 32 | e.setQuestion(question); 33 | choices.add(e); 34 | } 35 | }); 36 | } 37 | question.setChoices(choices); 38 | 39 | List examPapers = new ArrayList<>(); 40 | if (exampaperIds != null) { // 重置所属试卷 41 | exampaperIds.forEach(id -> { 42 | ExamPaper examPaper = new ExamPaper(); 43 | examPaper.setId(id); 44 | examPapers.add(examPaper); 45 | }); 46 | } 47 | question.setExampapers(examPapers); 48 | } 49 | 50 | public List getNewChoices() { 51 | return newChoices; 52 | } 53 | 54 | public void setNewChoices(List newChoices) { 55 | this.newChoices = newChoices; 56 | } 57 | 58 | public List getDeleteChoiceIds() { 59 | return deleteChoiceIds; 60 | } 61 | 62 | public void setDeleteChoiceIds(List deleteChoiceIds) { 63 | this.deleteChoiceIds = deleteChoiceIds; 64 | } 65 | 66 | public List getExampaperIds() { 67 | return exampaperIds; 68 | } 69 | 70 | public void setExampaperIds(List exampaperIds) { 71 | this.exampaperIds = exampaperIds; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/controller/sys/CaptchaController.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.controller.sys; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.io.IOException; 5 | import java.util.Objects; 6 | 7 | import javax.imageio.ImageIO; 8 | import javax.servlet.ServletOutputStream; 9 | import javax.servlet.http.HttpServletRequest; 10 | import javax.servlet.http.HttpServletResponse; 11 | import javax.servlet.http.HttpSession; 12 | 13 | import org.springframework.stereotype.Controller; 14 | import org.springframework.web.bind.annotation.GetMapping; 15 | import org.springframework.web.bind.annotation.RequestMapping; 16 | 17 | import pers.corvey.exam.util.CaptchaUtils; 18 | 19 | 20 | 21 | @Controller 22 | @RequestMapping("/captcha") 23 | public class CaptchaController { 24 | 25 | public static final String CAPTCHA_ATTRIBUTE_NAME = "captcha"; 26 | 27 | @GetMapping 28 | public void createCaptcha(HttpSession session, HttpServletResponse response) { 29 | String captchaCode = CaptchaUtils.createCaptcha(); 30 | session.setAttribute(CAPTCHA_ATTRIBUTE_NAME, captchaCode); 31 | 32 | response.setContentType("image/png"); 33 | response.setHeader("Cache-Control", "no-cache, no-store"); 34 | response.setHeader("Pragma", "no-cache"); 35 | response.setDateHeader("expries", -1); 36 | 37 | BufferedImage image = CaptchaUtils.createCaptchaImage(captchaCode); 38 | try { 39 | ServletOutputStream out = response.getOutputStream(); 40 | ImageIO.write(image, "png", out); 41 | out.flush(); 42 | out.close(); 43 | } catch (IOException e) { 44 | e.printStackTrace(); 45 | } 46 | } 47 | 48 | public static boolean judge(HttpServletRequest request) { 49 | HttpSession session = request.getSession(); 50 | String inputCode = request.getParameter(CAPTCHA_ATTRIBUTE_NAME); 51 | String correctCode = (String) session.getAttribute(CAPTCHA_ATTRIBUTE_NAME); 52 | session.removeAttribute(CAPTCHA_ATTRIBUTE_NAME); 53 | if (inputCode == null || correctCode == null) { 54 | return false; 55 | } 56 | return Objects.equals(inputCode.toLowerCase(), correctCode.toLowerCase()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/common/SysModifyLog.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity.common; 2 | 3 | import java.util.Date; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Entity; 7 | import javax.persistence.FetchType; 8 | import javax.persistence.GeneratedValue; 9 | import javax.persistence.Id; 10 | import javax.persistence.JoinColumn; 11 | import javax.persistence.OneToOne; 12 | 13 | import org.hibernate.annotations.GenericGenerator; 14 | 15 | import pers.corvey.exam.entity.sys.SysUser; 16 | 17 | @Entity 18 | public class SysModifyLog implements IdEntity { 19 | 20 | private static final long serialVersionUID = 6146093577543710236L; 21 | 22 | private String id; 23 | private SysUser creator; 24 | private Date createDate; 25 | private SysUser modifier; 26 | private Date modifiedDate; 27 | 28 | public SysModifyLog() {} 29 | 30 | @Id 31 | @GeneratedValue(generator = "uuid") 32 | @GenericGenerator(name = "uuid", strategy = "uuid") 33 | @Column(columnDefinition = "char(32)") 34 | @Override 35 | public String getId() { 36 | return id; 37 | } 38 | 39 | @Override 40 | public void setId(String id) { 41 | this.id = id; 42 | } 43 | 44 | @OneToOne(fetch=FetchType.LAZY) 45 | @JoinColumn(name = "creator_user_id", updatable = false) 46 | public SysUser getCreator() { 47 | return creator; 48 | } 49 | 50 | public void setCreator(SysUser creator) { 51 | this.creator = creator; 52 | } 53 | 54 | @Column(updatable = false) 55 | public Date getCreateDate() { 56 | return createDate == null ? new Date() : createDate; 57 | } 58 | 59 | public void setCreateDate(Date createDate) { 60 | this.createDate = createDate; 61 | } 62 | 63 | @OneToOne(fetch=FetchType.LAZY) 64 | @JoinColumn(name = "modifier_user_id") 65 | public SysUser getModifier() { 66 | return modifier; 67 | } 68 | 69 | public void setModifier(SysUser modifier) { 70 | this.modifier = modifier; 71 | } 72 | 73 | public Date getModifiedDate() { 74 | return modifiedDate; 75 | } 76 | 77 | public void setModifiedDate(Date modifiedDate) { 78 | this.modifiedDate = modifiedDate; 79 | } 80 | 81 | @Override 82 | public String toString() { 83 | return String.format("SysModifyLog[id=%s, create_date=%s, create_id=%s, modify_date=%s, modify_id=%s]", id, createDate, creator, modifiedDate, modifier); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/ui/CallBackMessage.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity.ui; 2 | 3 | import pers.corvey.exam.util.CurrentUtils; 4 | 5 | /** 6 | * 回调消息 7 | * @author Corvey 8 | * 对应bootstrap里的alert 9 | */ 10 | public class CallBackMessage { 11 | 12 | public static final String MESSAGE_ATTRIBUTE_NAME = "message"; 13 | 14 | private String cssClass; 15 | private String type; 16 | private String text; 17 | 18 | private CallBackMessage(String type, String text, String cssClass) { 19 | setType(type); 20 | setText(text); 21 | setCssClass(cssClass); 22 | } 23 | 24 | public static CallBackMessage createSuccessMsg(String text) { 25 | return new CallBackMessage("success", text, "alert-success"); 26 | } 27 | 28 | public static CallBackMessage createWarningMsg(String text) { 29 | return new CallBackMessage("failure", text, "alert-warning"); 30 | } 31 | 32 | public static CallBackMessage createDangerMsg(String text) { 33 | return new CallBackMessage("failure", text, "alert-danger"); 34 | } 35 | 36 | /** 37 | * 根据某个方法执行的结果返回消息 38 | * @param function 要执行的方法 39 | * @param successMessage 方法执行成功后返回的消息 40 | * @param failureMessage 方法执行失败后返回的消息 41 | * @return 42 | */ 43 | public static CallBackMessage createMsgAfterFunction( 44 | Runnable function, String successMessage, String failureMessage) { 45 | 46 | CallBackMessage msg; 47 | try { 48 | function.run(); 49 | msg = CallBackMessage.createSuccessMsg(successMessage); 50 | } catch (Exception e) { 51 | e.printStackTrace(); 52 | msg = CallBackMessage.createDangerMsg(failureMessage); 53 | } 54 | return msg; 55 | } 56 | 57 | public void addToCurrentSession() { 58 | CurrentUtils.addAttributeToSession(MESSAGE_ATTRIBUTE_NAME, this); 59 | } 60 | 61 | public void addToCurrentRequest() { 62 | CurrentUtils.addAttributeToRequest(MESSAGE_ATTRIBUTE_NAME, this); 63 | } 64 | 65 | public String getCssClass() { 66 | return cssClass; 67 | } 68 | 69 | private void setCssClass(String cssClass) { 70 | this.cssClass = cssClass; 71 | } 72 | 73 | public String getText() { 74 | return text; 75 | } 76 | 77 | public void setText(String text) { 78 | this.text = text; 79 | } 80 | 81 | public String getType() { 82 | return type; 83 | } 84 | 85 | public void setType(String type) { 86 | this.type = type; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/common/BaseServiceImpl.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service.common; 2 | 3 | import java.io.Serializable; 4 | import java.lang.reflect.ParameterizedType; 5 | import java.lang.reflect.Type; 6 | import java.util.List; 7 | 8 | import org.springframework.data.repository.CrudRepository; 9 | import org.springframework.transaction.annotation.Transactional; 10 | import org.springframework.util.Assert; 11 | 12 | import pers.corvey.exam.entity.common.BaseEntity; 13 | 14 | @Transactional 15 | public abstract class BaseServiceImpl, ID extends Serializable> 16 | implements BaseService { 17 | 18 | protected final CrudRepository mainDAO; 19 | private final Class entityClazz; 20 | 21 | /** 22 | * 为父类注入mainDAO 23 | * @param mainDAO 该service主要用到的dao实例 24 | */ 25 | public BaseServiceImpl(CrudRepository mainDAO) { 26 | this.mainDAO = mainDAO; 27 | entityClazz = getEntityClass(); 28 | } 29 | 30 | @Override 31 | public T save(T entity) { 32 | Assert.notNull(entity, "传入的实体不能为空!"); 33 | entity.updateSysModifyLog(); 34 | return mainDAO.save(entity); 35 | } 36 | 37 | @Override 38 | public T findByID(ID id) { 39 | return mainDAO.findOne(id); 40 | } 41 | 42 | @Override 43 | public List findAll() { 44 | return BaseService.iterableTolist(mainDAO.findAll()); 45 | } 46 | 47 | @Override 48 | public List findAll(Iterable ids) { 49 | return BaseService.iterableTolist(mainDAO.findAll(ids)); 50 | } 51 | 52 | @Override 53 | public void delete(ID id) { 54 | mainDAO.delete(id); 55 | } 56 | 57 | /** 58 | * 通过实体的空构造方法生成实体(实体必须要有空的构造方法) 59 | * @return 60 | */ 61 | @Override 62 | public T createEntity() { 63 | T entity = null; 64 | try { 65 | entity = entityClazz.newInstance(); 66 | } catch (InstantiationException e) { 67 | e.printStackTrace(); 68 | } catch (IllegalAccessException e) { 69 | e.printStackTrace(); 70 | } 71 | return entity; 72 | } 73 | 74 | /** 75 | * 通过反射获取实体的class 76 | * @return 77 | */ 78 | @SuppressWarnings("unchecked") 79 | private Class getEntityClass() { 80 | Type type = getClass().getGenericSuperclass(); 81 | ParameterizedType pType = (ParameterizedType) type; 82 | Type[] types = pType.getActualTypeArguments(); 83 | Class clazz = (Class) types[0]; 84 | return clazz; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/Resource.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity; 2 | 3 | import java.util.List; 4 | 5 | import javax.persistence.CascadeType; 6 | import javax.persistence.Entity; 7 | import javax.persistence.FetchType; 8 | import javax.persistence.JoinColumn; 9 | import javax.persistence.OneToMany; 10 | import javax.persistence.OrderBy; 11 | 12 | import pers.corvey.exam.entity.common.BaseEntityImpl; 13 | 14 | @Entity 15 | public class Resource extends BaseEntityImpl { 16 | 17 | private static final long serialVersionUID = 5215832972476878002L; 18 | 19 | private String name; 20 | private String description; 21 | private String fileName; 22 | private Long fileSize; 23 | private String filePath; 24 | private Integer price; 25 | private Integer downloadTimes = 0; 26 | private List comments; 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void setName(String name) { 33 | this.name = name; 34 | } 35 | 36 | public String getDescription() { 37 | return description; 38 | } 39 | 40 | public void setDescription(String description) { 41 | this.description = description; 42 | } 43 | 44 | public String getFileName() { 45 | return fileName; 46 | } 47 | 48 | public void setFileName(String fileName) { 49 | this.fileName = fileName; 50 | } 51 | 52 | public Long getFileSize() { 53 | return fileSize; 54 | } 55 | 56 | public void setFileSize(Long fileSize) { 57 | this.fileSize = fileSize; 58 | } 59 | 60 | public String getFilePath() { 61 | return filePath; 62 | } 63 | 64 | public void setFilePath(String filePath) { 65 | this.filePath = filePath; 66 | } 67 | 68 | public Integer getPrice() { 69 | return price; 70 | } 71 | 72 | public void setPrice(Integer price) { 73 | this.price = price; 74 | } 75 | 76 | public Integer getDownloadTimes() { 77 | return downloadTimes; 78 | } 79 | 80 | public void setDownloadTimes(Integer downloadTimes) { 81 | this.downloadTimes = downloadTimes; 82 | } 83 | 84 | @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) 85 | @JoinColumn(name = "resource_id") 86 | @OrderBy("good desc") 87 | public List getComments() { 88 | return comments; 89 | } 90 | 91 | public void setComments(List comments) { 92 | this.comments = comments; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/uploadfile-input.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 | 5 | <%@include file="/common/header.jsp"%> 6 | My JSP 'page.jsp' starting page 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 40 | 41 | 59 | 60 | 61 | 62 |
63 |
64 | 65 | 即刻上传 67 | 返回 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/main/webapp/static/uploadFive/uploadifive.css: -------------------------------------------------------------------------------- 1 | /* 2 | UploadiFive 3 | Copyright (c) 2012 Reactive Apps, Ronnie Garcia 4 | */ 5 | 6 | .uploadifive-button { 7 | background-color: #505050; 8 | background-image: linear-gradient(bottom, #505050 0%, #707070 100%); 9 | background-image: -o-linear-gradient(bottom, #505050 0%, #707070 100%); 10 | background-image: -moz-linear-gradient(bottom, #505050 0%, #707070 100%); 11 | background-image: -webkit-linear-gradient(bottom, #505050 0%, #707070 100%); 12 | background-image: -ms-linear-gradient(bottom, #505050 0%, #707070 100%); 13 | background-image: -webkit-gradient( 14 | linear, 15 | left bottom, 16 | left top, 17 | color-stop(0, #505050), 18 | color-stop(1, #707070) 19 | ); 20 | background-position: center top; 21 | background-repeat: no-repeat; 22 | -webkit-border-radius: 30px; 23 | -moz-border-radius: 30px; 24 | border-radius: 30px; 25 | border: 2px solid #808080; 26 | color: #FFF; 27 | font: bold 12px Arial, Helvetica, sans-serif; 28 | text-align: center; 29 | text-shadow: 0 -1px 0 rgba(0,0,0,0.25); 30 | text-transform: uppercase; 31 | width: 100%; 32 | } 33 | .uploadifive-button:hover { 34 | background-color: #606060; 35 | background-image: linear-gradient(top, #606060 0%, #808080 100%); 36 | background-image: -o-linear-gradient(top, #606060 0%, #808080 100%); 37 | background-image: -moz-linear-gradient(top, #606060 0%, #808080 100%); 38 | background-image: -webkit-linear-gradient(top, #606060 0%, #808080 100%); 39 | background-image: -ms-linear-gradient(top, #606060 0%, #808080 100%); 40 | background-image: -webkit-gradient( 41 | linear, 42 | left bottom, 43 | left top, 44 | color-stop(0, #606060), 45 | color-stop(1, #808080) 46 | ); 47 | background-position: center bottom; 48 | } 49 | .uploadifive-queue-item { 50 | background-color: #F5F5F5; 51 | border-bottom: 1px dotted #D5D5D5; 52 | -webkit-border-radius: 5px; 53 | -moz-border-radius: 5px; 54 | border-radius: 5px; 55 | font: 12px Arial, Helvetica, Sans-serif; 56 | margin-top: 3px; 57 | padding: 15px; 58 | } 59 | .uploadifive-queue-item .close { 60 | background: url('uploadifive-cancel.png') 0 0 no-repeat; 61 | display: block; 62 | float: right; 63 | height: 16px; 64 | text-indent: -9999px; 65 | width: 16px; 66 | } 67 | .uploadifive-queue-item .progress { 68 | border: 1px solid #D0D0D0; 69 | height: 3px; 70 | margin-top: 5px; 71 | width: 100%; 72 | } 73 | .uploadifive-queue-item .progress-bar { 74 | background-color: #0072BC; 75 | height: 3px; 76 | width: 0; 77 | } -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/controller/QuestionController.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.ui.Model; 6 | import org.springframework.web.bind.annotation.ModelAttribute; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | 11 | import pers.corvey.exam.controller.common.BaseControllerImpl; 12 | import pers.corvey.exam.entity.ExamPaper; 13 | import pers.corvey.exam.entity.Question; 14 | import pers.corvey.exam.helper.form.QuestionFormHelper; 15 | import pers.corvey.exam.service.ExamPaperService; 16 | import pers.corvey.exam.service.QuestionService; 17 | 18 | @Controller 19 | @RequestMapping("/question") 20 | public class QuestionController extends BaseControllerImpl { 21 | 22 | private final QuestionService questionService; 23 | private final ExamPaperService examPaperService; 24 | 25 | @Autowired 26 | public QuestionController(QuestionService service, ExamPaperService examPaperService) { 27 | super(service, "question-input.jsp", "question-list.jsp"); 28 | this.questionService = service; 29 | this.examPaperService = examPaperService; 30 | } 31 | 32 | @PostMapping(SAVE_PATH) 33 | public String save(Model model, 34 | @ModelAttribute(ENTITY_ATTRIBUTE_NAME) Question question, 35 | QuestionFormHelper questionFormHelper) { 36 | //System.out.println(questionFormHelper); 37 | questionFormHelper.updateToQuestion(question); 38 | return baseSave(question); 39 | } 40 | 41 | @Override 42 | public String showInputView(Model model, 43 | @ModelAttribute(ENTITY_ATTRIBUTE_NAME) Question entity) { 44 | 45 | Iterable exampapers = examPaperService.findAll(); 46 | model.addAttribute("exampapers", exampapers); 47 | return super.showInputView(model, entity); 48 | } 49 | 50 | @Override 51 | public String showDetailView(Model model, 52 | @ModelAttribute(ENTITY_ATTRIBUTE_NAME) Question entity) { 53 | 54 | Iterable exampapers = examPaperService.findAll(); 55 | model.addAttribute("exampapers", exampapers); 56 | return super.showDetailView(model, entity); 57 | } 58 | 59 | @RequestMapping("/{questionId}") 60 | public String show(Model model, @PathVariable Long questionId) { 61 | Question question = questionService.findByID(questionId); 62 | model.addAttribute("question", question); 63 | return "question-show"; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/BuyLogService.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | 6 | import pers.corvey.exam.dao.BuyLogDAO; 7 | import pers.corvey.exam.dao.ResourceDAO; 8 | import pers.corvey.exam.dao.SysUserDAO; 9 | import pers.corvey.exam.entity.BuyLog; 10 | import pers.corvey.exam.entity.Resource; 11 | import pers.corvey.exam.entity.sys.SysUser; 12 | import pers.corvey.exam.entity.ui.CallBackMessage; 13 | import pers.corvey.exam.service.common.BaseServiceImpl; 14 | import pers.corvey.exam.util.CurrentUtils; 15 | 16 | @Service 17 | public class BuyLogService extends BaseServiceImpl { 18 | 19 | private final BuyLogDAO dao; 20 | private final ResourceDAO resourceDAO; 21 | private final SysUserDAO userDAO; 22 | 23 | @Autowired 24 | public BuyLogService(BuyLogDAO dao, ResourceDAO resourceDAO, SysUserDAO userDAO) { 25 | super(dao); 26 | this.dao = dao; 27 | this.resourceDAO = resourceDAO; 28 | this.userDAO = userDAO; 29 | } 30 | 31 | public boolean hadBought(Resource resource) { 32 | SysUser user = CurrentUtils.getCurrentUser(); 33 | return resource.getSysModifyLog().getCreator().getId().equals(user.getId()) 34 | || dao.findByUserIdAndResourceId(user.getId(), resource.getId()) != null; 35 | } 36 | 37 | public boolean buy(Resource resource) { 38 | // 是否已购买 39 | if (hadBought(resource)) { 40 | return true; 41 | } 42 | 43 | SysUser buyer = CurrentUtils.getCurrentUser(); 44 | int buyerMoney = buyer.getMoney(); 45 | int resourcePrice = resource.getPrice(); 46 | 47 | // 检查买家够不够积分 48 | if (buyerMoney < resourcePrice) { 49 | CallBackMessage msg = CallBackMessage.createDangerMsg("您的积分不足!无法下载!"); 50 | CurrentUtils.addAttributeToSession(CallBackMessage.MESSAGE_ATTRIBUTE_NAME, msg); 51 | return false; 52 | } 53 | 54 | // 买家扣取相应积分 55 | buyer.setMoney(buyerMoney - resourcePrice); 56 | userDAO.save(buyer); 57 | 58 | // 卖家增加相应积分 59 | SysUser seller = resource.getSysModifyLog().getCreator(); 60 | seller.setMoney(seller.getMoney() + resourcePrice); 61 | userDAO.save(seller); 62 | 63 | // 资源增加下载次数 64 | resource.setDownloadTimes(resource.getDownloadTimes() + 1); 65 | resourceDAO.save(resource); 66 | 67 | // 购买记录 68 | BuyLog log = new BuyLog(); 69 | log.setUser(buyer); 70 | log.setResource(resource); 71 | log.setSpending(resourcePrice); 72 | dao.save(log); 73 | 74 | CallBackMessage msg = CallBackMessage.createSuccessMsg("下载成功!已扣除相应积分!"); 75 | CurrentUtils.addAttributeToSession(CallBackMessage.MESSAGE_ATTRIBUTE_NAME, msg); 76 | return true; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/Question.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | import javax.persistence.CascadeType; 7 | import javax.persistence.Entity; 8 | import javax.persistence.FetchType; 9 | import javax.persistence.JoinColumn; 10 | import javax.persistence.JoinTable; 11 | import javax.persistence.ManyToMany; 12 | import javax.persistence.OneToMany; 13 | import javax.persistence.OrderBy; 14 | import javax.persistence.Transient; 15 | 16 | import org.apache.commons.lang3.builder.ToStringBuilder; 17 | import org.apache.commons.lang3.builder.ToStringStyle; 18 | 19 | import pers.corvey.exam.entity.common.BaseEntityImpl; 20 | import pers.corvey.exam.entity.common.IdEntity; 21 | 22 | @Entity 23 | public class Question extends BaseEntityImpl { 24 | 25 | private String type; // 判断,单选,多选 26 | private String content; 27 | private List exampapers; 28 | private List choices; 29 | private List comments; 30 | 31 | public Question() {} 32 | 33 | public String getType() { 34 | return type; 35 | } 36 | 37 | public void setType(String type) { 38 | this.type = type; 39 | } 40 | 41 | public String getContent() { 42 | return content; 43 | } 44 | 45 | public void setContent(String content) { 46 | this.content = content; 47 | } 48 | 49 | @ManyToMany(fetch=FetchType.LAZY) 50 | @JoinTable(name="exampaper_question") 51 | public List getExampapers() { 52 | return exampapers; 53 | } 54 | 55 | public void setExampapers(List exampapers) { 56 | this.exampapers = exampapers; 57 | } 58 | 59 | @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) 60 | @JoinColumn(name="question_id") 61 | public List getChoices() { 62 | return choices; 63 | } 64 | 65 | public void setChoices(List choices) { 66 | this.choices = choices; 67 | } 68 | 69 | @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) 70 | @JoinColumn(name="question_id") 71 | @OrderBy("good desc") 72 | public List getComments() { 73 | return comments; 74 | } 75 | 76 | public void setComments(List comments) { 77 | this.comments = comments; 78 | } 79 | 80 | @Transient 81 | public List getAnswers() { 82 | if (getChoices() != null) { 83 | return getChoices().stream() 84 | .filter(e -> e.getAnswer() == true) 85 | .collect(Collectors.toList()); 86 | } 87 | return null; 88 | } 89 | 90 | // JSP用到的方法 91 | @Transient 92 | public List getExampaperIds() { 93 | return IdEntity.getCollectionIds(exampapers); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/controller/ExamResultController.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.controller; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.ModelAttribute; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | 12 | import pers.corvey.exam.controller.common.BaseControllerImpl; 13 | import pers.corvey.exam.entity.Exam; 14 | import pers.corvey.exam.entity.ExamResult; 15 | import pers.corvey.exam.entity.sys.SysUser; 16 | import pers.corvey.exam.service.ExamResultService; 17 | import pers.corvey.exam.service.ExamService; 18 | import pers.corvey.exam.service.sys.SysUserService; 19 | import pers.corvey.exam.util.CurrentUtils; 20 | 21 | @Controller 22 | @RequestMapping("/examresult") 23 | public class ExamResultController extends BaseControllerImpl { 24 | 25 | private final ExamResultService service; 26 | private final ExamService examService; 27 | private final SysUserService userService; 28 | 29 | public ExamResultController(ExamResultService service, ExamService examService, 30 | SysUserService userService) { 31 | super(service, "exam-result-input.jsp", "exam-result-list.jsp"); 32 | this.service = service; 33 | this.examService = examService; 34 | this.userService = userService; 35 | } 36 | 37 | @Override 38 | public String showInputView(Model model, @ModelAttribute("entity") ExamResult entity) { 39 | model.addAttribute("exams", examService.findAll()); 40 | model.addAttribute("users", userService.findAll()); 41 | return super.showInputView(model, entity); 42 | } 43 | 44 | @Override 45 | public String showDetailView(Model model, @ModelAttribute("entity") ExamResult entity) { 46 | model.addAttribute("exams", examService.findAll()); 47 | model.addAttribute("users", userService.findAll()); 48 | return super.showInputView(model, entity); 49 | } 50 | 51 | @PostMapping(SAVE_PATH) 52 | public String save(Model model, @ModelAttribute("entity") ExamResult entity, 53 | @RequestParam("examId") Long examId, 54 | @RequestParam("userId") Long userId) { 55 | 56 | Exam exam = examService.findByID(examId); 57 | SysUser user = userService.findByID(userId); 58 | entity.setExam(exam); 59 | entity.setUser(user); 60 | return baseSave(entity); 61 | } 62 | 63 | @RequestMapping("/show") 64 | public String show(Model model) { 65 | SysUser user = CurrentUtils.getCurrentUser(); 66 | List results = service.findByUserId(user.getId()); 67 | model.addAttribute("entities", results); 68 | return "exam-result-show"; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/controller/ExamPaperController.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.controller; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.util.List; 6 | 7 | import org.apache.poi.EncryptedDocumentException; 8 | import org.apache.poi.openxml4j.exceptions.InvalidFormatException; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.ui.Model; 12 | import org.springframework.web.bind.annotation.ModelAttribute; 13 | import org.springframework.web.bind.annotation.PostMapping; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RequestParam; 16 | import org.springframework.web.multipart.MultipartFile; 17 | 18 | import pers.corvey.exam.controller.common.BaseControllerImpl; 19 | import pers.corvey.exam.entity.ExamPaper; 20 | import pers.corvey.exam.entity.Question; 21 | import pers.corvey.exam.entity.ui.CallBackMessage; 22 | import pers.corvey.exam.service.ExamPaperService; 23 | import pers.corvey.exam.util.ExcelToQuestionUtils; 24 | 25 | @Controller 26 | @RequestMapping("/exampaper") 27 | public class ExamPaperController extends BaseControllerImpl { 28 | 29 | private final ExamPaperService examPaperService; 30 | 31 | @Autowired 32 | public ExamPaperController(ExamPaperService examPaperService) { 33 | super(examPaperService, "exampaper-input.jsp", "exampaper-list.jsp"); 34 | this.examPaperService = examPaperService; 35 | } 36 | 37 | @PostMapping(SAVE_PATH) 38 | public String save(Model model, @ModelAttribute("entity") ExamPaper examPaper, 39 | @RequestParam("file") MultipartFile file) { 40 | CallBackMessage msg; 41 | try { 42 | InputStream inputStream = file.getInputStream(); 43 | List questions = ExcelToQuestionUtils.readQuestions(inputStream); 44 | inputStream.close(); 45 | examPaper.setQuestions(questions); 46 | return baseSave(examPaper); 47 | } catch (IOException e) { 48 | e.printStackTrace(); 49 | msg = CallBackMessage.createDangerMsg("服务器异常,请重试!"); 50 | } catch (EncryptedDocumentException e) { 51 | e.printStackTrace(); 52 | msg = CallBackMessage.createDangerMsg("题目文档已被加密,无法识别!"); 53 | } catch (InvalidFormatException e) { 54 | e.printStackTrace(); 55 | msg = CallBackMessage.createDangerMsg("题目文档格式有误!"); 56 | } catch (IllegalArgumentException e) { 57 | e.printStackTrace(); 58 | msg = CallBackMessage.createDangerMsg(e.getMessage()); 59 | } 60 | msg.addToCurrentSession(); 61 | return redirect(LIST_PATH); 62 | } 63 | 64 | @PostMapping("/search") 65 | public String search(Model model, @RequestParam("keyword") String keyword) { 66 | return baseShowListView(model, examPaperService.search(keyword)); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/controller/sys/SysUserController.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.controller.sys; 2 | 3 | import java.util.List; 4 | import java.util.Set; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.ui.Model; 9 | import org.springframework.web.bind.annotation.ModelAttribute; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | 14 | import pers.corvey.exam.controller.common.BaseControllerImpl; 15 | import pers.corvey.exam.entity.sys.SysAuthority; 16 | import pers.corvey.exam.entity.sys.SysUser; 17 | import pers.corvey.exam.service.sys.SysAuthorityService; 18 | import pers.corvey.exam.service.sys.SysUserService; 19 | 20 | @Controller 21 | @RequestMapping("/sys/user") 22 | public class SysUserController extends BaseControllerImpl { 23 | 24 | private final SysUserService sysUserService; 25 | 26 | private final SysAuthorityService sysAuthorityService; 27 | 28 | @Autowired 29 | public SysUserController(SysUserService sysUserService, 30 | SysAuthorityService sysAuthorityService) { 31 | 32 | super(sysUserService, "sys/user-input.jsp", "sys/user-list.jsp"); 33 | this.sysUserService = sysUserService; 34 | this.sysAuthorityService = sysAuthorityService; 35 | } 36 | 37 | /** 38 | * 保存记录 39 | * @param user 40 | * @param ids 41 | * @return 42 | */ 43 | @PostMapping(SAVE_PATH) 44 | public String save(@ModelAttribute("entity") SysUser user, 45 | @RequestParam(name="authorityIds", required=false) List authorityIds) { 46 | if (user.getMoney() == null) { 47 | user.setMoney(10); 48 | } 49 | Set authorities = sysAuthorityService.findAll(authorityIds); 50 | authorities.add(sysAuthorityService.getDefaultAuthority()); 51 | user.setAuthorities(authorities); 52 | return baseSave(user); 53 | } 54 | 55 | @PostMapping("/search") 56 | public String search(Model model, @RequestParam("keyword") String keyword) { 57 | return baseShowListView(model, sysUserService.search(keyword)); 58 | } 59 | 60 | @Override 61 | public String showInputView(Model model, @ModelAttribute("entity") SysUser entity) { 62 | Iterable authorities = sysAuthorityService.findAll(); 63 | model.addAttribute("authorities", authorities); 64 | return super.showInputView(model, entity); 65 | } 66 | 67 | @Override 68 | public String showDetailView(Model model, @ModelAttribute("entity") SysUser entity) { 69 | Iterable authorities = sysAuthorityService.findAll(); 70 | model.addAttribute("authorities", authorities); 71 | return super.showDetailView(model, entity); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/service/ChooseLogService.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.service; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import pers.corvey.exam.dao.ChoiceDAO; 9 | import pers.corvey.exam.dao.ChooseLogDAO; 10 | import pers.corvey.exam.dao.ExamDAO; 11 | import pers.corvey.exam.dao.ExamResultDAO; 12 | import pers.corvey.exam.dao.QuestionDAO; 13 | import pers.corvey.exam.entity.ChooseLog; 14 | import pers.corvey.exam.entity.common.IdEntity; 15 | import pers.corvey.exam.service.common.BaseService; 16 | import pers.corvey.exam.service.common.BaseServiceImpl; 17 | import pers.corvey.exam.util.CurrentUtils; 18 | 19 | @Service 20 | public class ChooseLogService extends BaseServiceImpl { 21 | 22 | private final ChooseLogDAO dao; 23 | private final ExamDAO examDAO; 24 | private final QuestionDAO questionDAO; 25 | private final ChoiceDAO choiceDAO; 26 | private final ExamResultDAO examResultDAO; 27 | 28 | @Autowired 29 | public ChooseLogService(ChooseLogDAO dao, ExamDAO examDAO, ChoiceDAO choiceDAO, 30 | QuestionDAO questionDAO, ExamResultDAO examResultDAO) { 31 | 32 | super(dao); 33 | this.dao = dao; 34 | this.examDAO = examDAO; 35 | this.questionDAO = questionDAO; 36 | this.choiceDAO = choiceDAO; 37 | this.examResultDAO = examResultDAO; 38 | } 39 | 40 | @Override 41 | public ChooseLog save(ChooseLog entity) { 42 | Long examId = entity.getExam().getId(); 43 | entity.setExam(examDAO.findOne(examId)); 44 | Long questionId = entity.getQuestion().getId(); 45 | entity.setQuestion(questionDAO.findOne(questionId)); 46 | List choiceIds = IdEntity.getCollectionIds(entity.getChoose()); 47 | entity.setChoose(BaseService.iterableTolist(choiceDAO.findAll(choiceIds))); 48 | judge(entity); 49 | entity.setUser(CurrentUtils.getCurrentUser()); 50 | return super.save(entity); 51 | } 52 | 53 | public List findByExamIdAndUserId(Long examId, Long userId) { 54 | return dao.findByExamIdAndUserId(examId, userId); 55 | } 56 | 57 | public boolean judge(ChooseLog chooseLog) { 58 | List answerIds = IdEntity.getCollectionIds(chooseLog.getQuestion().getAnswers()); 59 | List chooseIds = IdEntity.getCollectionIds(chooseLog.getChoose()); 60 | boolean right = chooseIds != null && chooseIds.size() == answerIds.size() 61 | && chooseIds.containsAll(answerIds); 62 | chooseLog.setCorrect(right); 63 | chooseLog.setDisplay(right ? false : true); 64 | return right; 65 | } 66 | 67 | public List getUserWrong(Long userId) { 68 | return dao.findWrongByUserId(userId); 69 | } 70 | 71 | public void hideChooseLog(Long chooseLogId) { 72 | ChooseLog log = dao.findOne(chooseLogId); 73 | log.setDisplay(false); 74 | dao.save(log); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/webapp/common/page.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%-- action='#' 表示提交数据到本页 --%> 3 |
4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
64 | 66 | 67 | 68 | 69 |
70 |
71 | 72 |
73 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/login.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ include file="/common/taglibs.jsp"%> 4 | <%session.removeAttribute("message");%> 5 | 6 | 7 | 8 | 9 | <%@include file="/common/head.jsp" %> 10 | 29 | 30 | 31 | 32 |
79 | 80 | 81 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 6 | Archetype Created Web Application 7 | 8 | 9 | 10 | contextConfigLocation 11 | classpath:spring*.xml,classpath:/applicationContext*.xml 12 | 13 | 14 | 15 | 16 | characterEncodingFilter 17 | org.springframework.web.filter.CharacterEncodingFilter 18 | 19 | encoding 20 | UTF-8 21 | 22 | 23 | forceEncoding 24 | true 25 | 26 | 27 | 28 | characterEncodingFilter 29 | /* 30 | 31 | 32 | 33 | 34 | springSecurityFilterChain 35 | org.springframework.web.filter.DelegatingFilterProxy 36 | 37 | 38 | springSecurityFilterChain 39 | /* 40 | 41 | 42 | 43 | 44 | openEntityManagerInViewFilter 45 | org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter 46 | 47 | entityManagerFactoryBeanName 48 | entityManagerFactory 49 | 50 | 51 | 52 | openEntityManagerInViewFilter 53 | /* 54 | 55 | 56 | 57 | 58 | org.springframework.web.context.ContextLoaderListener 59 | 60 | 61 | org.springframework.web.context.request.RequestContextListener 62 | 63 | 64 | 65 | 66 | dispatcher 67 | org.springframework.web.servlet.DispatcherServlet 68 | 69 | contextConfigLocation 70 | classpath:spring.xml 71 | 72 | 1 73 | 74 | 75 | dispatcher 76 | / 77 | 78 | 79 | 80 | 81 | 82 | *.jsp 83 | true 84 | 85 | 86 | 87 | 88 | 89 | 30 90 | 91 | 92 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/wrong-question-show.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | <% 4 | Map int2char = new HashMap<>(); 5 | for (int i=0; i<26; ++i) { 6 | int2char.put(i, (char)('A' + i)); 7 | } 8 | request.setAttribute("int2char", int2char); 9 | %> 10 | 11 | 12 | 13 | <%@include file="/common/head.jsp" %> 14 | 15 | 16 | 17 | <%@include file="/common/header.jsp" %> 18 |
19 |
20 | 21 |
22 |
23 |
24 |

25 |  错题集 26 |

27 |
28 |
29 | 30 |
32 |
33 |

${result.question.type}题 34 | 不再显示 36 |

37 |
38 |
39 |

${result.question.content}

40 | 41 |
42 | 47 |
48 |
49 |

正确答案: 50 |   你的选择: 51 | 查看讨论区 53 | 54 |

55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | 63 | 95 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/register.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8"%> 3 | <%@ include file="/common/taglibs.jsp"%> 4 | 5 | 6 | 7 | <%@include file="/common/head.jsp" %> 8 | 27 | 28 | 29 | 30 |
31 |
32 |

注册用户

33 |
34 |
35 | 36 | 37 | 38 | 40 |

41 |
42 | 43 | 44 | 45 | 47 |

48 |
49 | 50 | 51 | 52 | 54 |

55 | <%--
56 | 58 | 60 | 验证码图片 61 | 62 |

63 |
64 | 65 | 66 | 忘记密码 67 |
--%> 68 |
69 |

70 | 71 |

72 |
73 |
74 | 77 | 78 | 返回 79 | 80 |
81 |
82 |
83 |
84 | 85 | 86 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/entity/sys/SysUser.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.entity.sys; 2 | 3 | import java.util.List; 4 | import java.util.Set; 5 | import java.util.stream.Collectors; 6 | 7 | import javax.persistence.Column; 8 | import javax.persistence.Entity; 9 | import javax.persistence.FetchType; 10 | import javax.persistence.JoinTable; 11 | import javax.persistence.ManyToMany; 12 | import javax.persistence.Transient; 13 | 14 | import org.springframework.security.core.userdetails.UserDetails; 15 | 16 | import pers.corvey.exam.entity.common.BaseEntityImpl; 17 | import pers.corvey.exam.entity.common.IdEntity; 18 | 19 | @Entity 20 | public class SysUser extends BaseEntityImpl implements UserDetails { 21 | 22 | private static final long serialVersionUID = -8934005291821318128L; 23 | private String name; 24 | private String username; 25 | private String password; 26 | private Integer money; 27 | private Set authorities; 28 | 29 | public SysUser() {} 30 | 31 | @Override 32 | public String toString() { 33 | return String.format("SysUser[id=%s, name=%s, username=%s, password=%s]", 34 | id, name, username, password); 35 | } 36 | 37 | @Column(length = 20, nullable = false) 38 | public String getName() { 39 | return name; 40 | } 41 | public void setName(String name) { 42 | this.name = name; 43 | } 44 | 45 | @Override 46 | @Column(length = 20, updatable = false, nullable = false, unique = true) 47 | public String getUsername() { 48 | return username; 49 | } 50 | public void setUsername(String username) { 51 | this.username = username; 52 | } 53 | 54 | @Override 55 | @Column(columnDefinition = "char(32)", nullable = false) 56 | public String getPassword() { 57 | return password; 58 | } 59 | public void setPassword(String password) { 60 | this.password = password; 61 | } 62 | 63 | public Integer getMoney() { 64 | return money; 65 | } 66 | 67 | public void setMoney(Integer money) { 68 | this.money = money; 69 | } 70 | 71 | @Override 72 | @ManyToMany(fetch=FetchType.LAZY) 73 | @JoinTable(name = "sys_user_authority") 74 | public Set getAuthorities() { 75 | return authorities; 76 | } 77 | 78 | public void setAuthorities(Set authorities) { 79 | this.authorities = authorities; 80 | } 81 | 82 | @Override 83 | @Transient 84 | public boolean isAccountNonExpired() { 85 | return true; 86 | } 87 | 88 | @Override 89 | @Transient 90 | public boolean isAccountNonLocked() { 91 | return true; 92 | } 93 | 94 | @Override 95 | @Transient 96 | public boolean isCredentialsNonExpired() { 97 | return true; 98 | } 99 | 100 | @Override 101 | @Transient 102 | public boolean isEnabled() { 103 | return true; 104 | } 105 | 106 | /*----------JSP需要用到的方法--------------*/ 107 | 108 | @Transient 109 | public Boolean getAdmin() { 110 | return authorities.stream() 111 | .map(x -> x.getAuthority()) 112 | .anyMatch(a -> a.equals("ROLE_ADMIN")); 113 | } 114 | 115 | @Transient 116 | public List getAuthorityIds() { 117 | return IdEntity.getCollectionIds(getAuthorities()); 118 | } 119 | 120 | @Transient 121 | public String getAuthorityNames() { 122 | if (authorities == null) { 123 | return null; 124 | } 125 | List names = authorities.stream() 126 | .sorted((a, b) -> a.getId() < b.getId() ? -1 : 1) 127 | .map(x -> x.getAuthority().replace("ROLE_", "")) 128 | .collect(Collectors.toList()); 129 | return String.join(", ", names); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/webapp/static/js/jquery.cookie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Cookie Plugin v1.4.1 3 | * https://github.com/carhartl/jquery-cookie 4 | * 5 | * Copyright 2013 Klaus Hartl 6 | * Released under the MIT license 7 | */ 8 | (function (factory) { 9 | if (typeof define === 'function' && define.amd) { 10 | // AMD 11 | define(['jquery'], factory); 12 | } else if (typeof exports === 'object') { 13 | // CommonJS 14 | factory(require('jquery')); 15 | } else { 16 | // Browser globals 17 | factory(jQuery); 18 | } 19 | }(function ($) { 20 | 21 | var pluses = /\+/g; 22 | 23 | function encode(s) { 24 | return config.raw ? s : encodeURIComponent(s); 25 | } 26 | 27 | function decode(s) { 28 | return config.raw ? s : decodeURIComponent(s); 29 | } 30 | 31 | function stringifyCookieValue(value) { 32 | return encode(config.json ? JSON.stringify(value) : String(value)); 33 | } 34 | 35 | function parseCookieValue(s) { 36 | if (s.indexOf('"') === 0) { 37 | // This is a quoted cookie as according to RFC2068, unescape... 38 | s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); 39 | } 40 | 41 | try { 42 | // Replace server-side written pluses with spaces. 43 | // If we can't decode the cookie, ignore it, it's unusable. 44 | // If we can't parse the cookie, ignore it, it's unusable. 45 | s = decodeURIComponent(s.replace(pluses, ' ')); 46 | return config.json ? JSON.parse(s) : s; 47 | } catch(e) {} 48 | } 49 | 50 | function read(s, converter) { 51 | var value = config.raw ? s : parseCookieValue(s); 52 | return $.isFunction(converter) ? converter(value) : value; 53 | } 54 | 55 | var config = $.cookie = function (key, value, options) { 56 | 57 | // Write 58 | 59 | if (value !== undefined && !$.isFunction(value)) { 60 | options = $.extend({}, config.defaults, options); 61 | 62 | if (typeof options.expires === 'number') { 63 | var days = options.expires, t = options.expires = new Date(); 64 | t.setTime(+t + days * 864e+5); 65 | } 66 | 67 | return (document.cookie = [ 68 | encode(key), '=', stringifyCookieValue(value), 69 | options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE 70 | options.path ? '; path=' + options.path : '', 71 | options.domain ? '; domain=' + options.domain : '', 72 | options.secure ? '; secure' : '' 73 | ].join('')); 74 | } 75 | 76 | // Read 77 | 78 | var result = key ? undefined : {}; 79 | 80 | // To prevent the for loop in the first place assign an empty array 81 | // in case there are no cookies at all. Also prevents odd result when 82 | // calling $.cookie(). 83 | var cookies = document.cookie ? document.cookie.split('; ') : []; 84 | 85 | for (var i = 0, l = cookies.length; i < l; i++) { 86 | var parts = cookies[i].split('='); 87 | var name = decode(parts.shift()); 88 | var cookie = parts.join('='); 89 | 90 | if (key && key === name) { 91 | // If second argument (value) is a function it's a converter... 92 | result = read(cookie, value); 93 | break; 94 | } 95 | 96 | // Prevent storing a cookie that we couldn't decode. 97 | if (!key && (cookie = read(cookie)) !== undefined) { 98 | result[name] = cookie; 99 | } 100 | } 101 | 102 | return result; 103 | }; 104 | 105 | config.defaults = {}; 106 | 107 | $.removeCookie = function (key, options) { 108 | if ($.cookie(key) === undefined) { 109 | return false; 110 | } 111 | 112 | // Must not alter options, thus extending a fresh object... 113 | $.cookie(key, '', $.extend({}, options, { expires: -1 })); 114 | return !$.cookie(key); 115 | }; 116 | 117 | })); 118 | -------------------------------------------------------------------------------- /src/main/resources/spring-security.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 37 | 43 | 44 | 45 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/question-show.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | <% 4 | Map int2char = new HashMap<>(); 5 | for (int i=0; i<26; ++i) { 6 | int2char.put(i, (char)('A' + i)); 7 | } 8 | request.setAttribute("int2char", int2char); 9 | %> 10 | 11 | 12 | 13 | <%@include file="/common/head.jsp"%> 14 | 15 | 16 | 17 | <%@include file="/common/header.jsp"%> 18 |
19 |
20 |
21 |
22 |
23 |

题目信息

24 |
25 |
26 |

${question.content} 27 | (${question.type}题) 28 |

29 | 30 |
31 | 36 |
37 |
38 |

正确答案: 39 |

40 |
41 | 42 |
43 |
44 |

讨论区

45 |
46 |
47 |
48 |
49 |

发表见解

50 |
51 |
52 |
54 | 55 | 57 | 58 |
59 |
60 |
61 | <%@include file="/common/show-message.jsp"%> 62 | 63 | 65 |
66 |
67 |
68 | 69 |

${comment.user.name}

70 |
71 |
${comment.content}
72 |
73 | 78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | 90 | 113 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/resource-show.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 | 5 | 6 | <%@include file="/common/head.jsp"%> 7 | 8 | 9 | 10 | <%@include file="/common/header.jsp"%> 11 |
12 |
13 |
14 |
15 |
16 |

资源信息

17 |
18 |
19 |

${resource.name}

20 |

${resource.description}

21 |

上传日期: 23 |

24 |

下载次数:${resource.downloadTimes}

25 |

文件大小:${resource.fileSize}

26 |

所需积分:${resource.price} 27 | 28 | 29 | 30 | 31 | 32 | 购买并下载 33 | 34 | 35 |

36 |
37 |
38 | 39 |
40 |
41 |

资源评论

42 |
43 |
44 |
45 |
46 |

发表评论

47 |
48 |
49 |
51 | 52 | 54 | 55 |
56 |
57 |
58 | <%@include file="/common/show-message.jsp"%> 59 | 60 | 62 |
63 |
64 |
65 | 66 |

${comment.user.name}

67 |
68 |
${comment.content}
69 |
70 | 75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | 86 | 87 | 112 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/exam-result.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | <% 4 | Map int2char = new HashMap<>(); 5 | for (int i=0; i<26; ++i) { 6 | int2char.put(i, (char)('A' + i)); 7 | } 8 | request.setAttribute("int2char", int2char); 9 | %> 10 | 11 | 12 | 13 | <%@include file="/common/head.jsp" %> 14 | 15 | 16 | 17 | <%@include file="/common/header.jsp" %> 18 |
19 |
20 | 21 |
22 |
23 |
24 |

25 |  题目导航 26 |

27 |
28 |
29 | 30 |
31 | ${st.count} 33 |
34 |
35 |
36 |
37 |
38 | 39 |
40 |
41 |
42 |

43 |  ${entities[0].exam.name} - 结果 44 |

45 |
46 | 47 |
48 |
49 |

考试成绩

50 |
51 |
成绩
52 |
${examResult.grade}
53 |
错题数
54 |
${examResult.wrongCount} / ${examResult.allCount}
55 |
56 |
57 | 58 |
60 |
61 |

${result.question.type}题

62 |
63 |
64 |

${st.count}. ${result.question.content}

65 | 66 |
67 | 72 |
73 |
74 |

正确答案: 75 |   你的选择: 76 | 查看讨论区 78 | 79 |

80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | 88 | 123 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/question-input.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 |
5 |
6 |
7 |

8 | 9 |  题目信息管理 10 |

11 |
12 |
13 | 15 | 16 |
17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 |
25 |
26 |
27 | 28 |
29 | 30 |
31 |
32 | 33 |
34 | 35 | 36 |
37 | 40 |
41 |
42 | 43 | 45 |
46 | 48 |
49 |
50 |
51 |
52 |

53 | 54 |

55 |
56 | 57 |
58 | 60 |
61 |
62 |

63 | 64 |      65 | 返回 66 |
67 |
68 |
69 |
70 |
71 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/exam.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | <% 4 | Map int2char = new HashMap<>(); 5 | for (int i=0; i<26; ++i) { 6 | int2char.put(i, (char)('A' + i)); 7 | } 8 | request.setAttribute("int2char", int2char); 9 | %> 10 | 11 | 12 | 13 | <%@include file="/common/head.jsp" %> 14 | 15 | 16 | 17 | <%@include file="/common/header.jsp" %> 18 |
19 |
20 | 21 |
22 |
23 |
24 |

25 |  题目导航 26 |

27 |
28 |
29 | 30 |
31 | ${st.count} 32 |
33 |
34 |
35 |
36 |

剩余时间

37 |

${entity.time}分钟0秒

38 |
39 |
40 |
41 |
42 |
43 | 44 |
45 |
46 |
47 |

48 |  ${entity.name} 49 |

50 |
51 | 52 |
53 |
54 | 55 | 56 | 58 |
59 |
60 |

${question.type}题

61 |
62 |
64 |

${st.count}. ${question.content}

65 | 66 |
67 | 72 |
73 |
74 |
75 |
76 |
77 |

78 | 79 |      80 | 返回 81 |
82 |
83 |
84 |
85 |
86 |
87 | 88 | 134 | -------------------------------------------------------------------------------- /src/main/java/pers/corvey/exam/controller/common/BaseControllerImpl.java: -------------------------------------------------------------------------------- 1 | package pers.corvey.exam.controller.common; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | 9 | import org.springframework.ui.Model; 10 | import org.springframework.web.bind.annotation.ModelAttribute; 11 | import org.springframework.web.bind.annotation.RequestParam; 12 | 13 | import pers.corvey.exam.entity.common.BaseEntity; 14 | import pers.corvey.exam.entity.ui.CallBackMessage; 15 | import pers.corvey.exam.service.common.BaseService; 16 | import pers.corvey.exam.util.CurrentUtils; 17 | 18 | public abstract class BaseControllerImpl, ID extends Serializable> 19 | implements BaseController { 20 | 21 | /** 22 | * 实体类在request中的属性名 23 | */ 24 | protected static final String ENTITY_ATTRIBUTE_NAME = "entity"; 25 | 26 | protected static final String ENTITIES_ATTRIBUTE_NAME = "entities"; 27 | 28 | /** 29 | * 管理模板页面名 30 | */ 31 | protected static final String MANAGER_VIEW_NAME = "manager-templet"; 32 | 33 | /** 34 | * 管理模块在request中的属性名 35 | */ 36 | protected static final String MANAGER_ATTRIBUTE_NAME = "contentJSP"; 37 | 38 | /** 39 | * 需要实体的url后缀 40 | */ 41 | protected final List needEntityURLSuffix; 42 | 43 | protected final BaseService mainService; 44 | protected final String inputViewName; 45 | protected final String listViewName; 46 | 47 | /** 48 | * 为父类的几个属性初始化 49 | * @param mainService 该controller主要用到的service 50 | * @param inputViewName input页面的视图名称 51 | * @param listViewName list页面的视图名称 52 | */ 53 | public BaseControllerImpl(BaseService mainService, 54 | String inputViewName, String listViewName) { 55 | this.mainService = mainService; 56 | this.inputViewName = inputViewName; 57 | this.listViewName = listViewName; 58 | 59 | needEntityURLSuffix = new ArrayList<>(); 60 | needEntityURLSuffix.add(SAVE_PATH); 61 | needEntityURLSuffix.add(DETAIL_PATH); 62 | needEntityURLSuffix.add(INPUT_PATH); 63 | } 64 | 65 | @Override 66 | public String showListView(Model model) { 67 | return baseShowListView(model, mainService.findAll()); 68 | } 69 | 70 | @Override 71 | public String showDetailView(Model model, 72 | @ModelAttribute(ENTITY_ATTRIBUTE_NAME) T entity) { 73 | 74 | model.addAttribute(MANAGER_ATTRIBUTE_NAME, inputViewName); 75 | return MANAGER_VIEW_NAME; 76 | } 77 | 78 | @Override 79 | public String showInputView(Model model, 80 | @ModelAttribute(ENTITY_ATTRIBUTE_NAME) T entity) { 81 | 82 | model.addAttribute(MANAGER_ATTRIBUTE_NAME, inputViewName); 83 | return MANAGER_VIEW_NAME; 84 | } 85 | 86 | @Override 87 | public String deleteById(ID id) { 88 | CallBackMessage msg = CallBackMessage.createMsgAfterFunction( 89 | () -> mainService.delete(id), "删除成功!", "删除失败"); 90 | CurrentUtils.addAttributeToSession(CallBackMessage.MESSAGE_ATTRIBUTE_NAME, msg); 91 | return redirect(LIST_PATH); 92 | } 93 | 94 | protected String baseSave(T entity) { 95 | // 若id为空,则为新增操作,否则为修改操作 96 | String optionName = entity.getId() == null ? "新增" : "修改"; 97 | CallBackMessage msg = CallBackMessage.createMsgAfterFunction( 98 | () -> mainService.save(entity), optionName + "成功!", optionName + "失败"); 99 | CurrentUtils.addAttributeToSession(CallBackMessage.MESSAGE_ATTRIBUTE_NAME, msg); 100 | return redirect(LIST_PATH); 101 | } 102 | 103 | /** 104 | * 针对需要entity的页面,通过id放入对应的entity 105 | * @param request 106 | * @param id 107 | */ 108 | @ModelAttribute 109 | protected void addEntityToRequest(HttpServletRequest request, Model model, 110 | @RequestParam(name="id", required=false) ID id) { 111 | 112 | String servletPath = request.getServletPath(); 113 | if (isNeedEntity(servletPath)) { 114 | T entity = null; 115 | if (id != null) { 116 | entity = mainService.findByID(id); 117 | } 118 | if (entity == null) { 119 | entity = mainService.createEntity(); 120 | } 121 | model.addAttribute(ENTITY_ATTRIBUTE_NAME, entity); 122 | } 123 | } 124 | 125 | protected String baseShowListView(Model model, Iterable entities) { 126 | model.addAttribute(ENTITIES_ATTRIBUTE_NAME, entities); 127 | model.addAttribute(MANAGER_ATTRIBUTE_NAME, listViewName); 128 | return MANAGER_VIEW_NAME; 129 | } 130 | 131 | /** 132 | * 跳转地址(仅支持最后一级目录跳转) 133 | * @param path 134 | * @return 135 | */ 136 | protected static String redirect(String path) { 137 | return "redirect:" + path.replaceFirst("^[/]+", ""); 138 | } 139 | 140 | /** 141 | * 该请求地址是否需要entity 142 | * @param servletPath 请求地址 143 | * @return 144 | */ 145 | private boolean isNeedEntity(String servletPath) { 146 | if (servletPath != null) { 147 | for (String suffix : needEntityURLSuffix) { 148 | if (servletPath.endsWith(suffix)) { 149 | return true; 150 | } 151 | } 152 | } 153 | return false; 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/views/resource-all.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 | <%@include file="/common/taglibs.jsp"%> 3 | 4 | 5 | 6 | <%@include file="/common/head.jsp"%> 7 | 8 | 9 | 10 | <%@include file="/common/header.jsp"%> 11 |
12 |
13 |
14 |
15 |
16 |

17 |  所有资源 18 |

19 |
20 |
21 | <%@include file="/common/show-message.jsp"%> 22 |
23 |
24 | 26 | 27 |
28 |
29 | 31 |
32 | 33 |
34 |
35 |
36 |
37 |
38 | 39 | 40 |
41 |
42 |

43 | ${resource.name} 44 |

45 |
46 |
47 |

${resource.description}

48 |

49 | 上传日期: 51 |   52 | 下载次数:${resource.downloadTimes} 53 |

54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | 114 | 115 | 123 | --------------------------------------------------------------------------------