MyController.java 86 KB

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