• Java项目:ssm在线答题系统


    作者主页:夜未央5788

     简介:Java领域优质创作者、Java项目、学习资料、技术互助

    文末获取源码

    ssm在线答题系统

    技术框架

    使用SSM+Vue的形式来实现,SSM框架用于处理后台的数据逻辑,Vue框架用于前端的数据显示

    系统分为客户端,管理端

    注意事项

    1 数据库文件在一级目录下,命名为answerWeb.sql,部署时,需要在answerWeb/config/dbconfig.properties配置文件中配置好数据库
    2 管理端用户表为'admins'表
    3 客户端用户表为'user'表,用户端登录页登录帐号为邮箱
    4 管理端,在创建题目时,在选择完图片后,图片会立即上传到百度云BOS对象存储中(需要在util包的BOSUtil工具类你的BOS对象存储),未点击添加题目时,此时试题的资源(图片,视频)是在BOS的临时文件夹下(在QuestionController类定义路径),当点击添加题目后,会把此试题的资源添加到目标文件夹下(在QuestionController类定义路径),临时文件夹下的东西可以设置任务调度器进行定时删除,防止浪费BOS存储空间。

    5 项目的jar包除了用maven管理外,有一部分jar需要手动导入(answerWeb/WebRoot/WEB-INF/lib)

    运行截图

     

     

     

     

     

     

     

    相关代码 

    管理员登入

    1. package cn.edu.lingnan.controller;
    2. import java.util.Map;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.stereotype.Controller;
    5. import org.springframework.web.bind.annotation.RequestMapping;
    6. import cn.edu.lingnan.pojo.Admins;
    7. import cn.edu.lingnan.service.AdminsService;
    8. @Controller
    9. public class AdminController extends BaseController {
    10. @Autowired
    11. private AdminsService adminsService;
    12. /**
    13. * 管理员登入
    14. * @param admins
    15. * @param map
    16. * @author lizhi
    17. */
    18. @RequestMapping("/adminLogin")
    19. public String adminLogin(Admins admins,Map map){
    20. if(adminsService.login(admins).size()<=0){
    21. map.put("loginError", "帐号或密码错误");
    22. return "/admin/login";
    23. }
    24. super.session.setAttribute("admins", adminsService.login(admins).get(0));
    25. return "redirect:/selectUserByExample";
    26. }
    27. /**
    28. * 更新管理员资料(修改密码)
    29. * @param admins
    30. * @author lizhi
    31. */
    32. @RequestMapping("/changeAdminPassword")
    33. public String changeAdminPassword(Admins admins){
    34. adminsService.updateSelective(admins);
    35. return "redirect:/selectUserByExample";
    36. }
    37. /**
    38. * 注销
    39. * @return
    40. */
    41. @RequestMapping("/logout")
    42. public String logout(){
    43. session.invalidate();
    44. return "/admin/login";
    45. }
    46. }

     获取题目基础类型

    1. package cn.edu.lingnan.controller;
    2. import java.util.ArrayList;
    3. import java.util.HashMap;
    4. import java.util.List;
    5. import java.util.Map;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.stereotype.Controller;
    8. import org.springframework.web.bind.annotation.PathVariable;
    9. import org.springframework.web.bind.annotation.RequestMapping;
    10. import org.springframework.web.bind.annotation.RequestMethod;
    11. import org.springframework.web.bind.annotation.ResponseBody;
    12. import org.springframework.web.servlet.ModelAndView;
    13. import cn.edu.lingnan.pojo.Options;
    14. import cn.edu.lingnan.pojo.Question;
    15. import cn.edu.lingnan.pojo.QuestionOption;
    16. import cn.edu.lingnan.pojo.QuestionType;
    17. import cn.edu.lingnan.pojo.User;
    18. import cn.edu.lingnan.pojo.WeChatUser;
    19. import cn.edu.lingnan.service.AnswerService;
    20. @Controller
    21. public class AnswerController extends BaseController {
    22. public static final int QUESTION_NUMBER = 10;
    23. @Autowired
    24. private AnswerService answerService;
    25. /**
    26. * @author huang
    27. * 获取题目基础类型
    28. */
    29. @ResponseBody
    30. @RequestMapping(value="user/getType")
    31. public Map getQuestionType() {
    32. Map map = new HashMap();
    33. List firstlist = answerService.findType();
    34. if (firstlist.size() <= 0) {
    35. map.put("error", "系统错误:一级菜单获取失败");
    36. } else {
    37. map.put("firstlist", firstlist);
    38. }
    39. return map;
    40. }
    41. /**
    42. * @author huang
    43. * 获取题目具体类型
    44. */
    45. @ResponseBody
    46. @RequestMapping(value="user/getType/{id}")
    47. public Map getQuestionType(@PathVariable int id) {
    48. Map map = new HashMap();
    49. List secondlist = answerService.findType(id);
    50. if (secondlist.size() <= 0) {
    51. map.put("error", id);
    52. } else {
    53. //判断是否为3级菜单
    54. List thirdList = answerService.findType(secondlist.get(0).getTypeno());
    55. if(thirdList.size() <= 0)
    56. map.put("grade", "two");
    57. else
    58. map.put("grade", "third");
    59. map.put("secondlist", secondlist);
    60. }
    61. return map;
    62. }
    63. /**
    64. * @author huang
    65. * 根据类型获取题目
    66. */
    67. @ResponseBody
    68. @RequestMapping(value="user/getQuestion/{typeno}")
    69. public Map getQuestion(@PathVariable int typeno) {
    70. Map map = new HashMap();
    71. List questionList = answerService.getQuestionByType(typeno);
    72. List questionOptionsList = new ArrayList();
    73. for (Question q : questionList) {
    74. List optionlist = answerService.getOptionsByQuestion(q.getQuestionno());
    75. QuestionOption questionOption = new QuestionOption(q,optionlist);
    76. questionOptionsList.add(questionOption);
    77. }
    78. map.put("question",questionOptionsList);
    79. map.put("maxnumber", QUESTION_NUMBER);
    80. map.put("title", answerService.getQuestionTypeByID(typeno).getTypename());
    81. return map;
    82. }
    83. /**
    84. * @author huang
    85. * 用户答题更新记录
    86. */
    87. @RequestMapping(value="user/refreshRecord/{typeno}/{status}")
    88. public void refreshRecord(@PathVariable int typeno, @PathVariable int status){
    89. User user = (User) super.session.getAttribute("user");
    90. WeChatUser weuser = (WeChatUser) super.session.getAttribute("weChatUser");
    91. if (user != null)
    92. answerService.answerRecord(user.getUserno(), typeno, status, 0);
    93. else if (weuser != null)
    94. answerService.answerRecord(weuser.getWechatuserno(), typeno, status, 1);
    95. }
    96. }

    可根据条件分页查询所有候选答案

    1. package cn.edu.lingnan.controller;
    2. import java.util.List;
    3. import java.util.Map;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.stereotype.Controller;
    6. import org.springframework.web.bind.annotation.RequestMapping;
    7. import org.springframework.web.bind.annotation.RequestParam;
    8. import com.github.pagehelper.PageHelper;
    9. import com.github.pagehelper.PageInfo;
    10. import cn.edu.lingnan.pojo.Options;
    11. import cn.edu.lingnan.pojo.OptionsExample;
    12. import cn.edu.lingnan.service.OptionsService;
    13. @Controller
    14. public class OptionsController extends BaseController {
    15. @Autowired
    16. private OptionsService optionsService;
    17. /**
    18. * 可根据条件分页查询所有候选答案
    19. * @return
    20. * @author lizhi
    21. */
    22. @RequestMapping("/selectOptions")
    23. public String selectOptions(OptionsExample options, Map map,
    24. @RequestParam(value = "pn", defaultValue = "1") Integer pn) {
    25. // 每页显示八条数据,且当前页是参数pn
    26. PageHelper.startPage(pn, 8);
    27. List list = optionsService.selectOptionsByExample(options);
    28. // 对数据进行分页处理
    29. PageInfo pageInfo = new PageInfo(list);
    30. map.put("optionsListPageInfo", pageInfo);
    31. // 到时候前端写出网页后再修改到具体的页面
    32. return "admin/index";
    33. }
    34. /**
    35. * 更新候选答案
    36. * @return
    37. * @author lizhi
    38. */
    39. @RequestMapping("/updateOptions")
    40. public String updateOptions(Options options){
    41. optionsService.updateByPrimaryKey(options);
    42. return "admin/index";
    43. }
    44. }

    QuestionController

    1. package cn.edu.lingnan.controller;
    2. import java.io.IOException;
    3. import java.text.SimpleDateFormat;
    4. import java.util.Date;
    5. import java.util.List;
    6. import java.util.Map;
    7. import java.util.concurrent.ThreadLocalRandom;
    8. import org.springframework.beans.factory.annotation.Autowired;
    9. import org.springframework.stereotype.Controller;
    10. import org.springframework.web.bind.annotation.RequestMapping;
    11. import org.springframework.web.bind.annotation.RequestParam;
    12. import org.springframework.web.bind.annotation.ResponseBody;
    13. import org.springframework.web.multipart.MultipartFile;
    14. import com.github.pagehelper.PageHelper;
    15. import com.github.pagehelper.PageInfo;
    16. import cn.edu.lingnan.pojo.Options;
    17. import cn.edu.lingnan.pojo.OptionsList;
    18. import cn.edu.lingnan.pojo.Question;
    19. import cn.edu.lingnan.pojo.TempUrl;
    20. import cn.edu.lingnan.service.OptionsService;
    21. import cn.edu.lingnan.service.QuestionService;
    22. import cn.edu.lingnan.service.QuestionTypeService;
    23. import cn.edu.lingnan.service.TempUrlService;
    24. import cn.edu.lingnan.utils.BOSUtil;
    25. @Controller
    26. public class QuestionController extends BaseController {
    27. @Autowired
    28. private QuestionService questionService;
    29. @Autowired
    30. private QuestionTypeService questionTypeService;
    31. @Autowired
    32. private OptionsService optionsService;
    33. @Autowired
    34. private TempUrlService tempUrlService;
    35. /**
    36. * 分页根据条件查找试题
    37. * @param question
    38. * @param map
    39. * @param pn
    40. * @author lizhi
    41. */
    42. @RequestMapping("/selectQuestion")
    43. public String selectQuestion(Question question, Map map,
    44. @RequestParam(value = "pn", defaultValue = "1") Integer pn,@RequestParam("toid")Integer toid) {
    45. // 每页显示八条数据,且当前页是参数pn
    46. PageHelper.startPage(pn, 6);
    47. List list = questionService.selectQuestionByExample(question);
    48. // 对数据进行分页处理
    49. PageInfo pageInfo = new PageInfo(list);
    50. map.put("pageInfo", pageInfo);
    51. //找出所有三级菜单类型,返回到前端多条件选择
    52. map.put("questionTypeList",questionTypeService.getAllQuestionType());
    53. //在选项卡一中显示
    54. map.put("toid", toid);
    55. // 到时候前端写出网页后再修改到具体的页面
    56. return "/admin/questionList";
    57. }
    58. /**
    59. * 更新试题第一步
    60. * @param question
    61. * @author lizhi
    62. */
    63. @RequestMapping("/updateQuestionFirst")
    64. public String updateQuestionFirst(@RequestParam("questionno")Integer questionno,Map map,@RequestParam("pn") Integer pn){
    65. //找出具体题目
    66. map.put("question",questionService.getQuestionByKey(questionno));
    67. //找出题目的候选答案
    68. map.put("optionsList",optionsService.getQuestionOptions(questionno));
    69. //找出所有三级菜单类型,返回到更新页面
    70. map.put("questionTypeList",questionTypeService.getAllQuestionType());
    71. map.put("pn",pn);
    72. return "/admin/updateQuestion";
    73. }
    74. /**
    75. * 更新试题第二步
    76. * @param question
    77. * @param pn
    78. * @author lizhi
    79. */
    80. @RequestMapping("/updateQuestionSecond")
    81. public String updateQuestionSecond(Question question,@RequestParam("pn") Integer pn,OptionsList optionsList,String oldContent,String oldDescription){
    82. //如果不同文件名,就要移动
    83. if(!question.getContent().equals(oldContent)){
    84. String strExtension = question.getContent().substring(question.getContent().lastIndexOf('.') + 1);
    85. String path = "/resource/images/question/";
    86. if(strExtension.equals("mp3")){
    87. path = "/resource/audio/";
    88. //将文件从临时文件夹移动到目标文件夹
    89. BOSUtil.moveFile("/temp/"+question.getContent(),path+question.getContent());
    90. }else if(strExtension.equals("mp4")){
    91. path = "/resource/video/";
    92. //将文件从临时文件夹移动到目标文件夹
    93. BOSUtil.moveFile("/temp/"+question.getContent(),path+question.getContent());
    94. }else if(strExtension.equals("jpg")||strExtension.equals("gif") ||strExtension.equals("png") || strExtension.equals("bmp")){
    95. //将文件从临时文件夹移动到目标文件夹
    96. BOSUtil.moveFile("/temp/"+question.getContent(),path+question.getContent());
    97. }
    98. }
    99. //如果不同文件名,就要删除原来的
    100. if(!question.getContent().equals(oldContent)){
    101. //把原来的文件删除
    102. String path="";
    103. String oldExtension = oldContent.substring(oldContent.lastIndexOf('.') + 1);
    104. String oldpath = "/resource/images/question/";
    105. if(oldExtension.equals("mp3")){
    106. path = "/resource/audio/";
    107. BOSUtil.deleteFile(path+oldContent);
    108. }else if(oldExtension.equals("mp4")){
    109. path = "/resource/video/";
    110. BOSUtil.deleteFile(path+oldContent);
    111. }else if(oldExtension.equals("jpg")||oldExtension.equals("gif") || oldExtension.equals("png") || oldExtension.equals("bmp")){
    112. BOSUtil.deleteFile(path+oldContent);
    113. }
    114. }
    115. //对答案图片进行更新
    116. if(question.getDesstatus()==2){
    117. if(!question.getDescription().equals(oldDescription)){
    118. String path = "/resource/images/answer/";
    119. //移动答案图片
    120. BOSUtil.moveFile("/temp/"+question.getDescription(),path+question.getDescription());
    121. //删除原来的答案图片
    122. BOSUtil.deleteFile(path+oldDescription);
    123. }
    124. }
    125. questionService.updateSelective(question);
    126. for(Options options:optionsList.getOptionsList()){
    127. optionsService.updateByPrimaryKey(options);
    128. }
    129. redirectAttributes.addAttribute("pn",pn);
    130. redirectAttributes.addAttribute("toid",1);
    131. return "redirect:/selectQuestion";
    132. }
    133. /**
    134. * 上传题目的图片,视频,音频
    135. * @param file
    136. * @param typename
    137. * @return
    138. * @throws IllegalStateException
    139. * @throws IOException
    140. */
    141. @ResponseBody
    142. @RequestMapping(value = "/addQuestionFile", produces = "text/html;charset=UTF-8")
    143. public String addQuestionFile(@RequestParam(value = "file", required = false) MultipartFile file,@RequestParam(value="desFile",required=false) MultipartFile desFile
    144. ,@RequestParam(value="flag",required=false) Integer flag ) throws IllegalStateException, IOException {
    145. if(flag == 1){
    146. /* String strExtension = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.') + 1);
    147. String path = "/resource/images/question/";
    148. if(strExtension.equals("mp3")){
    149. path = "/resource/audio/";
    150. }else if(strExtension.equals("mp4")){
    151. path = "/resource/video/";
    152. }*/
    153. // fileName唯一性
    154. int a = ThreadLocalRandom.current().nextInt(100,999);
    155. String fileName =+ a +"-"+ System.currentTimeMillis()+ file.getOriginalFilename();
    156. //上传到临时文件夹
    157. String typeImagesTempPath = "/temp/"+fileName;
    158. BOSUtil.upload(file, typeImagesTempPath);
    159. //插入上传记录
    160. SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmss");
    161. TempUrl tempUrl = new TempUrl(null,fileName,format.format(new Date()));
    162. tempUrlService.addTempUrl(tempUrl);
    163. return fileName;
    164. //这是答案详解图片的预览
    165. }else if(flag == 2){
    166. String path = "/resource/images/answer/";
    167. // fileName唯一性
    168. int a = ThreadLocalRandom.current().nextInt(100,999);
    169. String fileName =+ a +"-"+ System.currentTimeMillis()+ desFile.getOriginalFilename();
    170. //上传到临时文件夹
    171. String typeImagesTempPath = "/temp/"+fileName;
    172. BOSUtil.upload(desFile, typeImagesTempPath);
    173. //插入上传记录
    174. SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmss");
    175. TempUrl tempUrl = new TempUrl(null,fileName,format.format(new Date()));
    176. tempUrlService.addTempUrl(tempUrl);
    177. return fileName;
    178. }
    179. return "error";
    180. }
    181. /**
    182. * 增加试题
    183. * @param question
    184. * @author lizhi
    185. * @throws IOException
    186. * @throws IllegalStateException
    187. */
    188. @RequestMapping("/addQuestion")
    189. public String addQuestion(Question question,OptionsList optionsList,@RequestParam("pn") Integer pn) throws IllegalStateException, IOException{
    190. String strExtension = question.getContent().substring(question.getContent().lastIndexOf('.') + 1);
    191. String path = "/resource/images/question/";
    192. if(strExtension.equals("mp3")){
    193. path = "/resource/audio/";
    194. //将文件从临时文件夹移动到目标文件夹
    195. BOSUtil.moveFile("/temp/"+question.getContent(),path+question.getContent());
    196. }else if(strExtension.equals("mp4")){
    197. path = "/resource/video/";
    198. //将文件从临时文件夹移动到目标文件夹
    199. BOSUtil.moveFile("/temp/"+question.getContent(),path+question.getContent());
    200. }else if(strExtension.equals("jpg") || strExtension.equals("gif") || strExtension.equals("png") || strExtension.equals("bmp")){
    201. //将文件从临时文件夹移动到目标文件夹
    202. BOSUtil.moveFile("/temp/"+question.getContent(),path+question.getContent());
    203. }
    204. //移动答案图片
    205. if(question.getDesstatus()==2){
    206. String desImapgePath = "/resource/images/answer/";
    207. //移动答案图片
    208. BOSUtil.moveFile("/temp/"+question.getDescription(),desImapgePath+question.getDescription());
    209. }
    210. //插入数据库
    211. questionService.insertQuestion(question);
    212. for(Options options:optionsList.getOptionsList()){
    213. options.setQuestionno(question.getQuestionno());
    214. optionsService.insert(options);
    215. }
    216. redirectAttributes.addAttribute("pn",pn);
    217. redirectAttributes.addAttribute("toid",1);
    218. return "redirect:/selectQuestion";
    219. }
    220. /**
    221. * 根据试题id删除试题
    222. * @param id
    223. * @author lizhi
    224. */
    225. /*@RequestMapping(value="/deleteQuestion/{id}",method=RequestMethod.DELETE)
    226. public String deleteQuestion(@PathVariable(value="id") Integer id){
    227. questionService.deleteQuestion(id);
    228. return "/admin/index";
    229. }*/
    230. /**
    231. * 根据试题id删除试题
    232. * @param id
    233. * @author lizhi
    234. */
    235. @RequestMapping(value="/deleteQuestion")
    236. public String deleteQuestion(@RequestParam("questionno") Integer questionno,@RequestParam("pn") Integer pn){
    237. Question question = questionService.getQuestionByKey(questionno);
    238. questionService.deleteQuestion(questionno);
    239. redirectAttributes.addAttribute("pn", pn);
    240. redirectAttributes.addAttribute("toid",1);
    241. //删除题目内容对应的资源
    242. if(question.getConstatus()!=1){
    243. String contentExtension = question.getContent().substring(question.getContent().lastIndexOf('.') + 1);
    244. String path = "/resource/images/question/";
    245. if(contentExtension.equals("mp3")){
    246. path = "/resource/audio/";
    247. BOSUtil.deleteFile(path+question.getContent());
    248. }else if(contentExtension.equals("mp4")){
    249. path = "/resource/video/";
    250. BOSUtil.deleteFile(path+question.getContent());
    251. }else if(contentExtension.equals("jpg") || contentExtension.equals("gif") || contentExtension.equals("png") || contentExtension.equals("bmp")){
    252. BOSUtil.deleteFile(path+question.getContent());
    253. }
    254. }
    255. //删除题目答案对应的资源
    256. if(question.getDesstatus()==2){
    257. BOSUtil.deleteFile("/resource/images/answer/"+question.getDescription());
    258. }
    259. return "redirect:/selectQuestion";
    260. }
    261. }

    如果也想学习本系统,下面领取。关注并回复:017ssm 

  • 相关阅读:
    【3D建模制作技巧分享】3dmax如何设置视图布局
    ARM接口编程—RTC(exynos 4412平台)
    为什么HttpContextAccessor要这么设计?
    【差旅游记】启程-新疆哈密(1)
    信道估计 | 信道
    October 2019 Twice SQL Injection
    zookeeper应用场景(二)
    Android SystemUI去掉拖动亮度条QSPanel界面隐藏功能
    Makefile相关操作
    Docker - 镜像、容器、仓库
  • 原文地址:https://blog.csdn.net/hanyunlong1989/article/details/126797862