|
|
@@ -1,12 +1,16 @@
|
|
|
package nju.seec.helper.util;
|
|
|
|
|
|
+import com.fasterxml.jackson.annotation.JsonProperty;
|
|
|
import com.google.common.collect.ImmutableMap;
|
|
|
import com.google.common.collect.Maps;
|
|
|
import lombok.Data;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import nju.seec.helper.dto.question.BaseQuestionDTO;
|
|
|
+import nju.seec.helper.dto.question.ChoiceQuestionDTO;
|
|
|
+import nju.seec.helper.dto.question.TrueOrFalseQuestionDTO;
|
|
|
import nju.seec.helper.util.enums.ExceptionType;
|
|
|
+import nju.seec.helper.util.enums.QuestionType;
|
|
|
import nju.seec.helper.util.exception.HelperException;
|
|
|
-import nju.seec.helper.vo.question.BaseQuestionVO;
|
|
|
import nju.seec.helper.vo.question.BokQuestion;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.data.domain.Page;
|
|
|
@@ -14,10 +18,7 @@ import org.springframework.data.domain.PageImpl;
|
|
|
import org.springframework.data.domain.Pageable;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Collections;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
@@ -40,168 +41,111 @@ public class BokUtil {
|
|
|
this.cacheUtils = cacheUtils;
|
|
|
}
|
|
|
|
|
|
- public Page<BaseQuestionVO> bokFindByStemLike(String stem, Pageable pageable, boolean withAnswer) {
|
|
|
- try {
|
|
|
- Map<String, String> urlParams = ImmutableMap.of(
|
|
|
- "content", stem,
|
|
|
- "page", String.valueOf(1 + pageable.getPageNumber()),
|
|
|
- "size", String.valueOf(pageable.getPageSize()),
|
|
|
- "sort", pageable.getSort().toString().replaceAll(" ", "").replaceAll(":", ",")
|
|
|
- );
|
|
|
- BokSearchResult result = restRequestUtil.sendGetRequest(
|
|
|
- searchUrl + "findByStemLike?content={content}&sort={sort}&size={size}&page={page}", BokSearchResult.class, urlParams);
|
|
|
-
|
|
|
- List<BokQuestion> questions = result.get_embedded().getChoiceQuestions();
|
|
|
- List<BaseQuestionVO> questionVOList =
|
|
|
- questions.stream()
|
|
|
- .map(question -> {
|
|
|
- cacheUtils.set(CACHE_NAME, question.getTqId(), question);
|
|
|
- return BaseQuestionVO.convertBokQuestionToVO(question, withAnswer);
|
|
|
- })
|
|
|
- .collect(Collectors.toList());
|
|
|
- return new PageImpl<>(questionVOList, pageable, result.getPage().getTotalElements());
|
|
|
- } catch (Exception e) {
|
|
|
- log.error(e.getLocalizedMessage(), e);
|
|
|
- throw HelperException.of(ExceptionType.ERROR, "获取题目失败");
|
|
|
- }
|
|
|
+ public Page<BokQuestion> bokFindByStemLike(String stem, Pageable pageable) {
|
|
|
+ Map<String, String> urlParams = ImmutableMap.of(
|
|
|
+ "content", stem,
|
|
|
+ "page", String.valueOf(1 + pageable.getPageNumber()),
|
|
|
+ "size", String.valueOf(pageable.getPageSize()),
|
|
|
+ "sort", pageable.getSort().toString().replaceAll(" ", "").replaceAll(":", ",")
|
|
|
+ );
|
|
|
+ BokSearchResult result = restRequestUtil.sendGetRequest(
|
|
|
+ searchUrl + "findByStemLike?content={content}&sort={sort}&size={size}&page={page}", BokSearchResult.class, urlParams);
|
|
|
+
|
|
|
+ List<BokQuestion> questions = result.getEmbedded().getChoiceQuestions();
|
|
|
+ cacheUtils.setAll(BOK_CACHE_NAME,
|
|
|
+ questions.parallelStream()
|
|
|
+ .collect(Collectors.toMap(BokQuestion::getTqId, bokQuestion -> bokQuestion)));
|
|
|
+ return new PageImpl<>(questions, pageable, result.getPage().getTotalElements());
|
|
|
}
|
|
|
|
|
|
- private static String CACHE_NAME = "BOK";
|
|
|
-
|
|
|
- public List<BaseQuestionVO> bokFindByIdIn(final List<String> ids, boolean withAnswer) {
|
|
|
- try {
|
|
|
- final ImmutableMap<Object, Object> bokQuestionsMap = cacheUtils.multiGet(CACHE_NAME, ids);
|
|
|
-
|
|
|
- List<String> requestIds = new ArrayList<>(ids);
|
|
|
- Map<String, BaseQuestionVO> questionVOMap = Maps.newHashMapWithExpectedSize(ids.size());
|
|
|
-
|
|
|
- bokQuestionsMap
|
|
|
- .values()
|
|
|
- .forEach(value -> {
|
|
|
- BokQuestion bokQuestion = (BokQuestion) value;
|
|
|
- BaseQuestionVO questionVO = BaseQuestionVO.convertBokQuestionToVO(bokQuestion, withAnswer);
|
|
|
- questionVOMap.put(questionVO.getId(), questionVO);
|
|
|
- requestIds.remove(bokQuestion.getTqId());
|
|
|
- });
|
|
|
- //未缓存的去这里拿
|
|
|
- if (!requestIds.isEmpty()) {
|
|
|
- Map<String, String> urlParams = ImmutableMap.of("id", requestIds.stream().reduce((a, b) -> a + "," + b).orElse(""));
|
|
|
-
|
|
|
- BokSearchResult result = restRequestUtil.sendGetRequest(searchUrl + "findByIdIn?id={id}", BokSearchResult.class, urlParams);
|
|
|
- List<BokQuestion> questions = result.get_embedded().getChoiceQuestions();
|
|
|
- questions.forEach(question -> {
|
|
|
- cacheUtils.set(CACHE_NAME, question.getTqId(), question);
|
|
|
- BaseQuestionVO questionVO = BaseQuestionVO.convertBokQuestionToVO(question, withAnswer);
|
|
|
- questionVOMap.put(questionVO.getId(), questionVO);
|
|
|
+ private static String BOK_CACHE_NAME = "BOK";
|
|
|
+
|
|
|
+ public List<BokQuestion> bokFindByIdIn(final List<String> ids) {
|
|
|
+ final ImmutableMap<Object, Object> bokQuestionsMap = cacheUtils.multiGet(BOK_CACHE_NAME, ids);
|
|
|
+
|
|
|
+ List<String> requestIds = new ArrayList<>(ids);
|
|
|
+ Map<String, BokQuestion> bokQuestionMap = Maps.newHashMapWithExpectedSize(ids.size());
|
|
|
+
|
|
|
+ bokQuestionsMap
|
|
|
+ .values()
|
|
|
+ .forEach(value -> {
|
|
|
+ BokQuestion bokQuestion = (BokQuestion) value;
|
|
|
+ bokQuestionMap.put(bokQuestion.getTqId(), bokQuestion);
|
|
|
+ requestIds.remove(bokQuestion.getTqId());
|
|
|
});
|
|
|
- }
|
|
|
-
|
|
|
- return ids.stream()
|
|
|
- .map(questionVOMap::get)
|
|
|
- .collect(Collectors.toList());
|
|
|
- } catch (Exception e) {
|
|
|
- log.error(e.getLocalizedMessage(), e);
|
|
|
- throw HelperException.of(ExceptionType.ERROR, "获取题目失败");
|
|
|
+ //未缓存的去这里拿
|
|
|
+ if (!requestIds.isEmpty()) {
|
|
|
+ Map<String, String> urlParams = ImmutableMap.of("id", requestIds.stream().reduce((a, b) -> a + "," + b).orElse(""));
|
|
|
+
|
|
|
+ BokSearchResult result = restRequestUtil.sendGetRequest(searchUrl + "findByIdIn?id={id}", BokSearchResult.class, urlParams);
|
|
|
+ List<BokQuestion> bokQuestions = result.getEmbedded().getChoiceQuestions();
|
|
|
+ bokQuestions.forEach(bokQuestion -> {
|
|
|
+ cacheUtils.set(BOK_CACHE_NAME, bokQuestion.getTqId(), bokQuestion);
|
|
|
+ bokQuestionMap.put(bokQuestion.getTqId(), bokQuestion);
|
|
|
+ });
|
|
|
}
|
|
|
+
|
|
|
+ return ids.stream()
|
|
|
+ .map(bokQuestionMap::get)
|
|
|
+ .collect(Collectors.toList());
|
|
|
}
|
|
|
|
|
|
- public BaseQuestionVO bokFindById(String questionId, boolean withAnswer) {
|
|
|
- Object cachedBokQuestion = cacheUtils.get(CACHE_NAME, questionId);
|
|
|
+ public BokQuestion bokFindById(String questionId) {
|
|
|
+ Object cachedBokQuestion = cacheUtils.get(BOK_CACHE_NAME, questionId);
|
|
|
if (cachedBokQuestion instanceof BokQuestion) {
|
|
|
- return BaseQuestionVO.convertBokQuestionToVO((BokQuestion) cachedBokQuestion, withAnswer);
|
|
|
- }
|
|
|
- try {
|
|
|
- BokQuestion bokQuestion = restRequestUtil.sendGetRequest(tqUrl + questionId, BokQuestion.class, Collections.emptyMap());
|
|
|
- cacheUtils.set(CACHE_NAME, bokQuestion.getTqId(), bokQuestion);
|
|
|
- return BaseQuestionVO.convertBokQuestionToVO(bokQuestion, withAnswer);
|
|
|
- } catch (Exception e) {
|
|
|
- log.error(e.getLocalizedMessage(), e);
|
|
|
- throw HelperException.of(ExceptionType.ERROR, "获取题目失败");
|
|
|
+ return (BokQuestion) cachedBokQuestion;
|
|
|
}
|
|
|
+ BokQuestion bokQuestion = restRequestUtil.sendGetRequest(tqUrl + questionId, BokQuestion.class, Collections.emptyMap());
|
|
|
+ cacheUtils.set(BOK_CACHE_NAME, bokQuestion.getTqId(), bokQuestion);
|
|
|
+ return bokQuestion;
|
|
|
+ }
|
|
|
+
|
|
|
+ public BokQuestion createQuestion(BaseQuestionDTO baseQuestionDTO) {
|
|
|
+ BokQuestion bokQuestion = getQuestion(baseQuestionDTO);
|
|
|
+ bokQuestion.setTqId(UUID.randomUUID().toString());
|
|
|
+ bokQuestion = restRequestUtil.sendPostRequest(tqUrl, bokQuestion, BokQuestion.class);
|
|
|
+ return bokQuestion;
|
|
|
+ }
|
|
|
+
|
|
|
+ public BokQuestion modifyQuestion(String questionId, BaseQuestionDTO baseQuestionDTO) {
|
|
|
+ BokQuestion bokQuestion = getQuestion(baseQuestionDTO);
|
|
|
+ bokQuestion.setTqId(questionId);
|
|
|
+ restRequestUtil.sendPutRequest(tqUrl, bokQuestion);
|
|
|
+ return bokFindById(questionId);
|
|
|
}
|
|
|
|
|
|
-// @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
|
|
|
-// public BaseQuestionVO postNewQuestion(BaseQuestionVO vo) throws JsonProcessingException {
|
|
|
-// if (vo.getQuestionId() != null) {
|
|
|
-// throw HelperException.of(ExceptionType.PARAM_ERROR, "should POST a new question");
|
|
|
-// }
|
|
|
-// String questionId = null;
|
|
|
-// //我当时应该用uuid的,但是线上已经部署了,只能下次再改了(如果有下次
|
|
|
-// //因为线上用的也是Long Id 并且es不提供自增主键,先这样尝试插入
|
|
|
-// //之后对于新增bok的题目,应该有某种限制,未补全知识点的题目不允许插入
|
|
|
-// int tryNumber = 100;
|
|
|
-// int randomLength = 4;
|
|
|
-// for (int i = 0; i < tryNumber; i++) {
|
|
|
-// Date date = new Date();
|
|
|
-// Calendar calendar = Calendar.getInstance();
|
|
|
-// int year = calendar.get(Calendar.YEAR);
|
|
|
-// String month = String.valueOf(1 + calendar.get(Calendar.MONTH));
|
|
|
-// String day = String.valueOf(calendar.get(Calendar.DATE));
|
|
|
-// if (month.length() < 2) {
|
|
|
-// month = "0" + month;
|
|
|
-// }
|
|
|
-// if (day.length() < 2) {
|
|
|
-// month = "0" + month;
|
|
|
-// }
|
|
|
-// Random randomGet = new Random();
|
|
|
-// StringBuilder random = new StringBuilder(String.valueOf(randomGet.nextInt(10000)));
|
|
|
-// while (random.length() < randomLength) {
|
|
|
-// random.insert(0, "0");
|
|
|
-// }
|
|
|
-// questionId = "" + (year - 2010) + (month) + day + (random);
|
|
|
-// try {
|
|
|
-// Map ret = (Map) restRequestUtil.sendGetRequest(tqUrl + questionId, new HashMap<>());
|
|
|
-// } catch (HttpClientErrorException e) {
|
|
|
-// if (e.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
|
|
|
-// break;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// questionId = null;
|
|
|
-// }
|
|
|
-// if (questionId == null) {
|
|
|
-// throw HelperException.of(ExceptionType.ERROR, "暂时无法保存题目,请重试!");
|
|
|
-// }
|
|
|
-//
|
|
|
-// vo.setQuestionId(questionId);
|
|
|
-//
|
|
|
-// BokTq bokTq = new BokTq(vo);
|
|
|
-// restRequestUtil.sendPutRequest(tqUrl + questionId, bokTq);
|
|
|
-//
|
|
|
-// return vo;
|
|
|
-//
|
|
|
-// }
|
|
|
-//
|
|
|
-// @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
|
|
|
-// public BaseQuestionVO putQuestion(BaseQuestionVO vo) throws JsonProcessingException {
|
|
|
-// if (vo.getQuestionId() == null) {
|
|
|
-// throw HelperException.of(ExceptionType.PARAM_ERROR, "should POST a present question");
|
|
|
-// }
|
|
|
-// String questionId = vo.getQuestionId();
|
|
|
-// try {
|
|
|
-// restRequestUtil.sendGetRequest(tqUrl + questionId, new HashMap<>());
|
|
|
-// } catch (HttpClientErrorException e) {
|
|
|
-// if (e.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
|
|
|
-// throw HelperException.of(ExceptionType.PARAM_ERROR, "should POST a present question");
|
|
|
-// }
|
|
|
-// }
|
|
|
-// restRequestUtil.sendPutRequest(tqUrl + questionId, new BokTq(vo));
|
|
|
-//
|
|
|
-// cacheUtils.remove(CACHE_NAME, questionId);
|
|
|
-// return vo;
|
|
|
-// }
|
|
|
-//
|
|
|
-// public void deleteQuestion(String questionId) {
|
|
|
-// try {
|
|
|
-// restRequestUtil.sendDeleteRequest(tqUrl + questionId);
|
|
|
-// } catch (JsonProcessingException e) {
|
|
|
-// throw HelperException.of(ExceptionType.ERROR, "请求BOK题库数据错误:" + e.getMessage());
|
|
|
-// }
|
|
|
-// cacheUtils.remove(CACHE_NAME, questionId);
|
|
|
-// }
|
|
|
+ public void deleteQuestion(String questionId) {
|
|
|
+ restRequestUtil.sendDeleteRequest(tqUrl + questionId);
|
|
|
+ }
|
|
|
+
|
|
|
+ private BokQuestion getQuestion(BaseQuestionDTO baseQuestionDTO) {
|
|
|
+ BokQuestion bokQuestion = new BokQuestion();
|
|
|
+ bokQuestion.setType(baseQuestionDTO.getType());
|
|
|
+ bokQuestion.setStem(baseQuestionDTO.getStem());
|
|
|
+
|
|
|
+ final QuestionType questionType = QuestionType.getQuestionType(baseQuestionDTO.getType());
|
|
|
+ switch (Objects.requireNonNull(questionType)) {
|
|
|
+ case CHOICE:
|
|
|
+ ChoiceQuestionDTO choiceQuestionDTO = (ChoiceQuestionDTO) baseQuestionDTO;
|
|
|
+ bokQuestion.setOptions(choiceQuestionDTO.getOptions());
|
|
|
+ bokQuestion.setAnswer(choiceQuestionDTO.getAnswer());
|
|
|
+ bokQuestion.setAnalysis(choiceQuestionDTO.getAnalysis());
|
|
|
+ break;
|
|
|
+ case TRUE_FALSE:
|
|
|
+ TrueOrFalseQuestionDTO trueOrFalseQuestionDTO = (TrueOrFalseQuestionDTO) baseQuestionDTO;
|
|
|
+ bokQuestion.setAnswer(String.valueOf(trueOrFalseQuestionDTO.getAnswer()));
|
|
|
+ bokQuestion.setAnalysis(trueOrFalseQuestionDTO.getAnalysis());
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw HelperException.of(ExceptionType.ERROR, "不支持的题目类型");
|
|
|
+ }
|
|
|
+ return bokQuestion;
|
|
|
+ }
|
|
|
|
|
|
@Data
|
|
|
private static class BokSearchResult {
|
|
|
- private Embedded _embedded;
|
|
|
+ @JsonProperty("_embedded")
|
|
|
+ private Embedded embedded;
|
|
|
private Page page;
|
|
|
|
|
|
@Data
|