MyController.java 86 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701
  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 = true) String module,
  582. @RequestParam(required = true) 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. dto.setQuestionType(questionType);
  601. JSONObject placeMap = new JSONObject();
  602. JSONObject difficultMap = new JSONObject();
  603. Integer correctTime = 0;
  604. Integer incorrectTime = 0;
  605. List<QuestionNo> list = relationList.stream().filter((row)->row.getQuestion().getQuestionType().equals(questionType)).collect(Collectors.toList());
  606. dto.setQuestionNumber(list.size());
  607. PaperStat stat = questionNoService.statPaper(list);
  608. dto.setTotalCorrect(stat.getTotalCorrect());
  609. dto.setTotalNumber(stat.getTotalNumber());
  610. dto.setTotalTime(stat.getTotalTime());
  611. Collection questionNoIds = Transform.getIds(list, QuestionNo.class, "id");
  612. List<UserQuestion> userQuestionList = userQuestionService.listByQuestionWithTime(user.getId(), QuestionModule.BASE, questionNoIds, startTime, endTime);
  613. Map userQuestionMap = Transform.getMap(userQuestionList, UserQuestion.class, "questionNoId");
  614. dto.setUserQuestion(userQuestionMap.size());
  615. UserQuestionStat userQuestionStat = userQuestionService.statQuestion(userQuestionList);
  616. dto.setUserCorrect(userQuestionStat.getUserCorrect());
  617. dto.setUserNumber(userQuestionStat.getUserNumber());
  618. dto.setUserTime(userQuestionStat.getUserTime());
  619. for (UserQuestion userQuestion:userQuestionList){
  620. QuestionNoRelation relation = relationMap.get(userQuestion.getQuestionNoId());
  621. // 考点用时,以及正确度
  622. String placeKey = relation.getQuestion().getPlace();
  623. JSONObject place = placeMap.getJSONObject(placeKey);
  624. if (place == null){
  625. place = new JSONObject();
  626. place.put("key", placeKey);
  627. place.put("userNumber", 1);
  628. place.put("userCorrect", userQuestion.getIsCorrect());
  629. place.put("userTime", userQuestion.getUserTime());
  630. placeMap.put(placeKey, place);
  631. }else{
  632. place.put("userNumber", place.getInteger("userNumber") + 1);
  633. place.put("userCorrect", place.getInteger("userCorrect") + userQuestion.getIsCorrect());
  634. place.put("userTime", place.getInteger("userTime") + userQuestion.getUserTime());
  635. }
  636. // 难度正确度
  637. String difficultKey = relation.getQuestion().getDifficult();
  638. JSONObject difficult = difficultMap.getJSONObject(difficultKey);
  639. if (difficult == null){
  640. difficult = new JSONObject();
  641. difficult.put("key", difficultKey);
  642. difficult.put("userNumber", 1);
  643. difficult.put("userCorrect", userQuestion.getIsCorrect());
  644. difficult.put("totalNumber", relation.getTotalNumber());
  645. difficult.put("totalCorrect", relation.getTotalCorrect());
  646. difficultMap.put(difficultKey, difficult);
  647. }else{
  648. difficult.put("userNumber", difficult.getInteger("userNumber") + 1);
  649. difficult.put("userCorrect", difficult.getInteger("userCorrect") + userQuestion.getIsCorrect());
  650. difficult.put("totalNumber", difficult.getInteger("totalNumber") + relation.getTotalNumber());
  651. difficult.put("totalCorrect", difficult.getInteger("totalCorrect") + relation.getTotalCorrect());
  652. }
  653. if (userQuestion.getIsCorrect() > 0){
  654. correctTime += userQuestion.getUserTime();
  655. }else{
  656. incorrectTime += userQuestion.getUserTime();
  657. }
  658. }
  659. JSONArray difficult = new JSONArray();
  660. JSONArray place = new JSONArray();
  661. difficult.addAll(difficultMap.values());
  662. place.addAll(placeMap.values());
  663. dto.setDifficult(difficult);
  664. dto.setPlace(place);
  665. dto.setCorrectTime(correctTime);
  666. dto.setIncorrectTime(incorrectTime);
  667. dtoMap.put(questionType, dto);
  668. }
  669. return ResponseHelp.success(dtoMap);
  670. }
  671. @RequestMapping(value = "/collect/experience/add", method = RequestMethod.PUT)
  672. @ApiOperation(value = "添加心经收藏", notes = "添加心经收藏", httpMethod = "PUT")
  673. public Response<Boolean> addExperienceCollect(@RequestBody @Validated UserCollectExperienceDto dto) {
  674. UserCollectExperience entity = Transform.dtoToEntity(dto);
  675. User user = (User) shiroHelp.getLoginUser();
  676. entity.setUserId(user.getId());
  677. userCollectExperienceService.addExperience(entity);
  678. return ResponseHelp.success(true);
  679. }
  680. @RequestMapping(value = "/collect/experience/delete", method = RequestMethod.DELETE)
  681. @ApiOperation(value = "移除心经收藏", notes = "移除心经收藏", httpMethod = "DELETE")
  682. public Response<Boolean> deleteExperienceCollect(Integer experienceId) {
  683. User user = (User) shiroHelp.getLoginUser();
  684. Boolean result = userCollectExperienceService.deleteExperience(user.getId(), experienceId);
  685. return ResponseHelp.success(result);
  686. }
  687. @RequestMapping(value = "/collect/experience/list", method = RequestMethod.GET)
  688. @ApiOperation(value = "获取收藏心经列表", notes = "获取收藏心经列表", httpMethod = "GET")
  689. public Response<PageMessage<CourseExperience>> listExperienceCollect(
  690. @RequestParam(required = false, defaultValue = "1") int page,
  691. @RequestParam(required = false, defaultValue = "100") int size,
  692. @RequestParam(required = false) String startTime,
  693. @RequestParam(required = false) String endTime,
  694. @RequestParam(required = false, defaultValue = "id") String order, // collect_time, update_time
  695. @RequestParam(required = false, defaultValue = "desc") String direction,
  696. HttpSession session) {
  697. User user = (User) shiroHelp.getLoginUser();
  698. Page<CourseExperience> p = courseExperienceService.listWithUser(page, size, user.getId(), startTime, endTime, order, DirectionStatus.ValueOf(direction));
  699. return ResponseHelp.success(p, page, size, p.getTotal());
  700. }
  701. @RequestMapping(value = "/collect/question/add", method = RequestMethod.PUT)
  702. @ApiOperation(value = "添加题目收藏", notes = "添加题目收藏", httpMethod = "PUT")
  703. public Response<Boolean> addQuestionCollect(@RequestBody @Validated UserCollectQuestionDto dto) {
  704. UserCollectQuestion entity = Transform.dtoToEntity(dto);
  705. User user = (User) shiroHelp.getLoginUser();
  706. switch (QuestionModule.ValueOf(dto.getQuestionModule())){
  707. case BASE:
  708. entity.setQuestionModule(QuestionModule.BASE.key);
  709. QuestionNo questionNo = questionNoService.get(dto.getQuestionNoId());
  710. entity.setQuestionId(questionNo.getQuestionId());
  711. entity.setQuestionNoId(questionNo.getId());
  712. break;
  713. case SENTENCE:
  714. entity.setQuestionModule(QuestionModule.SENTENCE.key);
  715. SentenceQuestion sentenceQuestion = sentenceQuestionService.get(dto.getQuestionNoId());
  716. entity.setQuestionId(sentenceQuestion.getQuestionId());
  717. entity.setQuestionNoId(sentenceQuestion.getId());
  718. break;
  719. case TEXTBOOK:
  720. entity.setQuestionModule(QuestionModule.TEXTBOOK.key);
  721. TextbookQuestion textbookQuestion = textbookQuestionService.get(dto.getQuestionNoId());
  722. entity.setQuestionId(textbookQuestion.getQuestionId());
  723. entity.setQuestionNoId(textbookQuestion.getId());
  724. break;
  725. }
  726. entity.setUserId(user.getId());
  727. userCollectQuestionService.addQuestion(entity);
  728. return ResponseHelp.success(true);
  729. }
  730. @RequestMapping(value = "/collect/question/delete", method = RequestMethod.DELETE)
  731. @ApiOperation(value = "移除题目收藏", notes = "移除题目收藏", httpMethod = "DELETE")
  732. public Response<Boolean> deleteQuestionCollect(String questionModule, Integer questionNoId) {
  733. User user = (User) shiroHelp.getLoginUser();
  734. Integer questionId = null;
  735. switch (QuestionModule.ValueOf(questionModule)){
  736. case BASE:
  737. QuestionNo questionNo = questionNoService.get(questionNoId);
  738. questionId = questionNo.getQuestionId();
  739. break;
  740. case SENTENCE:
  741. SentenceQuestion sentenceQuestion = sentenceQuestionService.get(questionNoId);
  742. questionId = sentenceQuestion.getQuestionId();
  743. break;
  744. case TEXTBOOK:
  745. TextbookQuestion textbookQuestion = textbookQuestionService.get(questionNoId);
  746. questionId = textbookQuestion.getQuestionId();
  747. break;
  748. }
  749. Boolean result = userCollectQuestionService.deleteQuestion(user.getId(), questionId);
  750. return ResponseHelp.success(result);
  751. }
  752. @RequestMapping(value = "/collect/question/bind", method = RequestMethod.POST)
  753. @ApiOperation(value = "收藏题目组卷", notes = "收藏题目组卷", httpMethod = "POST")
  754. public Response<UserPaper> bindQuestionCollect(@RequestBody @Validated UserCustomBindDto dto) {
  755. User user = (User) shiroHelp.getLoginUser();
  756. UserPaper userPaper = questionFlowService.makePaper(
  757. user.getId(),
  758. QuestionModule.ValueOf(dto.getQuestionModule()),
  759. PaperOrigin.COLLECT,
  760. Arrays.stream(dto.getQuestionNoIds()).collect(Collectors.toList()),
  761. dto.getFilterTimes()
  762. );
  763. return ResponseHelp.success(userPaper);
  764. }
  765. @RequestMapping(value = "/collect/question/list", method = RequestMethod.GET)
  766. @ApiOperation(value = "获取收藏题目列表", notes = "获取收藏题目列表", httpMethod = "GET")
  767. public Response<PageMessage<UserCollectQuestionInfoDto>> listQuestionCollect(
  768. @RequestParam(required = false, defaultValue = "1") int page,
  769. @RequestParam(required = false, defaultValue = "100") int size,
  770. @RequestParam(required = false) String keyword,
  771. @RequestParam(required = false) String module,
  772. @RequestParam(required = false) String[] questionTypes,
  773. @RequestParam(required = false) Integer[] structIds,
  774. @RequestParam(required = false) String startTime,
  775. @RequestParam(required = false) String endTime,
  776. @RequestParam(required = false) Boolean latest,
  777. @RequestParam(required = false) String year,
  778. @RequestParam(required = false) String order, // (pid asc, no asc), time, correct, question_type, latest_time
  779. HttpSession session) {
  780. User user = (User) shiroHelp.getLoginUser();
  781. QuestionNoModule questionNoModule = QuestionNoModule.ValueOf(module);
  782. Page<UserCollectQuestion> p = null;
  783. if(questionNoModule == QuestionNoModule.EXERCISE){
  784. p = userCollectQuestionService.listExercise(page, size, user.getId(), keyword, questionTypes, structIds, startTime, endTime, order != null ? order.replace("|", " ") : null);
  785. }else if (questionNoModule == QuestionNoModule.EXAMINATION){
  786. Integer libraryId = null;
  787. if (latest != null){
  788. if (latest) {
  789. TextbookLibrary textbookLibrary = textbookLibraryService.getLatest();
  790. libraryId = textbookLibrary.getId();
  791. year = null;
  792. }
  793. }
  794. p = userCollectQuestionService.listExamination(page, size, user.getId(), keyword, questionTypes, structIds, libraryId, year, startTime, endTime, order != null ? order.replace("|", " ") : null);
  795. }else{
  796. throw new ParameterException("参数逻辑错误");
  797. }
  798. List<UserCollectQuestionInfoDto> pr = Transform.convert(p, UserCollectQuestionInfoDto.class);
  799. // 获取题目信息
  800. Collection questionIds = Transform.getIds(pr, UserCollectQuestionInfoDto.class, "questionId");
  801. List<Question> questionList = questionService.select(questionIds);
  802. Transform.combine(pr, questionList, UserCollectQuestionInfoDto.class, "questionId", "question", Question.class, "id", QuestionExtendDto.class);
  803. List<UserCollectQuestionInfoDto> basePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.BASE.key)).collect(Collectors.toList());
  804. Collection baseQuestionNoIds = Transform.getIds(basePr, UserCollectQuestionInfoDto.class, "questionNoId");
  805. List<QuestionNo> baseQuestionNoList = questionNoService.select(baseQuestionNoIds);
  806. Transform.combine(basePr, baseQuestionNoList, UserCollectQuestionInfoDto.class, "questionNoId", "questionNo", QuestionNo.class, "id", QuestionNoExtendDto.class);
  807. List<UserCollectQuestionInfoDto> sentencePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.SENTENCE.key)).collect(Collectors.toList());
  808. Collection sentenceQuestionNoIds = Transform.getIds(sentencePr, UserCollectQuestionInfoDto.class, "questionNoId");
  809. List<SentenceQuestion> sentenceQuestionList = sentenceQuestionService.select(sentenceQuestionNoIds);
  810. Transform.combine(sentencePr, sentenceQuestionList, UserCollectQuestionInfoDto.class, "questionNoId", "questionNo", SentenceQuestion.class, "id", QuestionNoExtendDto.class);
  811. List<UserCollectQuestionInfoDto> textbookPr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.TEXTBOOK.key)).collect(Collectors.toList());
  812. Collection textbookQuestionNoIds = Transform.getIds(textbookPr, UserCollectQuestionInfoDto.class, "questionNoId");
  813. List<TextbookQuestion> textbookQuestionList = textbookQuestionService.select(textbookQuestionNoIds);
  814. Transform.combine(textbookPr, textbookQuestionList, UserCollectQuestionInfoDto.class, "questionNoId", "questionNo", TextbookQuestion.class, "id", QuestionNoExtendDto.class);
  815. // 绑定题目统计
  816. List<UserQuestion> userQuestionList = userQuestionService.listByQuestion(user.getId(), questionIds);
  817. Map<Object, UserQuestionStat> stats = userQuestionService.statQuestionMap(userQuestionList);
  818. Transform.combine(pr, stats, UserCollectQuestionInfoDto.class, "questionId", "stat");
  819. // 最近做题
  820. List<UserQuestion> lastList = userQuestionService.listWithLast(questionIds);
  821. Map lastMap = Transform.getMap(lastList, UserQuestion.class, "id", "createTime");
  822. Transform.combine(pr, lastMap, UserQuestionErrorInfoDto.class, "questionId", "latestTime");
  823. return ResponseHelp.success(pr, page, size, p.getTotal());
  824. }
  825. @RequestMapping(value = "/error/list", method = RequestMethod.GET)
  826. @ApiOperation(value = "获取错题列表", notes = "获取错题列表", httpMethod = "GET")
  827. public Response<PageMessage<UserQuestionErrorInfoDto>> listError(
  828. @RequestParam(required = false, defaultValue = "1") int page,
  829. @RequestParam(required = false, defaultValue = "100") int size,
  830. @RequestParam(required = false) String keyword,
  831. @RequestParam(required = false) String module,
  832. @RequestParam(required = false) String[] questionTypes,
  833. @RequestParam(required = false) Integer[] structIds,
  834. @RequestParam(required = false) String startTime,
  835. @RequestParam(required = false) String endTime,
  836. @RequestParam(required = false) Boolean latest,
  837. @RequestParam(required = false) String year,
  838. @RequestParam(required = false) String order // (pid asc, no asc), time, correct, question_type, latest_time
  839. ) {
  840. User user = (User) shiroHelp.getLoginUser();
  841. QuestionNoModule questionNoModule = QuestionNoModule.ValueOf(module);
  842. Page<UserQuestion> p = null;
  843. if(questionNoModule == QuestionNoModule.EXERCISE){
  844. p = userQuestionService.listExerciseError(page, size, user.getId(), keyword, questionTypes, structIds, startTime, endTime, order != null ? order.replace("|", " ") : null);
  845. }else if (questionNoModule == QuestionNoModule.EXAMINATION){
  846. Integer libraryId = null;
  847. if (latest != null){
  848. if (latest) {
  849. TextbookLibrary textbookLibrary = textbookLibraryService.getLatest();
  850. libraryId = textbookLibrary.getId();
  851. year = null;
  852. }
  853. }
  854. p = userQuestionService.listExaminationError(page, size, user.getId(), keyword, questionTypes, structIds, libraryId, year, startTime, endTime, order != null ? order.replace("|", " ") : null);
  855. }else{
  856. throw new ParameterException("参数逻辑错误");
  857. }
  858. List<UserQuestionErrorInfoDto> pr = Transform.convert(p, UserQuestionErrorInfoDto.class);
  859. // 获取题目信息
  860. Collection questionIds = Transform.getIds(pr, UserQuestionErrorInfoDto.class, "questionId");
  861. List<Question> questionList = questionService.select(questionIds);
  862. Transform.combine(pr, questionList, UserQuestionErrorInfoDto.class, "questionId", "question", Question.class, "id", QuestionExtendDto.class);
  863. List<UserQuestionErrorInfoDto> basePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.BASE.key)).collect(Collectors.toList());
  864. Collection baseQuestionNoIds = Transform.getIds(basePr, UserQuestionErrorInfoDto.class, "questionNoId");
  865. List<QuestionNo> baseQuestionNoList = questionNoService.select(baseQuestionNoIds);
  866. Transform.combine(basePr, baseQuestionNoList, UserQuestionErrorInfoDto.class, "questionNoId", "questionNo", QuestionNo.class, "id", QuestionNoExtendDto.class);
  867. List<UserQuestionErrorInfoDto> sentencePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.SENTENCE.key)).collect(Collectors.toList());
  868. Collection sentenceQuestionNoIds = Transform.getIds(sentencePr, UserQuestionErrorInfoDto.class, "questionNoId");
  869. List<SentenceQuestion> sentenceQuestionList = sentenceQuestionService.select(sentenceQuestionNoIds);
  870. Transform.combine(sentencePr, sentenceQuestionList, UserQuestionErrorInfoDto.class, "questionNoId", "questionNo", SentenceQuestion.class, "id", QuestionNoExtendDto.class);
  871. List<UserQuestionErrorInfoDto> textbookPr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.TEXTBOOK.key)).collect(Collectors.toList());
  872. Collection textbookQuestionNoIds = Transform.getIds(textbookPr, UserQuestionErrorInfoDto.class, "questionNoId");
  873. List<TextbookQuestion> textbookQuestionList = textbookQuestionService.select(textbookQuestionNoIds);
  874. Transform.combine(textbookPr, textbookQuestionList, UserQuestionErrorInfoDto.class, "questionNoId", "questionNo", TextbookQuestion.class, "id", QuestionNoExtendDto.class);
  875. // 绑定题目统计
  876. List<UserQuestion> userQuestionList = userQuestionService.listByQuestion(user.getId(), questionIds);
  877. Map<Object, UserQuestionStat> stats = userQuestionService.statQuestionMap(userQuestionList);
  878. Transform.combine(pr, stats, UserQuestionErrorInfoDto.class, "questionId", "stat");
  879. // 最近做题
  880. List<UserQuestion> lastList = userQuestionService.listWithLast(questionIds);
  881. Map lastMap = Transform.getMap(lastList, UserQuestion.class, "id", "createTime");
  882. Transform.combine(pr, lastMap, UserQuestionErrorInfoDto.class, "questionId", "latestTime");
  883. return ResponseHelp.success(pr, page, size, p.getTotal());
  884. }
  885. @RequestMapping(value = "/error/bind", method = RequestMethod.POST)
  886. @ApiOperation(value = "错题组卷", notes = "错题组卷", httpMethod = "POST")
  887. public Response<UserPaper> bindError(@RequestBody @Validated UserCustomBindDto dto) {
  888. User user = (User) shiroHelp.getLoginUser();
  889. UserPaper userPaper = questionFlowService.makePaper(
  890. user.getId(),
  891. QuestionModule.ValueOf(dto.getQuestionModule()),
  892. PaperOrigin.ERROR,
  893. Arrays.stream(dto.getQuestionNoIds()).collect(Collectors.toList()),
  894. dto.getFilterTimes()
  895. );
  896. return ResponseHelp.success(userPaper);
  897. }
  898. @RequestMapping(value = "/error/clear", method = RequestMethod.POST)
  899. @ApiOperation(value = "错题移除", notes = "错题移除", httpMethod = "POST")
  900. public Response<Boolean> clearError(@RequestBody @Validated UserQuestionIdsDto dto) {
  901. User user = (User) shiroHelp.getLoginUser();
  902. List<UserQuestion> questionList = userQuestionService.select(dto.getQuestionNoIds());
  903. userPaperQuestionService.addRemoveError(questionList);
  904. return ResponseHelp.success(true);
  905. }
  906. @RequestMapping(value = "/error/remove", method = RequestMethod.POST)
  907. @ApiOperation(value = "移除正确题", notes = "移除正确题", httpMethod = "POST")
  908. public Response<Boolean> removeError(@RequestBody @Validated ErrorReportDto dto) {
  909. User user = (User) shiroHelp.getLoginUser();
  910. UserReport report = userReportService.get(dto.getUserReportId());
  911. if (report.getIsFinish() == 0){
  912. throw new ParameterException("试卷未完成");
  913. }
  914. List<UserQuestion> questionList = userQuestionService.listByReport(user.getId(), dto.getUserReportId());
  915. userPaperQuestionService.addRemoveError(questionList);
  916. return ResponseHelp.success(true);
  917. }
  918. @RequestMapping(value = "/note/question", method = RequestMethod.PUT)
  919. @ApiOperation(value = "更新题目笔记", notes = "更新题目笔记", httpMethod = "PUT")
  920. public Response<Boolean> updateNoteQuestion(@RequestBody @Validated UserNoteQuestionDto dto) {
  921. UserNoteQuestion entity = Transform.dtoToEntity(dto);
  922. User user = (User) shiroHelp.getLoginUser();
  923. entity.setUserId(user.getId());
  924. switch (QuestionModule.ValueOf(dto.getQuestionModule())){
  925. case BASE:
  926. entity.setQuestionModule(QuestionModule.BASE.key);
  927. QuestionNo questionNo = questionNoService.get(dto.getQuestionNoId());
  928. entity.setQuestionId(questionNo.getQuestionId());
  929. entity.setQuestionNoId(questionNo.getId());
  930. break;
  931. case SENTENCE:
  932. entity.setQuestionModule(QuestionModule.SENTENCE.key);
  933. SentenceQuestion sentenceQuestion = sentenceQuestionService.get(dto.getQuestionNoId());
  934. entity.setQuestionId(sentenceQuestion.getQuestionId());
  935. entity.setQuestionNoId(sentenceQuestion.getId());
  936. break;
  937. case TEXTBOOK:
  938. entity.setQuestionModule(QuestionModule.TEXTBOOK.key);
  939. TextbookQuestion textbookQuestion = textbookQuestionService.get(dto.getQuestionNoId());
  940. entity.setQuestionId(textbookQuestion.getQuestionId());
  941. entity.setQuestionNoId(textbookQuestion.getId());
  942. break;
  943. }
  944. userNoteQuestionService.update(entity);
  945. return ResponseHelp.success(true);
  946. }
  947. @RequestMapping(value = "/note/question/list", method = RequestMethod.GET)
  948. @ApiOperation(value = "获取题目笔记列表", notes = "获取笔记列表", httpMethod = "GET")
  949. public Response<PageMessage<UserNoteQuestionInfoDto>> listNoteQuestion(
  950. @RequestParam(required = false, defaultValue = "1") int page,
  951. @RequestParam(required = false, defaultValue = "100") int size,
  952. @RequestParam(required = false) String keyword,
  953. @RequestParam(required = false) String module,
  954. @RequestParam(required = false) String[] questionTypes,
  955. @RequestParam(required = false) Integer[] structIds,
  956. @RequestParam(required = false) String startTime,
  957. @RequestParam(required = false) String endTime,
  958. @RequestParam(required = false) Boolean latest,
  959. @RequestParam(required = false) String year,
  960. @RequestParam(required = false) String order, // update_time
  961. HttpSession session) {
  962. User user = (User) shiroHelp.getLoginUser();
  963. QuestionNoModule questionNoModule = QuestionNoModule.ValueOf(module);
  964. Page<UserNoteQuestion> p = null;
  965. if(questionNoModule == QuestionNoModule.EXERCISE){
  966. p = userNoteQuestionService.listExercise(page, size, user.getId(), keyword, questionTypes, structIds, startTime, endTime, order != null ? order.replace("|", " ") : null);
  967. }else if (questionNoModule == QuestionNoModule.EXAMINATION){
  968. Integer libraryId = null;
  969. if (latest != null){
  970. if (latest) {
  971. TextbookLibrary textbookLibrary = textbookLibraryService.getLatest();
  972. libraryId = textbookLibrary.getId();
  973. year = null;
  974. }
  975. }
  976. p = userNoteQuestionService.listExamination(page, size, user.getId(), keyword, questionTypes, structIds, libraryId, year, startTime, endTime, order != null ? order.replace("|", " ") : null);
  977. }else{
  978. throw new ParameterException("参数逻辑错误");
  979. }
  980. List<UserNoteQuestionInfoDto> pr = Transform.convert(p, UserNoteQuestionInfoDto.class);
  981. // 获取题目信息
  982. Collection questionIds = Transform.getIds(pr, UserNoteQuestionInfoDto.class, "questionId");
  983. List<Question> questionList = questionService.select(questionIds);
  984. Transform.combine(pr, questionList, UserNoteQuestionInfoDto.class, "questionId", "question", Question.class, "id", QuestionExtendDto.class);
  985. List<UserNoteQuestionInfoDto> basePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.BASE.key)).collect(Collectors.toList());
  986. Collection baseQuestionNoIds = Transform.getIds(basePr, UserNoteQuestionInfoDto.class, "questionNoId");
  987. List<QuestionNo> baseQuestionNoList = questionNoService.select(baseQuestionNoIds);
  988. Transform.combine(basePr, baseQuestionNoList, UserNoteQuestionInfoDto.class, "questionNoId", "questionNo", QuestionNo.class, "id", QuestionNoExtendDto.class);
  989. List<UserNoteQuestionInfoDto> sentencePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.SENTENCE.key)).collect(Collectors.toList());
  990. Collection sentenceQuestionNoIds = Transform.getIds(sentencePr, UserNoteQuestionInfoDto.class, "questionNoId");
  991. List<SentenceQuestion> sentenceQuestionList = sentenceQuestionService.select(sentenceQuestionNoIds);
  992. Transform.combine(sentencePr, sentenceQuestionList, UserNoteQuestionInfoDto.class, "questionNoId", "questionNo", SentenceQuestion.class, "id", QuestionNoExtendDto.class);
  993. List<UserNoteQuestionInfoDto> textbookPr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.TEXTBOOK.key)).collect(Collectors.toList());
  994. Collection textbookQuestionNoIds = Transform.getIds(textbookPr, UserNoteQuestionInfoDto.class, "questionNoId");
  995. List<TextbookQuestion> textbookQuestionList = textbookQuestionService.select(textbookQuestionNoIds);
  996. Transform.combine(textbookPr, textbookQuestionList, UserNoteQuestionInfoDto.class, "questionNoId", "questionNo", TextbookQuestion.class, "id", QuestionNoExtendDto.class);
  997. return ResponseHelp.success(pr, page, size, p.getTotal());
  998. }
  999. @RequestMapping(value = "/note/course", method = RequestMethod.PUT)
  1000. @ApiOperation(value = "更新课程笔记", notes = "更新课程笔记", httpMethod = "PUT")
  1001. public Response<Boolean> updateNoteCourse(@RequestBody @Validated UserNoteQuestionDto dto) {
  1002. UserNoteCourse entity = Transform.dtoToEntity(dto);
  1003. User user = (User) shiroHelp.getLoginUser();
  1004. entity.setUserId(user.getId());
  1005. userNoteCourseService.update(entity);
  1006. return ResponseHelp.success(true);
  1007. }
  1008. @RequestMapping(value = "/report/list", method = RequestMethod.GET)
  1009. @ApiOperation(value = "获取报告列表", notes = "获取报告列表", httpMethod = "GET")
  1010. public Response<PageMessage<UserPaperDto>> listReport(
  1011. @RequestParam(required = false, defaultValue = "1") int page,
  1012. @RequestParam(required = false, defaultValue = "100") int size,
  1013. @RequestParam(required = false) String keyword,
  1014. @RequestParam(required = false) String module,
  1015. @RequestParam(required = false) String origin,
  1016. @RequestParam(required = false) String[] questionTypes,
  1017. @RequestParam(required = false) Integer[] structIds,
  1018. @RequestParam(required = false) String startTime,
  1019. @RequestParam(required = false) String endTime,
  1020. @RequestParam(required = false) Boolean latest,
  1021. @RequestParam(required = false) String year,
  1022. @RequestParam(required = false) String[] courseModules,
  1023. @RequestParam(required = false) String order, // title, latest_time,correct,time
  1024. HttpSession session) {
  1025. User user = (User) shiroHelp.getLoginUser();
  1026. PaperOrigin paperOrigin = PaperOrigin.ValueOf(origin);
  1027. QuestionNoModule questionNoModule = QuestionNoModule.ValueOf(module);
  1028. Page<UserPaper> p = null;
  1029. if (questionNoModule != null && (paperOrigin == PaperOrigin.COLLECT || paperOrigin == PaperOrigin.ERROR)){
  1030. p = userPaperService.list(page, size, user.getId(), keyword, paperOrigin, startTime, endTime, order != null ? order.replace("|", " ") : null);
  1031. }else if(questionNoModule == QuestionNoModule.EXERCISE){
  1032. p = userPaperService.listExercise(page, size, user.getId(), keyword, questionTypes, structIds, courseModules, startTime, endTime, order != null ? order.replace("|", " ") : null);
  1033. }else if (questionNoModule == QuestionNoModule.EXAMINATION){
  1034. Integer libraryId = null;
  1035. if (latest != null){
  1036. paperOrigin = PaperOrigin.TEXTBOOK;
  1037. if (latest) {
  1038. TextbookLibrary textbookLibrary = textbookLibraryService.getLatest();
  1039. libraryId = textbookLibrary.getId();
  1040. year = null;
  1041. }
  1042. }
  1043. p = userPaperService.listExamination(page, size, user.getId(), keyword, structIds, libraryId, year, startTime, endTime, order != null ? order.replace("|", " ") : null);
  1044. }else{
  1045. throw new ParameterException("参数逻辑错误");
  1046. }
  1047. List<UserPaperDto> pr = Transform.convert(p, UserPaperDto.class);
  1048. Collection paperIds = Transform.getIds(p, UserPaper.class, "id");
  1049. // 绑定用户报告
  1050. Map<Object, Collection<UserReport>> reportByPaper = userReportService.mapByPaper(paperIds);
  1051. Transform.combine(pr, reportByPaper, UserPaperDto.class, "id", "reports", UserReportExtendDto.class);
  1052. // 获取试卷统计信息
  1053. List<UserPaperDto> basePr = pr.stream().filter((row)->QuestionModule.BASE == QuestionModule.WithPaper(PaperModule.ValueOf(row.getPaperModule()))).collect(Collectors.toList());
  1054. Map<Integer, Integer[]> baseIdsMap = new HashMap<>();
  1055. for(UserPaperDto paper : basePr){
  1056. baseIdsMap.put(paper.getId(), paper.getQuestionNoIds());
  1057. }
  1058. Map baseStatMap = questionNoService.statPaperMap(baseIdsMap);
  1059. Transform.combine(pr, baseStatMap, UserPaperDto.class, "id", "stat");
  1060. List<UserPaperDto> sentencePr = pr.stream().filter((row)->QuestionModule.SENTENCE == QuestionModule.WithPaper(PaperModule.ValueOf(row.getPaperModule()))).collect(Collectors.toList());
  1061. Map<Integer, Integer[]> sentenceIdsMap = new HashMap<>();
  1062. for(UserPaperDto paper : sentencePr){
  1063. sentenceIdsMap.put(paper.getId(), paper.getQuestionNoIds());
  1064. }
  1065. Map sentenceStatMap = sentenceQuestionService.statPaperMap(sentenceIdsMap);
  1066. Transform.combine(pr, sentenceStatMap, UserPaperDto.class, "id", "stat");
  1067. List<UserPaperDto> textbookPr = pr.stream().filter((row)->QuestionModule.TEXTBOOK == QuestionModule.WithPaper(PaperModule.ValueOf(row.getPaperModule()))).collect(Collectors.toList());
  1068. Map<Integer, Integer[]> textbookIdsMap = new HashMap<>();
  1069. for(UserPaperDto paper : textbookPr){
  1070. textbookIdsMap.put(paper.getId(), paper.getQuestionNoIds());
  1071. }
  1072. Map textbookStatMap = textbookQuestionService.statPaperMap(textbookIdsMap);
  1073. Transform.combine(pr, textbookStatMap, UserPaperDto.class, "id", "stat");
  1074. return ResponseHelp.success(pr, page, size, p.getTotal());
  1075. }
  1076. @RequestMapping(value = "/ask/question", method = RequestMethod.POST)
  1077. @ApiOperation(value = "添加题目提问", notes = "添加题目提问", httpMethod = "POST")
  1078. public Response<Boolean> addAskQuestion(@RequestBody @Validated UserAskQuestionDto dto) {
  1079. UserAskQuestion entity = Transform.dtoToEntity(dto);
  1080. User user = (User) shiroHelp.getLoginUser();
  1081. entity.setUserId(user.getId());
  1082. PaperModule paperModule = PaperModule.ValueOf(dto.getPaperModule());
  1083. QuestionModule questionModule = QuestionModule.WithPaper(paperModule);
  1084. Question question;
  1085. switch (questionModule){
  1086. case BASE:
  1087. entity.setQuestionModule(QuestionModule.BASE.key);
  1088. QuestionNo questionNo = questionNoService.get(dto.getQuestionNoId());
  1089. entity.setQuestionId(questionNo.getQuestionId());
  1090. entity.setQuestionNoId(questionNo.getId());
  1091. question = questionService.get(questionNo.getQuestionId());
  1092. break;
  1093. case SENTENCE:
  1094. entity.setQuestionModule(QuestionModule.SENTENCE.key);
  1095. SentenceQuestion sentenceQuestion = sentenceQuestionService.get(dto.getQuestionNoId());
  1096. entity.setQuestionId(sentenceQuestion.getQuestionId());
  1097. entity.setQuestionNoId(sentenceQuestion.getId());
  1098. question = questionService.get(sentenceQuestion.getQuestionId());
  1099. break;
  1100. case TEXTBOOK:
  1101. entity.setQuestionModule(QuestionModule.TEXTBOOK.key);
  1102. TextbookQuestion textbookQuestion = textbookQuestionService.get(dto.getQuestionNoId());
  1103. entity.setQuestionId(textbookQuestion.getQuestionId());
  1104. entity.setQuestionNoId(textbookQuestion.getId());
  1105. question = questionService.get(textbookQuestion.getQuestionId());
  1106. break;
  1107. default:
  1108. throw new ParameterException("题目模块错误");
  1109. }
  1110. entity.setAskModule(AskModule.WithPaper(paperModule).key);
  1111. Integer assignId = null;
  1112. if (dto.getUserPaperId() != null && dto.getUserPaperId() > 0){
  1113. UserPaper userPaper = userPaperService.get(dto.getUserPaperId());
  1114. if(userPaper != null && userPaper.getPaperOrigin().equals(PaperOrigin.PREVIEW.key)){
  1115. assignId = userPaper.getOriginId();
  1116. }
  1117. }
  1118. Integer recordId = questionFlowService.questionRelationCourse(user.getId(), assignId, QuestionType.ValueOf(question.getQuestionType()));
  1119. if (recordId != null){
  1120. // 绑定提问权限
  1121. entity.setRecordId(recordId);
  1122. UserOrderRecord record = userOrderRecordService.get(recordId);
  1123. entity.setAskTime(record.getAskTime());
  1124. Date now = new Date();
  1125. entity.setExpireTime(Tools.addHour(now, record.getAskTime() / 3600));
  1126. }else{
  1127. // todo 判断题目是否有提问权限
  1128. }
  1129. userAskQuestionService.add(entity);
  1130. return ResponseHelp.success(true);
  1131. }
  1132. @RequestMapping(value = "/ask/question/delete", method = RequestMethod.DELETE)
  1133. @ApiOperation(value = "提问删除", httpMethod = "DELETE")
  1134. public Response<Boolean> deleteAskQuestion(@RequestParam int id, HttpServletRequest request) {
  1135. UserAskQuestion in = userAskQuestionService.get(id);
  1136. User user = (User) shiroHelp.getLoginUser();
  1137. if(in == null){
  1138. throw new ParameterException("提问不存在");
  1139. }
  1140. if (!in.getUserId().equals(user.getId())){
  1141. throw new ParameterException("提问不存在");
  1142. }
  1143. if (in.getAnswerStatus()== AskStatus.ANSWER.index){
  1144. throw new ParameterException("提问已回答");
  1145. }
  1146. userAskQuestionService.delete(id);
  1147. // 如果
  1148. return ResponseHelp.success(true);
  1149. }
  1150. @RequestMapping(value = "/ask/question/list", method = RequestMethod.GET)
  1151. @ApiOperation(value = "获取题目提问列表", notes = "获取题目提问列表", httpMethod = "GET")
  1152. public Response<PageMessage<UserAskQuestionInfoDto>> listAskQuestion(
  1153. @RequestParam(required = false, defaultValue = "1") int page,
  1154. @RequestParam(required = false, defaultValue = "100") int size,
  1155. @RequestParam(required = false) String keyword,
  1156. @RequestParam(required = false) String module,
  1157. @RequestParam(required = false) String[] questionTypes,
  1158. @RequestParam(required = false) Integer[] structIds,
  1159. @RequestParam(required = false) String startTime,
  1160. @RequestParam(required = false) String endTime,
  1161. @RequestParam(required = false) Integer askStatus,
  1162. @RequestParam(required = false) Boolean latest,
  1163. @RequestParam(required = false) String year,
  1164. @RequestParam(required = false) String order, // create_time, answer_time
  1165. HttpSession session) {
  1166. User user = (User) shiroHelp.getLoginUser();
  1167. QuestionNoModule questionNoModule = QuestionNoModule.ValueOf(module);
  1168. Page<UserAskQuestion> p = null;
  1169. if(questionNoModule == QuestionNoModule.EXERCISE){
  1170. p = userAskQuestionService.listExercise(page, size, user.getId(), keyword, questionTypes, structIds, AskStatus.ValueOf(askStatus),startTime, endTime, order != null ? order.replace("|", " ") : null);
  1171. }else if (questionNoModule == QuestionNoModule.EXAMINATION){
  1172. Integer libraryId = null;
  1173. if (latest != null){
  1174. if (latest) {
  1175. TextbookLibrary textbookLibrary = textbookLibraryService.getLatest();
  1176. libraryId = textbookLibrary.getId();
  1177. year = null;
  1178. }
  1179. }
  1180. p = userAskQuestionService.listExamination(page, size, user.getId(), keyword, questionTypes, structIds, libraryId, year, AskStatus.ValueOf(askStatus), startTime, endTime, order != null ? order.replace("|", " ") : null);
  1181. }else{
  1182. throw new ParameterException("参数逻辑错误");
  1183. }
  1184. List<UserAskQuestionInfoDto> pr = Transform.convert(p, UserAskQuestionInfoDto.class);
  1185. // 获取题目信息
  1186. Collection questionIds = Transform.getIds(pr, UserNoteQuestionInfoDto.class, "questionId");
  1187. List<Question> questionList = questionService.select(questionIds);
  1188. Transform.combine(pr, questionList, UserNoteQuestionInfoDto.class, "questionId", "question", Question.class, "id", QuestionExtendDto.class);
  1189. List<UserAskQuestionInfoDto> basePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.BASE.key)).collect(Collectors.toList());
  1190. Collection baseQuestionNoIds = Transform.getIds(basePr, UserAskQuestionInfoDto.class, "questionNoId");
  1191. List<QuestionNo> baseQuestionNoList = questionNoService.select(baseQuestionNoIds);
  1192. Transform.combine(basePr, baseQuestionNoList, UserAskQuestionInfoDto.class, "questionNoId", "questionNo", QuestionNo.class, "id", QuestionNoExtendDto.class);
  1193. List<UserAskQuestionInfoDto> sentencePr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.SENTENCE.key)).collect(Collectors.toList());
  1194. Collection sentenceQuestionNoIds = Transform.getIds(sentencePr, UserAskQuestionInfoDto.class, "questionNoId");
  1195. List<SentenceQuestion> sentenceQuestionList = sentenceQuestionService.select(sentenceQuestionNoIds);
  1196. Transform.combine(sentencePr, sentenceQuestionList, UserAskQuestionInfoDto.class, "questionNoId", "questionNo", SentenceQuestion.class, "id", QuestionNoExtendDto.class);
  1197. List<UserAskQuestionInfoDto> textbookPr = pr.stream().filter((row)->row.getQuestionModule().equals(QuestionModule.TEXTBOOK.key)).collect(Collectors.toList());
  1198. Collection textbookQuestionNoIds = Transform.getIds(textbookPr, UserAskQuestionInfoDto.class, "questionNoId");
  1199. List<TextbookQuestion> textbookQuestionList = textbookQuestionService.select(textbookQuestionNoIds);
  1200. Transform.combine(textbookPr, textbookQuestionList, UserAskQuestionInfoDto.class, "questionNoId", "questionNo", TextbookQuestion.class, "id", QuestionNoExtendDto.class);
  1201. return ResponseHelp.success(pr, page, size, p.getTotal());
  1202. }
  1203. @RequestMapping(value = "/ask/course", method = RequestMethod.POST)
  1204. @ApiOperation(value = "添加课程提问", notes = "添加课程提问", httpMethod = "POST")
  1205. public Response<Boolean> addAskCourse(@RequestBody @Validated UserAskCourseDto dto) {
  1206. UserAskCourse entity = Transform.dtoToEntity(dto);
  1207. User user = (User) shiroHelp.getLoginUser();
  1208. entity.setUserId(user.getId());
  1209. UserCourse userCourse = courseExtendService.userCourse(user.getId(), dto.getCourseId());
  1210. if (userCourse != null){
  1211. // 绑定提问权限
  1212. entity.setRecordId(userCourse.getRecordId());
  1213. UserOrderRecord record = userOrderRecordService.get(userCourse.getRecordId());
  1214. entity.setAskTime(record.getAskTime());
  1215. Date now = new Date();
  1216. entity.setExpireTime(Tools.addHour(now, record.getAskTime() / 3600));
  1217. }else{
  1218. throw new ParameterException("课程需开通后才能提问");
  1219. }
  1220. userAskCourseService.add(entity);
  1221. return ResponseHelp.success(true);
  1222. }
  1223. @RequestMapping(value = "/feedback/error/question", method = RequestMethod.POST)
  1224. @ApiOperation(value = "添加题目勘误", notes = "添加勘误", httpMethod = "POST")
  1225. public Response<Boolean> addFeedbackErrorQuestion(@RequestBody @Validated UserFeedbackErrorQuestionDto dto) {
  1226. UserFeedbackError entity = Transform.dtoToEntity(dto);
  1227. User user = (User) shiroHelp.getLoginUser();
  1228. entity.setUserId(user.getId());
  1229. entity.setModule(FeedbackModule.QUESTION.key);
  1230. entity.setStatus(0);
  1231. Question question;
  1232. switch (QuestionModule.ValueOf(dto.getQuestionModule())){
  1233. case BASE:
  1234. entity.setQuestionModule(QuestionModule.BASE.key);
  1235. QuestionNo questionNo = questionNoService.get(dto.getQuestionNoId());
  1236. entity.setModuleId(questionNo.getQuestionId());
  1237. entity.setQuestionNoId(questionNo.getId());
  1238. question = questionService.get(questionNo.getQuestionId());
  1239. break;
  1240. case SENTENCE:
  1241. entity.setQuestionModule(QuestionModule.SENTENCE.key);
  1242. SentenceQuestion sentenceQuestion = sentenceQuestionService.get(dto.getQuestionNoId());
  1243. entity.setModuleId(sentenceQuestion.getQuestionId());
  1244. entity.setQuestionNoId(sentenceQuestion.getId());
  1245. question = questionService.get(sentenceQuestion.getQuestionId());
  1246. break;
  1247. case TEXTBOOK:
  1248. entity.setQuestionModule(QuestionModule.SENTENCE.key);
  1249. TextbookQuestion textbookQuestion = textbookQuestionService.get(dto.getQuestionNoId());
  1250. entity.setModuleId(textbookQuestion.getQuestionId());
  1251. entity.setQuestionNoId(textbookQuestion.getId());
  1252. question = questionService.get(textbookQuestion.getQuestionId());
  1253. break;
  1254. default:
  1255. throw new ParameterException("题目模块错误");
  1256. }
  1257. entity.setQuestionType(question.getQuestionType());
  1258. userFeedbackErrorService.add(entity);
  1259. return ResponseHelp.success(true);
  1260. }
  1261. @RequestMapping(value = "/feedback/error/data", method = RequestMethod.POST)
  1262. @ApiOperation(value = "添加资料勘误", notes = "添加勘误", httpMethod = "POST")
  1263. public Response<Boolean> addFeedbackError(@RequestBody @Validated UserFeedbackErrorDataDto dto) {
  1264. UserFeedbackError entity = Transform.dtoToEntity(dto);
  1265. User user = (User) shiroHelp.getLoginUser();
  1266. entity.setUserId(user.getId());
  1267. entity.setModule(FeedbackModule.DATA.key);
  1268. entity.setModuleId(dto.getDataId());
  1269. entity.setStatus(0);
  1270. userFeedbackErrorService.add(entity);
  1271. return ResponseHelp.success(true);
  1272. }
  1273. @RequestMapping(value = "/faq", method = RequestMethod.POST)
  1274. @ApiOperation(value = "添加faq", notes = "添加faq", httpMethod = "POST")
  1275. public Response<Boolean> addFaq(@RequestBody @Validated FaqDto dto) {
  1276. Faq entity = Transform.dtoToEntity(dto);
  1277. User user = (User) shiroHelp.getLoginUser();
  1278. entity.setUserId(user.getId());
  1279. entity.setMessage(1);
  1280. // 取消邮箱发送
  1281. // entity.setEmail(user.getEmail());
  1282. faqService.add(entity);
  1283. return ResponseHelp.success(true);
  1284. }
  1285. @RequestMapping(value = "/comment", method = RequestMethod.POST)
  1286. @ApiOperation(value = "添加评论", notes = "添加评论", httpMethod = "POST")
  1287. public Response<Boolean> addComment(@RequestBody @Validated CommentDto dto) {
  1288. Comment entity = Transform.dtoToEntity(dto);
  1289. User user = (User) shiroHelp.getLoginUser();
  1290. entity.setUserId(user.getId());
  1291. commentService.add(entity);
  1292. return ResponseHelp.success(true);
  1293. }
  1294. @RequestMapping(value = "/data/subscribe", method = RequestMethod.POST)
  1295. @ApiOperation(value = "资料订阅", notes = "资料订阅", httpMethod = "POST")
  1296. public Response<Boolean> addComment(@RequestBody @Validated DataSubscribeDto dto) {
  1297. User user = (User) shiroHelp.getLoginUser();
  1298. if (user == null){
  1299. throw new AuthException("请先登录");
  1300. }
  1301. usersService.edit(User.builder()
  1302. .id(user.getId())
  1303. .dataEmailSubscribe(dto.getSubscribe() ? 1 : 0)
  1304. .build());
  1305. return ResponseHelp.success(true);
  1306. }
  1307. @RequestMapping(value = "/data/history", method = RequestMethod.GET)
  1308. @ApiOperation(value = "资料更新记录", httpMethod = "GET")
  1309. public Response<PageMessage<CourseDataHistoryInfoDto>> listDataHistory(
  1310. @RequestParam(required = false, defaultValue = "1") int page,
  1311. @RequestParam(required = false, defaultValue = "100") int size,
  1312. @RequestParam(required = false) Integer dataId,
  1313. HttpSession session) {
  1314. User user = (User) shiroHelp.getLoginUser();
  1315. Page<CourseDataHistory> p = courseDataHistoryService.listByUser(page, size, dataId, user.getId());
  1316. List<CourseDataHistoryInfoDto> pr = Transform.convert(p, CourseDataHistoryInfoDto.class);
  1317. // 绑定资料
  1318. Collection dataIds = Transform.getIds(p, CourseDataHistory.class, "dataId");
  1319. List<CourseData> dataList = courseDataService.select(dataIds);
  1320. Transform.combine(pr, dataList, CourseDataHistoryInfoDto.class, "dataId", "data", CourseData.class, "id", CourseDataExtendDto.class);
  1321. return ResponseHelp.success(pr, page, size, p.getTotal());
  1322. }
  1323. @RequestMapping(value = "/data/list", method = RequestMethod.GET)
  1324. @ApiOperation(value = "购买的资料记录", httpMethod = "GET")
  1325. public Response<PageMessage<CourseData>> listData(
  1326. @RequestParam(required = false, defaultValue = "1") int page,
  1327. @RequestParam(required = false, defaultValue = "100") int size,
  1328. @RequestParam(required = false) Integer structId,
  1329. @RequestParam(required = false) String dataType,
  1330. @RequestParam(required = false, defaultValue = "id") String order, // latest_time, sale_number
  1331. @RequestParam(required = false, defaultValue = "desc") String direction,
  1332. HttpSession session) {
  1333. User user = (User) shiroHelp.getLoginUser();
  1334. Page<CourseData> p = courseDataService.listByUser(page, size, user.getId(), structId, DataType.ValueOf(dataType),order, DirectionStatus.ValueOf(direction));
  1335. return ResponseHelp.success(p, page, size, p.getTotal());
  1336. }
  1337. @RequestMapping(value = "/course/list", method = RequestMethod.GET)
  1338. @ApiOperation(value = "购买的课程记录", httpMethod = "GET")
  1339. public Response<PageMessage<UserCourseDetailDto>> listCourse(
  1340. @RequestParam(required = false, defaultValue = "1") int page,
  1341. @RequestParam(required = false, defaultValue = "100") int size,
  1342. @RequestParam(required = false) String courseModule,
  1343. @RequestParam(required = false) Boolean isUsed,
  1344. @RequestParam(required = false) Boolean isEnd,
  1345. @RequestParam(required = false, defaultValue = "id") String order, // useEndTime desc
  1346. @RequestParam(required = false, defaultValue = "desc") String direction,
  1347. HttpSession session) {
  1348. User user = (User) shiroHelp.getLoginUser();
  1349. Page<UserOrderRecord> p = userOrderRecordService.listWithCourse(page, size, user.getId(), CourseModule.ValueOf(courseModule), isUsed, isEnd, order, DirectionStatus.ValueOf(direction));
  1350. List<UserCourseDetailDto> pr = Transform.convert(p, UserCourseDetailDto.class);
  1351. Collection recordIds = Transform.getIds(p, UserOrderRecord.class,"id");
  1352. // 绑定课程
  1353. Collection courseIds = Transform.getIds(p, UserOrderRecord.class, "productId");
  1354. List<Course> courseList = courseService.select(courseIds);
  1355. Transform.combine(pr, courseList, UserCourseDetailDto.class, "productId", "course", Course.class, "id", CourseExtendDto.class);
  1356. // 绑定课时、预约、进度
  1357. Map<Object, Collection<CourseNo>> courseNoMap = courseNoService.groupByCourseId(courseIds);
  1358. Transform.combine(pr, courseNoMap, UserCourseDetailDto.class, "productId", "courseNos", CourseNoExtendDto.class);
  1359. Map<Object, Collection<UserCourseAppointment>> appointmentMap = userCourseAppointmentService.groupByRecordId(recordIds);
  1360. Transform.combine(pr, appointmentMap, UserCourseDetailDto.class, "productId", "appointments", UserCourseAppointmentExtendDto.class);
  1361. Map<Object, Collection<UserCourseProgress>> progressMap = userCourseProgressService.groupByRecordId(recordIds);
  1362. Map<Object, Collection<UserCourseRecord>> recordMap = userCourseRecordService.groupByRecordId(recordIds);
  1363. for(UserCourseDetailDto dto : pr){
  1364. Collection<UserCourseProgress> list = progressMap.get(dto.getId());
  1365. if (list == null || list.size() == 0) continue;
  1366. Collection<CourseNo> courseNos = courseNoMap.get(dto.getProductId());
  1367. dto.setCurrentNo(courseExtendService.computeCourseNoCurrent(courseNos, list));
  1368. dto.setTotalDays(courseExtendService.computeCourseDay(recordMap.get(dto.getId())));
  1369. }
  1370. // 获取每个科目的所有作业
  1371. Map<Object, Collection<UserPreviewPaperRelation>> previewMap = previewService.groupByCourseId(user.getId(), recordIds, 1000);
  1372. Transform.combine(pr, previewMap, UserCourseDetailDto.class, "productId", "papers", UserPaperBaseExtendDto.class);
  1373. for(UserCourseDetailDto dto : pr){
  1374. Collection<UserPreviewPaperRelation> list = previewMap.get(dto.getId());
  1375. if (list == null || list.size() == 0) continue;
  1376. int finish = 0;
  1377. for(UserPreviewPaperRelation relation : list){
  1378. if (relation.getPaper() == null) continue;
  1379. UserPaper paper = relation.getPaper();
  1380. if (paper.getTimes() > 0){
  1381. finish += 1;
  1382. }
  1383. }
  1384. dto.setPreviewProgress(finish * 100 / list.size());
  1385. }
  1386. // 绑定老师
  1387. Collection teacherIds = Transform.getIds(p, UserOrderRecord.class, "teacherId");
  1388. List<CourseTeacher> teacherList = courseTeacherService.select(teacherIds);
  1389. Transform.combine(pr, teacherList, UserCourseDetailDto.class, "teacherId", "teacher", CourseTeacher.class, "id", CourseTeacherExtendDto.class);
  1390. return ResponseHelp.success(pr, page, size, p.getTotal());
  1391. }
  1392. @RequestMapping(value = "/course/suspend", method = RequestMethod.POST)
  1393. @ApiOperation(value = "申请停课", notes = "申请停课", httpMethod = "POST")
  1394. public Response<Boolean> suspendCourse(@RequestBody @Validated CourseSuspendDto dto) {
  1395. User user = (User) shiroHelp.getLoginUser();
  1396. courseExtendService.suspendCourse(user.getId(), dto.getRecordId());
  1397. return ResponseHelp.success(true);
  1398. }
  1399. @RequestMapping(value = "/course/restore", method = RequestMethod.POST)
  1400. @ApiOperation(value = "恢复停课", notes = "恢复停课", httpMethod = "POST")
  1401. public Response<Boolean> restoreCourse(@RequestBody @Validated CourseRestoreDto dto) {
  1402. User user = (User) shiroHelp.getLoginUser();
  1403. courseExtendService.restoreCourse(user.getId(), dto.getRecordId());
  1404. return ResponseHelp.success(true);
  1405. }
  1406. @RequestMapping(value = "/course/time", method = RequestMethod.GET)
  1407. @ApiOperation(value = "时间表", notes = "时间表", httpMethod = "GET")
  1408. public Response<List<UserCourseTimeDto>> timeCourse(int id) {
  1409. User user = (User) shiroHelp.getLoginUser();
  1410. List<UserCourseTimeDto> dtos = new ArrayList<>();
  1411. UserOrderRecord record = userOrderRecordService.get(id);
  1412. if (record == null){
  1413. throw new ParameterException("记录不存在");
  1414. }
  1415. if (!record.getUserId().equals(user.getId())){
  1416. throw new ParameterException("记录不存在");
  1417. }
  1418. Integer courseId = record.getProductId();
  1419. // 获取停课记录
  1420. Date suspend = record.getSuspendTime();
  1421. if (suspend != null){
  1422. Date restore = record.getRestoreTime();
  1423. if (restore == null) restore = new Date();
  1424. while(suspend.before(restore)){
  1425. UserCourseTimeDto dto = new UserCourseTimeDto();
  1426. dto.setType("stop");
  1427. dto.setDay(Tools.day(suspend));
  1428. dtos.add(dto);
  1429. suspend = Tools.addDate(suspend, 1);
  1430. }
  1431. }
  1432. List<Long> tmpList = new ArrayList<>();
  1433. // 获取听课记录
  1434. List<UserCourseRecord> userCourseRecordList = userCourseRecordService.allWithRecord(id);
  1435. tmpList.clear();
  1436. for(UserCourseRecord userCourseRecord:userCourseRecordList){
  1437. Date day = Tools.day(userCourseRecord.getCreateTime());
  1438. if (!tmpList.contains(day.getTime())){
  1439. tmpList.add(day.getTime());
  1440. UserCourseTimeDto dto = new UserCourseTimeDto();
  1441. dto.setType("course");
  1442. dto.setDay(day);
  1443. dtos.add(dto);
  1444. }
  1445. }
  1446. // 预习作业
  1447. List<CourseNo> courseNoList = courseNoService.allCourse(courseId);
  1448. Collection courseNoIds = Transform.getIds(courseNoList, CourseNo.class, "id");
  1449. List<PreviewAssign> previewAssignList = previewAssignService.listByCourseNos(courseId, courseNoIds);
  1450. Collection assignIds = Transform.getIds(previewAssignList, PreviewAssign.class, "id");
  1451. List<UserPaper> userPaperList = userPaperService.listWithCourse(user.getId(), assignIds, id);
  1452. Collection paperIds = Transform.getIds(userPaperList, UserPaper.class, "id");
  1453. List<UserReport> userReportList = userReportService.listByPaper(paperIds);
  1454. tmpList.clear();
  1455. for(UserReport userReport:userReportList){
  1456. Date day = Tools.day(userReport.getCreateTime());
  1457. if (!tmpList.contains(day.getTime())){
  1458. tmpList.add(day.getTime());
  1459. UserCourseTimeDto dto = new UserCourseTimeDto();
  1460. dto.setType("preview");
  1461. dto.setDay(day);
  1462. dtos.add(dto);
  1463. }
  1464. }
  1465. return ResponseHelp.success(dtos);
  1466. }
  1467. }