基于javaweb+mysql的springboot在线考试平台(java+springboot+ssm+mysql+maven+thymeleaf+html+redis)
运行环境
Java≥8、MySQL≥5.7
开发工具
eclipse/idea/myeclipse/sts等均可配置运行
适用
课程设计,大作业,毕业设计,项目练习,学习演示等
功能说明
基于javaweb+mysql的SpringBoot在线考试平台(java+springboot+ssm+mysql+maven+thymeleaf+html+redis)
一、项目简述
功能列表 考试前台 /系统登录:学生、教师、管理员登录 /门户首页:无需认证访问 /在线考试:需认证即可查看当前考除目 /题库中心:需认证查看题库 /成绩查询:需认证查询成绩 /留言板:需认证留言 管理后台 /考:署理:发布考试,考试列表,课程管理,题库管 理,成绩管理,成绩情况 /权限管理:学院管理,班级管理,用户管理,角色管 理,资源管理 4网站管理:基础信息,友链管理,评论管理,标签管理 /系统管理:在线用户 /上传管理:云存储配置 /运维管理:数据监控
二、项目运行
环境配置: Jdk1.8 + Tomcat8.5 + mysql + Eclispe (IntelliJ IDEA,Eclispe,MyEclispe,Sts 都支持)
项目技术: JSP +SpringBoot + MyBatis + Redis+ Thymeleaf+ Druid+ JQuery + SLF4J+ Fileupload + maven等等
@Controller
@RequestMapping("/permission")
public class PermissionController{
private static final Logger logger = LoggerFactory.getLogger(PermissionController.class);
/**1:全部资源,2:菜单资源*/
private static final String[] MENU_FLAG ={"1","2"};
@Autowired
private PermissionService permissionService;
@Autowired
private ShiroService shiroService;
/*权限列表数据*/
@PostMapping("/list")
@ResponseBody
public List<Permission> loadPermissions(String flag){
List<Permission> permissionListList = new ArrayList<Permission>();
if(StringUtils.isBlank(flag) || MENU_FLAG[0].equals(flag)){
permissionListList = permissionService.selectAll(CoreConst.STATUS_VALID);
}else if(MENU_FLAG[1].equals(flag)){
permissionListList = permissionService.selectAllMenuName(CoreConst.STATUS_VALID);
}
return permissionListList;
}
/*添加权限*/
@ResponseBody
@PostMapping("/add")
public ResponseVo addPermission(Permission permission){
try {
int a = permissionService.insert(permission);
if (a > 0) {
shiroService.updatePermission();
return ResultUtil.success("添加权限成功");
@Controller
public class RenderController {
@Autowired
private QuestionService questionService;
@Autowired
private UserService userService;
@Autowired
private SubjectService subjectService;
@Autowired
private InstituteService instituteService;
@Autowired
private CommentService commentService;
@Autowired
private ClassesService classesService;
@Autowired
private ExaminationService examService;
/*工作台*/
@GetMapping("/workdest")
public String workdest(Model model){
examService.updateExamToStart();
examService.updateExamToEnd();
int questionNums = questionService.totalNum();
int userNums = userService.userNums();
int subjectNums = subjectService.totalNum();
int commentNums = commentService.totalNum(CoreConst.STATUS_INVALID);
model.addAttribute("questionNums", questionNums);
model.addAttribute("userNums", userNums);
model.addAttribute("subjectNums", subjectNums);
@Controller
public class RenderController {
@Autowired
private QuestionService questionService;
@Autowired
private UserService userService;
@Autowired
private SubjectService subjectService;
@Autowired
private InstituteService instituteService;
@Autowired
private CommentService commentService;
@Autowired
private ClassesService classesService;
@Autowired
private ExaminationService examService;
/*工作台*/
@GetMapping("/workdest")
public String workdest(Model model){
examService.updateExamToStart();
examService.updateExamToEnd();
int questionNums = questionService.totalNum();
int userNums = userService.userNums();
int subjectNums = subjectService.totalNum();
int commentNums = commentService.totalNum(CoreConst.STATUS_INVALID);
model.addAttribute("questionNums", questionNums);
model.addAttribute("userNums", userNums);
model.addAttribute("subjectNums", subjectNums);
model.addAttribute("commentNums", commentNums);
return "manager/workdest";
}
/**用户列表入口*/
@GetMapping("/users")
public String userList(Model model){
List<Institute> institutes = instituteService.selectAll();
public String data(Model model) {
List<Examination> examList = examService.selectAllByStatus(CoreConst.STATUS_INVALID);
List<String> grades = userService.selectGradeList();
List<Institute> institutes = instituteService.selectAll();
List<Classes> classes = classesService.selectAll();
List<Subject> subjects = subjectService.selectAll();
model.addAttribute("exams", examList);
model.addAttribute("grades", grades);
model.addAttribute("institutes", institutes);
model.addAttribute("classes", classes);
model.addAttribute("subjects", subjects);
return "statistics/list";
}
/*评论*/
@GetMapping("/comments")
public String comments(){
return "comment/list";
}
}
package com.exam.controller;
List<Integer> questionIds = new ArrayList<>();
for(ExamQuestion examQuestion : examQuestions) {
questionIds.add(examQuestion.getQuestionId());
}
model.addAttribute("questionIds", questionIds);
return "exam/detail";
}
@PostMapping("/edit")
@ResponseBody
public ResponseVo edit(Examination examination, Integer[]question) {
examination.setStatus(0);
examService.updateNotNull(examination);
examQuestionService.removeByExamId(examination.getId());
examQuestionService.insertList(examination.getId(),question);
return ResultUtil.success("编辑考试成功");
}
@PostMapping("/delete")
@ResponseBody
public ResponseVo delete(Integer id) {
int i = examService.deleteBatch(new Integer[] {id});
int j = examQuestionService.deleteBatch(new Integer[] {id});
if(i > 0 && j > 0) {
return ResultUtil.success("删除考试成功");
}else {
return ResultUtil.error("删除考试失败");
}
}
@PostMapping("/batch/delete")
@ResponseBody
public ResponseVo deleteBatch(@RequestParam("ids[]") Integer[] ids) {
int i = examService.deleteBatch(ids);
int j = examQuestionService.deleteBatch(ids);
if(i > 0 && j > 0) {
return ResultUtil.success("批量删除成功");
}else {
return ResultUtil.error("批量删除失败");
}
}
}
package com.exam.controller;
String dir =cloudStorageConfig.getQiniuPrefix();
String md5 = MD5.getMessageDigest(file.getBytes());
String filePath = String.format("%1$s/%2$s%3$s", dir, md5, suffix);
ResponseVo responseVo = QiNiuYunUtil.writeFile(cloudStorageConfig,filePath,file.getBytes());
String qiniuDomain = cloudStorageConfig.getQiniuDomain();
String url = String.format("%1$s/%2$s", qiniuDomain, filePath);
if(responseVo.getStatus().equals(CoreConst.SUCCESS_CODE)){
Map<String, Object> resultMap = new HashMap<>(3);
resultMap.put("success", 1);
resultMap.put("message", "上传成功");
resultMap.put("filename", url);
return resultMap;
}else{
return new UploadResponse(originalFilename, CoreConst.FAIL_CODE, responseVo.getMsg());
}
} catch (Exception e) {
logger.error(String.format("UploadController.upload%s", e));
throw e;
}
}
@GetMapping(value = "/config")
public String config(Model model){
String value = sysConfigService.selectAll().get(SysConfigKey.CLOUD_STORAGE_CONFIG.getValue());
Gson gson = new Gson();
CloudStorageConfigVo cloudStorageConfig = gson.fromJson(value,CloudStorageConfigVo.class);
model.addAttribute("cloudStorageConfig",cloudStorageConfig);
return "upload/config";
}
@ResponseBody
@PostMapping(value = "/saveConfig")
public ResponseVo saveConfig(CloudStorageConfigVo cloudStorageConfig){
Gson gson = new Gson();
String value = gson.toJson(cloudStorageConfig);
int a = sysConfigService.updateByKey(SysConfigKey.CLOUD_STORAGE_CONFIG.getValue(),value);
if (a > 0) {
return ResultUtil.success("云存储配置保存成功!");
} else {
return ResultUtil.error("云存储配置保存失败!");
}
}
@Controller
@RequestMapping("/upload")
public class UploadController{
private static final Logger logger = LoggerFactory.getLogger(UploadController.class);
@Autowired
private SysConfigService sysConfigService;
@Autowired
private QuestionService questionService;
@Autowired
private UserService userService;
//腾讯云对象存储
@ResponseBody
@PostMapping(value = "/upload")
public UploadResponse upload(@RequestParam(value = "file", required = false) MultipartFile file) throws Exception {
if(file == null || file.isEmpty()) {
throw new UploadFileNotFoundException(UploadResponse.Error.FILENOTFOUND);
}
try {
String originalFileName = file.getOriginalFilename();
String suffix = originalFileName.substring(originalFileName.lastIndexOf(".")).toLowerCase();
String value = sysConfigService.selectAll().get(SysConfigKey.CLOUD_STORAGE_CONFIG.getValue());
Gson gson = new Gson();
CloudStorageConfigVo cloudStorageConfig = gson.fromJson(value, CloudStorageConfigVo.class);
String dir = cloudStorageConfig.getQcloudPrefix();
String md5 = MD5.getMessageDigest(file.getBytes());
String filePath = String.format("%1$s/%2$s%3$s", dir, md5, suffix);
ResponseVo responseVo = QCloudUtil.writeFile(cloudStorageConfig, filePath, file);
String qCloudDomain = cloudStorageConfig.getQcloudDomain();
String url = String.format("%1$s/%2$s", qCloudDomain, filePath);
if(responseVo.getStatus().equals(CoreConst.SUCCESS_CODE)){
return new UploadResponse(url,originalFileName, suffix, url, CoreConst.SUCCESS_CODE);
}else{
return new UploadResponse(originalFileName, CoreConst.FAIL_CODE,responseVo.getMsg());
}
} catch (Exception e) {
logger.error(String.format("UploadController.upload%s", e));
throw e;
}
}
//上传到七牛云图床
/*@ResponseBody
@PostMapping(value = "/upload")
public UploadResponse upload(@RequestParam(value = "file", required = false) MultipartFile file) throws Exception{
if (file == null || file.isEmpty()) {
classes.setCreateTime(date);
classes.setUpdateTime(date);
classes.setStatus(CoreConst.STATUS_INVALID);
int i = classesService.insert(classes);
if(i > 0) {
return ResultUtil.success("新增班级信息成功");
}else {
return ResultUtil.error("新增班级信息失败");
}
}
/**
* 更新班级信息
* @param model
* @param id
* @return
*/
@GetMapping("/edit")
public String edit(Model model,Integer id) {
Classes classes = classesService.selectById(id);
List<Institute> institutes = instituteService.selectAll();
model.addAttribute("institutes",institutes);
model.addAttribute("classes", classes);
return "classes/detail";
}
@PostMapping("/edit")
@ResponseBody
public ResponseVo edit(Classes classes) {
int i = classesService.updateNotNull(classes);
if(i > 0) {
return ResultUtil.success("更新班级信息成功");
}else {
return ResultUtil.error("更新班级信息失败");
}
}
/**
* 删除班级信息
* @param id
* @return
private SubjectService subjectService;
@PostMapping("list")
@ResponseBody
public PageResultVo loadQuestion(QuestionConditionVo questionConditionVo, Integer limit, Integer offset) {
PageHelper.startPage(PageUtil.getPageNo(limit, offset),limit);
List<Question> questionList = questionService.findByCondition(questionConditionVo);
PageInfo<Question> pages = new PageInfo<>(questionList);
return ResultUtil.table(questionList, pages.getTotal(),pages);
}
//添加题目
@GetMapping("/add")
public String addQuestion(Model model) {
Subject subject = new Subject();
subject.setStatus(CoreConst.STATUS_INVALID);
List<Subject> subjects = subjectService.selectSubjects(subject);
model.addAttribute("subjects", JSON.toJSONString(subjects));
return "question/add";
}
@PostMapping("/add")
@ResponseBody
public ResponseVo add(Question question) {
try {
question.setStatus(CoreConst.STATUS_INVALID);
Question questions = questionService.insertQuestion(question);
return ResultUtil.success("新增题目成功!");
} catch (Exception e) {
return ResultUtil.error("新增题目失败!");
}
}
@GetMapping("/edit")
public String edit(Model model, Integer id) {
Question question = questionService.selectById(id);
model.addAttribute("question", question);
Subject subject = new Subject();
subject.setStatus(CoreConst.STATUS_INVALID);
List<Subject> subjects = subjectService.selectSubjects(subject);
model.addAttribute("subjects", JSON.toJSONString(subjects));
return "question/detail";
}
}else {
int j = classesService.deleteBatch(ids);
if(j > 0) {
return ResultUtil.success("批量删除班级信息成功");
}else {
return ResultUtil.error("批量删除班级信息失败");
}
}
}
}
package com.exam.controller;
@RestController
@RequestMapping("comment")
public class CommentController {
@Autowired
private CommentService commentService;
model.addAttribute("classes", classes);
model.addAttribute("grades", grades);
return "user/userDetail";
}
/**编辑用户*/
@PostMapping("/edit")
@ResponseBody
public ResponseVo editUser(User userFrom){
int a = userService.updateByUserId(userFrom);
if (a > 0) {
return ResultUtil.success("编辑用户成功!");
} else {
return ResultUtil.error("编辑用户失败");
}
}
/**
* 禁用用户
* @param userId
* @return
*/
@PostMapping("/ban")
@ResponseBody
public ResponseVo banUser(String userId) {
List<String> userIdsList = Arrays.asList(userId);
int a = userService.updateStatusBatch(userIdsList,CoreConst.STATUS_INVALID);
if(a > 0) {
return ResultUtil.success("禁用用户成功");
}else {
return ResultUtil.error("禁用用户失败");
}
}
/**批量禁用用户*/
@PostMapping("/batch/ban")
@ResponseBody
public ResponseVo batchBanUser(String userIdStr) {
String[] userIds = userIdStr.split(",");
List<String> userIdsList = Arrays.asList(userIds);
int a = userService.updateStatusBatch(userIdsList,CoreConst.STATUS_INVALID);
if (a > 0) {
return ResultUtil.success("批量禁用用户成功");
} else {
return ResultUtil.error("批量禁用用户失败");
}
} catch (Exception e) {
logger.error(String.format("UploadController.upload%s", e));
throw e;
}
}
@ResponseBody
@PostMapping(value = "/importUserExcel")
public UploadResponse importUserExcel(@RequestParam(value = "file", required = false) MultipartFile file) throws IOException {
if (file == null || file.isEmpty()) {
throw new UploadFileNotFoundException(UploadResponse.Error.FILENOTFOUND);
}
try {
ResponseVo responseVo = userService.importUserExcel(file);
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
String md5 = MD5.getMessageDigest(file.getBytes());
String url = String.format("%1$s/%2$s", md5, suffix);
if(responseVo.getStatus().equals(CoreConst.SUCCESS_CODE)){
return new UploadResponse(originalFilename, suffix, url, CoreConst.SUCCESS_CODE, responseVo.getMsg());
}else {
return new UploadResponse(originalFilename, CoreConst.FAIL_CODE,responseVo.getMsg());
}
} catch (Exception e) {
logger.error(String.format("UploadController.upload%s", e));
throw e;
}
}
@ResponseBody
@PostMapping("/upload2QiniuForMd")
public Object upload2QiniuForMd(@RequestParam("file") MultipartFile file) throws IOException {
if (file == null || file.isEmpty()) {
throw new UploadFileNotFoundException(UploadResponse.Error.FILENOTFOUND);
}
try {
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
String value = sysConfigService.selectAll().get(SysConfigKey.CLOUD_STORAGE_CONFIG.getValue());
Gson gson = new Gson();
CloudStorageConfigVo cloudStorageConfig = gson.fromJson(value,CloudStorageConfigVo.class);
String dir =cloudStorageConfig.getQiniuPrefix();
String md5 = MD5.getMessageDigest(file.getBytes());
String filePath = String.format("%1$s/%2$s%3$s", dir, md5, suffix);
ResponseVo responseVo = QiNiuYunUtil.writeFile(cloudStorageConfig,filePath,file.getBytes());
String qiniuDomain = cloudStorageConfig.getQiniuDomain();
String url = String.format("%1$s/%2$s", qiniuDomain, filePath);
if(responseVo.getStatus().equals(CoreConst.SUCCESS_CODE)){
/**新增用户*/
@PostMapping("/add")
@ResponseBody
public ResponseVo add(User userForm, String confirmPassword, Integer passwordType){
String username = userForm.getUsername();
User user = userService.selectByUsername(username);
if (null != user) {
return ResultUtil.error("该学号已存在");
}
if(passwordType == 0) {
String password = userForm.getPassword();
//判断两次输入密码是否相等
if (confirmPassword != null && password != null) {
if (!confirmPassword.equals(password)) {
return ResultUtil.error("两次密码不一致");
}
}
}else {
userForm.setPassword(CoreConst.DEFAULT_PASSWORD);
}
userForm.setUserId(UUIDUtil.getUniqueIdByUUId());
userForm.setImg(CoreConst.DEFAULT_IMG);
userForm.setStatus(CoreConst.STATUS_VALID);
Date date = new Date();
userForm.setCreateTime(date);
userForm.setUpdateTime(date);
userForm.setLastLoginTime(date);
PasswordHelper.encryptPassword(userForm);
int num = userService.register(userForm);
if(num > 0){
return ResultUtil.success("添加用户成功");
}else {
return ResultUtil.error("添加用户失败");
}
}
/**编辑用户详情*/
@GetMapping("/edit")
public String userDetail(Model model, String userId){
User user = userService.selectByUserId(userId);
List<Classes> classes = classesService.selectAll();
List<String> grades = userService.selectGradeList();
model.addAttribute("user", user);
model.addAttribute("classes", classes);
@ResponseBody
public ResponseVo edit(Examination examination, Integer[]question) {
examination.setStatus(0);
examService.updateNotNull(examination);
examQuestionService.removeByExamId(examination.getId());
examQuestionService.insertList(examination.getId(),question);
return ResultUtil.success("编辑考试成功");
}
@PostMapping("/delete")
@ResponseBody
public ResponseVo delete(Integer id) {
int i = examService.deleteBatch(new Integer[] {id});
int j = examQuestionService.deleteBatch(new Integer[] {id});
if(i > 0 && j > 0) {
return ResultUtil.success("删除考试成功");
}else {
return ResultUtil.error("删除考试失败");
}
}
@PostMapping("/batch/delete")
@ResponseBody
public ResponseVo deleteBatch(@RequestParam("ids[]") Integer[] ids) {
int i = examService.deleteBatch(ids);
int j = examQuestionService.deleteBatch(ids);
if(i > 0 && j > 0) {
return ResultUtil.success("批量删除成功");
}else {
return ResultUtil.error("批量删除失败");
}
}
}
package com.exam.controller;
@Controller
@RequestMapping("question")
public class QuestionController {
@Autowired
private QuestionService questionService;
@Autowired
private SubjectService subjectService;
@PostMapping("list")
@ResponseBody
public PageResultVo loadQuestion(QuestionConditionVo questionConditionVo, Integer limit, Integer offset) {
PageHelper.startPage(PageUtil.getPageNo(limit, offset),limit);
List<Question> questionList = questionService.findByCondition(questionConditionVo);
PageInfo<Question> pages = new PageInfo<>(questionList);
return ResultUtil.table(questionList, pages.getTotal(),pages);
}
//添加题目
@GetMapping("/add")
public String addQuestion(Model model) {
Subject subject = new Subject();
subject.setStatus(CoreConst.STATUS_INVALID);
List<Subject> subjects = subjectService.selectSubjects(subject);
model.addAttribute("subjects", JSON.toJSONString(subjects));
return "question/add";
}
@PostMapping("/add")
@ResponseBody
@Controller
@RequestMapping("/online/user")
public class OnlineUserController {
@Autowired
private UserService userService;
// 在线用户列表
@PostMapping("/list")
@ResponseBody
public PageResultVo onlineUsers(UserOnlineVo user, Integer limit, Integer offset){
List<UserOnlineVo> userList = userService.selectOnlineUsers(user);
PageInfo<UserOnlineVo> pages = new PageInfo<>(userList);
int endIndex = (offset+limit) > userList.size() ? userList.size() : (offset+limit);
return ResultUtil.table(userList.subList(offset,endIndex),(long)userList.size(),pages);
}
// 强制踢出用户
@PostMapping("/kickout")
@ResponseBody
public ResponseVo kickout(String sessionId,String username) {
try {
if(SecurityUtils.getSubject().getSession().getId().equals(sessionId)){
return ResultUtil.error("不能踢出自己");
}
userService.kickout(sessionId,username);
return ResultUtil.success("踢出用户成功");
} catch (Exception e) {
return ResultUtil.error("踢出用户失败");
}
}
// 批量强制踢出用户
@PostMapping("/batch/kickout")
@ResponseBody
public ResponseVo kickout(@RequestBody List<UserSessionVo> sessions) {
try {
//要踢出的用户中是否有自己
boolean hasOwn=false;
Serializable sessionId = SecurityUtils.getSubject().getSession().getId();
for (UserSessionVo sessionVo : sessions) {
if(sessionVo.getSessionId().equals(sessionId)){
hasOwn=true;
}else{
userService.kickout(sessionVo.getSessionId(),sessionVo.getUsername());
}
}
if(hasOwn){
return ResultUtil.success("不能踢出自己");
}
if(responseVo.getStatus().equals(CoreConst.SUCCESS_CODE)){
Map<String, Object> resultMap = new HashMap<>(3);
resultMap.put("success", 1);
resultMap.put("message", "上传成功");
resultMap.put("filename", url);
return resultMap;
}else{
return new UploadResponse(originalFilename, CoreConst.FAIL_CODE, responseVo.getMsg());
}
} catch (Exception e) {
logger.error(String.format("UploadController.upload%s", e));
throw e;
}
}
@GetMapping(value = "/config")
public String config(Model model){
String value = sysConfigService.selectAll().get(SysConfigKey.CLOUD_STORAGE_CONFIG.getValue());
Gson gson = new Gson();
CloudStorageConfigVo cloudStorageConfig = gson.fromJson(value,CloudStorageConfigVo.class);
model.addAttribute("cloudStorageConfig",cloudStorageConfig);
return "upload/config";
}
@ResponseBody
@PostMapping(value = "/saveConfig")
public ResponseVo saveConfig(CloudStorageConfigVo cloudStorageConfig){
Gson gson = new Gson();
String value = gson.toJson(cloudStorageConfig);
int a = sysConfigService.updateByKey(SysConfigKey.CLOUD_STORAGE_CONFIG.getValue(),value);
if (a > 0) {
return ResultUtil.success("云存储配置保存成功!");
} else {
return ResultUtil.error("云存储配置保存失败!");
}
}
}
package com.exam.controller;
List<Classes> classesList = classesService.findByCondition(classesConditionVo);
PageInfo<Classes> pages = new PageInfo<>(classesList);
return ResultUtil.table(classesList, pages.getTotal(), pages);
}
/**
* 新增班级
* @param classes
* @return
*/
@PostMapping("/add")
@ResponseBody
public ResponseVo add(Classes classes) {
User user = (User)SecurityUtils.getSubject().getPrincipal();
classes.setAuthor(user.getNickname());
Date date = new Date();
classes.setCreateTime(date);
classes.setUpdateTime(date);
classes.setStatus(CoreConst.STATUS_INVALID);
int i = classesService.insert(classes);
if(i > 0) {
return ResultUtil.success("新增班级信息成功");
}else {
return ResultUtil.error("新增班级信息失败");
}
}
/**
* 更新班级信息
* @param model
* @param id
* @return
*/
@GetMapping("/edit")
public String edit(Model model,Integer id) {
Classes classes = classesService.selectById(id);
List<Institute> institutes = instituteService.selectAll();
model.addAttribute("institutes",institutes);
model.addAttribute("classes", classes);
return "classes/detail";
}
/*修改密码*/
@RequestMapping(value = "/changePassword",method = RequestMethod.POST)
@ResponseBody
public ResponseVo changePassword(ChangePasswordVo changePasswordVo) {
if(!changePasswordVo.getNewPassword().equals(changePasswordVo.getConfirmNewPassword())){
return ResultUtil.error("两次密码输入不一致");
}
User loginUser = userService.selectByUserId(((User) SecurityUtils.getSubject().getPrincipal()).getUserId());
User newUser = CopyUtil.getCopy(loginUser,User.class);
String sysOldPassword = loginUser.getPassword();
newUser.setPassword(changePasswordVo.getOldPassword());
String entryOldPassword = PasswordHelper.getPassword(newUser);
if(sysOldPassword.equals(entryOldPassword)){
newUser.setPassword(changePasswordVo.getNewPassword());
PasswordHelper.encryptPassword(newUser);
userService.updateUserByPrimaryKey(newUser);
//*清除登录缓存*//
List<String> userIds = new ArrayList<>();
userIds.add(loginUser.getUserId());
shiroRealm.removeCachedAuthenticationInfo(userIds);
/*SecurityUtils.getSubject().logout();*/
}else{
return ResultUtil.error("您输入的旧密码有误");
}
return ResultUtil.success("修改密码成功");
}
}
package com.exam.controller;
Question questions = questionService.insertQuestion(question);
return ResultUtil.success("新增题目成功!");
} catch (Exception e) {
return ResultUtil.error("新增题目失败!");
}
}
@GetMapping("/edit")
public String edit(Model model, Integer id) {
Question question = questionService.selectById(id);
model.addAttribute("question", question);
Subject subject = new Subject();
subject.setStatus(CoreConst.STATUS_INVALID);
List<Subject> subjects = subjectService.selectSubjects(subject);
model.addAttribute("subjects", JSON.toJSONString(subjects));
return "question/detail";
}
@PostMapping("/edit")
@ResponseBody
public ResponseVo edit(Question question) {
question.setStatus(CoreConst.STATUS_INVALID);
questionService.updateNotNull(question);
return ResultUtil.success("编辑题目成功");
}
/**
* 删除
* @param id
* @return
*/
@PostMapping("/delete")
@ResponseBody
public ResponseVo delete(Integer id) {
int i = questionService.deleteBatch(new Integer[]{id});
if(i > 0) {
return ResultUtil.success("删除题目成功");
}else {
return ResultUtil.error("删除题目失败");
}
}
/**
* 批量删除
* @param ids
* @return
*/
@PostMapping("/batch/delete")
@ResponseBody
public ResponseVo deleteBatch(@RequestParam("ids[]") Integer[]ids) {
int i = questionService.deleteBatch(ids);
if(i > 0) {
return ResultUtil.success("批量删除题目成功");
}else {
return ResultUtil.error("批量删除题目失败");
saveRequest(request);
Map<String, String> resultMap = new HashMap<String, String>();
//判断是不是Ajax请求
if ("XMLHttpRequest".equalsIgnoreCase(((HttpServletRequest) request).getHeader("X-Requested-With"))) {
resultMap.put("user_status", "300");
resultMap.put("message", "您已经在其他地方登录,请重新登录!");
//输出json串
out(response, resultMap);
}else{
//重定向
WebUtils.issueRedirect(request, response, kickoutUrl);
}
return false;
}
return true;
}
private void out(ServletResponse hresponse, Map<String, String> resultMap)
throws IOException {
try {
hresponse.setCharacterEncoding("UTF-8");
PrintWriter out = hresponse.getWriter();
out.println(JSON.toJSONString(resultMap));
out.flush();
out.close();
} catch (Exception e) {
System.err.println("KickoutSessionFilter.class 输出JSON异常,可以忽略。");
}
}
}
package com.exam.controller;
/*登陆*/
@GetMapping("/login")
public String login(Model model){
if(SecurityUtils.getSubject().isAuthenticated()){
return "redirect:/";
}
return "system/login";
}
/*提交登录*/
@PostMapping("/login")
@ResponseBody
public ResponseVo login(HttpServletRequest request, String username, String password, String verification,
@RequestParam(value = "rememberMe", defaultValue = "0") Integer rememberMe){
//判断验证码
String rightCode = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
if (StringUtils.isNotBlank(verification) && StringUtils.isNotBlank(rightCode) && verification.equals(rightCode)) {
//验证码通过
} else {
return ResultUtil.error("验证码错误!");
}
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try{
token.setRememberMe(1 == rememberMe);
Subject subject = SecurityUtils.getSubject();
subject.login(token);
} catch (LockedAccountException e) {
token.clear();
return ResultUtil.error("用户已经被锁定不能登录,请联系管理员!");
} catch (AuthenticationException e) {
token.clear();
return ResultUtil.error("用户名或者密码错误!");
}
//更新最后登录时间
userService.updateLastLoginTime((User) SecurityUtils.getSubject().getPrincipal());
return ResultUtil.success("登录成功!");
}
/*登出*/
@RequestMapping(value = "/logout")
@ResponseBody
public ResponseVo logout() {
Subject subject = SecurityUtils.getSubject();
if(null!=subject){
String username = ((User) SecurityUtils.getSubject().getPrincipal()).getUsername();
@Controller
public class ExamWebController {
@Autowired
private ExaminationService examService;
@Autowired
private GradeService gradeService;
@Autowired
private QuestionService questionService;
@Autowired
private SubjectService subjectService;
@Autowired
private CommentService commentService;
@Autowired
private LoveService loveService;
@Autowired
private UserService userService;
@Autowired
private ClassesService classesService;
@Autowired
private ShiroRealm shiroRealm;
/**
* 考试界面
* @param model
* @param examConditionVo
* @return
*/
@GetMapping("/exam/examination")
public String toExam() {
if(SecurityUtils.getSubject().isAuthenticated()) {
return "index/examination";
}else {
@Autowired
private QuestionService questionService;
@Autowired
private UserService userService;
@Autowired
private SubjectService subjectService;
@Autowired
private InstituteService instituteService;
@Autowired
private CommentService commentService;
@Autowired
private ClassesService classesService;
@Autowired
private ExaminationService examService;
/*工作台*/
@GetMapping("/workdest")
public String workdest(Model model){
examService.updateExamToStart();
examService.updateExamToEnd();
int questionNums = questionService.totalNum();
int userNums = userService.userNums();
int subjectNums = subjectService.totalNum();
int commentNums = commentService.totalNum(CoreConst.STATUS_INVALID);
model.addAttribute("questionNums", questionNums);
model.addAttribute("userNums", userNums);
model.addAttribute("subjectNums", subjectNums);
model.addAttribute("commentNums", commentNums);
return "manager/workdest";
}
/**用户列表入口*/
@GetMapping("/users")
public String userList(Model model){
List<Institute> institutes = instituteService.selectAll();
List<Classes> classes = classesService.selectAll();
List<String> grades = userService.selectGradeList();
model.addAttribute("institutes",institutes);
model.addAttribute("classes", classes);
model.addAttribute("grades", grades);
return "user/list";
}
/*角色列表入口*/
//判断是不是Ajax请求
if ("XMLHttpRequest".equalsIgnoreCase(((HttpServletRequest) request).getHeader("X-Requested-With"))) {
resultMap.put("user_status", "300");
resultMap.put("message", "您已经在其他地方登录,请重新登录!");
//输出json串
out(response, resultMap);
}else{
//重定向
WebUtils.issueRedirect(request, response, kickoutUrl);
}
return false;
}
return true;
}
private void out(ServletResponse hresponse, Map<String, String> resultMap)
throws IOException {
try {
hresponse.setCharacterEncoding("UTF-8");
PrintWriter out = hresponse.getWriter();
out.println(JSON.toJSONString(resultMap));
out.flush();
out.close();
} catch (Exception e) {
System.err.println("KickoutSessionFilter.class 输出JSON异常,可以忽略。");
}
}
}
package com.exam.controller;
Session kickoutSession = sessionManager.getSession(new DefaultSessionKey(kickoutSessionId));
if(kickoutSession != null) {
//设置会话的kickout属性表示踢出了
kickoutSession.setAttribute("kickout", true);
}
} catch (Exception e) {//ignore exception
}
}
//如果被踢出了,直接退出,重定向到踢出后的地址
if ((Boolean)session.getAttribute("kickout")!=null&&(Boolean)session.getAttribute("kickout") == true) {
//会话被踢出了
try {
//退出登录
subject.logout();
} catch (Exception e) { //ignore
}
saveRequest(request);
Map<String, String> resultMap = new HashMap<String, String>();
//判断是不是Ajax请求
if ("XMLHttpRequest".equalsIgnoreCase(((HttpServletRequest) request).getHeader("X-Requested-With"))) {
resultMap.put("user_status", "300");
resultMap.put("message", "您已经在其他地方登录,请重新登录!");
//输出json串
out(response, resultMap);
}else{
//重定向
WebUtils.issueRedirect(request, response, kickoutUrl);
}
return false;
}
return true;
}
private void out(ServletResponse hresponse, Map<String, String> resultMap)
throws IOException {
try {
hresponse.setCharacterEncoding("UTF-8");
PrintWriter out = hresponse.getWriter();
out.println(JSON.toJSONString(resultMap));
out.flush();
out.close();