package com.syzton.sunread.controller.exam; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import javassist.NotFoundException; import javax.validation.Valid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.syzton.sunread.dto.common.PageResource; import com.syzton.sunread.dto.exam.CapacityPaperDTO; import com.syzton.sunread.dto.exam.CollatExamDTO; import com.syzton.sunread.dto.exam.SpeedPaperExamDTO; import com.syzton.sunread.dto.exam.SpeedTestRecordDTO; import com.syzton.sunread.dto.exam.SubjectivePaperDTO; import com.syzton.sunread.dto.exam.VerifyExamPassDTO; import com.syzton.sunread.dto.exam.VerifyPaperDTO; import com.syzton.sunread.dto.exam.VerifyPaperExamDTO; import com.syzton.sunread.exception.bookshelf.BookInShelfDuplicateVerifiedException; import com.syzton.sunread.model.book.Book; import com.syzton.sunread.model.book.Dictionary; import com.syzton.sunread.model.book.DictionaryType; import com.syzton.sunread.model.coinhistory.CoinHistory; import com.syzton.sunread.model.coinhistory.CoinHistory.CoinFrom; import com.syzton.sunread.model.coinhistory.CoinHistory.CoinType; import com.syzton.sunread.model.exam.Answer; import com.syzton.sunread.model.exam.Article; import com.syzton.sunread.model.exam.CapacityQuestion; import com.syzton.sunread.model.exam.CapacityQuestion.CapacityQuestionType; import com.syzton.sunread.model.exam.Exam; import com.syzton.sunread.model.exam.Exam.ExamType; import com.syzton.sunread.model.exam.ObjectiveQuestion; import com.syzton.sunread.model.exam.SpeedTestRecord; import com.syzton.sunread.model.exam.SubjectiveAnswer; import com.syzton.sunread.model.exam.SubjectiveQuestion; import com.syzton.sunread.model.organization.Clazz; import com.syzton.sunread.model.organization.ClazzCategoryCount; import com.syzton.sunread.model.pointhistory.PointHistory; import com.syzton.sunread.model.pointhistory.PointHistory.PointFrom; import com.syzton.sunread.model.pointhistory.PointHistory.PointType; import com.syzton.sunread.model.semester.Semester; import com.syzton.sunread.model.user.CategoryCount; import com.syzton.sunread.model.user.Student; import com.syzton.sunread.model.user.User; import com.syzton.sunread.repository.book.DictionaryRepository; import com.syzton.sunread.repository.exam.SpeedTestRecordRepository; import com.syzton.sunread.repository.organization.ClazzRepository; import com.syzton.sunread.service.book.BookService; import com.syzton.sunread.service.book.TestPassService; import com.syzton.sunread.service.bookshelf.BookInShelfService; import com.syzton.sunread.service.coinhistory.CoinHistoryService; import com.syzton.sunread.service.exam.ArticleService; import com.syzton.sunread.service.exam.ExamService; import com.syzton.sunread.service.organization.CampusService; import com.syzton.sunread.service.pointhistory.PointHistoryService; import com.syzton.sunread.service.semester.SemesterService; import com.syzton.sunread.service.user.UserService; @Controller @RequestMapping(value = "/api") public class ExamController { private static final Logger LOGGER = LoggerFactory .getLogger(ExamController.class); private ExamService service; private TestPassService testPassService; private CoinHistoryService coinService; private PointHistoryService pointService; private UserService userService; private BookService bookService; private BookInShelfService shelfService; private SemesterService semesterService; private ClazzRepository clazzRepository; private DictionaryRepository dictionaryRepository; private SpeedTestRecordRepository srRepo; private ArticleService articleService; private CampusService campusService; @Autowired public ExamController(ExamService service, TestPassService tService, CoinHistoryService coinService, PointHistoryService pointService, UserService userService, BookService bookService, BookInShelfService shelfService, ClazzRepository clazzRepository, DictionaryRepository dictionaryRepository, SemesterService semesterService, SpeedTestRecordRepository srRepo, ArticleService articleService, CampusService campusService) { this.service = service; this.testPassService = tService; this.coinService = coinService; this.pointService = pointService; this.userService = userService; this.bookService = bookService; this.shelfService = shelfService; this.semesterService = semesterService; this.clazzRepository = clazzRepository; this.dictionaryRepository = dictionaryRepository; this.srRepo = srRepo; this.articleService = articleService; this.campusService = campusService; } @RequestMapping(value = "/exam", method = RequestMethod.POST) @ResponseBody public Exam add(@Valid @RequestBody Exam dto) { LOGGER.debug("Adding a new exam entry with information: {}", dto); Exam added = service.add(dto); LOGGER.debug("Added a exam entry with information: {}", added); return added; } @RequestMapping(value = "/exam/{id}", method = RequestMethod.DELETE) @ResponseBody public Exam deleteById(@PathVariable("id") Long id) throws NotFoundException { LOGGER.debug("Deleting a exam entry with id: {}", id); Exam deleted = service.deleteById(id); LOGGER.debug("Deleted exam entry with information: {}", deleted); return deleted; } @RequestMapping(value = "/exam", method = RequestMethod.GET) @ResponseBody public PageResource<Exam> findAll(@RequestParam("page") int page, @RequestParam("size") int size, @RequestParam("sortBy") String sortBy) throws NotFoundException { LOGGER.debug("Finding all exam entries."); sortBy = sortBy == null ? "id" : sortBy; Pageable pageable = new PageRequest(page, size, new Sort(sortBy)); Page<Exam> pageResult = service.findAll(pageable); LOGGER.debug("Found {} exam entries.", pageResult.getTotalElements()); return new PageResource<>(pageResult, "page", "size"); } @RequestMapping(value = "/exam/verifypaper/{studentid}/{bookid}", method = RequestMethod.GET) @ResponseBody public VerifyPaperDTO createVerifyPaper( @PathVariable("studentid") Long studentId, @PathVariable("bookid") Long bookId) throws NotFoundException { LOGGER.debug("Finding all exam entries."); VerifyPaperDTO dto = new VerifyPaperDTO(); if (service.isPassVerifyTest(bookId, studentId)) { dto.setCode("2"); dto.setMessage("Student " + studentId + " have verified the book " + bookId); return dto; } List<Exam> list = service.getTodayVerifyTestStatus(bookId, studentId); if (list.size() >= 2) { dto.setCode("3"); dto.setMessage("Student{" + studentId + "} verify test with book{" + bookId + "} greater than twice, system ignore this verify test request."); return dto; } List<ObjectiveQuestion> questions = service.takeVerifyTest(bookId); dto.setQuestions(questions); dto.setCode("1"); dto.setMessage("Get questions complete."); LOGGER.debug("Found {} exam entries.", questions.size()); return dto; } @RequestMapping(value = "/exam/wordpaper/{studentid}/{bookid}", method = RequestMethod.GET) @ResponseBody public List<ObjectiveQuestion> createWordPaper( @PathVariable("studentid") Long studentId, @PathVariable("bookid") Long bookId) throws NotFoundException { LOGGER.debug("Finding all exam entries."); List<ObjectiveQuestion> questions = service.takeWordTest(bookId); LOGGER.debug("Found {} exam entries.", questions.size()); return questions; } @RequestMapping(value = "/exam/capacitypaper/{level}", method = RequestMethod.GET) @ResponseBody public List<CapacityQuestion> createCapacityPaper( @PathVariable("level") int level) throws NotFoundException { LOGGER.debug("Finding all todo entries."); List<CapacityQuestion> questions = service.takeCapacityTest(level); LOGGER.debug("Found {} exam entries.", questions.size()); return questions; } @RequestMapping(value = "/exam/thinkpaper/{bookid}", method = RequestMethod.GET) @ResponseBody public List<SubjectiveQuestion> createThinkPaper( @PathVariable("bookid") Long bookId) throws NotFoundException { LOGGER.debug("Finding all exam entries."); List<SubjectiveQuestion> questions = service.takeThinkTest(bookId); LOGGER.debug("Found {} exam entries.", questions.size()); return questions; } @RequestMapping(value = "/exam/verifypaper", method = RequestMethod.POST) @ResponseBody public CollatExamDTO handInVerifyPaper( @Valid @RequestBody VerifyPaperExamDTO dto) throws NotFoundException, BookInShelfDuplicateVerifiedException { Exam exam = dto.fromOTD(); CollatExamDTO collatExamDto = new CollatExamDTO(); LOGGER.debug("hand in exam entrie."); long studentId = exam.getStudentId(); long bookId = exam.getBook().getId(); if (service.isPassVerifyTest(bookId, studentId)) { collatExamDto.setCode("2"); collatExamDto.setMessage("Student " + studentId + " have verified the book " + bookId); return collatExamDto; } List<Exam> list = service.getTodayVerifyTestStatus(studentId, bookId); if (list.size() >= 2) { collatExamDto.setCode("3"); collatExamDto .setMessage("Student{" + studentId + "} verify test with book{" + bookId + "} greater than twice, system ignore this verify test request."); return collatExamDto; } Exam examResult = service.handInVerifyPaper(exam); Student student = userService.findByStudentId(studentId); student.getStatistic().increaseTestPasses(); if (examResult.isPass()) { Book book = bookService.findById(bookId); Dictionary dictionary = dictionaryRepository.findByTypeAndValue( DictionaryType.CATEGORY, book.getExtra().getCategory()); if (dictionary != null) { Set<CategoryCount> categoryCounts = student.getCategoryCount(); if (categoryCounts.size() > 0) { for (CategoryCount categoryCount : categoryCounts) { if (categoryCount.getDictionary().getId() == dictionary .getId()) { categoryCount.increaseCount(); categoryCounts.add(categoryCount); } } } else { CategoryCount categoryCount = new CategoryCount(); categoryCount.increaseCount(); categoryCount.setDictionary(dictionary); categoryCounts.add(categoryCount); } } Clazz clazz = clazzRepository.findOne(student.getClazzId()); Set<ClazzCategoryCount> clazzCategoryCounts = clazz .getCategoryCount(); if (clazzCategoryCounts.size() > 0) { for (ClazzCategoryCount categoryCount : clazzCategoryCounts) { if (categoryCount.getDictionary().getId() == dictionary .getId()) { categoryCount.increaseCount(); clazzCategoryCounts.add(categoryCount); } } } else { List<Dictionary> categoryDics = dictionaryRepository .findByType(DictionaryType.CATEGORY); for (Dictionary categoryDic : categoryDics) { if (categoryDic.getId() == 0) continue; ClazzCategoryCount categoryCount = new ClazzCategoryCount(); categoryCount.setDictionary(categoryDic); if (categoryDic.getId() == dictionary.getId()) { categoryCount.increaseCount(); } clazzCategoryCounts.add(categoryCount); } } clazzRepository.save(clazz); shelfService.updateReadState(studentId, bookId); testPassService.hotBookUpdate(bookId, studentId); CoinHistory coinHistory = new CoinHistory(); coinHistory.setCoinFrom(CoinFrom.FROM_VERIFY_TEST); coinHistory.setCoinType(CoinType.IN); coinHistory.setNum(book.getCoin()); coinHistory.setStudent(student); coinService.add(coinHistory); PointHistory pointHistory = new PointHistory(); pointHistory.setPointFrom(PointFrom.FROM_VERIFY_TEST); pointHistory.setPointType(PointType.IN); pointHistory.setNum(book.getPoint()); pointHistory.setStudent(student); pointService.add(pointHistory); } userService.saveStudent(student); LOGGER.debug("return a exam entry result with information: {}", exam); collatExamDto.setCode("1"); collatExamDto.setExam(exam); collatExamDto.setMessage("Exam collat complete."); return collatExamDto; } @RequestMapping(value = "/exam/wordpaper", method = RequestMethod.POST) @ResponseBody public Exam handInWordPaper(@Valid @RequestBody VerifyPaperExamDTO dto) throws NotFoundException { Exam exam = dto.fromOTD(); LOGGER.debug("hand in exam entrie."); Exam examResult = service.handInWordPaper(exam); LOGGER.debug("return a exam entry result with information: {}", exam); return examResult; } @RequestMapping(value = "/exam/speedpaper", method = RequestMethod.POST) @ResponseBody public Exam handInSpeedPaper(@Valid @RequestBody SpeedPaperExamDTO dto) throws NotFoundException { Exam exam = dto.fromOTD(); LOGGER.debug("hand in exam entrie."); Exam examResult = service.handInSpeedTest(exam); if (examResult.isPass()) { SpeedTestRecord testRecord = new SpeedTestRecord(); testRecord.setArticleId(exam.getArticleId()); Article article = articleService.getArticle(exam.getArticleId()); int length = article.getContent().length(); testRecord.setTime(dto.getTime()); testRecord.setSpeed(length * 60 / dto.getTime()); testRecord.setUserId(examResult.getStudentId()); testRecord.setScore(examResult.getExamScore()); Student student = userService.findByStudentId(examResult .getStudentId()); testRecord.setSchoolId(student.getCampusId()); srRepo.save(testRecord); } LOGGER.debug("return a exam entry result with information: {}", exam); return examResult; } @RequestMapping(value = "/speedlist/{num}", method = RequestMethod.GET) @ResponseBody public List<SpeedTestRecordDTO> speedList(@PathVariable("num") int num) throws NotFoundException { List<SpeedTestRecord> srs = srRepo.getTopStudent(num); List<SpeedTestRecordDTO> dtos = new ArrayList<SpeedTestRecordDTO>(); for (int i = 0; i < srs.size(); i++) { SpeedTestRecord sr = srs.get(i); SpeedTestRecordDTO dto = new SpeedTestRecordDTO(); dto.setArticleId(sr.getArticleId()); dto.setId(sr.getId()); long schoolId = sr.getSchoolId(); dto.setSchoolName(campusService.findById(schoolId).getName()); dto.setSchoolId(schoolId); dto.setScore(sr.getScore()); dto.setSpeed(sr.getSpeed()); dto.setTime(sr.getTime()); long userId = sr.getUserId(); dto.setUserId(userId); dto.setUserName(userService.findByStudentId(userId).getUsername()); dtos.add(dto); } return dtos; } @RequestMapping(value = "/speedschoollist/{schoolid}/{num}", method = RequestMethod.GET) @ResponseBody public List<SpeedTestRecordDTO> speedListFromSchool( @PathVariable("schoolid") long schoolId, @PathVariable("num") int num) throws NotFoundException { List<SpeedTestRecord> srs = srRepo.getTopStudentBySchool(num, schoolId); List<SpeedTestRecordDTO> dtos = new ArrayList<SpeedTestRecordDTO>(); String schoolName = campusService.findById(schoolId).getName(); for (int i = 0; i < srs.size(); i++) { SpeedTestRecord sr = srs.get(i); long userId = sr.getUserId(); Student user = userService.findByStudentId(userId); Clazz clazz = clazzRepository.findOne(user.getClazzId()); SpeedTestRecordDTO dto = new SpeedTestRecordDTO(); dto.setArticleId(sr.getArticleId()); dto.setId(sr.getId()); dto.setSchoolId(schoolId); dto.setSchoolName(schoolName); dto.setSchoolId(schoolId); dto.setScore(sr.getScore()); dto.setSpeed(sr.getSpeed()); dto.setTime(sr.getTime()); dto.setClazzName(clazz.getName()); dto.setUserId(userId); dto.setUserName(user.getUsername()); dtos.add(dto); } return dtos; } @RequestMapping(value = "/speedpersonlist/{userid}/{num}", method = RequestMethod.GET) @ResponseBody public List<SpeedTestRecord> speedListPersonal( @PathVariable("userid") long userId, @PathVariable("num") int num) throws NotFoundException { List<SpeedTestRecord> srs = srRepo.getPersonalHistory(num, userId); return srs; } @RequestMapping(value = "/exam/thinkpaper", method = RequestMethod.POST) @ResponseBody public Exam handInThinkPaper(@Valid @RequestBody SubjectivePaperDTO paper) throws NotFoundException { Exam exam = paper.fromOTD(); Student user = userService.findByStudentId(exam.getStudentId()); Set<Answer> answers = exam.getAnswers(); for (Answer answer : answers) { SubjectiveAnswer subjectAnswer = (SubjectiveAnswer) answer; subjectAnswer.setCampusId(user.getCampusId()); } LOGGER.debug("hand in exam entrie."); Exam examResult = service.handInThinkTest(exam); LOGGER.debug("return a exam entry result with information: {}", exam); return examResult; } @RequestMapping(value = "/exam/capacitypaper", method = RequestMethod.POST) @ResponseBody public Exam handInCapacityPaper(@Valid @RequestBody CapacityPaperDTO dto) throws NotFoundException { Exam exam = dto.fromOTD(); LOGGER.debug("hand in exam entrie."); Exam examResult = service.handInCapacityTest(exam); LOGGER.debug("return a exam entry result with information: {}", exam); return examResult; } @RequestMapping(value = "/exam/{id}", method = RequestMethod.GET) @ResponseBody public Exam findById(@PathVariable("id") Long id) throws NotFoundException { LOGGER.debug("Finding to-do entry with id: {}", id); Exam found = service.findById(id); LOGGER.debug("Found to-do entry with information: {}", found); return found; } @RequestMapping(value = "/verifyexams/pass/{userid}", method = RequestMethod.GET) @ResponseBody public VerifyExamPassDTO findPassVerifyExam( @PathVariable("userid") Long userId) throws NotFoundException { LOGGER.debug("Finding objective question entry with id: {}"); VerifyExamPassDTO examPassDTO = service.findAllByExamTypeAndPassStatus( userId, ExamType.VERIFY); return examPassDTO; } @RequestMapping(value = "/verifyexams/{userid}", method = RequestMethod.GET) @ResponseBody public VerifyExamPassDTO findVerifyExams(@PathVariable("userid") Long userId) throws NotFoundException { LOGGER.debug("Finding objective question entry with id: {}"); VerifyExamPassDTO examPassDTO = service.findAllByExamType(userId, ExamType.VERIFY); return examPassDTO; } @RequestMapping(value = "/wordexams/{userid}", method = RequestMethod.GET) @ResponseBody public VerifyExamPassDTO findWordExams(@PathVariable("userid") Long userId) throws NotFoundException { LOGGER.debug("Finding objective question entry with id: {}"); VerifyExamPassDTO examPassDTO = service.findAllByExamType(userId, ExamType.WORD); return examPassDTO; } @RequestMapping(value = "/capacityexams/{userid}", method = RequestMethod.GET) @ResponseBody public VerifyExamPassDTO findCapacityExams( @PathVariable("userid") Long userId) throws NotFoundException { LOGGER.debug("Finding objective question entry with id: {}"); VerifyExamPassDTO examPassDTO = service.findAllByExamType(userId, ExamType.CAPACITY); return examPassDTO; } @RequestMapping(value = "/thinkexams/{userid}", method = RequestMethod.GET) @ResponseBody public VerifyExamPassDTO findThinkExams(@PathVariable("userid") Long userId) throws NotFoundException { LOGGER.debug("Finding objective question entry with id: {}"); VerifyExamPassDTO examPassDTO = service.findAllByExamType(userId, ExamType.THINK); return examPassDTO; } @RequestMapping(value = "/verifyexams/average/{studentid}/{semester}", method = RequestMethod.GET) @ResponseBody public int getAverageVerifyExamsPassRate( @PathVariable("studentid") Long studentId, @PathVariable("semester") Long semesterId) throws NotFoundException { Semester semester = semesterService.findOne(semesterId); int passRate = service.findPassVerifyExamPassRate(studentId, semester.getStartTime(), semester.getEndTime()); return passRate; } @RequestMapping(value = "/verifyexams/fistpassrate/{studentid}/{semester}", method = RequestMethod.GET) @ResponseBody public int getFirstPassExamsPassRate( @PathVariable("studentid") Long studentId, @PathVariable("semester") Long semesterId) throws NotFoundException { Semester semester = semesterService.findOne(semesterId); int passRate = service.findFirstPassRate(studentId, semester.getStartTime(), semester.getEndTime()); return passRate; } @RequestMapping(value = "/verifyexams/secondpassrate/{studentid}/{semester}", method = RequestMethod.GET) @ResponseBody public int getSecondPassExamsPassRate( @PathVariable("studentid") Long studentId, @PathVariable("semester") Long semesterId) throws NotFoundException { Semester semester = semesterService.findOne(semesterId); int passRate = service.findSecondPassRate(studentId, semester.getStartTime(), semester.getEndTime()); return passRate; } @RequestMapping(value = "/verifyexams/passrate/{studentId}/{semesterId}", method = RequestMethod.GET) @ResponseBody public String getPassRate(@PathVariable("studentId") Long studentId, @PathVariable("semesterId") Long semesterId) throws NotFoundException { int average = getAverageVerifyExamsPassRate(studentId, semesterId); int firstpassrate = getFirstPassExamsPassRate(studentId, semesterId); int secondpassrate = getSecondPassExamsPassRate(studentId, semesterId); return "{\"average\":" + average + ",\"firstpassrate\":" + firstpassrate + ",\"secondpassrate\":" + secondpassrate + "}"; } @RequestMapping(value = "/capacityexam/everytypepassrate/{studentid}/{semester}", method = RequestMethod.GET) @ResponseBody public Map<CapacityQuestionType, Integer> getCapacityQuestionPassrate( @PathVariable("studentid") Long studentId, @PathVariable("semester") Long semesterId) { Semester semester = semesterService.findOne(semesterId); Map<CapacityQuestionType, Integer> passRate = service .getStudentCapacityStatus(studentId, semester.getStartTime(), semester.getEndTime()); return passRate; } }