MyController.java 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657
  1. package com.qxgmat.controller.api;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.github.pagehelper.Page;
  5. import com.nuliji.tools.*;
  6. import com.nuliji.tools.exception.ParameterException;
  7. import com.nuliji.tools.exception.SystemException;
  8. import com.qxgmat.data.constants.enums.MessageType;
  9. import com.qxgmat.data.constants.enums.QuestionSubject;
  10. import com.qxgmat.data.constants.enums.QuestionType;
  11. import com.qxgmat.data.constants.enums.SettingKey;
  12. import com.qxgmat.data.constants.enums.module.*;
  13. import com.qxgmat.data.constants.enums.status.AskStatus;
  14. import com.qxgmat.data.constants.enums.status.DirectionStatus;
  15. import com.qxgmat.data.constants.enums.user.DataType;
  16. import com.qxgmat.data.dao.entity.*;
  17. import com.qxgmat.data.inline.PaperStat;
  18. import com.qxgmat.data.inline.UserQuestionStat;
  19. import com.qxgmat.data.relation.entity.*;
  20. import com.qxgmat.dto.extend.*;
  21. import com.qxgmat.dto.request.*;
  22. import com.qxgmat.dto.request.CommentDto;
  23. import com.qxgmat.dto.request.FaqDto;
  24. import com.qxgmat.dto.request.UserCollectQuestionDto;
  25. import com.qxgmat.dto.request.UserNoteQuestionDto;
  26. import com.qxgmat.dto.response.*;
  27. import com.qxgmat.help.AiHelp;
  28. import com.qxgmat.help.MailHelp;
  29. import com.qxgmat.help.ShiroHelp;
  30. import com.qxgmat.service.*;
  31. import com.qxgmat.service.extend.*;
  32. import com.qxgmat.service.inline.*;
  33. import io.swagger.annotations.Api;
  34. import io.swagger.annotations.ApiOperation;
  35. import org.apache.logging.log4j.util.Strings;
  36. import org.springframework.beans.factory.annotation.Autowired;
  37. import org.springframework.beans.factory.annotation.Value;
  38. import org.springframework.http.MediaType;
  39. import org.springframework.validation.annotation.Validated;
  40. import org.springframework.web.bind.annotation.*;
  41. import org.springframework.web.multipart.MultipartFile;
  42. import javax.servlet.http.HttpServletRequest;
  43. import javax.servlet.http.HttpSession;
  44. import javax.tools.Tool;
  45. import javax.validation.Validator;
  46. import java.io.File;
  47. import java.io.IOException;
  48. import java.text.DateFormat;
  49. import java.text.ParseException;
  50. import java.util.*;
  51. import java.util.stream.Collectors;
  52. /**
  53. * Created by GaoJie on 2017/10/31.
  54. */
  55. @RestController
  56. @RequestMapping("/api/my")
  57. @Api(tags = "用户接口", description = "获取与操作当前用户信息", produces = MediaType.APPLICATION_JSON_VALUE)
  58. public class MyController {
  59. @Value("${upload.local_path}")
  60. private String localPath;
  61. @Value("${upload.web_url}")
  62. private String webUrl;
  63. @Autowired
  64. private Validator validator;
  65. @Autowired
  66. private ShiroHelp shiroHelp;
  67. @Autowired
  68. private AiHelp aiHelp;
  69. @Autowired
  70. private MailHelp mailHelp;
  71. @Autowired
  72. private PreviewService previewService;
  73. @Autowired
  74. private SettingService settingService;
  75. @Autowired
  76. private ExerciseStructService exerciseStructService;
  77. @Autowired
  78. private CourseService courseService;
  79. @Autowired
  80. private CourseNoService courseNoService;
  81. @Autowired
  82. private QuestionService questionService;
  83. @Autowired
  84. private QuestionNoService questionNoService;
  85. @Autowired
  86. private SentenceQuestionService sentenceQuestionService;
  87. @Autowired
  88. private TextbookQuestionService textbookQuestionService;
  89. @Autowired
  90. private TextbookTopicService textbookTopicService;
  91. @Autowired
  92. private TextbookLibraryService textbookLibraryService;
  93. @Autowired
  94. private CourseDataService courseDataService;
  95. @Autowired
  96. private CourseExperienceService courseExperienceService;
  97. @Autowired
  98. private CourseDataHistoryService courseDataHistoryService;
  99. @Autowired
  100. private CourseTeacherService courseTeacherService;
  101. @Autowired
  102. private FaqService faqService;
  103. @Autowired
  104. private CommentService commentService;
  105. @Autowired
  106. private PreviewAssignService previewAssignService;
  107. @Autowired
  108. private UsersService usersService;
  109. @Autowired
  110. private UserMessageService userMessageService;
  111. @Autowired
  112. private UserCourseRecordService userCourseRecordService;
  113. @Autowired
  114. private UserCourseAppointmentService userCourseAppointmentService;
  115. @Autowired
  116. private UserCourseProgressService userCourseProgressService;
  117. @Autowired
  118. private UserSentenceRecordService userSentenceRecordService;
  119. @Autowired
  120. private UserServiceService userServiceService;
  121. @Autowired
  122. private UserCollectQuestionService userCollectQuestionService;
  123. @Autowired
  124. private UserCollectExperienceService userCollectExperienceService;
  125. @Autowired
  126. private UserNoteQuestionService userNoteQuestionService;
  127. @Autowired
  128. private UserNoteCourseService userNoteCourseService;
  129. @Autowired
  130. private UserAskQuestionService userAskQuestionService;
  131. @Autowired
  132. private UserAskCourseService userAskCourseService;
  133. @Autowired
  134. private UserFeedbackErrorService userFeedbackErrorService;
  135. @Autowired
  136. private UserTextbookFeedbackService userTextbookFeedbackService;
  137. @Autowired
  138. private UserQuestionService userQuestionService;
  139. @Autowired
  140. private UserReportService userReportService;
  141. @Autowired
  142. private UserPaperService userPaperService;
  143. @Autowired
  144. private UserPaperQuestionService userPaperQuestionService;
  145. @Autowired
  146. private UserOrderService userOrderService;
  147. @Autowired
  148. private UserOrderRecordService userOrderRecordService;
  149. @Autowired
  150. private QuestionFlowService questionFlowService;
  151. @Autowired
  152. private SentenceService sentenceService;
  153. @Autowired
  154. private CourseExtendService courseExtendService;
  155. @Autowired
  156. private OrderFlowService orderFlowService;
  157. @Autowired
  158. private MessageExtendService messageExtendService;
  159. @RequestMapping(value = "/email", method = RequestMethod.POST)
  160. @ApiOperation(value = "绑定邮箱", httpMethod = "POST")
  161. public Response<Boolean> email(@RequestBody @Validated UserEmailDto dto, HttpSession session, HttpServletRequest request) {
  162. User user = (User) shiroHelp.getLoginUser();
  163. usersService.edit(User.builder()
  164. .id(user.getId())
  165. .email(dto.getEmail())
  166. .build());
  167. messageExtendService.sendEmailChange(user);
  168. return ResponseHelp.success(true);
  169. }
  170. @RequestMapping(value = "/mobile", method = RequestMethod.POST)
  171. @ApiOperation(value = "绑定手机", httpMethod = "POST")
  172. public Response<Boolean> mobile(@RequestBody @Validated UserMobileDto dto, HttpSession session, HttpServletRequest request) {
  173. User user = (User) shiroHelp.getLoginUser();
  174. User in = usersService.get(user.getId());
  175. if (in.getArea().equals(dto.getArea()) && in.getMobile().equals(dto.getMobile())) {
  176. return ResponseHelp.success(true);
  177. }
  178. User other = usersService.getByMobile(dto.getArea(), dto.getMobile());
  179. if (other != null){
  180. throw new ParameterException("该手机已绑定其他账号,请更换手机号码");
  181. }
  182. usersService.edit(User.builder()
  183. .id(user.getId())
  184. .area(dto.getArea())
  185. .mobile(dto.getMobile())
  186. .build());
  187. return ResponseHelp.success(true);
  188. }
  189. @RequestMapping(value = "/info", method = RequestMethod.POST)
  190. @ApiOperation(value = "修改用户信息", httpMethod = "POST")
  191. public Response<Boolean> info(@RequestBody @Validated UserInfoDto dto){
  192. User user = (User) shiroHelp.getLoginUser();
  193. usersService.edit(User.builder()
  194. .id(user.getId())
  195. .nickname(dto.getNickname())
  196. .avatar(dto.getAvatar())
  197. .build());
  198. return ResponseHelp.success(true);
  199. }
  200. @RequestMapping(value = "/real/front", produces = MediaType.IMAGE_JPEG_VALUE, method = RequestMethod.POST)
  201. @ApiOperation(value = "实名认证", notes = "保存用户实名信息", httpMethod = "POST")
  202. public Response<UserRealDto> realFront(@RequestParam("file") MultipartFile file) throws IOException {
  203. if (file.isEmpty()) {
  204. throw new ParameterException("上传文件为空");
  205. }
  206. User user = (User) shiroHelp.getLoginUser();
  207. UserRealDto dto = new UserRealDto();
  208. Map<String, String> map = aiHelp.orcIdcardFront(file.getBytes());
  209. dto.setName(map.get("name"));
  210. dto.setAddress(map.get("address"));
  211. dto.setIdentity(map.get("identity"));
  212. User in = usersService.getByIdentity(map.get("identity"));
  213. if (in != null){
  214. throw new ParameterException("该身份证已被其他账号认证");
  215. }
  216. String frontName = UUID.randomUUID().toString();
  217. try {
  218. File frontDest = new File(localPath + File.separator+frontName);
  219. file.transferTo(frontDest);
  220. dto.setPhotoFront(webUrl+frontName);
  221. usersService.edit(User.builder()
  222. .id(user.getId())
  223. .realAddress(dto.getAddress())
  224. .realName(dto.getName())
  225. .realIdentity(dto.getIdentity())
  226. .realPhotoFront(dto.getPhotoFront())
  227. .build());
  228. return ResponseHelp.success(dto);
  229. } catch (IOException e) {
  230. e.printStackTrace();
  231. return ResponseHelp.exception(new SystemException("图片上传失败"));
  232. }
  233. }
  234. @RequestMapping(value = "/real/back", produces = MediaType.IMAGE_JPEG_VALUE, method = RequestMethod.POST)
  235. @ApiOperation(value = "实名认证", notes = "保存用户实名信息", httpMethod = "POST")
  236. public Response<UserRealDto> realBack(@RequestParam("file") MultipartFile file) throws IOException {
  237. if (file.isEmpty()) {
  238. throw new ParameterException("上传文件为空");
  239. }
  240. User user = (User) shiroHelp.getLoginUser();
  241. UserRealDto dto = new UserRealDto();
  242. aiHelp.orcIdcardBack(file.getBytes());
  243. String backName = UUID.randomUUID().toString();
  244. try {
  245. File backDest = new File(localPath + File.separator+backName);
  246. file.transferTo(backDest);
  247. dto.setPhotoBack(webUrl+backName);
  248. usersService.edit(User.builder()
  249. .id(user.getId())
  250. .realPhotoBack(dto.getPhotoBack())
  251. .build());
  252. return ResponseHelp.success(dto);
  253. } catch (IOException e) {
  254. e.printStackTrace();
  255. return ResponseHelp.exception(new SystemException("图片上传失败"));
  256. }
  257. }
  258. @RequestMapping(value = "/real/finish", produces = MediaType.IMAGE_JPEG_VALUE, method = RequestMethod.POST)
  259. @ApiOperation(value = "实名认证", notes = "保存用户实名信息", httpMethod = "POST")
  260. public Response<UserRealDto> realFinish() {
  261. User user = (User) shiroHelp.getLoginUser();
  262. UserRealDto dto = new UserRealDto();
  263. User in = usersService.get(user.getId());
  264. if (in.getRealAddress() == null || !in.getRealAddress().equals("")){
  265. throw new ParameterException("实名认证流程错误");
  266. }
  267. if (in.getRealIdentity() == null || !in.getRealIdentity().equals("")){
  268. throw new ParameterException("实名认证流程错误");
  269. }
  270. if (in.getRealName() == null || !in.getRealName().equals("")){
  271. throw new ParameterException("实名认证流程错误");
  272. }
  273. if (in.getRealPhotoFront() == null || !in.getRealPhotoFront().equals("")){
  274. throw new ParameterException("实名认证流程错误");
  275. }
  276. if (in.getRealPhotoBack() == null || !in.getRealPhotoBack().equals("")){
  277. throw new ParameterException("实名认证流程错误");
  278. }
  279. usersService.edit(User.builder()
  280. .id(user.getId())
  281. .realStatus(1)
  282. .realTime(new Date())
  283. .build());
  284. orderFlowService.giveReal(user.getId());
  285. return ResponseHelp.success(dto);
  286. }
  287. @RequestMapping(value = "/invite/email", method = RequestMethod.POST)
  288. @ApiOperation(value = "发送邮件邀请", httpMethod = "POST")
  289. public Response<Boolean> inviteEmail(@RequestBody @Validated InviteEmailDto dto) {
  290. User user = (User) shiroHelp.getLoginUser();
  291. messageExtendService.sendInviteEmail(user, dto.getEmails(), user.getInviteCode());
  292. return ResponseHelp.success(true);
  293. }
  294. @RequestMapping(value = "/message", method = RequestMethod.GET)
  295. @ApiOperation(value = "用户站内信", notes = "用户消息列表", httpMethod = "GET")
  296. public Response<PageMessage<UserMessage>> message(
  297. @RequestParam(required = false, defaultValue = "1") int page,
  298. @RequestParam(required = false, defaultValue = "100") int size,
  299. @RequestParam(required = false) String messageType,
  300. @RequestParam(required = false) Integer read
  301. ) {
  302. User user = (User) shiroHelp.getLoginUser();
  303. Page<UserMessage> p = userMessageService.list(page, size, user.getId(), MessageType.ValueOf(messageType), read);
  304. return ResponseHelp.success(p, page, size, p.getTotal());
  305. }
  306. @RequestMapping(value = "/message/read", method = RequestMethod.PUT)
  307. @ApiOperation(value = "读取消息", notes = "读取用户消息/全部", httpMethod = "PUT")
  308. public Response<Boolean> readMessage(@RequestBody @Validated MessageReadDto dto) {
  309. User user = (User) shiroHelp.getLoginUser();
  310. if (dto.getAll()){
  311. userMessageService.clearAll(user.getId());
  312. }else{
  313. userMessageService.clear(user.getId(), dto.getId());
  314. }
  315. return ResponseHelp.success(true);
  316. }
  317. @RequestMapping(value = "/clear/exercise/latest", method = RequestMethod.PUT)
  318. @ApiOperation(value = "清除最后一次做题记录", notes = "清除最后一次做题记录", httpMethod = "PUT")
  319. public Response<Boolean> clearLatestExercise() {
  320. User user = (User) shiroHelp.getLoginUser();
  321. usersService.edit(User.builder().id(user.getId()).latestExercise(0).build());
  322. return ResponseHelp.success(true);
  323. }
  324. @RequestMapping(value = "/clear/error/latest", method = RequestMethod.PUT)
  325. @ApiOperation(value = "清除最后一次错题组卷做题记录", notes = "清除最后一次错题组卷做题记录", httpMethod = "PUT")
  326. public Response<Boolean> clearLatestError() {
  327. User user = (User) shiroHelp.getLoginUser();
  328. usersService.edit(User.builder().id(user.getId()).latestError(0).build());
  329. return ResponseHelp.success(true);
  330. }
  331. @RequestMapping(value = "/prepare", method = RequestMethod.PUT)
  332. @ApiOperation(value = "修改备考信息", notes = "修改用户备考信息", httpMethod = "PUT")
  333. public Response<Boolean> editPrepare(@RequestBody @Validated UserPrepareDto dto) {
  334. User entity = Transform.dtoToEntity(dto);
  335. User user = (User) shiroHelp.getLoginUser();
  336. entity.setId(user.getId());
  337. if (user.getPrepareTime() == null){
  338. // 邀请奖励
  339. orderFlowService.givePrepare(user.getId());
  340. }
  341. entity.setPrepareTime(new Date());
  342. usersService.edit(entity);
  343. return ResponseHelp.success(true);
  344. }
  345. @RequestMapping(value = "/prepare", method = RequestMethod.GET)
  346. @ApiOperation(value = "获取备考信息", notes = "获取备考信息及分布", httpMethod = "GET")
  347. public Response<UserPrepareDetailDto> getPrepare() {
  348. User user = (User) shiroHelp.getLoginUser();
  349. User entity = usersService.get(user.getId());
  350. UserPrepareDetailDto dto = Transform.convert(entity, UserPrepareDetailDto.class);
  351. Setting setting = settingService.getByKey(SettingKey.PREPARE_INFO);
  352. JSONObject value = setting.getValue();
  353. dto.setStat(value);
  354. return ResponseHelp.success(dto);
  355. }
  356. @RequestMapping(value = "/study", method = RequestMethod.GET)
  357. @ApiOperation(value = "获取学习记录", notes = "获取选择那天的做题信息", httpMethod = "GET")
  358. public Response<UserStudyDayDto> studyTime(
  359. @RequestParam(required = false) String date
  360. ) {
  361. User user = (User) shiroHelp.getLoginUser();
  362. Date day;
  363. try {
  364. day = DateFormat.getDateInstance().parse(date);
  365. } catch (ParseException e) {
  366. throw new ParameterException("日期格式错误");
  367. }
  368. Date endDay = Tools.addDate(day, 1);
  369. String startTime = day.toString();
  370. String endTime = endDay.toString();
  371. UserStudyDayDto dto = new UserStudyDayDto();
  372. List<ExerciseStruct> p = exerciseStructService.main();
  373. Map<String, String> m = new HashMap<>();
  374. for (ExerciseStruct struct : p){
  375. if (struct.getExtend() == null || struct.getExtend().isEmpty()) continue;
  376. m.put(struct.getExtend(), struct.getTitleZh() + (struct.getTitleEn().isEmpty() ? "":" "+struct.getTitleEn()));
  377. }
  378. // 获取总用户数
  379. Integer total = usersService.count();
  380. // 获取练习统计 - 按题型进行分组统计
  381. Integer exerciseTime = 0;
  382. Integer exerciseQuestion = 0;
  383. List<UserExerciseExtendDto> exerciseList = new ArrayList<>();
  384. List<UserStudyStatRelation> typeList = userReportService.statGroupExerciseType(user.getId(), startTime, endTime);
  385. for(UserStudyStatRelation type:typeList){
  386. exerciseTime += type.getUserTime();
  387. exerciseQuestion += type.getUserNumber();
  388. exerciseList.add(new UserExerciseExtendDto(m.get(type.getModule()), type.getUserNumber(), type.getUserTime(), type.getUserCorrect()));
  389. }
  390. // todo 练习统计排行
  391. UserRankStatRelation exerciseRank = userReportService.rankExerciseByTime(user.getId(), startTime, endTime);
  392. exerciseRank.setTotal(total);
  393. dto.setExerciseTime(exerciseTime);
  394. dto.setExerciseQuestion(exerciseQuestion);
  395. dto.setExerciseList(exerciseList);
  396. dto.setExerciseExceed(exerciseRank);
  397. // 获取模考统计 - 按卷子
  398. Integer examinationTime = 0;
  399. Integer examinationPaper = 0;
  400. List<UserReport> userReportList = userReportService.getByModule(user.getId(), PaperModule.EXAMINATION, startTime, endTime);
  401. Collection paperIds = Transform.getIds(userReportList, UserReport.class, "paperId");
  402. List<UserPaper> userPaperList = userPaperService.select(paperIds);
  403. Map userPaper = Transform.getMap(userPaperList, UserPaper.class, "id");
  404. List<UserPaperDetailExtendDto> examinationPaperList = new ArrayList<>(userReportList.size());
  405. for(UserReport report: userReportList){
  406. examinationTime += report.getUserTime();
  407. examinationPaper += 1;
  408. UserPaperDetailExtendDto d = Transform.convert(userPaper.get(report.getPaperId()), UserPaperDetailExtendDto.class);
  409. d.setReport(Transform.convert(report, UserReportExtendDto.class));
  410. examinationPaperList.add(d);
  411. }
  412. // todo 模考统计排行
  413. UserRankStatRelation examinationRank = userReportService.rankExaminationByTime(user.getId(), startTime, endTime);
  414. examinationRank.setTotal(total);
  415. dto.setExaminationTime(examinationTime);
  416. dto.setExaminationPaper(examinationPaper);
  417. dto.setExaminationList(examinationPaperList);
  418. dto.setExaminationExceed(examinationRank);
  419. // 获取课程访问记录 - 按课时
  420. Integer courseTime = 0;
  421. Integer courseNumber = 0;
  422. List<UserCourseRecord> userCourseRecordList = userCourseRecordService.getByTime(user.getId(), startTime, endTime);
  423. Collection courseIds = Transform.getIds(userCourseRecordList, UserCourseRecord.class, "courseId");
  424. Collection courseNoIds = Transform.getIds(userCourseRecordList, UserCourseRecord.class, "noId");
  425. List<Course> courseList = courseService.select(courseIds);
  426. Map courseMap = Transform.getMap(courseList, Course.class, "id", "title");
  427. List<CourseNo> courseNoList = courseNoService.select(courseNoIds);
  428. Map classCourseNoMap = Transform.getMap(courseNoList, CourseNo.class, "id", "content");
  429. List<UserCourseResultExtendDto> courseResultList = new ArrayList<>(userCourseRecordList.size());
  430. for(UserCourseRecord record:userCourseRecordList){
  431. courseTime += record.getUserTime();
  432. courseNumber += 1;
  433. UserCourseResultExtendDto d = Transform.convert(record, UserCourseResultExtendDto.class);
  434. d.setTitle((String)courseMap.get(record.getCourseId()));
  435. d.setContent((String)classCourseNoMap.get(record.getCourseNoId()));
  436. courseResultList.add(d);
  437. }
  438. // todo 听课统计排行
  439. UserRankStatRelation classRank = userCourseRecordService.rankByTime(user.getId(), startTime, endTime);
  440. classRank.setTotal(total);
  441. dto.setCourseTime(courseTime);
  442. dto.setCourseNumber(courseNumber);
  443. dto.setCourseList(courseResultList);
  444. dto.setCourseExceed(classRank);
  445. return ResponseHelp.success(dto);
  446. }
  447. @RequestMapping(value = "/study/week", method = RequestMethod.GET)
  448. @ApiOperation(value = "获取本周记录", notes = "获取本周学习记录", httpMethod = "GET")
  449. public Response<UserStudyDetailDto> studyWeekTime(
  450. @RequestParam(required = false) Integer week
  451. ) {
  452. User user = (User) shiroHelp.getLoginUser();
  453. UserStudyDetailDto dto = new UserStudyDetailDto();
  454. dto.setCreateTime(user.getCreateTime());
  455. dto.setDays((int)((user.getCreateTime().getTime() - new Date().getTime()) / (1000*3600*24)));
  456. Date now = Tools.today();
  457. int day = Tools.getDayOfWeek(now);
  458. Date start = Tools.addDate(now, -1 * (day + week * 7));
  459. Date end = Tools.addDate(start, 7);
  460. Integer time = 0;
  461. time += courseExtendService.studyTime(user.getId(), start, end);
  462. time += sentenceService.studyTime(user.getId(), start, end);
  463. time += questionFlowService.studyTime(user.getId(), start, end);
  464. dto.setTime(time);
  465. Integer avgTime = 0;
  466. avgTime += courseExtendService.studyAvgTime(start, end);
  467. avgTime += sentenceService.studyAvgTime(start, end);
  468. avgTime += questionFlowService.studyAvgTime(start, end);
  469. dto.setAvgTime(avgTime);
  470. return ResponseHelp.success(dto);
  471. }
  472. @RequestMapping(value = "/study/total", method = RequestMethod.GET)
  473. @ApiOperation(value = "获取总学习记录", notes = "获取总学习记录", httpMethod = "GET")
  474. public Response<UserStudyDetailDto> studyTotalTime() {
  475. User user = (User) shiroHelp.getLoginUser();
  476. UserStudyDetailDto dto = new UserStudyDetailDto();
  477. dto.setCreateTime(user.getCreateTime());
  478. dto.setDays((int)((user.getCreateTime().getTime() - new Date().getTime()) / (1000*3600*24)));
  479. Integer totalTime = 0;
  480. Map<String, Integer> categoryMap = new HashMap<>();
  481. // 按模块来源分组查询: module=> sentence, examination, collect+error, 忽略exercise,preview
  482. List<UserStudyStatRelation> moduleList = userReportService.statGroupModule(user.getId());
  483. for(UserStudyStatRelation module:moduleList){
  484. // 练习时间过滤
  485. if (module.getModule().equals(PaperModule.EXERCISE.key)){
  486. continue;
  487. }
  488. Integer time = module.getUserTime();
  489. String key = module.getModule();
  490. totalTime += time;
  491. // 收藏及错误组卷合并
  492. if (module.getModule().equals(PaperOrigin.COLLECT.key)
  493. || module.getModule().equals(PaperOrigin.ERROR.key)){
  494. key = "freedom";
  495. time += categoryMap.getOrDefault(key, 0);
  496. }else if (module.getModule().equals(PaperOrigin.PREVIEW.key)){
  497. key = PaperOrigin.EXERCISE.key;
  498. }
  499. categoryMap.put(key, time);
  500. }
  501. // 按题型统计练习
  502. List<UserStudyStatRelation> exerciseList = userReportService.statGroupExerciseType(user.getId(), null, null);
  503. for(UserStudyStatRelation type:exerciseList){
  504. totalTime += type.getUserTime();
  505. categoryMap.put(type.getModule(), type.getUserTime());
  506. }
  507. // 按题型统计预习作业
  508. List<UserStudyStatRelation> previewList = userReportService.statGroupExerciseType(user.getId(), null, null);
  509. for(UserStudyStatRelation type:previewList){
  510. totalTime += type.getUserTime();
  511. categoryMap.put(type.getModule(), type.getUserTime());
  512. }
  513. // 按题型统计课程
  514. List<UserModuleRecordStatRelation> recordList = userCourseRecordService.statGroupType(user.getId(), null, null);
  515. for (UserModuleRecordStatRelation record : recordList){
  516. totalTime += record.getUserTime();
  517. // 累加同类型时间
  518. Integer time = categoryMap.getOrDefault(record.getModule(), 0);
  519. categoryMap.put(record.getModule(), time);
  520. }
  521. // 获取长难句阅读统计
  522. UserRecordStatRelation sentenceStatRelation = userSentenceRecordService.stat(user.getId(), null, null);
  523. if (sentenceStatRelation != null){
  524. Integer sentenceTime = categoryMap.getOrDefault(PaperModule.SENTENCE.key, 0);
  525. categoryMap.put(PaperModule.SENTENCE.key, sentenceTime + sentenceStatRelation.getUserTime());
  526. }
  527. List<ExerciseStruct> p = exerciseStructService.main();
  528. Map<String, String> m = new HashMap<>();
  529. for (ExerciseStruct struct : p){
  530. if (struct.getExtend() == null || struct.getExtend().isEmpty()) continue;
  531. m.put(struct.getExtend(), struct.getTitleZh() + (struct.getTitleEn().isEmpty() ? "":" "+struct.getTitleEn()));
  532. }
  533. // 组装数据
  534. List<UserStudyExtendDto> categorys = new ArrayList<>();
  535. if (categoryMap.containsKey(PaperModule.SENTENCE.key)) categorys.add(new UserStudyExtendDto(m.get(PaperModule.SENTENCE.key), categoryMap.get(PaperModule.SENTENCE.key)));
  536. if (categoryMap.containsKey(QuestionType.SC.key)) categorys.add(new UserStudyExtendDto(m.get(QuestionType.SC.key), categoryMap.get(QuestionType.SC.key)));
  537. if (categoryMap.containsKey(QuestionType.RC.key)) categorys.add(new UserStudyExtendDto(m.get(QuestionType.RC.key), categoryMap.get(QuestionType.RC.key)));
  538. if (categoryMap.containsKey(QuestionType.CR.key)) categorys.add(new UserStudyExtendDto(m.get(QuestionType.CR.key), categoryMap.get(QuestionType.CR.key)));
  539. if (categoryMap.containsKey(QuestionType.PS.key)){
  540. // 累加数学
  541. Integer time = categoryMap.getOrDefault(QuestionSubject.QUANT.key, 0);
  542. categoryMap.put(QuestionSubject.QUANT.key, time + categoryMap.get(QuestionType.PS.key));
  543. }
  544. if (categoryMap.containsKey(QuestionType.DS.key)){
  545. // 累加数学
  546. Integer time = categoryMap.getOrDefault(QuestionSubject.QUANT.key, 0);
  547. categoryMap.put(QuestionSubject.QUANT.key, time + categoryMap.get(QuestionType.DS.key));
  548. }
  549. if (categoryMap.containsKey(QuestionSubject.QUANT.key)) categorys.add(new UserStudyExtendDto(m.get(QuestionSubject.QUANT.key), categoryMap.get(QuestionSubject.QUANT.key)));
  550. if (categoryMap.containsKey(QuestionType.IR.key)) categorys.add(new UserStudyExtendDto(m.get(QuestionType.IR.key), categoryMap.get(QuestionType.IR.key)));
  551. if (categoryMap.containsKey(QuestionType.AWA.key)) categorys.add(new UserStudyExtendDto(m.get(QuestionType.AWA.key), categoryMap.get(QuestionType.AWA.key)));
  552. if (categoryMap.containsKey(PaperModule.EXAMINATION.key)) categorys.add(new UserStudyExtendDto("模考", categoryMap.get(PaperModule.EXAMINATION.key)));
  553. if (categoryMap.containsKey("freedom")) categorys.add(new UserStudyExtendDto("自由组卷", categoryMap.get("freedom")));
  554. dto.setTime(totalTime);
  555. dto.setCategorys(categorys);
  556. return ResponseHelp.success(dto);
  557. }
  558. @RequestMapping(value = "/data", method = RequestMethod.GET)
  559. @ApiOperation(value = "获取做题数据", notes = "获取做题数据", httpMethod = "GET")
  560. public Response<Map<String, UserDataDto>> questionData(
  561. @RequestParam(required = false) String module,
  562. @RequestParam(required = false) String subject,
  563. @RequestParam(required = false) Integer[] structIds,
  564. @RequestParam(required = false) String startTime,
  565. @RequestParam(required = false) String endTime
  566. ) {
  567. User user = (User) shiroHelp.getLoginUser();
  568. QuestionSubject questionSubject = QuestionSubject.ValueOf(subject);
  569. StructModule structModule = StructModule.ValueOf(module);
  570. List<QuestionNo> questionNoList = questionNoService.listByStruct(structModule, structIds);
  571. List<QuestionNoRelation> relationList = questionNoService.relation(questionNoList);
  572. Map<Number, QuestionNoRelation> relationMap = new HashMap<>();
  573. for(QuestionNoRelation relation : relationList){
  574. relationMap.put(relation.getId(), relation);
  575. }
  576. List<String> questionTypes = QuestionType.FromSubject(questionSubject);
  577. Map<String, UserDataDto> dtoMap = new HashMap<>();
  578. for(String questionType : questionTypes){
  579. UserDataDto dto = new UserDataDto();
  580. JSONObject placeMap = new JSONObject();
  581. JSONObject difficultMap = new JSONObject();
  582. Integer correctTime = 0;
  583. Integer incorrectTime = 0;
  584. List<QuestionNo> list = relationList.stream().filter((row)->row.getQuestion().getQuestionType().equals(questionType)).collect(Collectors.toList());
  585. PaperStat stat = questionNoService.statPaper(list);
  586. dto.setTotalCorrect(stat.getTotalCorrect());
  587. dto.setTotalNumber(stat.getTotalNumber());
  588. dto.setTotalTime(stat.getTotalTime());
  589. Collection questionNoIds = Transform.getIds(list, QuestionNo.class, "id");
  590. List<UserQuestion> userQuestionList = userQuestionService.listByQuestionWithTime(user.getId(), QuestionModule.BASE, questionNoIds, startTime, endTime);
  591. UserQuestionStat userQuestionStat = userQuestionService.statQuestion(userQuestionList);
  592. dto.setUserCorrect(userQuestionStat.getUserCorrect());
  593. dto.setUserNumber(userQuestionStat.getUserNumber());
  594. dto.setUserTime(userQuestionStat.getUserTime());
  595. for (UserQuestion userQuestion:userQuestionList){
  596. QuestionNoRelation relation = relationMap.get(userQuestion.getQuestionNoId());
  597. // 考点用时,以及正确度
  598. String placeKey = relation.getQuestion().getPlace();
  599. JSONObject place = placeMap.getJSONObject(placeKey);
  600. if (place == null){
  601. place = new JSONObject();
  602. place.put("key", placeKey);
  603. place.put("userNumber", 1);
  604. place.put("userCorrect", userQuestion.getIsCorrect());
  605. place.put("userTime", userQuestion.getUserTime());
  606. placeMap.put(placeKey, place);
  607. }else{
  608. place.put("userNumber", place.getInteger("userNumber") + 1);
  609. place.put("userCorrect", place.getInteger("userCorrect") + userQuestion.getIsCorrect());
  610. place.put("userTime", place.getInteger("userTime") + userQuestion.getUserTime());
  611. }
  612. // 难度正确度
  613. String difficultKey = relation.getQuestion().getDifficult();
  614. JSONObject difficult = difficultMap.getJSONObject(difficultKey);
  615. if (difficult == null){
  616. difficult = new JSONObject();
  617. difficult.put("key", difficultKey);
  618. difficult.put("userNumber", 1);
  619. difficult.put("userCorrect", userQuestion.getIsCorrect());
  620. difficult.put("totalNumber", relation.getTotalNumber());
  621. difficult.put("totalCorrect", relation.getTotalCorrect());
  622. difficultMap.put(difficultKey, difficult);
  623. }else{
  624. difficult.put("userNumber", difficult.getInteger("userNumber") + 1);
  625. difficult.put("userCorrect", difficult.getInteger("userCorrect") + userQuestion.getIsCorrect());
  626. difficult.put("totalNumber", difficult.getInteger("totalNumber") + relation.getTotalNumber());
  627. difficult.put("totalCorrect", difficult.getInteger("totalCorrect") + relation.getTotalCorrect());
  628. }
  629. if (userQuestion.getIsCorrect() > 0){
  630. correctTime += userQuestion.getUserTime();
  631. }else{
  632. incorrectTime += userQuestion.getUserTime();
  633. }
  634. }
  635. JSONArray difficult = new JSONArray();
  636. JSONArray place = new JSONArray();
  637. difficult.addAll(difficultMap.values());
  638. place.addAll(placeMap.values());
  639. dto.setDifficult(difficult);
  640. dto.setPlace(place);
  641. dto.setCorrectTime(correctTime);
  642. dto.setIncorrectTime(incorrectTime);
  643. dtoMap.put(questionType, dto);
  644. }
  645. return ResponseHelp.success(dtoMap);
  646. }
  647. @RequestMapping(value = "/collect/experience/add", method = RequestMethod.PUT)
  648. @ApiOperation(value = "添加心经收藏", notes = "添加心经收藏", httpMethod = "PUT")
  649. public Response<Boolean> addExperienceCollect(@RequestBody @Validated UserCollectExperienceDto dto) {
  650. UserCollectExperience entity = Transform.dtoToEntity(dto);
  651. User user = (User) shiroHelp.getLoginUser();
  652. entity.setUserId(user.getId());
  653. userCollectExperienceService.addExperience(entity);
  654. return ResponseHelp.success(true);
  655. }
  656. @RequestMapping(value = "/collect/experience/delete", method = RequestMethod.DELETE)
  657. @ApiOperation(value = "移除心经收藏", notes = "移除心经收藏", httpMethod = "DELETE")
  658. public Response<Boolean> deleteExperienceCollect(Integer experienceId) {
  659. User user = (User) shiroHelp.getLoginUser();
  660. Boolean result = userCollectExperienceService.deleteExperience(user.getId(), experienceId);
  661. return ResponseHelp.success(result);
  662. }
  663. @RequestMapping(value = "/collect/experience/list", method = RequestMethod.GET)
  664. @ApiOperation(value = "获取收藏心经列表", notes = "获取收藏心经列表", httpMethod = "GET")
  665. public Response<PageMessage<CourseExperience>> listExperienceCollect(
  666. @RequestParam(required = false, defaultValue = "1") int page,
  667. @RequestParam(required = false, defaultValue = "100") int size,
  668. @RequestParam(required = false) String startTime,
  669. @RequestParam(required = false) String endTime,
  670. @RequestParam(required = false, defaultValue = "id") String order, // collect_time, update_time
  671. @RequestParam(required = false, defaultValue = "desc") String direction,
  672. HttpSession session) {
  673. User user = (User) shiroHelp.getLoginUser();
  674. Page<CourseExperience> p = courseExperienceService.listWithUser(page, size, user.getId(), startTime, endTime, order, DirectionStatus.ValueOf(direction));
  675. return ResponseHelp.success(p, page, size, p.getTotal());
  676. }
  677. @RequestMapping(value = "/collect/question/add", method = RequestMethod.PUT)
  678. @ApiOperation(value = "添加题目收藏", notes = "添加题目收藏", httpMethod = "PUT")
  679. public Response<Boolean> addQuestionCollect(@RequestBody @Validated UserCollectQuestionDto dto) {
  680. UserCollectQuestion entity = Transform.dtoToEntity(dto);
  681. User user = (User) shiroHelp.getLoginUser();
  682. switch (QuestionModule.ValueOf(dto.getQuestionModule())){
  683. case BASE:
  684. entity.setQuestionModule(QuestionModule.BASE.key);
  685. QuestionNo questionNo = questionNoService.get(dto.getQuestionNoId());
  686. entity.setQuestionId(questionNo.getQuestionId());
  687. entity.setQuestionNoId(questionNo.getId());
  688. break;
  689. case SENTENCE:
  690. entity.setQuestionModule(QuestionModule.SENTENCE.key);
  691. SentenceQuestion sentenceQuestion = sentenceQuestionService.get(dto.getQuestionNoId());
  692. entity.setQuestionId(sentenceQuestion.getQuestionId());
  693. entity.setQuestionNoId(sentenceQuestion.getId());
  694. break;
  695. case TEXTBOOK:
  696. entity.setQuestionModule(QuestionModule.TEXTBOOK.key);
  697. TextbookQuestion textbookQuestion = textbookQuestionService.get(dto.getQuestionNoId());
  698. entity.setQuestionId(textbookQuestion.getQuestionId());
  699. entity.setQuestionNoId(textbookQuestion.getId());
  700. break;
  701. }
  702. entity.setUserId(user.getId());
  703. userCollectQuestionService.addQuestion(entity);
  704. return ResponseHelp.success(true);
  705. }
  706. @RequestMapping(value = "/collect/question/delete", method = RequestMethod.DELETE)
  707. @ApiOperation(value = "移除题目收藏", notes = "移除题目收藏", httpMethod = "DELETE")
  708. public Response<Boolean> deleteQuestionCollect(String questionModule, Integer questionNoId) {
  709. User user = (User) shiroHelp.getLoginUser();
  710. Integer questionId = null;
  711. switch (QuestionModule.ValueOf(questionModule)){
  712. case BASE:
  713. QuestionNo questionNo = questionNoService.get(questionNoId);
  714. questionId = questionNo.getQuestionId();
  715. break;
  716. case SENTENCE:
  717. SentenceQuestion sentenceQuestion = sentenceQuestionService.get(questionNoId);
  718. questionId = sentenceQuestion.getQuestionId();
  719. break;
  720. case TEXTBOOK:
  721. TextbookQuestion textbookQuestion = textbookQuestionService.get(questionNoId);
  722. questionId = textbookQuestion.getQuestionId();
  723. break;
  724. }
  725. Boolean result = userCollectQuestionService.deleteQuestion(user.getId(), questionId);
  726. return ResponseHelp.success(result);
  727. }
  728. @RequestMapping(value = "/collect/question/bind", method = RequestMethod.POST)
  729. @ApiOperation(value = "收藏题目组卷", notes = "收藏题目组卷", httpMethod = "POST")
  730. public Response<UserPaper> bindQuestionCollect(@RequestBody @Validated UserCustomBindDto dto) {
  731. User user = (User) shiroHelp.getLoginUser();
  732. UserPaper userPaper = questionFlowService.makePaper(
  733. user.getId(),
  734. QuestionModule.ValueOf(dto.getQuestionModule()),
  735. PaperOrigin.COLLECT,
  736. Arrays.stream(dto.getQuestionNoIds()).collect(Collectors.toList()),
  737. dto.getFilterTimes()
  738. );
  739. return ResponseHelp.success(userPaper);
  740. }
  741. @RequestMapping(value = "/collect/question/list", method = RequestMethod.GET)
  742. @ApiOperation(value = "获取收藏题目列表", notes = "获取收藏题目列表", httpMethod = "GET")
  743. public Response<PageMessage<UserCollectQuestionInfoDto>> listQuestionCollect(
  744. @RequestParam(required = false, defaultValue = "1") int page,
  745. @RequestParam(required = false, defaultValue = "100") int size,
  746. @RequestParam(required = false) String keyword,
  747. @RequestParam(required = false) String module,
  748. @RequestParam(required = false) String[] questionTypes,
  749. @RequestParam(required = false) Integer[] structIds,
  750. @RequestParam(required = false) String startTime,
  751. @RequestParam(required = false) String endTime,
  752. @RequestParam(required = false) Boolean latest,
  753. @RequestParam(required = false) String year,
  754. @RequestParam(required = false) String order, // (pid asc, no asc), time, correct, question_type, latest_time
  755. HttpSession session) {
  756. User user = (User) shiroHelp.getLoginUser();
  757. QuestionNoModule questionNoModule = QuestionNoModule.ValueOf(module);
  758. Page<UserCollectQuestion> p = null;
  759. if(questionNoModule == QuestionNoModule.EXERCISE){
  760. p = userCollectQuestionService.listExercise(page, size, user.getId(), keyword, questionTypes, structIds, startTime, endTime, order != null ? order.replace("|", " ") : null);
  761. }else if (questionNoModule == QuestionNoModule.EXAMINATION){
  762. Integer libraryId = null;
  763. if (latest != null){
  764. if (latest) {
  765. TextbookLibrary textbookLibrary = textbookLibraryService.getLatest();
  766. libraryId = textbookLibrary.getId();
  767. year = null;
  768. }
  769. }
  770. p = userCollectQuestionService.listExamination(page, size, user.getId(), keyword, questionTypes, structIds, libraryId, year, startTime, endTime, order != null ? order.replace("|", " ") : null);
  771. }else{
  772. throw new ParameterException("参数逻辑错误");
  773. }
  774. List<UserCollectQuestionInfoDto> pr = Transform.convert(p, UserCollectQuestionInfoDto.class);
  775. // 获取题目信息
  776. Collection questionIds = Transform.getIds(pr, UserCollectQuestionInfoDto.class, "questionId");
  777. List<Question> questionList = questionService.select(questionIds);
  778. Transform.combine(pr, questionList, UserCollectQuestionInfoDto.class, "questionId", "question", Question.class, "id", QuestionExtendDto.class);
  779. List<UserCollectQuestionInfoDto> basePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.BASE.key)).collect(Collectors.toList());
  780. Collection baseQuestionNoIds = Transform.getIds(basePr, UserCollectQuestionInfoDto.class, "questionNoId");
  781. List<QuestionNo> baseQuestionNoList = questionNoService.select(baseQuestionNoIds);
  782. Transform.combine(basePr, baseQuestionNoList, UserCollectQuestionInfoDto.class, "questionNoId", "questionNo", QuestionNo.class, "id", QuestionNoExtendDto.class);
  783. List<UserCollectQuestionInfoDto> sentencePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.SENTENCE.key)).collect(Collectors.toList());
  784. Collection sentenceQuestionNoIds = Transform.getIds(sentencePr, UserCollectQuestionInfoDto.class, "questionNoId");
  785. List<SentenceQuestion> sentenceQuestionList = sentenceQuestionService.select(sentenceQuestionNoIds);
  786. Transform.combine(sentencePr, sentenceQuestionList, UserCollectQuestionInfoDto.class, "questionNoId", "questionNo", SentenceQuestion.class, "id", QuestionNoExtendDto.class);
  787. List<UserCollectQuestionInfoDto> textbookPr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.TEXTBOOK.key)).collect(Collectors.toList());
  788. Collection textbookQuestionNoIds = Transform.getIds(textbookPr, UserCollectQuestionInfoDto.class, "questionNoId");
  789. List<TextbookQuestion> textbookQuestionList = textbookQuestionService.select(textbookQuestionNoIds);
  790. Transform.combine(textbookPr, textbookQuestionList, UserCollectQuestionInfoDto.class, "questionNoId", "questionNo", TextbookQuestion.class, "id", QuestionNoExtendDto.class);
  791. // 绑定题目统计
  792. List<UserQuestion> userQuestionList = userQuestionService.listByQuestion(user.getId(), questionIds);
  793. Map<Object, UserQuestionStat> stats = userQuestionService.statQuestionMap(userQuestionList);
  794. Transform.combine(pr, stats, UserCollectQuestionInfoDto.class, "questionId", "stat");
  795. // 最近做题
  796. List<UserQuestion> lastList = userQuestionService.listWithLast(questionIds);
  797. Map lastMap = Transform.getMap(lastList, UserQuestion.class, "id", "createTime");
  798. Transform.combine(pr, lastMap, UserQuestionErrorInfoDto.class, "questionId", "latestTime");
  799. return ResponseHelp.success(pr, page, size, p.getTotal());
  800. }
  801. @RequestMapping(value = "/error/list", method = RequestMethod.GET)
  802. @ApiOperation(value = "获取错题列表", notes = "获取错题列表", httpMethod = "GET")
  803. public Response<PageMessage<UserQuestionErrorInfoDto>> listError(
  804. @RequestParam(required = false, defaultValue = "1") int page,
  805. @RequestParam(required = false, defaultValue = "100") int size,
  806. @RequestParam(required = false) String keyword,
  807. @RequestParam(required = false) String module,
  808. @RequestParam(required = false) String[] questionTypes,
  809. @RequestParam(required = false) Integer[] structIds,
  810. @RequestParam(required = false) String startTime,
  811. @RequestParam(required = false) String endTime,
  812. @RequestParam(required = false) Boolean latest,
  813. @RequestParam(required = false) String year,
  814. @RequestParam(required = false) String order // (pid asc, no asc), time, correct, question_type, latest_time
  815. ) {
  816. User user = (User) shiroHelp.getLoginUser();
  817. QuestionNoModule questionNoModule = QuestionNoModule.ValueOf(module);
  818. Page<UserQuestion> p = null;
  819. if(questionNoModule == QuestionNoModule.EXERCISE){
  820. p = userQuestionService.listExerciseError(page, size, user.getId(), keyword, questionTypes, structIds, startTime, endTime, order != null ? order.replace("|", " ") : null);
  821. }else if (questionNoModule == QuestionNoModule.EXAMINATION){
  822. Integer libraryId = null;
  823. if (latest != null){
  824. if (latest) {
  825. TextbookLibrary textbookLibrary = textbookLibraryService.getLatest();
  826. libraryId = textbookLibrary.getId();
  827. year = null;
  828. }
  829. }
  830. p = userQuestionService.listExaminationError(page, size, user.getId(), keyword, questionTypes, structIds, libraryId, year, startTime, endTime, order != null ? order.replace("|", " ") : null);
  831. }else{
  832. throw new ParameterException("参数逻辑错误");
  833. }
  834. List<UserQuestionErrorInfoDto> pr = Transform.convert(p, UserQuestionErrorInfoDto.class);
  835. // 获取题目信息
  836. Collection questionIds = Transform.getIds(pr, UserQuestionErrorInfoDto.class, "questionId");
  837. List<Question> questionList = questionService.select(questionIds);
  838. Transform.combine(pr, questionList, UserQuestionErrorInfoDto.class, "questionId", "question", Question.class, "id", QuestionExtendDto.class);
  839. List<UserQuestionErrorInfoDto> basePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.BASE.key)).collect(Collectors.toList());
  840. Collection baseQuestionNoIds = Transform.getIds(basePr, UserQuestionErrorInfoDto.class, "questionNoId");
  841. List<QuestionNo> baseQuestionNoList = questionNoService.select(baseQuestionNoIds);
  842. Transform.combine(basePr, baseQuestionNoList, UserQuestionErrorInfoDto.class, "questionNoId", "questionNo", QuestionNo.class, "id", QuestionNoExtendDto.class);
  843. List<UserQuestionErrorInfoDto> sentencePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.SENTENCE.key)).collect(Collectors.toList());
  844. Collection sentenceQuestionNoIds = Transform.getIds(sentencePr, UserQuestionErrorInfoDto.class, "questionNoId");
  845. List<SentenceQuestion> sentenceQuestionList = sentenceQuestionService.select(sentenceQuestionNoIds);
  846. Transform.combine(sentencePr, sentenceQuestionList, UserQuestionErrorInfoDto.class, "questionNoId", "questionNo", SentenceQuestion.class, "id", QuestionNoExtendDto.class);
  847. List<UserQuestionErrorInfoDto> textbookPr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.TEXTBOOK.key)).collect(Collectors.toList());
  848. Collection textbookQuestionNoIds = Transform.getIds(textbookPr, UserQuestionErrorInfoDto.class, "questionNoId");
  849. List<TextbookQuestion> textbookQuestionList = textbookQuestionService.select(textbookQuestionNoIds);
  850. Transform.combine(textbookPr, textbookQuestionList, UserQuestionErrorInfoDto.class, "questionNoId", "questionNo", TextbookQuestion.class, "id", QuestionNoExtendDto.class);
  851. // 绑定题目统计
  852. List<UserQuestion> userQuestionList = userQuestionService.listByQuestion(user.getId(), questionIds);
  853. Map<Object, UserQuestionStat> stats = userQuestionService.statQuestionMap(userQuestionList);
  854. Transform.combine(pr, stats, UserQuestionErrorInfoDto.class, "questionId", "stat");
  855. // 最近做题
  856. List<UserQuestion> lastList = userQuestionService.listWithLast(questionIds);
  857. Map lastMap = Transform.getMap(lastList, UserQuestion.class, "id", "createTime");
  858. Transform.combine(pr, lastMap, UserQuestionErrorInfoDto.class, "questionId", "latestTime");
  859. return ResponseHelp.success(pr, page, size, p.getTotal());
  860. }
  861. @RequestMapping(value = "/error/bind", method = RequestMethod.POST)
  862. @ApiOperation(value = "错题组卷", notes = "错题组卷", httpMethod = "POST")
  863. public Response<UserPaper> bindError(@RequestBody @Validated UserCustomBindDto dto) {
  864. User user = (User) shiroHelp.getLoginUser();
  865. UserPaper userPaper = questionFlowService.makePaper(
  866. user.getId(),
  867. QuestionModule.ValueOf(dto.getQuestionModule()),
  868. PaperOrigin.ERROR,
  869. Arrays.stream(dto.getQuestionNoIds()).collect(Collectors.toList()),
  870. dto.getFilterTimes()
  871. );
  872. return ResponseHelp.success(userPaper);
  873. }
  874. @RequestMapping(value = "/error/clear", method = RequestMethod.POST)
  875. @ApiOperation(value = "错题移除", notes = "错题移除", httpMethod = "POST")
  876. public Response<Boolean> clearError(@RequestBody @Validated UserQuestionIdsDto dto) {
  877. User user = (User) shiroHelp.getLoginUser();
  878. List<UserQuestion> questionList = userQuestionService.select(dto.getQuestionNoIds());
  879. userPaperQuestionService.addRemoveError(questionList);
  880. return ResponseHelp.success(true);
  881. }
  882. @RequestMapping(value = "/error/remove", method = RequestMethod.POST)
  883. @ApiOperation(value = "移除正确题", notes = "移除正确题", httpMethod = "POST")
  884. public Response<Boolean> removeError(@RequestBody @Validated ErrorReportDto dto) {
  885. User user = (User) shiroHelp.getLoginUser();
  886. UserReport report = userReportService.get(dto.getUserReportId());
  887. if (report.getIsFinish() == 0){
  888. throw new ParameterException("试卷未完成");
  889. }
  890. List<UserQuestion> questionList = userQuestionService.listByReport(user.getId(), dto.getUserReportId());
  891. userPaperQuestionService.addRemoveError(questionList);
  892. return ResponseHelp.success(true);
  893. }
  894. @RequestMapping(value = "/note/question", method = RequestMethod.PUT)
  895. @ApiOperation(value = "更新题目笔记", notes = "更新题目笔记", httpMethod = "PUT")
  896. public Response<Boolean> updateNoteQuestion(@RequestBody @Validated UserNoteQuestionDto dto) {
  897. UserNoteQuestion entity = Transform.dtoToEntity(dto);
  898. User user = (User) shiroHelp.getLoginUser();
  899. entity.setUserId(user.getId());
  900. switch (QuestionModule.ValueOf(dto.getQuestionModule())){
  901. case BASE:
  902. entity.setQuestionModule(QuestionModule.BASE.key);
  903. QuestionNo questionNo = questionNoService.get(dto.getQuestionNoId());
  904. entity.setQuestionId(questionNo.getQuestionId());
  905. entity.setQuestionNoId(questionNo.getId());
  906. break;
  907. case SENTENCE:
  908. entity.setQuestionModule(QuestionModule.SENTENCE.key);
  909. SentenceQuestion sentenceQuestion = sentenceQuestionService.get(dto.getQuestionNoId());
  910. entity.setQuestionId(sentenceQuestion.getQuestionId());
  911. entity.setQuestionNoId(sentenceQuestion.getId());
  912. break;
  913. case TEXTBOOK:
  914. entity.setQuestionModule(QuestionModule.TEXTBOOK.key);
  915. TextbookQuestion textbookQuestion = textbookQuestionService.get(dto.getQuestionNoId());
  916. entity.setQuestionId(textbookQuestion.getQuestionId());
  917. entity.setQuestionNoId(textbookQuestion.getId());
  918. break;
  919. }
  920. userNoteQuestionService.update(entity);
  921. return ResponseHelp.success(true);
  922. }
  923. @RequestMapping(value = "/note/question/list", method = RequestMethod.GET)
  924. @ApiOperation(value = "获取题目笔记列表", notes = "获取笔记列表", httpMethod = "GET")
  925. public Response<PageMessage<UserNoteQuestionInfoDto>> listNoteQuestion(
  926. @RequestParam(required = false, defaultValue = "1") int page,
  927. @RequestParam(required = false, defaultValue = "100") int size,
  928. @RequestParam(required = false) String keyword,
  929. @RequestParam(required = false) String module,
  930. @RequestParam(required = false) String[] questionTypes,
  931. @RequestParam(required = false) Integer[] structIds,
  932. @RequestParam(required = false) String startTime,
  933. @RequestParam(required = false) String endTime,
  934. @RequestParam(required = false) Boolean latest,
  935. @RequestParam(required = false) String year,
  936. @RequestParam(required = false) String order, // update_time
  937. HttpSession session) {
  938. User user = (User) shiroHelp.getLoginUser();
  939. QuestionNoModule questionNoModule = QuestionNoModule.ValueOf(module);
  940. Page<UserNoteQuestion> p = null;
  941. if(questionNoModule == QuestionNoModule.EXERCISE){
  942. p = userNoteQuestionService.listExercise(page, size, user.getId(), keyword, questionTypes, structIds, startTime, endTime, order != null ? order.replace("|", " ") : null);
  943. }else if (questionNoModule == QuestionNoModule.EXAMINATION){
  944. Integer libraryId = null;
  945. if (latest != null){
  946. if (latest) {
  947. TextbookLibrary textbookLibrary = textbookLibraryService.getLatest();
  948. libraryId = textbookLibrary.getId();
  949. year = null;
  950. }
  951. }
  952. p = userNoteQuestionService.listExamination(page, size, user.getId(), keyword, questionTypes, structIds, libraryId, year, startTime, endTime, order != null ? order.replace("|", " ") : null);
  953. }else{
  954. throw new ParameterException("参数逻辑错误");
  955. }
  956. List<UserNoteQuestionInfoDto> pr = Transform.convert(p, UserNoteQuestionInfoDto.class);
  957. // 获取题目信息
  958. Collection questionIds = Transform.getIds(pr, UserNoteQuestionInfoDto.class, "questionId");
  959. List<Question> questionList = questionService.select(questionIds);
  960. Transform.combine(pr, questionList, UserNoteQuestionInfoDto.class, "questionId", "question", Question.class, "id", QuestionExtendDto.class);
  961. List<UserNoteQuestionInfoDto> basePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.BASE.key)).collect(Collectors.toList());
  962. Collection baseQuestionNoIds = Transform.getIds(basePr, UserNoteQuestionInfoDto.class, "questionNoId");
  963. List<QuestionNo> baseQuestionNoList = questionNoService.select(baseQuestionNoIds);
  964. Transform.combine(basePr, baseQuestionNoList, UserNoteQuestionInfoDto.class, "questionNoId", "questionNo", QuestionNo.class, "id", QuestionNoExtendDto.class);
  965. List<UserNoteQuestionInfoDto> sentencePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.SENTENCE.key)).collect(Collectors.toList());
  966. Collection sentenceQuestionNoIds = Transform.getIds(sentencePr, UserNoteQuestionInfoDto.class, "questionNoId");
  967. List<SentenceQuestion> sentenceQuestionList = sentenceQuestionService.select(sentenceQuestionNoIds);
  968. Transform.combine(sentencePr, sentenceQuestionList, UserNoteQuestionInfoDto.class, "questionNoId", "questionNo", SentenceQuestion.class, "id", QuestionNoExtendDto.class);
  969. List<UserNoteQuestionInfoDto> textbookPr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.TEXTBOOK.key)).collect(Collectors.toList());
  970. Collection textbookQuestionNoIds = Transform.getIds(textbookPr, UserNoteQuestionInfoDto.class, "questionNoId");
  971. List<TextbookQuestion> textbookQuestionList = textbookQuestionService.select(textbookQuestionNoIds);
  972. Transform.combine(textbookPr, textbookQuestionList, UserNoteQuestionInfoDto.class, "questionNoId", "questionNo", TextbookQuestion.class, "id", QuestionNoExtendDto.class);
  973. return ResponseHelp.success(pr, page, size, p.getTotal());
  974. }
  975. @RequestMapping(value = "/note/course", method = RequestMethod.PUT)
  976. @ApiOperation(value = "更新课程笔记", notes = "更新课程笔记", httpMethod = "PUT")
  977. public Response<Boolean> updateNoteCourse(@RequestBody @Validated UserNoteQuestionDto dto) {
  978. UserNoteCourse entity = Transform.dtoToEntity(dto);
  979. User user = (User) shiroHelp.getLoginUser();
  980. entity.setUserId(user.getId());
  981. userNoteCourseService.update(entity);
  982. return ResponseHelp.success(true);
  983. }
  984. @RequestMapping(value = "/report/list", method = RequestMethod.GET)
  985. @ApiOperation(value = "获取报告列表", notes = "获取报告列表", httpMethod = "GET")
  986. public Response<PageMessage<UserPaperDto>> listReport(
  987. @RequestParam(required = false, defaultValue = "1") int page,
  988. @RequestParam(required = false, defaultValue = "100") int size,
  989. @RequestParam(required = false) String keyword,
  990. @RequestParam(required = false) String module,
  991. @RequestParam(required = false) String origin,
  992. @RequestParam(required = false) String[] questionTypes,
  993. @RequestParam(required = false) Integer[] structIds,
  994. @RequestParam(required = false) String startTime,
  995. @RequestParam(required = false) String endTime,
  996. @RequestParam(required = false) Boolean latest,
  997. @RequestParam(required = false) String year,
  998. @RequestParam(required = false) String[] courseModules,
  999. @RequestParam(required = false) String order, // title, latest_time,correct,time
  1000. HttpSession session) {
  1001. User user = (User) shiroHelp.getLoginUser();
  1002. PaperOrigin paperOrigin = PaperOrigin.ValueOf(origin);
  1003. QuestionNoModule questionNoModule = QuestionNoModule.ValueOf(module);
  1004. Page<UserPaper> p = null;
  1005. if (questionNoModule != null && (paperOrigin == PaperOrigin.COLLECT || paperOrigin == PaperOrigin.ERROR)){
  1006. p = userPaperService.list(page, size, user.getId(), keyword, paperOrigin, startTime, endTime, order != null ? order.replace("|", " ") : null);
  1007. }else if(questionNoModule == QuestionNoModule.EXERCISE){
  1008. p = userPaperService.listExercise(page, size, user.getId(), keyword, questionTypes, structIds, courseModules, startTime, endTime, order != null ? order.replace("|", " ") : null);
  1009. }else if (questionNoModule == QuestionNoModule.EXAMINATION){
  1010. Integer libraryId = null;
  1011. if (latest != null){
  1012. paperOrigin = PaperOrigin.TEXTBOOK;
  1013. if (latest) {
  1014. TextbookLibrary textbookLibrary = textbookLibraryService.getLatest();
  1015. libraryId = textbookLibrary.getId();
  1016. year = null;
  1017. }
  1018. }
  1019. p = userPaperService.listExamination(page, size, user.getId(), keyword, structIds, libraryId, year, startTime, endTime, order != null ? order.replace("|", " ") : null);
  1020. }else{
  1021. throw new ParameterException("参数逻辑错误");
  1022. }
  1023. List<UserPaperDto> pr = Transform.convert(p, UserPaperDto.class);
  1024. Collection paperIds = Transform.getIds(p, UserPaper.class, "id");
  1025. // 绑定用户报告
  1026. Map<Object, Collection<UserReport>> reportByPaper = userReportService.mapByPaper(paperIds);
  1027. Transform.combine(pr, reportByPaper, UserPaperDto.class, "id", "reports", UserReportExtendDto.class);
  1028. // 获取试卷统计信息
  1029. List<UserPaperDto> basePr = pr.stream().filter((row)->QuestionModule.BASE == QuestionModule.WithPaper(PaperModule.ValueOf(row.getPaperModule()))).collect(Collectors.toList());
  1030. Map<Integer, Integer[]> baseIdsMap = new HashMap<>();
  1031. for(UserPaperDto paper : basePr){
  1032. baseIdsMap.put(paper.getId(), paper.getQuestionNoIds());
  1033. }
  1034. Map baseStatMap = questionNoService.statPaperMap(baseIdsMap);
  1035. Transform.combine(pr, baseStatMap, UserPaperDto.class, "id", "stat");
  1036. List<UserPaperDto> sentencePr = pr.stream().filter((row)->QuestionModule.SENTENCE == QuestionModule.WithPaper(PaperModule.ValueOf(row.getPaperModule()))).collect(Collectors.toList());
  1037. Map<Integer, Integer[]> sentenceIdsMap = new HashMap<>();
  1038. for(UserPaperDto paper : sentencePr){
  1039. sentenceIdsMap.put(paper.getId(), paper.getQuestionNoIds());
  1040. }
  1041. Map sentenceStatMap = sentenceQuestionService.statPaperMap(sentenceIdsMap);
  1042. Transform.combine(pr, sentenceStatMap, UserPaperDto.class, "id", "stat");
  1043. List<UserPaperDto> textbookPr = pr.stream().filter((row)->QuestionModule.TEXTBOOK == QuestionModule.WithPaper(PaperModule.ValueOf(row.getPaperModule()))).collect(Collectors.toList());
  1044. Map<Integer, Integer[]> textbookIdsMap = new HashMap<>();
  1045. for(UserPaperDto paper : textbookPr){
  1046. textbookIdsMap.put(paper.getId(), paper.getQuestionNoIds());
  1047. }
  1048. Map textbookStatMap = textbookQuestionService.statPaperMap(textbookIdsMap);
  1049. Transform.combine(pr, textbookStatMap, UserPaperDto.class, "id", "stat");
  1050. return ResponseHelp.success(pr, page, size, p.getTotal());
  1051. }
  1052. @RequestMapping(value = "/ask/question", method = RequestMethod.POST)
  1053. @ApiOperation(value = "添加题目提问", notes = "添加题目提问", httpMethod = "POST")
  1054. public Response<Boolean> addAskQuestion(@RequestBody @Validated UserAskQuestionDto dto) {
  1055. UserAskQuestion entity = Transform.dtoToEntity(dto);
  1056. User user = (User) shiroHelp.getLoginUser();
  1057. entity.setUserId(user.getId());
  1058. PaperModule paperModule = PaperModule.ValueOf(dto.getPaperModule());
  1059. QuestionModule questionModule = QuestionModule.WithPaper(paperModule);
  1060. Question question;
  1061. switch (questionModule){
  1062. case BASE:
  1063. entity.setQuestionModule(QuestionModule.BASE.key);
  1064. QuestionNo questionNo = questionNoService.get(dto.getQuestionNoId());
  1065. entity.setQuestionId(questionNo.getQuestionId());
  1066. entity.setQuestionNoId(questionNo.getId());
  1067. question = questionService.get(questionNo.getQuestionId());
  1068. break;
  1069. case SENTENCE:
  1070. entity.setQuestionModule(QuestionModule.SENTENCE.key);
  1071. SentenceQuestion sentenceQuestion = sentenceQuestionService.get(dto.getQuestionNoId());
  1072. entity.setQuestionId(sentenceQuestion.getQuestionId());
  1073. entity.setQuestionNoId(sentenceQuestion.getId());
  1074. question = questionService.get(sentenceQuestion.getQuestionId());
  1075. break;
  1076. case TEXTBOOK:
  1077. entity.setQuestionModule(QuestionModule.TEXTBOOK.key);
  1078. TextbookQuestion textbookQuestion = textbookQuestionService.get(dto.getQuestionNoId());
  1079. entity.setQuestionId(textbookQuestion.getQuestionId());
  1080. entity.setQuestionNoId(textbookQuestion.getId());
  1081. question = questionService.get(textbookQuestion.getQuestionId());
  1082. break;
  1083. default:
  1084. throw new ParameterException("题目模块错误");
  1085. }
  1086. entity.setAskModule(AskModule.WithPaper(paperModule).key);
  1087. Integer assignId = null;
  1088. if (dto.getUserPaperId() != null && dto.getUserPaperId() > 0){
  1089. UserPaper userPaper = userPaperService.get(dto.getUserPaperId());
  1090. if(userPaper != null && userPaper.getPaperOrigin().equals(PaperOrigin.PREVIEW.key)){
  1091. assignId = userPaper.getOriginId();
  1092. }
  1093. }
  1094. Integer recordId = questionFlowService.questionRelationCourse(user.getId(), assignId, QuestionType.ValueOf(question.getQuestionType()));
  1095. if (recordId != null){
  1096. // 绑定提问权限
  1097. entity.setRecordId(recordId);
  1098. UserOrderRecord record = userOrderRecordService.get(recordId);
  1099. entity.setAskTime(record.getAskTime());
  1100. Date now = new Date();
  1101. entity.setExpireTime(Tools.addHour(now, record.getAskTime() / 3600));
  1102. }else{
  1103. // todo 判断题目是否有提问权限
  1104. }
  1105. userAskQuestionService.add(entity);
  1106. return ResponseHelp.success(true);
  1107. }
  1108. @RequestMapping(value = "/ask/question/delete", method = RequestMethod.DELETE)
  1109. @ApiOperation(value = "提问删除", httpMethod = "DELETE")
  1110. public Response<Boolean> deleteAskQuestion(@RequestParam int id, HttpServletRequest request) {
  1111. UserAskQuestion in = userAskQuestionService.get(id);
  1112. User user = (User) shiroHelp.getLoginUser();
  1113. if(in == null){
  1114. throw new ParameterException("提问不存在");
  1115. }
  1116. if (!in.getUserId().equals(user.getId())){
  1117. throw new ParameterException("提问不存在");
  1118. }
  1119. if (in.getAnswerStatus()== AskStatus.ANSWER.index){
  1120. throw new ParameterException("提问已回答");
  1121. }
  1122. userAskQuestionService.delete(id);
  1123. // 如果
  1124. return ResponseHelp.success(true);
  1125. }
  1126. @RequestMapping(value = "/ask/question/list", method = RequestMethod.GET)
  1127. @ApiOperation(value = "获取题目提问列表", notes = "获取题目提问列表", httpMethod = "GET")
  1128. public Response<PageMessage<UserAskQuestionInfoDto>> listAskQuestion(
  1129. @RequestParam(required = false, defaultValue = "1") int page,
  1130. @RequestParam(required = false, defaultValue = "100") int size,
  1131. @RequestParam(required = false) String keyword,
  1132. @RequestParam(required = false) String module,
  1133. @RequestParam(required = false) String[] questionTypes,
  1134. @RequestParam(required = false) Integer[] structIds,
  1135. @RequestParam(required = false) String startTime,
  1136. @RequestParam(required = false) String endTime,
  1137. @RequestParam(required = false) Integer askStatus,
  1138. @RequestParam(required = false) Boolean latest,
  1139. @RequestParam(required = false) String year,
  1140. @RequestParam(required = false) String order, // create_time, answer_time
  1141. HttpSession session) {
  1142. User user = (User) shiroHelp.getLoginUser();
  1143. QuestionNoModule questionNoModule = QuestionNoModule.ValueOf(module);
  1144. Page<UserAskQuestion> p = null;
  1145. if(questionNoModule == QuestionNoModule.EXERCISE){
  1146. p = userAskQuestionService.listExercise(page, size, user.getId(), keyword, questionTypes, structIds, AskStatus.ValueOf(askStatus),startTime, endTime, order != null ? order.replace("|", " ") : null);
  1147. }else if (questionNoModule == QuestionNoModule.EXAMINATION){
  1148. Integer libraryId = null;
  1149. if (latest != null){
  1150. if (latest) {
  1151. TextbookLibrary textbookLibrary = textbookLibraryService.getLatest();
  1152. libraryId = textbookLibrary.getId();
  1153. year = null;
  1154. }
  1155. }
  1156. p = userAskQuestionService.listExamination(page, size, user.getId(), keyword, questionTypes, structIds, libraryId, year, AskStatus.ValueOf(askStatus), startTime, endTime, order != null ? order.replace("|", " ") : null);
  1157. }else{
  1158. throw new ParameterException("参数逻辑错误");
  1159. }
  1160. List<UserAskQuestionInfoDto> pr = Transform.convert(p, UserAskQuestionInfoDto.class);
  1161. // 获取题目信息
  1162. Collection questionIds = Transform.getIds(pr, UserNoteQuestionInfoDto.class, "questionId");
  1163. List<Question> questionList = questionService.select(questionIds);
  1164. Transform.combine(pr, questionList, UserNoteQuestionInfoDto.class, "questionId", "question", Question.class, "id", QuestionExtendDto.class);
  1165. List<UserAskQuestionInfoDto> basePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.BASE.key)).collect(Collectors.toList());
  1166. Collection baseQuestionNoIds = Transform.getIds(basePr, UserAskQuestionInfoDto.class, "questionNoId");
  1167. List<QuestionNo> baseQuestionNoList = questionNoService.select(baseQuestionNoIds);
  1168. Transform.combine(basePr, baseQuestionNoList, UserAskQuestionInfoDto.class, "questionNoId", "questionNo", QuestionNo.class, "id", QuestionNoExtendDto.class);
  1169. List<UserAskQuestionInfoDto> sentencePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.SENTENCE.key)).collect(Collectors.toList());
  1170. Collection sentenceQuestionNoIds = Transform.getIds(sentencePr, UserAskQuestionInfoDto.class, "questionNoId");
  1171. List<SentenceQuestion> sentenceQuestionList = sentenceQuestionService.select(sentenceQuestionNoIds);
  1172. Transform.combine(sentencePr, sentenceQuestionList, UserAskQuestionInfoDto.class, "questionNoId", "questionNo", SentenceQuestion.class, "id", QuestionNoExtendDto.class);
  1173. List<UserAskQuestionInfoDto> textbookPr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.TEXTBOOK.key)).collect(Collectors.toList());
  1174. Collection textbookQuestionNoIds = Transform.getIds(textbookPr, UserAskQuestionInfoDto.class, "questionNoId");
  1175. List<TextbookQuestion> textbookQuestionList = textbookQuestionService.select(textbookQuestionNoIds);
  1176. Transform.combine(textbookPr, textbookQuestionList, UserAskQuestionInfoDto.class, "questionNoId", "questionNo", TextbookQuestion.class, "id", QuestionNoExtendDto.class);
  1177. return ResponseHelp.success(pr, page, size, p.getTotal());
  1178. }
  1179. @RequestMapping(value = "/ask/course", method = RequestMethod.POST)
  1180. @ApiOperation(value = "添加课程提问", notes = "添加课程提问", httpMethod = "POST")
  1181. public Response<Boolean> addAskCourse(@RequestBody @Validated UserAskCourseDto dto) {
  1182. UserAskCourse entity = Transform.dtoToEntity(dto);
  1183. User user = (User) shiroHelp.getLoginUser();
  1184. entity.setUserId(user.getId());
  1185. UserCourse userCourse = courseExtendService.userCourse(user.getId(), dto.getCourseId());
  1186. if (userCourse != null){
  1187. // 绑定提问权限
  1188. entity.setRecordId(userCourse.getRecordId());
  1189. UserOrderRecord record = userOrderRecordService.get(userCourse.getRecordId());
  1190. entity.setAskTime(record.getAskTime());
  1191. Date now = new Date();
  1192. entity.setExpireTime(Tools.addHour(now, record.getAskTime() / 3600));
  1193. }else{
  1194. throw new ParameterException("课程需开通后才能提问");
  1195. }
  1196. userAskCourseService.add(entity);
  1197. return ResponseHelp.success(true);
  1198. }
  1199. @RequestMapping(value = "/feedback/error/question", method = RequestMethod.POST)
  1200. @ApiOperation(value = "添加题目勘误", notes = "添加勘误", httpMethod = "POST")
  1201. public Response<Boolean> addFeedbackErrorQuestion(@RequestBody @Validated UserFeedbackErrorQuestionDto dto) {
  1202. UserFeedbackError entity = Transform.dtoToEntity(dto);
  1203. User user = (User) shiroHelp.getLoginUser();
  1204. entity.setUserId(user.getId());
  1205. entity.setModule(FeedbackModule.QUESTION.key);
  1206. entity.setStatus(0);
  1207. Question question;
  1208. switch (QuestionModule.ValueOf(dto.getQuestionModule())){
  1209. case BASE:
  1210. entity.setQuestionModule(QuestionModule.BASE.key);
  1211. QuestionNo questionNo = questionNoService.get(dto.getQuestionNoId());
  1212. entity.setModuleId(questionNo.getQuestionId());
  1213. entity.setQuestionNoId(questionNo.getId());
  1214. question = questionService.get(questionNo.getQuestionId());
  1215. break;
  1216. case SENTENCE:
  1217. entity.setQuestionModule(QuestionModule.SENTENCE.key);
  1218. SentenceQuestion sentenceQuestion = sentenceQuestionService.get(dto.getQuestionNoId());
  1219. entity.setModuleId(sentenceQuestion.getQuestionId());
  1220. entity.setQuestionNoId(sentenceQuestion.getId());
  1221. question = questionService.get(sentenceQuestion.getQuestionId());
  1222. break;
  1223. case TEXTBOOK:
  1224. entity.setQuestionModule(QuestionModule.SENTENCE.key);
  1225. TextbookQuestion textbookQuestion = textbookQuestionService.get(dto.getQuestionNoId());
  1226. entity.setModuleId(textbookQuestion.getQuestionId());
  1227. entity.setQuestionNoId(textbookQuestion.getId());
  1228. question = questionService.get(textbookQuestion.getQuestionId());
  1229. break;
  1230. default:
  1231. throw new ParameterException("题目模块错误");
  1232. }
  1233. entity.setQuestionType(question.getQuestionType());
  1234. userFeedbackErrorService.add(entity);
  1235. return ResponseHelp.success(true);
  1236. }
  1237. @RequestMapping(value = "/feedback/error/data", method = RequestMethod.POST)
  1238. @ApiOperation(value = "添加资料勘误", notes = "添加勘误", httpMethod = "POST")
  1239. public Response<Boolean> addFeedbackError(@RequestBody @Validated UserFeedbackErrorDataDto dto) {
  1240. UserFeedbackError entity = Transform.dtoToEntity(dto);
  1241. User user = (User) shiroHelp.getLoginUser();
  1242. entity.setUserId(user.getId());
  1243. entity.setModule(FeedbackModule.DATA.key);
  1244. entity.setModuleId(dto.getDataId());
  1245. entity.setStatus(0);
  1246. userFeedbackErrorService.add(entity);
  1247. return ResponseHelp.success(true);
  1248. }
  1249. @RequestMapping(value = "/faq", method = RequestMethod.POST)
  1250. @ApiOperation(value = "添加faq", notes = "添加faq", httpMethod = "POST")
  1251. public Response<Boolean> addFaq(@RequestBody @Validated FaqDto dto) {
  1252. Faq entity = Transform.dtoToEntity(dto);
  1253. User user = (User) shiroHelp.getLoginUser();
  1254. entity.setUserId(user.getId());
  1255. entity.setMessage(1);
  1256. // 取消邮箱发送
  1257. // entity.setEmail(user.getEmail());
  1258. faqService.add(entity);
  1259. return ResponseHelp.success(true);
  1260. }
  1261. @RequestMapping(value = "/comment", method = RequestMethod.POST)
  1262. @ApiOperation(value = "添加评论", notes = "添加评论", httpMethod = "POST")
  1263. public Response<Boolean> addComment(@RequestBody @Validated CommentDto dto) {
  1264. Comment entity = Transform.dtoToEntity(dto);
  1265. User user = (User) shiroHelp.getLoginUser();
  1266. entity.setUserId(user.getId());
  1267. commentService.add(entity);
  1268. return ResponseHelp.success(true);
  1269. }
  1270. @RequestMapping(value = "/data/history", method = RequestMethod.GET)
  1271. @ApiOperation(value = "资料更新记录", httpMethod = "GET")
  1272. public Response<PageMessage<CourseDataHistoryInfoDto>> listDataHistory(
  1273. @RequestParam(required = false, defaultValue = "1") int page,
  1274. @RequestParam(required = false, defaultValue = "100") int size,
  1275. @RequestParam(required = false) Integer dataId,
  1276. HttpSession session) {
  1277. User user = (User) shiroHelp.getLoginUser();
  1278. Page<CourseDataHistory> p = courseDataHistoryService.listByUser(page, size, dataId, user.getId());
  1279. List<CourseDataHistoryInfoDto> pr = Transform.convert(p, CourseDataHistoryInfoDto.class);
  1280. // 绑定资料
  1281. Collection dataIds = Transform.getIds(p, CourseDataHistory.class, "dataId");
  1282. List<CourseData> dataList = courseDataService.select(dataIds);
  1283. Transform.combine(pr, dataList, CourseDataHistoryInfoDto.class, "dataId", "data", CourseData.class, "id", CourseDataExtendDto.class);
  1284. return ResponseHelp.success(pr, page, size, p.getTotal());
  1285. }
  1286. @RequestMapping(value = "/data/list", method = RequestMethod.GET)
  1287. @ApiOperation(value = "购买的资料记录", httpMethod = "GET")
  1288. public Response<PageMessage<CourseData>> listData(
  1289. @RequestParam(required = false, defaultValue = "1") int page,
  1290. @RequestParam(required = false, defaultValue = "100") int size,
  1291. @RequestParam(required = false) Integer structId,
  1292. @RequestParam(required = false) String dataType,
  1293. @RequestParam(required = false, defaultValue = "id") String order, // latest_time, sale_number
  1294. @RequestParam(required = false, defaultValue = "desc") String direction,
  1295. HttpSession session) {
  1296. User user = (User) shiroHelp.getLoginUser();
  1297. Page<CourseData> p = courseDataService.listByUser(page, size, user.getId(), structId, DataType.ValueOf(dataType),order, DirectionStatus.ValueOf(direction));
  1298. return ResponseHelp.success(p, page, size, p.getTotal());
  1299. }
  1300. @RequestMapping(value = "/course/list", method = RequestMethod.GET)
  1301. @ApiOperation(value = "购买的课程记录", httpMethod = "GET")
  1302. public Response<PageMessage<UserCourseDetailDto>> listCourse(
  1303. @RequestParam(required = false, defaultValue = "1") int page,
  1304. @RequestParam(required = false, defaultValue = "100") int size,
  1305. @RequestParam(required = false) String courseModule,
  1306. @RequestParam(required = false) Boolean isUsed,
  1307. @RequestParam(required = false) Boolean isEnd,
  1308. @RequestParam(required = false, defaultValue = "id") String order, // useEndTime desc
  1309. @RequestParam(required = false, defaultValue = "desc") String direction,
  1310. HttpSession session) {
  1311. User user = (User) shiroHelp.getLoginUser();
  1312. Page<UserOrderRecord> p = userOrderRecordService.listWithCourse(page, size, user.getId(), CourseModule.ValueOf(courseModule), isUsed, isEnd, order, DirectionStatus.ValueOf(direction));
  1313. List<UserCourseDetailDto> pr = Transform.convert(p, UserCourseDetailDto.class);
  1314. Collection recordIds = Transform.getIds(p, UserOrderRecord.class,"id");
  1315. // 绑定课程
  1316. Collection courseIds = Transform.getIds(p, UserOrderRecord.class, "productId");
  1317. List<Course> courseList = courseService.select(courseIds);
  1318. Transform.combine(pr, courseList, UserCourseDetailDto.class, "productId", "course", Course.class, "id", CourseExtendDto.class);
  1319. // 绑定课时、预约、进度
  1320. Map<Object, Collection<CourseNo>> courseNoMap = courseNoService.groupByCourseId(courseIds);
  1321. Transform.combine(pr, courseNoMap, UserCourseDetailDto.class, "productId", "courseNos", CourseNoExtendDto.class);
  1322. Map<Object, Collection<UserCourseAppointment>> appointmentMap = userCourseAppointmentService.groupByRecordId(recordIds);
  1323. Transform.combine(pr, appointmentMap, UserCourseDetailDto.class, "productId", "appointments", UserCourseAppointmentExtendDto.class);
  1324. Map<Object, Collection<UserCourseProgress>> progressMap = userCourseProgressService.groupByRecordId(recordIds);
  1325. Map<Object, Collection<UserCourseRecord>> recordMap = userCourseRecordService.groupByRecordId(recordIds);
  1326. for(UserCourseDetailDto dto : pr){
  1327. Collection<UserCourseProgress> list = progressMap.get(dto.getId());
  1328. if (list == null || list.size() == 0) continue;
  1329. Collection<CourseNo> courseNos = courseNoMap.get(dto.getProductId());
  1330. dto.setCurrentNo(courseExtendService.computeCourseNoCurrent(courseNos, list));
  1331. dto.setTotalDays(courseExtendService.computeCourseDay(recordMap.get(dto.getId())));
  1332. }
  1333. // 获取每个科目的所有作业
  1334. Map<Object, Collection<UserPreviewPaperRelation>> previewMap = previewService.groupByCourseId(user.getId(), recordIds, 1000);
  1335. Transform.combine(pr, previewMap, UserCourseDetailDto.class, "productId", "papers", UserPaperBaseExtendDto.class);
  1336. for(UserCourseDetailDto dto : pr){
  1337. Collection<UserPreviewPaperRelation> list = previewMap.get(dto.getId());
  1338. if (list == null || list.size() == 0) continue;
  1339. int finish = 0;
  1340. for(UserPreviewPaperRelation relation : list){
  1341. if (relation.getPaper() == null) continue;
  1342. UserPaper paper = relation.getPaper();
  1343. if (paper.getTimes() > 0){
  1344. finish += 1;
  1345. }
  1346. }
  1347. dto.setPreviewProgress(finish * 100 / list.size());
  1348. }
  1349. // 绑定老师
  1350. Collection teacherIds = Transform.getIds(p, UserOrderRecord.class, "teacherId");
  1351. List<CourseTeacher> teacherList = courseTeacherService.select(teacherIds);
  1352. Transform.combine(pr, teacherList, UserCourseDetailDto.class, "teacherId", "teacher", CourseTeacher.class, "id", CourseTeacherExtendDto.class);
  1353. return ResponseHelp.success(pr, page, size, p.getTotal());
  1354. }
  1355. @RequestMapping(value = "/course/suspend", method = RequestMethod.POST)
  1356. @ApiOperation(value = "申请停课", notes = "申请停课", httpMethod = "POST")
  1357. public Response<Boolean> suspendCourse(@RequestBody @Validated CourseSuspendDto dto) {
  1358. User user = (User) shiroHelp.getLoginUser();
  1359. courseExtendService.suspendCourse(user.getId(), dto.getRecordId());
  1360. return ResponseHelp.success(true);
  1361. }
  1362. @RequestMapping(value = "/course/restore", method = RequestMethod.POST)
  1363. @ApiOperation(value = "恢复停课", notes = "恢复停课", httpMethod = "POST")
  1364. public Response<Boolean> restoreCourse(@RequestBody @Validated CourseRestoreDto dto) {
  1365. User user = (User) shiroHelp.getLoginUser();
  1366. courseExtendService.restoreCourse(user.getId(), dto.getRecordId());
  1367. return ResponseHelp.success(true);
  1368. }
  1369. @RequestMapping(value = "/course/time", method = RequestMethod.GET)
  1370. @ApiOperation(value = "时间表", notes = "时间表", httpMethod = "GET")
  1371. public Response<List<UserCourseTimeDto>> timeCourse(int id) {
  1372. User user = (User) shiroHelp.getLoginUser();
  1373. List<UserCourseTimeDto> dtos = new ArrayList<>();
  1374. UserOrderRecord record = userOrderRecordService.get(id);
  1375. if (record == null){
  1376. throw new ParameterException("记录不存在");
  1377. }
  1378. if (!record.getUserId().equals(user.getId())){
  1379. throw new ParameterException("记录不存在");
  1380. }
  1381. Integer courseId = record.getProductId();
  1382. // 获取停课记录
  1383. Date suspend = record.getSuspendTime();
  1384. if (suspend != null){
  1385. Date restore = record.getRestoreTime();
  1386. if (restore == null) restore = new Date();
  1387. while(suspend.before(restore)){
  1388. UserCourseTimeDto dto = new UserCourseTimeDto();
  1389. dto.setType("stop");
  1390. dto.setDay(Tools.day(suspend));
  1391. dtos.add(dto);
  1392. suspend = Tools.addDate(suspend, 1);
  1393. }
  1394. }
  1395. List<Long> tmpList = new ArrayList<>();
  1396. // 获取听课记录
  1397. List<UserCourseRecord> userCourseRecordList = userCourseRecordService.allWithRecord(id);
  1398. tmpList.clear();
  1399. for(UserCourseRecord userCourseRecord:userCourseRecordList){
  1400. Date day = Tools.day(userCourseRecord.getCreateTime());
  1401. if (!tmpList.contains(day.getTime())){
  1402. tmpList.add(day.getTime());
  1403. UserCourseTimeDto dto = new UserCourseTimeDto();
  1404. dto.setType("course");
  1405. dto.setDay(day);
  1406. dtos.add(dto);
  1407. }
  1408. }
  1409. // 预习作业
  1410. List<CourseNo> courseNoList = courseNoService.allCourse(courseId);
  1411. Collection courseNoIds = Transform.getIds(courseNoList, CourseNo.class, "id");
  1412. List<PreviewAssign> previewAssignList = previewAssignService.listByCourseNos(courseId, courseNoIds);
  1413. Collection assignIds = Transform.getIds(previewAssignList, PreviewAssign.class, "id");
  1414. List<UserPaper> userPaperList = userPaperService.listWithCourse(user.getId(), assignIds, id);
  1415. Collection paperIds = Transform.getIds(userPaperList, UserPaper.class, "id");
  1416. List<UserReport> userReportList = userReportService.listByPaper(paperIds);
  1417. tmpList.clear();
  1418. for(UserReport userReport:userReportList){
  1419. Date day = Tools.day(userReport.getCreateTime());
  1420. if (!tmpList.contains(day.getTime())){
  1421. tmpList.add(day.getTime());
  1422. UserCourseTimeDto dto = new UserCourseTimeDto();
  1423. dto.setType("preview");
  1424. dto.setDay(day);
  1425. dtos.add(dto);
  1426. }
  1427. }
  1428. return ResponseHelp.success(dtos);
  1429. }
  1430. }