|
|
@@ -1,361 +0,0 @@
|
|
|
-package cn.seecoder.data.server.service.Impl;
|
|
|
-
|
|
|
-import cn.hutool.core.text.csv.CsvData;
|
|
|
-import cn.hutool.core.text.csv.CsvReader;
|
|
|
-import cn.hutool.core.text.csv.CsvRow;
|
|
|
-import cn.seecoder.bok.client.SeecoderBokClient;
|
|
|
-import cn.seecoder.bok.common.vo.InteractionVO;
|
|
|
-import cn.seecoder.bok.common.vo.QuestionVO;
|
|
|
-import cn.seecoder.data.server.domain.GeneralRecordDao;
|
|
|
-import cn.seecoder.data.server.domain.knowledge.KnowledgeDao;
|
|
|
-import cn.seecoder.data.server.domain.knowledge.KnowledgeOnPositionDao;
|
|
|
-import cn.seecoder.data.server.domain.knowledge.PositionWeightDao;
|
|
|
-import cn.seecoder.data.server.repository.GeneralRecordRepository;
|
|
|
-import cn.seecoder.data.server.repository.knowledge.KnowledgeRepository;
|
|
|
-import cn.seecoder.data.server.repository.knowledge.PositionWeightRepository;
|
|
|
-import cn.seecoder.data.server.service.KnowledgeService;
|
|
|
-import cn.seecoder.data.server.vo.knowledge.KnowledgePointVO;
|
|
|
-import cn.seecoder.data.server.vo.knowledge.KnowledgeVO;
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.beans.factory.annotation.Value;
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
-
|
|
|
-import java.io.File;
|
|
|
-import java.nio.charset.StandardCharsets;
|
|
|
-import java.time.LocalDateTime;
|
|
|
-import java.util.*;
|
|
|
-import java.util.stream.Collectors;
|
|
|
-
|
|
|
-@Service
|
|
|
-public class KnowledgeServiceImpl implements KnowledgeService {
|
|
|
-
|
|
|
- @Value("${sys.bok.url}")
|
|
|
- private String bokBaseUrl;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- KnowledgeRepository knowledgeRepository;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- PositionWeightRepository positionWeightRepository;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- GeneralRecordRepository generalRecordRepository;
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<KnowledgeVO> getAllKnowledgeAndWeight() {
|
|
|
- List knowledgeOnPositionList = knowledgeRepository.findAllInfo();
|
|
|
- ArrayList<KnowledgeOnPositionDao> knowledgeOnPositionDaos = objectToDao(knowledgeOnPositionList);
|
|
|
- ArrayList<KnowledgeVO> knowledgeVOS = new ArrayList<>();
|
|
|
- KnowledgeVO knowledgeVO = null;
|
|
|
- if(knowledgeOnPositionDaos.size()>0)
|
|
|
- knowledgeVO = new KnowledgeVO(knowledgeOnPositionDaos.get(0));
|
|
|
- for(int i=1;i<knowledgeOnPositionDaos.size();i++){
|
|
|
- KnowledgeOnPositionDao knowledge = knowledgeOnPositionDaos.get(i);
|
|
|
- if(knowledge.getIsleaf()==0)
|
|
|
- continue;
|
|
|
- if(knowledgeOnPositionDaos.get(i).getId()==knowledgeOnPositionDaos.get(i-1).getId() && knowledge.getPosition()!=null && knowledge.getWeight()!=0){
|
|
|
- knowledgeVO.getWeightOnPosition().put(knowledge.getPosition(),knowledge.getWeight());
|
|
|
- }
|
|
|
- else{
|
|
|
- knowledgeVOS.add(knowledgeVO);
|
|
|
- knowledgeVO = new KnowledgeVO(knowledgeOnPositionDaos.get(i));
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
- return knowledgeVOS;
|
|
|
- }
|
|
|
-
|
|
|
- private ArrayList<KnowledgeOnPositionDao> objectToDao(List knowledgeOnPositionList) {
|
|
|
- ArrayList<KnowledgeOnPositionDao> ans = new ArrayList<>();
|
|
|
- for(int i=0;i<knowledgeOnPositionList.size();i++){
|
|
|
- Object[] tempDaos = (Object[]) knowledgeOnPositionList.get(i);
|
|
|
- KnowledgeOnPositionDao knowledgeOnPositionDao = (KnowledgeOnPositionDao.builder()
|
|
|
- .id(Integer.valueOf(tempDaos[0].toString()))
|
|
|
- .name(tempDaos[1].toString())
|
|
|
- .nameEng(tempDaos[2].toString())
|
|
|
- .abbreviation(tempDaos[3].toString())
|
|
|
- .parentId(Integer.valueOf(tempDaos[4].toString()))
|
|
|
- .parentName(tempDaos[5].toString())
|
|
|
- .pid(Integer.valueOf(tempDaos[6].toString()))
|
|
|
- .uid(Integer.valueOf(tempDaos[7].toString()))
|
|
|
- .isleaf(Integer.valueOf(tempDaos[8].toString())).build());
|
|
|
- if(tempDaos[9]!=null && tempDaos[10]!=null){
|
|
|
- knowledgeOnPositionDao.setPosition(tempDaos[9].toString());
|
|
|
- knowledgeOnPositionDao.setWeight(Double.valueOf(tempDaos[10].toString()));
|
|
|
- }
|
|
|
- ans.add(knowledgeOnPositionDao);
|
|
|
- }
|
|
|
- return ans;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public KnowledgeVO updatePositionWeight(KnowledgeVO knowledgeVO) {
|
|
|
- Map<String,Double> positonWeight = knowledgeVO.getWeightOnPosition();
|
|
|
- for(String position : positonWeight.keySet()){
|
|
|
- PositionWeightDao positionWeightDao = new PositionWeightDao(knowledgeVO.getId(),position,positonWeight.get(position));
|
|
|
- positionWeightRepository.save(positionWeightDao);
|
|
|
- }
|
|
|
- List<PositionWeightDao> positionWeightDaos = positionWeightRepository.findByKnowledgeId(knowledgeVO.getId());
|
|
|
- Map<String,Double> ans = new HashMap<>();
|
|
|
- for(int i=0;i<positionWeightDaos.size();i++)
|
|
|
- ans.put(positionWeightDaos.get(i).getPosition(),positionWeightDaos.get(i).getWeight());
|
|
|
- knowledgeVO.setWeightOnPosition(ans);
|
|
|
- return knowledgeVO;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public KnowledgePointVO getTreeByPosition(String position) {
|
|
|
- List<PositionWeightDao> positionWeightDaos;
|
|
|
- if(position.equals("all")) {
|
|
|
- positionWeightDaos = objectToPositonDao(knowledgeRepository.findAllInfo());
|
|
|
- }
|
|
|
- else
|
|
|
- positionWeightDaos = positionWeightRepository.findByPosition(position);
|
|
|
- SeecoderBokClient seecoderBokClient = new SeecoderBokClient("http://bok.seec.seecoder.cn");
|
|
|
- KnowledgePointVO root = new KnowledgePointVO("SE","软件工程",0,0,0,0,0,0,0,null,0);
|
|
|
- for(int i=0;i<positionWeightDaos.size();i++){
|
|
|
- PositionWeightDao positionWeight = positionWeightDaos.get(i);
|
|
|
- KnowledgeDao knowledgeInfo = knowledgeRepository.findById(positionWeight.getKnowledgeId());
|
|
|
- if(knowledgeInfo==null || knowledgeInfo.getIsleaf()==0)
|
|
|
- continue;
|
|
|
- String[] knowledgeLevel = knowledgeInfo.getAbbreviation().split("\\.");
|
|
|
- String prefix = "";
|
|
|
- KnowledgePointVO upNode = root;
|
|
|
- KnowledgePointVO nodeToAdd = null;
|
|
|
- for(int j=0;j<knowledgeLevel.length;j++){
|
|
|
- if(prefix!="")
|
|
|
- prefix = prefix + ".";
|
|
|
- String tempLevel = prefix + knowledgeLevel[j];
|
|
|
- if(!getAbbOnVO(upNode.getKnowledgePointVOs()).contains(tempLevel)){
|
|
|
- nodeToAdd = new KnowledgePointVO(tempLevel,knowledgeInfo.getName(),0,0,0,0,0,0,0,null,0);
|
|
|
- if(j+1==knowledgeLevel.length) {
|
|
|
- ArrayList<String> knowledgeIds = new ArrayList<>();
|
|
|
- knowledgeIds.add(tempLevel);
|
|
|
- long questionNum = seecoderBokClient.getQuestionList(null, null, null, null,knowledgeIds,null).getTotalElements();
|
|
|
- nodeToAdd.setQuestionsNumTotal(questionNum);
|
|
|
- }
|
|
|
- if(knowledgeRepository.findByAbbreviation(tempLevel).getIsleaf()==1)
|
|
|
- nodeToAdd.setLeafWeight(positionWeight.getWeight());
|
|
|
- else{
|
|
|
- String nodeName = knowledgeRepository.findByAbbreviation(tempLevel).getName();
|
|
|
- nodeToAdd.setName(nodeName);
|
|
|
- }
|
|
|
- if(upNode.getKnowledgePointVOs()==null){
|
|
|
- List<KnowledgePointVO> nodes = new ArrayList<>();
|
|
|
- nodes.add(nodeToAdd);
|
|
|
- upNode.setKnowledgePointVOs(nodes);
|
|
|
- }
|
|
|
- else
|
|
|
- upNode.getKnowledgePointVOs().add(nodeToAdd);
|
|
|
- upNode = nodeToAdd;
|
|
|
- }
|
|
|
- else
|
|
|
- upNode = upNode.getKnowledgePointVOs().get(getAbbOnVO(upNode.getKnowledgePointVOs()).indexOf(tempLevel));
|
|
|
- prefix = tempLevel;
|
|
|
- }
|
|
|
- }
|
|
|
- getQuestionTotal(root);
|
|
|
- return root;
|
|
|
- }
|
|
|
-
|
|
|
- private List<PositionWeightDao> objectToPositonDao(List<Object> knowledgeOnPositionList) {
|
|
|
- ArrayList<PositionWeightDao> ans = new ArrayList<>();
|
|
|
- for(int i=0;i<knowledgeOnPositionList.size();i++){
|
|
|
- Object[] tempDaos = (Object[]) knowledgeOnPositionList.get(i);
|
|
|
- PositionWeightDao positionWeightDao = PositionWeightDao.builder()
|
|
|
- .knowledgeId(Integer.valueOf(tempDaos[0].toString())).build();
|
|
|
- if(tempDaos[9]!=null && tempDaos[10]!=null){
|
|
|
- positionWeightDao.setPosition(tempDaos[9].toString());
|
|
|
- positionWeightDao.setWeight(Double.valueOf(tempDaos[10].toString()));
|
|
|
- }
|
|
|
- ans.add(positionWeightDao);
|
|
|
- }
|
|
|
- return ans;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public KnowledgePointVO getTreeByPositionAndUser(String position, int userId) {
|
|
|
- KnowledgePointVO root = getTreeByPosition(position);
|
|
|
- List generalRecordDaos = generalRecordRepository.getByUserIdMaxScore(userId);
|
|
|
- ArrayList<String> questionIds = new ArrayList<>();
|
|
|
- ArrayList<Double> scores = new ArrayList<>();
|
|
|
- ArrayList<Double> scoresTotal = new ArrayList<>();
|
|
|
- ArrayList<String> abbs = new ArrayList<>();
|
|
|
- getLeafAbbOnNode(root,abbs);
|
|
|
- for(int i=0;i<generalRecordDaos.size();i++) {
|
|
|
- Object[] cells = (Object[]) generalRecordDaos.get(i);
|
|
|
- questionIds.add((String)cells[0]);
|
|
|
- scores.add(Double.valueOf(cells[1].toString()));
|
|
|
- scoresTotal.add(Double.valueOf(generalRecordRepository.getByQuestionId((String)cells[0]).get(0).getScoreTotal()));
|
|
|
- }
|
|
|
- SeecoderBokClient seecoderBokClient = new SeecoderBokClient("http://bok.seec.seecoder.cn");
|
|
|
- List<QuestionVO> questionVOS = seecoderBokClient.getQuestionListByIds(questionIds);
|
|
|
- for(int i=0;i<questionVOS.size();i++){
|
|
|
- QuestionVO questionInfo = questionVOS.get(i);
|
|
|
- List<String> knowledges = questionInfo.getKnowledgeId();
|
|
|
- if(knowledges!=null)
|
|
|
- for(String knowledge : knowledges){
|
|
|
- if(abbs.contains(knowledge) && knowledgeRepository.findByAbbreviation(knowledge).getIsleaf()==1 && !knowledge.equals("SE"))
|
|
|
- addScoreToNode(root,scores.get(i),scoresTotal.get(i),questionInfo,knowledge,1);
|
|
|
- }
|
|
|
- }
|
|
|
- return root;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Map<String, Integer> getKnowledgeWeekCount(int userId) {
|
|
|
- LocalDateTime endTime = LocalDateTime.now();
|
|
|
- LocalDateTime startTime = endTime.minusDays(7);
|
|
|
- List<GeneralRecordDao> questionRecords = generalRecordRepository.getByUserIdAndSubmitTimeBetween(userId,startTime,endTime);
|
|
|
- SeecoderBokClient seecoderBokClient = new SeecoderBokClient(bokBaseUrl);
|
|
|
- HashMap<String, Integer> ans = new HashMap<>();
|
|
|
- List<String> questionIds = questionRecords.stream().map(record->record.getQuestionId()).collect(Collectors.toList());
|
|
|
- List<QuestionVO> questions = seecoderBokClient.getQuestionListByIds(questionIds);
|
|
|
- questions.stream().map(question->question.getKnowledgeId()).forEach((List<String> knowledges)-> {
|
|
|
- if(knowledges!=null && knowledges.size()>0)
|
|
|
- knowledges.stream().forEach((String knowledge)->{
|
|
|
- String name = knowledgeRepository.findByAbbreviation(knowledge).getName();
|
|
|
- if(ans.containsKey(name))
|
|
|
- ans.put(name,ans.get(name)+1);
|
|
|
- else
|
|
|
- ans.put(name,1);
|
|
|
- });
|
|
|
- });
|
|
|
- HashMap<String,Integer> ans2 = new LinkedHashMap<>();
|
|
|
- ans.entrySet().stream().sorted((p1,p2)->p2.getValue().compareTo(p1.getValue())).collect(Collectors.toList()).forEach(ele -> ans2.put(ele.getKey(), ele.getValue()));
|
|
|
- return ans2;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public double getBokInteractionScore(int userId) {
|
|
|
- double score = 0;
|
|
|
- try {
|
|
|
- SeecoderBokClient seecoderBokClient = new SeecoderBokClient(bokBaseUrl);
|
|
|
- List<InteractionVO> records = seecoderBokClient.getUserInteractiveQuestionIn(userId + "", null);
|
|
|
- long collectTime = records.stream().map(n -> n.getCollection()).filter(collect -> collect == true).count();
|
|
|
- long rateTime = records.stream().map(n -> n.getRate()).filter(rate -> rate > 0).count();
|
|
|
- score = score + collectTime * 5 + rateTime * 5;
|
|
|
- }catch (Exception e){
|
|
|
- LoggerFactory.getLogger(this.getClass()).error("score: bok_event得分计算失败" + " userId: "+userId, e);
|
|
|
- }
|
|
|
- return score;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Double getFAHPScoreOnPosition(String position,int userId) {
|
|
|
- File file = new File(".\\seec-data-server\\src\\main\\java\\cn\\seecoder\\data\\server\\utils\\FAHPmatrix\\"+position+".csv");
|
|
|
- CsvReader csvReader = new CsvReader();
|
|
|
- csvReader.setContainsHeader(true);
|
|
|
- CsvData csv = csvReader.read(file, StandardCharsets.UTF_8);
|
|
|
- HashMap<String,Double> FAHPdata= new HashMap<>();
|
|
|
- double div = 0;
|
|
|
- double score = 0;
|
|
|
- for (CsvRow row : csv.getRows())
|
|
|
- div = div + Double.valueOf(row.get(1));
|
|
|
- for (CsvRow row : csv.getRows())
|
|
|
- FAHPdata.put(row.get(0),Double.valueOf(row.get(1))/div);
|
|
|
-
|
|
|
-// List records = generalRecordRepository.getByUserIdMaxScore(userId);
|
|
|
-// List<String> questionIds = new ArrayList<>();
|
|
|
-// for(Object record : records){
|
|
|
-// Object[] cells = (Object[]) record;
|
|
|
-// questionIds.add((String) cells[0]);
|
|
|
-// }
|
|
|
-// List<QuestionVO> questionVOS = new ArrayList<>();
|
|
|
-// List<String> knowledgeName = new ArrayList<>();
|
|
|
-// for(int i=0;i<questionIds.size();i=i+10)
|
|
|
-// questionVOS.addAll(seecoderBokClient.getQuestionListByIds(questionIds.subList(i,i+10>questionIds.size()?questionIds.size():i+10)));
|
|
|
-// questionVOS.stream().map(a->a.getKnowledgeId()).forEach(ids->{
|
|
|
-// if(ids!=null) {
|
|
|
-// ids.stream().forEach(id -> {
|
|
|
-// knowledgeName.add(knowledgeRepository.findByAbbreviation(id).getName());
|
|
|
-// });
|
|
|
-// }
|
|
|
-// });
|
|
|
- KnowledgePointVO root = getTreeByPositionAndUser(position,userId);
|
|
|
- score = calScore(root,FAHPdata);
|
|
|
- return score;
|
|
|
- }
|
|
|
-
|
|
|
- private double calScore(KnowledgePointVO root,Map<String,Double> data){
|
|
|
- double score = 0.0;
|
|
|
- if(data.containsKey(root.getName()))
|
|
|
- score = score + data.get(root.getName())*root.getScore();
|
|
|
- else if(root.getKnowledgePointVOs()!=null){
|
|
|
- for(KnowledgePointVO node : root.getKnowledgePointVOs())
|
|
|
- score = score + calScore(node,data);
|
|
|
- }
|
|
|
- return score;
|
|
|
- }
|
|
|
-
|
|
|
- private KnowledgePointVO addScoreToNode(KnowledgePointVO root, Double score, Double scoreTotal, QuestionVO questionInfo,String knowledege,int deep) {
|
|
|
- String[] nodeKnowledge = knowledege.split("\\.");
|
|
|
- double[] questionWeight = {1,1,1,1.05,1.1};
|
|
|
- String now = nodeKnowledge[0];
|
|
|
- for(int i=1;i<deep && i<nodeKnowledge.length;i++)
|
|
|
- now = now + "." + nodeKnowledge[i];
|
|
|
- root.setQuestionsNumDone(root.getQuestionsNumDone()+1);
|
|
|
- if(root.getLeafWeight()==0 && root.getKnowledgePointVOs()!=null){
|
|
|
- KnowledgePointVO nextNode = root.getKnowledgePointVOs().get(getAbbOnVO(root.getKnowledgePointVOs()).indexOf(now));
|
|
|
- KnowledgePointVO leafNode = addScoreToNode(nextNode,score,scoreTotal,questionInfo,knowledege,deep+1);
|
|
|
- double weight = leafNode.getLeafWeight();
|
|
|
- if(questionInfo.getWeight()!=null)
|
|
|
- root.setScoreGotten(root.getScoreGotten()+(score*weight*questionWeight[questionInfo.getWeight()]));
|
|
|
- else
|
|
|
- root.setScoreGotten(root.getScoreGotten()+score*root.getLeafWeight());
|
|
|
- root.setScoreTotal(root.getScoreTotal()+scoreTotal*weight);
|
|
|
- if(root.getScoreTotal()!=0)
|
|
|
- root.setCorrectRate(root.getScoreGotten()/root.getScoreTotal());
|
|
|
- if(root.getQuestionsNumTotal()!=0)
|
|
|
- root.setCoverageRate(root.getQuestionsNumDone()/root.getQuestionsNumTotal());
|
|
|
- root.setScore(30*root.getCoverageRate() + 70*root.getCorrectRate());
|
|
|
- return leafNode;
|
|
|
- }
|
|
|
- else{
|
|
|
- if(questionInfo.getWeight()!=null)
|
|
|
- root.setScoreGotten(root.getScoreGotten()+(score*root.getLeafWeight()*questionWeight[questionInfo.getWeight()]));
|
|
|
- else
|
|
|
- root.setScoreGotten(root.getScoreGotten()+score*root.getLeafWeight());
|
|
|
- root.setScoreTotal(root.getScoreTotal()+scoreTotal*root.getLeafWeight());
|
|
|
- if(root.getScoreTotal()!=0)
|
|
|
- root.setCorrectRate(root.getScoreGotten()/root.getScoreTotal());
|
|
|
- if(root.getQuestionsNumTotal()!=0)
|
|
|
- root.setCoverageRate(root.getQuestionsNumDone()/root.getQuestionsNumTotal());
|
|
|
- root.setQuestionsNumDone(root.getQuestionsNumDone()+1);
|
|
|
- root.setScore(30*root.getCoverageRate() + 70*root.getCorrectRate());
|
|
|
- return root;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private double getQuestionTotal(KnowledgePointVO root) {
|
|
|
- if(root.getQuestionsNumTotal()!=0)
|
|
|
- return root.getQuestionsNumTotal();
|
|
|
- else{
|
|
|
- double num = 0;
|
|
|
- if(root.getKnowledgePointVOs()!=null){
|
|
|
- for(KnowledgePointVO knowledgePointVO : root.getKnowledgePointVOs())
|
|
|
- num = num + getQuestionTotal(knowledgePointVO);
|
|
|
- root.setQuestionsNumTotal(num);
|
|
|
- }
|
|
|
- return num;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public ArrayList<String> getAbbOnVO(List<KnowledgePointVO> knowledgePointVOS){
|
|
|
- ArrayList<String> arrayList= new ArrayList<>();
|
|
|
- if(knowledgePointVOS!=null && knowledgePointVOS.size()>0) {
|
|
|
- for (KnowledgePointVO knowledgePointVO : knowledgePointVOS)
|
|
|
- arrayList.add(knowledgePointVO.getKnowledge());
|
|
|
- }
|
|
|
- return arrayList;
|
|
|
- }
|
|
|
-
|
|
|
- public void getLeafAbbOnNode(KnowledgePointVO knowledgePointVO,ArrayList<String> ans){
|
|
|
- if(knowledgePointVO.getKnowledgePointVOs()==null)
|
|
|
- ans.add(knowledgePointVO.getKnowledge());
|
|
|
- else
|
|
|
- for(KnowledgePointVO child : knowledgePointVO.getKnowledgePointVOs())
|
|
|
- getLeafAbbOnNode(child,ans);
|
|
|
- }
|
|
|
-}
|