|
@@ -1,29 +1,27 @@
|
|
|
package nju.seec.helper.api.bok;
|
|
package nju.seec.helper.api.bok;
|
|
|
|
|
|
|
|
-import com.fasterxml.jackson.annotation.JsonProperty;
|
|
|
|
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
import com.google.common.collect.ImmutableMap;
|
|
import com.google.common.collect.ImmutableMap;
|
|
|
-import com.google.common.collect.Lists;
|
|
|
|
|
-import com.google.common.collect.Maps;
|
|
|
|
|
import lombok.Data;
|
|
import lombok.Data;
|
|
|
|
|
+import nju.seec.helper.api.bok.constant.QuestionType;
|
|
|
|
|
+import nju.seec.helper.api.bok.vo.PageableQuestionListVO;
|
|
|
|
|
+import nju.seec.helper.api.bok.vo.QuestionVO;
|
|
|
import nju.seec.helper.dto.question.BaseQuestionDTO;
|
|
import nju.seec.helper.dto.question.BaseQuestionDTO;
|
|
|
import nju.seec.helper.dto.question.ChoiceQuestionDTO;
|
|
import nju.seec.helper.dto.question.ChoiceQuestionDTO;
|
|
|
import nju.seec.helper.dto.question.TrueOrFalseQuestionDTO;
|
|
import nju.seec.helper.dto.question.TrueOrFalseQuestionDTO;
|
|
|
import nju.seec.helper.enums.ExceptionType;
|
|
import nju.seec.helper.enums.ExceptionType;
|
|
|
-import nju.seec.helper.enums.QuestionType;
|
|
|
|
|
import nju.seec.helper.exception.HelperException;
|
|
import nju.seec.helper.exception.HelperException;
|
|
|
import nju.seec.helper.util.Consts;
|
|
import nju.seec.helper.util.Consts;
|
|
|
import nju.seec.helper.util.RestRequestUtil;
|
|
import nju.seec.helper.util.RestRequestUtil;
|
|
|
import nju.seec.helper.util.cache.CaffeineCacheUtils;
|
|
import nju.seec.helper.util.cache.CaffeineCacheUtils;
|
|
|
-import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
|
|
+import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
|
import org.springframework.data.domain.Page;
|
|
import org.springframework.data.domain.Page;
|
|
|
import org.springframework.data.domain.PageImpl;
|
|
import org.springframework.data.domain.PageImpl;
|
|
|
import org.springframework.data.domain.Pageable;
|
|
import org.springframework.data.domain.Pageable;
|
|
|
import org.springframework.stereotype.Component;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
|
|
-import java.util.Collections;
|
|
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
-import java.util.Objects;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -32,143 +30,92 @@ import java.util.stream.Collectors;
|
|
|
* updated by cst
|
|
* updated by cst
|
|
|
*/
|
|
*/
|
|
|
@Component
|
|
@Component
|
|
|
|
|
+@ConfigurationProperties("bok.question")
|
|
|
|
|
+@Data
|
|
|
public class QuestionApi {
|
|
public class QuestionApi {
|
|
|
|
|
+ private static final String BOK_QUESTION_CACHE_NAME = Consts.BOK_QUESTION_CACHE_NAME;
|
|
|
|
|
+
|
|
|
private final RestRequestUtil restRequestUtil;
|
|
private final RestRequestUtil restRequestUtil;
|
|
|
private final CaffeineCacheUtils cacheUtils;
|
|
private final CaffeineCacheUtils cacheUtils;
|
|
|
- @Value("${bok.tqUrl}")
|
|
|
|
|
- private String tqUrl;
|
|
|
|
|
- @Value("${bok.tqStemSearchUrl}")
|
|
|
|
|
- private String tqStemSearchUrl;
|
|
|
|
|
- @Value("${bok.tqIdSearchUrl}")
|
|
|
|
|
- private String tqIdSearchUrl;
|
|
|
|
|
|
|
+ private String url;
|
|
|
|
|
+ private String searchUrl;
|
|
|
|
|
|
|
|
public QuestionApi(RestRequestUtil restRequestUtil, CaffeineCacheUtils cacheUtils) {
|
|
public QuestionApi(RestRequestUtil restRequestUtil, CaffeineCacheUtils cacheUtils) {
|
|
|
this.restRequestUtil = restRequestUtil;
|
|
this.restRequestUtil = restRequestUtil;
|
|
|
this.cacheUtils = cacheUtils;
|
|
this.cacheUtils = cacheUtils;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public Page<QuestionVO> bokFindByStemLike(String stem, Pageable pageable) {
|
|
|
|
|
- Map<String, String> urlParams = ImmutableMap.of(
|
|
|
|
|
- "content", stem,
|
|
|
|
|
- "page", String.valueOf(1 + pageable.getPageNumber()),
|
|
|
|
|
- "size", String.valueOf(pageable.getPageSize())
|
|
|
|
|
- );
|
|
|
|
|
- BokSearchResult result = restRequestUtil.sendGetRequest(tqStemSearchUrl, BokSearchResult.class, urlParams);
|
|
|
|
|
-
|
|
|
|
|
- List<QuestionVO> questionVOList = result.getEmbedded().getQuestions();
|
|
|
|
|
|
|
+ @SuppressWarnings({"unchecked", "rawtypes"})
|
|
|
|
|
+ public Page<QuestionVO> searchQuestions(String stem, String tag, String knowledgeId, Pageable pageable) {
|
|
|
|
|
+ Map<String, ?> urlParams = (Map) ImmutableMap.builder()
|
|
|
|
|
+ .put("stem", stem)
|
|
|
|
|
+ .put("tag", tag)
|
|
|
|
|
+ .put("knowledgeId", knowledgeId)
|
|
|
|
|
+ .put("page", String.valueOf(1 + pageable.getPageNumber()))
|
|
|
|
|
+ .put("size", String.valueOf(pageable.getPageSize()))
|
|
|
|
|
+ .put("sort", pageable.getSort().stream()
|
|
|
|
|
+ .map(order -> StrUtil.concat(true, "sort=", order.getProperty(), ",", order.getDirection().toString()))
|
|
|
|
|
+ .reduce((o1, o2) -> StrUtil.join("&", o1, o2))
|
|
|
|
|
+ .orElse("")
|
|
|
|
|
+ )
|
|
|
|
|
+ .build();
|
|
|
|
|
+ PageableQuestionListVO result = restRequestUtil.sendGetRequest(searchUrl, PageableQuestionListVO.class, urlParams);
|
|
|
|
|
+
|
|
|
|
|
+ List<QuestionVO> questionVOList = result.getQuestions();
|
|
|
cacheUtils.setAll(BOK_QUESTION_CACHE_NAME, questionVOList.parallelStream().collect(Collectors.toMap(QuestionVO::getId, bokQuestion -> bokQuestion)));
|
|
cacheUtils.setAll(BOK_QUESTION_CACHE_NAME, questionVOList.parallelStream().collect(Collectors.toMap(QuestionVO::getId, bokQuestion -> bokQuestion)));
|
|
|
return new PageImpl<>(questionVOList, pageable, result.getPage().getTotalElements());
|
|
return new PageImpl<>(questionVOList, pageable, result.getPage().getTotalElements());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private static final String BOK_QUESTION_CACHE_NAME = Consts.SYS_NAME + "_bok_question";
|
|
|
|
|
-
|
|
|
|
|
- @SuppressWarnings({"unchecked", "rawtypes"})
|
|
|
|
|
- public List<QuestionVO> bokFindByIdIn(final List<String> ids) {
|
|
|
|
|
- Map<String, QuestionVO> bokQuestionsMap = Maps.newHashMapWithExpectedSize(ids.size());
|
|
|
|
|
-
|
|
|
|
|
- final Map<String, QuestionVO> cacheBokQuestionsMap = (Map) cacheUtils.multiGet(BOK_QUESTION_CACHE_NAME, ids);
|
|
|
|
|
- bokQuestionsMap.putAll(cacheBokQuestionsMap);
|
|
|
|
|
-
|
|
|
|
|
- List<String> requestIds = Lists.newArrayList(ids);
|
|
|
|
|
- requestIds.removeAll(cacheBokQuestionsMap.keySet());
|
|
|
|
|
- //未缓存的去这里拿
|
|
|
|
|
- if (!requestIds.isEmpty()) {
|
|
|
|
|
- Map<String, String> urlParams = ImmutableMap.of("id", requestIds.stream().reduce((a, b) -> a + "," + b).orElse(""));
|
|
|
|
|
-
|
|
|
|
|
- BokSearchResult result = restRequestUtil.sendGetRequest(tqIdSearchUrl, BokSearchResult.class, urlParams);
|
|
|
|
|
- List<QuestionVO> questionVOList = result.getEmbedded().getQuestions();
|
|
|
|
|
-
|
|
|
|
|
- Map<String, QuestionVO> remoteBokQuestionsMap = questionVOList.parallelStream().collect(Collectors.toMap(QuestionVO::getId, bokQuestion -> bokQuestion));
|
|
|
|
|
-
|
|
|
|
|
- bokQuestionsMap.putAll(remoteBokQuestionsMap);
|
|
|
|
|
- cacheUtils.setAll(BOK_QUESTION_CACHE_NAME, (Map) remoteBokQuestionsMap);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return ids.stream()
|
|
|
|
|
- .map(bokQuestionsMap::get)
|
|
|
|
|
- .collect(Collectors.toList());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public QuestionVO bokFindById(String questionId) {
|
|
|
|
|
|
|
+ public QuestionVO findQuestionsById(String questionId) {
|
|
|
Object cachedBokQuestion = cacheUtils.get(BOK_QUESTION_CACHE_NAME, questionId);
|
|
Object cachedBokQuestion = cacheUtils.get(BOK_QUESTION_CACHE_NAME, questionId);
|
|
|
if (cachedBokQuestion instanceof QuestionVO) {
|
|
if (cachedBokQuestion instanceof QuestionVO) {
|
|
|
return (QuestionVO) cachedBokQuestion;
|
|
return (QuestionVO) cachedBokQuestion;
|
|
|
}
|
|
}
|
|
|
- QuestionVO questionVO = restRequestUtil.sendGetRequest(tqUrl + "/" + questionId, QuestionVO.class, Collections.emptyMap());
|
|
|
|
|
|
|
+ QuestionVO questionVO = restRequestUtil.sendGetRequest(url + "/" + questionId, QuestionVO.class);
|
|
|
cacheUtils.set(BOK_QUESTION_CACHE_NAME, questionVO.getId(), questionVO);
|
|
cacheUtils.set(BOK_QUESTION_CACHE_NAME, questionVO.getId(), questionVO);
|
|
|
return questionVO;
|
|
return questionVO;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public QuestionVO createQuestion(String questionId, BaseQuestionDTO baseQuestionDTO) {
|
|
public QuestionVO createQuestion(String questionId, BaseQuestionDTO baseQuestionDTO) {
|
|
|
- QuestionVO questionVO = getQuestion(baseQuestionDTO);
|
|
|
|
|
|
|
+ QuestionVO questionVO = createQuestionVO(baseQuestionDTO);
|
|
|
questionVO.setId(questionId);
|
|
questionVO.setId(questionId);
|
|
|
- questionVO = restRequestUtil.sendPostRequest(tqUrl, questionVO, QuestionVO.class);
|
|
|
|
|
|
|
+ questionVO = restRequestUtil.sendPostRequest(url, questionVO, QuestionVO.class);
|
|
|
return questionVO;
|
|
return questionVO;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public QuestionVO modifyQuestion(String questionId, BaseQuestionDTO baseQuestionDTO) {
|
|
public QuestionVO modifyQuestion(String questionId, BaseQuestionDTO baseQuestionDTO) {
|
|
|
- QuestionVO questionVO = getQuestion(baseQuestionDTO);
|
|
|
|
|
|
|
+ QuestionVO questionVO = createQuestionVO(baseQuestionDTO);
|
|
|
questionVO.setId(questionId);
|
|
questionVO.setId(questionId);
|
|
|
- restRequestUtil.sendPutRequest(tqUrl + "/" + questionId, questionVO);
|
|
|
|
|
- return bokFindById(questionId);
|
|
|
|
|
|
|
+ restRequestUtil.sendPutRequest(url + "/" + questionId, questionVO);
|
|
|
|
|
+ return findQuestionsById(questionId);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void deleteQuestion(String questionId) {
|
|
public void deleteQuestion(String questionId) {
|
|
|
- restRequestUtil.sendDeleteRequest(tqUrl + "/" + questionId);
|
|
|
|
|
|
|
+ restRequestUtil.sendDeleteRequest(url + "/" + questionId);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private QuestionVO getQuestion(BaseQuestionDTO baseQuestionDTO) {
|
|
|
|
|
|
|
+ private QuestionVO createQuestionVO(BaseQuestionDTO baseQuestionDTO) {
|
|
|
QuestionVO questionVO = new QuestionVO();
|
|
QuestionVO questionVO = new QuestionVO();
|
|
|
- questionVO.setType(baseQuestionDTO.getType());
|
|
|
|
|
|
|
+ questionVO.setType(QuestionType.valueOf(baseQuestionDTO.getType()));
|
|
|
questionVO.setStem(baseQuestionDTO.getStem());
|
|
questionVO.setStem(baseQuestionDTO.getStem());
|
|
|
questionVO.setKeyPoints(baseQuestionDTO.getKeyPoints());
|
|
questionVO.setKeyPoints(baseQuestionDTO.getKeyPoints());
|
|
|
questionVO.setTags(baseQuestionDTO.getTags());
|
|
questionVO.setTags(baseQuestionDTO.getTags());
|
|
|
questionVO.setKnowledgeId(baseQuestionDTO.getKnowledgeId());
|
|
questionVO.setKnowledgeId(baseQuestionDTO.getKnowledgeId());
|
|
|
|
|
+ questionVO.setAnalysis(baseQuestionDTO.getAnalysis());
|
|
|
|
|
|
|
|
- final QuestionType questionType = QuestionType.getQuestionType(baseQuestionDTO.getType());
|
|
|
|
|
- switch (Objects.requireNonNull(questionType)) {
|
|
|
|
|
- case CHOICE:
|
|
|
|
|
|
|
+ switch (questionVO.getType()) {
|
|
|
|
|
+ case choice:
|
|
|
ChoiceQuestionDTO choiceQuestionDTO = (ChoiceQuestionDTO) baseQuestionDTO;
|
|
ChoiceQuestionDTO choiceQuestionDTO = (ChoiceQuestionDTO) baseQuestionDTO;
|
|
|
questionVO.setOptions(choiceQuestionDTO.getOptions());
|
|
questionVO.setOptions(choiceQuestionDTO.getOptions());
|
|
|
questionVO.setAnswer(choiceQuestionDTO.getAnswer());
|
|
questionVO.setAnswer(choiceQuestionDTO.getAnswer());
|
|
|
- questionVO.setAnalysis(choiceQuestionDTO.getAnalysis());
|
|
|
|
|
break;
|
|
break;
|
|
|
- case TRUE_FALSE:
|
|
|
|
|
|
|
+ case true_false:
|
|
|
TrueOrFalseQuestionDTO trueOrFalseQuestionDTO = (TrueOrFalseQuestionDTO) baseQuestionDTO;
|
|
TrueOrFalseQuestionDTO trueOrFalseQuestionDTO = (TrueOrFalseQuestionDTO) baseQuestionDTO;
|
|
|
questionVO.setAnswer(String.valueOf(trueOrFalseQuestionDTO.getAnswer()));
|
|
questionVO.setAnswer(String.valueOf(trueOrFalseQuestionDTO.getAnswer()));
|
|
|
- questionVO.setAnalysis(trueOrFalseQuestionDTO.getAnalysis());
|
|
|
|
|
break;
|
|
break;
|
|
|
default:
|
|
default:
|
|
|
throw HelperException.of(ExceptionType.ERROR, "不支持的题目类型");
|
|
throw HelperException.of(ExceptionType.ERROR, "不支持的题目类型");
|
|
|
}
|
|
}
|
|
|
return questionVO;
|
|
return questionVO;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- public void starQuestion(String userId, String questionId) {
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void likeQuestion(String userId, String questionId) {
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Data
|
|
|
|
|
- private static class BokSearchResult {
|
|
|
|
|
- @JsonProperty("_embedded")
|
|
|
|
|
- private Embedded embedded = new Embedded();
|
|
|
|
|
- private Page page;
|
|
|
|
|
-
|
|
|
|
|
- @Data
|
|
|
|
|
- private static class Embedded {
|
|
|
|
|
- private List<QuestionVO> questions = Collections.emptyList();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- @Data
|
|
|
|
|
- private static class Page {
|
|
|
|
|
- private int size;
|
|
|
|
|
- private int number;
|
|
|
|
|
- private int totalPages;
|
|
|
|
|
- private long totalElements;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|