BokQuestionApi.java 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package nju.seec.helper.api.bok;
  2. import com.fasterxml.jackson.annotation.JsonProperty;
  3. import com.google.common.collect.ImmutableMap;
  4. import com.google.common.collect.Lists;
  5. import com.google.common.collect.Maps;
  6. import lombok.Data;
  7. import nju.seec.helper.dto.question.BaseQuestionDTO;
  8. import nju.seec.helper.dto.question.ChoiceQuestionDTO;
  9. import nju.seec.helper.dto.question.TrueOrFalseQuestionDTO;
  10. import nju.seec.helper.enums.ExceptionType;
  11. import nju.seec.helper.enums.QuestionType;
  12. import nju.seec.helper.exception.HelperException;
  13. import nju.seec.helper.util.Consts;
  14. import nju.seec.helper.util.RestRequestUtil;
  15. import nju.seec.helper.util.cache.GuavaCacheUtils;
  16. import nju.seec.helper.vo.question.BokQuestionVO;
  17. import org.springframework.beans.factory.annotation.Value;
  18. import org.springframework.data.domain.Page;
  19. import org.springframework.data.domain.PageImpl;
  20. import org.springframework.data.domain.Pageable;
  21. import org.springframework.stereotype.Component;
  22. import java.util.Collections;
  23. import java.util.List;
  24. import java.util.Map;
  25. import java.util.Objects;
  26. import java.util.stream.Collectors;
  27. /**
  28. * @author xst
  29. * <p>
  30. * updated by cst
  31. */
  32. @Component
  33. public class BokQuestionApi {
  34. private final RestRequestUtil restRequestUtil;
  35. private final GuavaCacheUtils cacheUtils;
  36. @Value("${bok.tqUrl}")
  37. private String tqUrl;
  38. @Value("${bok.tqStemSearchUrl}")
  39. private String tqStemSearchUrl;
  40. @Value("${bok.tqIdSearchUrl}")
  41. private String tqIdSearchUrl;
  42. public BokQuestionApi(RestRequestUtil restRequestUtil, GuavaCacheUtils cacheUtils) {
  43. this.restRequestUtil = restRequestUtil;
  44. this.cacheUtils = cacheUtils;
  45. }
  46. public Page<BokQuestionVO> bokFindByStemLike(String stem, Pageable pageable) {
  47. Map<String, String> urlParams = ImmutableMap.of(
  48. "content", stem,
  49. "page", String.valueOf(1 + pageable.getPageNumber()),
  50. "size", String.valueOf(pageable.getPageSize())
  51. );
  52. BokSearchResult result = restRequestUtil.sendGetRequest(tqStemSearchUrl, BokSearchResult.class, urlParams);
  53. List<BokQuestionVO> bokQuestionVOList = result.getEmbedded().getQuestions();
  54. cacheUtils.setAll(BOK_QUESTION_CACHE_NAME, bokQuestionVOList.parallelStream().collect(Collectors.toMap(BokQuestionVO::getId, bokQuestion -> bokQuestion)));
  55. return new PageImpl<>(bokQuestionVOList, pageable, result.getPage().getTotalElements());
  56. }
  57. private static final String BOK_QUESTION_CACHE_NAME = Consts.SYS_NAME + "_bok_question";
  58. @SuppressWarnings({"unchecked", "rawtypes"})
  59. public List<BokQuestionVO> bokFindByIdIn(final List<String> ids) {
  60. Map<String, BokQuestionVO> bokQuestionsMap = Maps.newHashMapWithExpectedSize(ids.size());
  61. final Map<String, BokQuestionVO> cacheBokQuestionsMap = (Map) cacheUtils.multiGet(BOK_QUESTION_CACHE_NAME, ids);
  62. bokQuestionsMap.putAll(cacheBokQuestionsMap);
  63. List<String> requestIds = Lists.newArrayList(ids);
  64. requestIds.removeAll(cacheBokQuestionsMap.keySet());
  65. //未缓存的去这里拿
  66. if (!requestIds.isEmpty()) {
  67. Map<String, String> urlParams = ImmutableMap.of("id", requestIds.stream().reduce((a, b) -> a + "," + b).orElse(""));
  68. BokSearchResult result = restRequestUtil.sendGetRequest(tqIdSearchUrl, BokSearchResult.class, urlParams);
  69. List<BokQuestionVO> bokQuestionVOList = result.getEmbedded().getQuestions();
  70. Map<String, BokQuestionVO> remoteBokQuestionsMap = bokQuestionVOList.parallelStream().collect(Collectors.toMap(BokQuestionVO::getId, bokQuestion -> bokQuestion));
  71. bokQuestionsMap.putAll(remoteBokQuestionsMap);
  72. cacheUtils.setAll(BOK_QUESTION_CACHE_NAME, (Map) remoteBokQuestionsMap);
  73. }
  74. return ids.stream()
  75. .map(bokQuestionsMap::get)
  76. .collect(Collectors.toList());
  77. }
  78. public BokQuestionVO bokFindById(String questionId) {
  79. Object cachedBokQuestion = cacheUtils.get(BOK_QUESTION_CACHE_NAME, questionId);
  80. if (cachedBokQuestion instanceof BokQuestionVO) {
  81. return (BokQuestionVO) cachedBokQuestion;
  82. }
  83. BokQuestionVO bokQuestionVO = restRequestUtil.sendGetRequest(tqUrl + "/" + questionId, BokQuestionVO.class, Collections.emptyMap());
  84. cacheUtils.set(BOK_QUESTION_CACHE_NAME, bokQuestionVO.getId(), bokQuestionVO);
  85. return bokQuestionVO;
  86. }
  87. public BokQuestionVO createQuestion(String questionId, BaseQuestionDTO baseQuestionDTO) {
  88. BokQuestionVO bokQuestionVO = getQuestion(baseQuestionDTO);
  89. bokQuestionVO.setId(questionId);
  90. bokQuestionVO = restRequestUtil.sendPostRequest(tqUrl, bokQuestionVO, BokQuestionVO.class);
  91. return bokQuestionVO;
  92. }
  93. public BokQuestionVO modifyQuestion(String questionId, BaseQuestionDTO baseQuestionDTO) {
  94. BokQuestionVO bokQuestionVO = getQuestion(baseQuestionDTO);
  95. bokQuestionVO.setId(questionId);
  96. restRequestUtil.sendPutRequest(tqUrl + "/" + questionId, bokQuestionVO);
  97. return bokFindById(questionId);
  98. }
  99. public void deleteQuestion(String questionId) {
  100. restRequestUtil.sendDeleteRequest(tqUrl + "/" + questionId);
  101. }
  102. public void starQuestion(String userId, String questionId) {
  103. }
  104. private BokQuestionVO getQuestion(BaseQuestionDTO baseQuestionDTO) {
  105. BokQuestionVO bokQuestionVO = new BokQuestionVO();
  106. bokQuestionVO.setType(baseQuestionDTO.getType());
  107. bokQuestionVO.setStem(baseQuestionDTO.getStem());
  108. bokQuestionVO.setKeyPoints(baseQuestionDTO.getKeyPoints());
  109. bokQuestionVO.setTags(baseQuestionDTO.getTags());
  110. bokQuestionVO.setKnowledgeId(baseQuestionDTO.getKnowledgeId());
  111. final QuestionType questionType = QuestionType.getQuestionType(baseQuestionDTO.getType());
  112. switch (Objects.requireNonNull(questionType)) {
  113. case CHOICE:
  114. ChoiceQuestionDTO choiceQuestionDTO = (ChoiceQuestionDTO) baseQuestionDTO;
  115. bokQuestionVO.setOptions(choiceQuestionDTO.getOptions());
  116. bokQuestionVO.setAnswer(choiceQuestionDTO.getAnswer());
  117. bokQuestionVO.setAnalysis(choiceQuestionDTO.getAnalysis());
  118. break;
  119. case TRUE_FALSE:
  120. TrueOrFalseQuestionDTO trueOrFalseQuestionDTO = (TrueOrFalseQuestionDTO) baseQuestionDTO;
  121. bokQuestionVO.setAnswer(String.valueOf(trueOrFalseQuestionDTO.getAnswer()));
  122. bokQuestionVO.setAnalysis(trueOrFalseQuestionDTO.getAnalysis());
  123. break;
  124. default:
  125. throw HelperException.of(ExceptionType.ERROR, "不支持的题目类型");
  126. }
  127. return bokQuestionVO;
  128. }
  129. @Data
  130. private static class BokSearchResult {
  131. @JsonProperty("_embedded")
  132. private Embedded embedded = new Embedded();
  133. private Page page;
  134. @Data
  135. private static class Embedded {
  136. private List<BokQuestionVO> questions = Collections.emptyList();
  137. }
  138. @Data
  139. private static class Page {
  140. private int size;
  141. private int number;
  142. private int totalPages;
  143. private long totalElements;
  144. }
  145. }
  146. }