QuestionNoService.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. package com.qxgmat.service.inline;
  2. import com.github.pagehelper.Page;
  3. import com.nuliji.tools.AbstractService;
  4. import com.nuliji.tools.PageResult;
  5. import com.nuliji.tools.Transform;
  6. import com.nuliji.tools.exception.ParameterException;
  7. import com.nuliji.tools.exception.SystemException;
  8. import com.nuliji.tools.mybatis.Example;
  9. import com.qxgmat.data.constants.enums.module.StructModule;
  10. import com.qxgmat.data.constants.enums.status.DirectionStatus;
  11. import com.qxgmat.data.dao.QuestionNoMapper;
  12. import com.qxgmat.data.dao.entity.Question;
  13. import com.qxgmat.data.dao.entity.QuestionNo;
  14. import com.qxgmat.data.dao.entity.UserQuestion;
  15. import com.qxgmat.data.inline.PaperStat;
  16. import com.qxgmat.data.relation.QuestionNoRelationMapper;
  17. import com.qxgmat.data.relation.entity.QuestionNoRelation;
  18. import org.slf4j.Logger;
  19. import org.slf4j.LoggerFactory;
  20. import org.springframework.stereotype.Service;
  21. import org.springframework.transaction.annotation.Transactional;
  22. import javax.annotation.Resource;
  23. import java.util.*;
  24. import java.util.stream.Collectors;
  25. @Service
  26. public class QuestionNoService extends AbstractService {
  27. private static final Logger logger = LoggerFactory.getLogger(QuestionNoService.class);
  28. protected boolean SOFT_FLAG = true;
  29. final static String formatSet = "FIND_IN_SET('%d', module_struct)";
  30. @Resource
  31. private QuestionNoMapper questionNoMapper;
  32. @Resource
  33. private QuestionNoRelationMapper questionNoRelationMapper;
  34. @Resource
  35. private QuestionService questionService;
  36. /**
  37. * 根据题干搜索相似题目: 相似度80%
  38. * @param page
  39. * @param size
  40. * @param stem
  41. * @return
  42. */
  43. public PageResult<QuestionNoRelation> searchStem(int page, int size, String stem){
  44. // String[] stems = stem.replaceAll("\\.?,?!?:?;?\\??", "").split(" ");
  45. Page<QuestionNo> p = page(()->{
  46. questionNoRelationMapper.searchStem(stem);
  47. }, page, size);
  48. Collection ids = Transform.getIds(p, QuestionNo.class, "id");
  49. // 获取详细数据
  50. List<QuestionNo> list = select(ids);
  51. return new PageResult<>(relation(list), p.getTotal());
  52. }
  53. /**
  54. * 根据题目编号搜索相似题目
  55. * @param page
  56. * @param size
  57. * @param keyword
  58. * @param module
  59. * @return
  60. */
  61. public PageResult<QuestionNoRelation> searchNo(int page, int size, String keyword, String module){
  62. logger.info("SearchNo: {}, {}", page, size);
  63. Example example = new Example(QuestionNo.class);
  64. if(keyword != null)
  65. example.and(
  66. example.createCriteria()
  67. .andLike("title", "%"+keyword+"%")
  68. );
  69. if (module != null)
  70. example.and(
  71. example.createCriteria()
  72. .andEqualTo("module", module)
  73. );
  74. example.orderBy("id").asc();
  75. Page<QuestionNo> p = page(()->select(questionNoMapper, example), page, size);
  76. logger.info("SearchNo result: {}", p.toString());
  77. return new PageResult<>(relation(p), p.getTotal());
  78. }
  79. /**
  80. * 获取结构模块下的题目列表: 按序号排列
  81. * @param module
  82. * @param structId
  83. * @return
  84. */
  85. public List<QuestionNoRelation> listByStruct(StructModule module, Integer structId){
  86. Example example = new Example(QuestionNo.class);
  87. example.and(
  88. example.createCriteria()
  89. .andEqualTo("module", module.key)
  90. .andCondition(String.format(formatSet, structId))
  91. );
  92. example.orderBy("no").asc();
  93. return relation(select(questionNoMapper, example));
  94. }
  95. /**
  96. * 根据题目标号列表获取题目
  97. * @param nos
  98. * @param module
  99. * @return
  100. */
  101. public List<QuestionNoRelation> listWithRelationByNos(String[] nos, String module){
  102. if (nos.length == 0) return new ArrayList<>();
  103. Example example = new Example(QuestionNo.class);
  104. example.and(
  105. example.createCriteria()
  106. .andIn("no", Arrays.stream(nos).collect(Collectors.toList()))
  107. );
  108. if (module != null)
  109. example.and(
  110. example.createCriteria()
  111. .andEqualTo("module", module)
  112. );
  113. List<QuestionNo> p = select(questionNoMapper, example);
  114. return relation(p);
  115. }
  116. /**
  117. * 根据题目获取关联的题目编号
  118. * @param questionId
  119. * @return
  120. */
  121. public List<QuestionNo> listByQuestion(Number questionId){
  122. Example example = new Example(QuestionNo.class);
  123. example.and(
  124. example.createCriteria()
  125. .andEqualTo("questionId", questionId)
  126. );
  127. return select(questionNoMapper, example);
  128. }
  129. /**
  130. * 根据题目编号id列表获取关联题目
  131. * @param ids
  132. * @return
  133. */
  134. public List<QuestionNoRelation> listWithRelationByIds(Number[] ids){
  135. List<QuestionNo> p = select(questionNoMapper, ids);
  136. return relation(p);
  137. }
  138. /**
  139. * 根据题目编号id列表获取关联题目
  140. * @param ids
  141. * @return
  142. */
  143. public Map<Number, QuestionNoRelation> mapWithRelationByIds(Number[] ids){
  144. List<QuestionNo> p = select(questionNoMapper, ids);
  145. List<QuestionNoRelation> list = relation(p);
  146. Map<Number, QuestionNoRelation> map = new HashMap<>();
  147. for(QuestionNoRelation relation : list){
  148. map.put(relation.getId(), relation);
  149. }
  150. return map;
  151. }
  152. /**
  153. * 根据题目编号id获取关联题目
  154. * @param id
  155. * @return
  156. */
  157. public QuestionNoRelation getWithRelation(Number id){
  158. QuestionNo questionNo = get(id);
  159. return relation(questionNo);
  160. }
  161. /**
  162. * 绑定no和question
  163. * @param ids
  164. * @param questionId
  165. * @return
  166. */
  167. public Boolean bindQuestion(Integer[] ids, Integer questionId){
  168. if (ids.length == 0) return false;
  169. Example example = new Example(QuestionNo.class);
  170. example.and(
  171. example.createCriteria()
  172. .andIn("id", Arrays.stream(ids).collect(Collectors.toList()))
  173. );
  174. int result = update(questionNoMapper, example, QuestionNo.builder().questionId(questionId).deleteTime(null).build());
  175. return result > 0;
  176. }
  177. /**
  178. * 设定编号关联关系
  179. * @param ids
  180. * @return
  181. */
  182. public Boolean relationQuestion(int[] ids){
  183. if (ids.length == 0) return false;
  184. Example example = new Example(QuestionNo.class);
  185. example.and(
  186. example.createCriteria()
  187. .andIn("id", Arrays.stream(ids).boxed().collect(Collectors.toList()))
  188. );
  189. int result = update(questionNoMapper, example, QuestionNo.builder().relationQuestion(ids).deleteTime(null).build());
  190. return result > 0;
  191. }
  192. /**
  193. * 根据题目获取总试卷统计信息
  194. * @param questionNoList
  195. * @return
  196. */
  197. public PaperStat statPaper(List<QuestionNo> questionNoList){
  198. PaperStat stat = new PaperStat();
  199. Integer totalTime = 0;
  200. Integer totalNumber = 0;
  201. Integer totalCorrect = 0;
  202. for(QuestionNo questionNo : questionNoList){
  203. totalTime += questionNo.getTotalTime();
  204. totalNumber += questionNo.getTotalNumber();
  205. totalCorrect += questionNo.getTotalCorrect();
  206. }
  207. stat.setTotalCorrect(totalCorrect);
  208. stat.setTotalNumber(totalNumber);
  209. stat.setTotalTime(totalTime);
  210. return stat;
  211. }
  212. /**
  213. * 累加做题记录到questionNo
  214. * @param question
  215. */
  216. public void accumulation(UserQuestion question){
  217. questionNoRelationMapper.accumulation(question.getQuestionNoId(), 1, question.getTime(), question.getIsCorrect());
  218. }
  219. /**
  220. * 根据试卷分组获取统计信息
  221. * @param questionNoIdsMap
  222. * @return
  223. */
  224. public Map<Integer, PaperStat> statPaperMap(Map<Integer, Integer[]> questionNoIdsMap){
  225. Map<Integer, PaperStat> relationMap = new HashMap<>();
  226. List<Integer> ids = new ArrayList<>();
  227. for(Integer[] questionNoIds : questionNoIdsMap.values()){
  228. ids.addAll(Arrays.stream(questionNoIds).collect(Collectors.toList()));
  229. }
  230. List<QuestionNo> questionNoList = select(ids);
  231. Map questionNoMap = Transform.getMap(questionNoList, QuestionNo.class, "id");
  232. List<QuestionNo> l = new ArrayList<>();
  233. for(Integer k: questionNoIdsMap.keySet()){
  234. l.clear();
  235. for (Integer questionNoId : questionNoIdsMap.get(k)){
  236. l.add((QuestionNo)questionNoMap.get(questionNoId));
  237. }
  238. relationMap.put(k, statPaper(l));
  239. }
  240. return relationMap;
  241. }
  242. public List<QuestionNoRelation> relation(List<QuestionNo> p){
  243. List<QuestionNoRelation> relationList = Transform.convert(p, QuestionNoRelation.class);
  244. Collection questionIds = Transform.getIds(p, QuestionNo.class, "questionId");
  245. List<Question> questions = questionService.select(questionIds);
  246. Transform.combine(relationList, questions, QuestionNoRelation.class, "questionId", "question", Question.class, "id");
  247. return relationList;
  248. }
  249. public QuestionNoRelation relation(QuestionNo p){
  250. QuestionNoRelation relation = Transform.convert(p, QuestionNoRelation.class);
  251. Question question = questionService.get(p.getQuestionId());
  252. relation.setQuestion(question);
  253. return relation;
  254. }
  255. /**
  256. * 通过题目编号获取
  257. * @param title
  258. * @return
  259. */
  260. public QuestionNo getByNo(String title, String module){
  261. return one(questionNoMapper, QuestionNo.builder().title(title).module(module).build());
  262. }
  263. @Transactional
  264. public QuestionNo add(QuestionNo question){
  265. QuestionNo in = getByNo(question.getTitle(), question.getModule());
  266. if (in != null){
  267. return in;
  268. }
  269. int result = insert(questionNoMapper, question);
  270. question = one(questionNoMapper, question.getId());
  271. if(question == null){
  272. throw new SystemException("题目添加失败");
  273. }
  274. return question;
  275. }
  276. @Deprecated
  277. public QuestionNo edit(QuestionNo question){
  278. QuestionNo in = one(questionNoMapper, question.getId());
  279. if(in == null){
  280. throw new ParameterException("题目不存在");
  281. }
  282. int result = update(questionNoMapper, question);
  283. return question;
  284. }
  285. public boolean delete(Number id){
  286. QuestionNo in = one(questionNoMapper, id);
  287. if(in == null){
  288. throw new ParameterException("题目不存在");
  289. }
  290. int result = delete(questionNoMapper, id, SOFT_FLAG);
  291. return result > 0;
  292. }
  293. public QuestionNo get(Number id){
  294. QuestionNo in = one(questionNoMapper, id);
  295. if(in == null){
  296. throw new ParameterException("题目不存在");
  297. }
  298. return in;
  299. }
  300. public Page<QuestionNo> select(int page, int pageSize){
  301. return select(questionNoMapper, page, pageSize);
  302. }
  303. public List<QuestionNo> select(Collection ids){
  304. return select(questionNoMapper, ids);
  305. }
  306. }