|
@@ -1,28 +1,25 @@
|
|
|
package cn.iselab.mooctest.site.web.logic.impl;
|
|
|
|
|
|
-import cn.iselab.mooctest.site.service.AssignedTaskService;
|
|
|
-import cn.iselab.mooctest.site.service.CaseGraphService;
|
|
|
-import cn.iselab.mooctest.site.service.CaughtNodeService;
|
|
|
-import cn.iselab.mooctest.site.service.GeneralCalculateScoreService;
|
|
|
-import cn.iselab.mooctest.site.service.UserCatchService;
|
|
|
-import cn.iselab.mooctest.site.service.WeightGeneralService;
|
|
|
+import cn.iselab.mooctest.site.service.*;
|
|
|
import cn.iselab.mooctest.site.util.data.JSONUtil;
|
|
|
import cn.iselab.mooctest.site.web.data.forInternalUse.GeneralGradeDTO;
|
|
|
import cn.iselab.mooctest.site.web.data.forInternalUse.NodeExtends;
|
|
|
import cn.iselab.mooctest.site.web.data.forMongo.CaseGraphDTO;
|
|
|
import cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CatchDTO;
|
|
|
+import cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO;
|
|
|
import cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.UserCatchDTO;
|
|
|
import cn.iselab.mooctest.site.web.data.forMongo.graph.Category;
|
|
|
import cn.iselab.mooctest.site.web.data.forMongo.graph.Node;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.scheduling.annotation.Async;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.scheduling.annotation.Async;
|
|
|
-import org.springframework.stereotype.Component;
|
|
|
|
|
|
/**
|
|
|
* asyncTask
|
|
@@ -33,157 +30,222 @@ import org.springframework.stereotype.Component;
|
|
|
@Component
|
|
|
public class GeneralCalculateScoreComponent {
|
|
|
|
|
|
- //获取元node服务
|
|
|
- @Autowired
|
|
|
- CaseGraphService caseGraphService;
|
|
|
- //获取被命中nodes的服务
|
|
|
- @Autowired
|
|
|
- CaughtNodeService caughtNodeService;
|
|
|
- @Autowired
|
|
|
- UserCatchService userCatchService;
|
|
|
- @Autowired
|
|
|
- GeneralCalculateScoreService generalCalculateScoreService;
|
|
|
- @Autowired
|
|
|
- WeightGeneralService weightGeneralService;
|
|
|
- @Autowired
|
|
|
- AssignedTaskService assignedTaskService;
|
|
|
-
|
|
|
- @Async("calculateGradeAsync")
|
|
|
- public void calculateGrade(long taskId, long caseId, Long userId) {
|
|
|
-
|
|
|
- List<UserCatchDTO> userCatchDTOList;
|
|
|
- if (userId == null) {
|
|
|
- userCatchDTOList = userCatchService.getUserCatchListOneBigPage(taskId, caseId);
|
|
|
- } else {
|
|
|
- userCatchDTOList = userCatchService.getUserCatchDTOs(userId, taskId, caseId);
|
|
|
- }
|
|
|
- Map<Long,Map<String,Double>> userScoreMap = calculateTypeScore(caseId,userCatchDTOList);
|
|
|
- List<GeneralGradeDTO> gradeDTOList = new ArrayList<>();
|
|
|
- List<Long> uidList = new ArrayList<>();//记录所有考生id
|
|
|
+ //获取元node服务
|
|
|
+ @Autowired
|
|
|
+ CaseGraphService caseGraphService;
|
|
|
+ //获取被命中nodes的服务
|
|
|
+ @Autowired
|
|
|
+ CaughtNodeService caughtNodeService;
|
|
|
+ @Autowired
|
|
|
+ UserCatchService userCatchService;
|
|
|
+ @Autowired
|
|
|
+ GeneralCalculateScoreService generalCalculateScoreService;
|
|
|
+ @Autowired
|
|
|
+ WeightGeneralService weightGeneralService;
|
|
|
+ @Autowired
|
|
|
+ AssignedTaskService assignedTaskService;
|
|
|
+
|
|
|
+ @Async("calculateGradeAsync")
|
|
|
+ public void calculateGrade(long taskId, long caseId, Long userId) {
|
|
|
+
|
|
|
+ List<UserCatchDTO> userCatchDTOList;
|
|
|
+ if (userId == null) {
|
|
|
+ userCatchDTOList = userCatchService.getUserCatchListOneBigPage(taskId, caseId);
|
|
|
+ } else {
|
|
|
+ userCatchDTOList = userCatchService.getUserCatchDTOs(userId, taskId, caseId);
|
|
|
+ }
|
|
|
+ Map<Long, Map<String, Double>> userScoreMap = calculateTypeScore(caseId, userCatchDTOList);
|
|
|
+ List<GeneralGradeDTO> gradeDTOList = new ArrayList<>();
|
|
|
+ List<Long> uidList = new ArrayList<>();//记录所有考生id
|
|
|
+
|
|
|
+ if (userScoreMap != null) {
|
|
|
+ userScoreMap.keySet().forEach(uid -> {
|
|
|
+ uidList.add(uid);
|
|
|
+ Map<String, Double> typeScoreMap = userScoreMap.get(uid);
|
|
|
+ typeScoreMap.keySet().forEach(type -> {
|
|
|
+ GeneralGradeDTO gradeDTO = new GeneralGradeDTO(uid, taskId, caseId, type, typeScoreMap.get(type));
|
|
|
+ gradeDTOList.add(gradeDTO);
|
|
|
+ });
|
|
|
+ });
|
|
|
|
|
|
- if(userScoreMap != null){
|
|
|
- userScoreMap.keySet().forEach(uid->{
|
|
|
- uidList.add(uid);
|
|
|
- Map<String,Double> typeScoreMap = userScoreMap.get(uid);
|
|
|
- typeScoreMap.keySet().forEach(type->{
|
|
|
- GeneralGradeDTO gradeDTO = new GeneralGradeDTO(uid,taskId,caseId,type,typeScoreMap.get(type));
|
|
|
- gradeDTOList.add(gradeDTO);
|
|
|
- });
|
|
|
- });
|
|
|
|
|
|
+ generalCalculateScoreService.updateTypeGrade(gradeDTOList);
|
|
|
|
|
|
- generalCalculateScoreService.updateTypeGrade(gradeDTOList);
|
|
|
+ uidList.forEach(uid -> saveGrade(uid, taskId, caseId, calculateCaseScore(taskId, caseId, uid)));
|
|
|
|
|
|
- uidList.forEach(uid -> saveGrade(uid,taskId,caseId, calculateCaseScore(taskId,caseId,uid)));
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
- }
|
|
|
+ private void saveGrade(long workerId, long taskId, long caseId, double score) {
|
|
|
+ assignedTaskService.addCase(taskId, caseId, workerId, "");
|
|
|
+ assignedTaskService.recordScore(taskId, caseId, workerId, score);
|
|
|
+ }
|
|
|
|
|
|
- private void saveGrade(long workerId, long taskId, long caseId, double score){
|
|
|
- assignedTaskService.addCase(taskId,caseId,workerId,"");
|
|
|
- assignedTaskService.recordScore(taskId,caseId,workerId,score);
|
|
|
- }
|
|
|
|
|
|
+ /**
|
|
|
+ * 计算一位用户一道题所有type的分数
|
|
|
+ *
|
|
|
+ * @param caseId 题目id
|
|
|
+ * @param userCatchDTOS userCatchDTOS
|
|
|
+ * @return <userId, <type,score>>
|
|
|
+ */
|
|
|
+ private Map<Long, Map<String, Double>> calculateTypeScore(long caseId, List<UserCatchDTO> userCatchDTOS) {
|
|
|
+ //元node数据
|
|
|
+ CaseGraphDTO basicNode = caseGraphService.getCaseGraph(caseId);
|
|
|
+ //List<UserCatchDTO> userCatchDTOS = userCatchService.getUserCatchDTOs(userId,taskId,caseId);
|
|
|
+
|
|
|
+ if (basicNode == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
|
|
|
|
|
|
+ if (userCatchDTOS != null && userCatchDTOS.size() != 0) {
|
|
|
+ Map<Long, Map<String, Double>> userScoreMap = new HashMap<>();
|
|
|
+ for (UserCatchDTO userCatchDTO : userCatchDTOS) {
|
|
|
+
|
|
|
+ Map<String, Double> typeScoreMap = new HashMap<>();
|
|
|
+ for (Node node : basicNode.getNodes()) {
|
|
|
+ for (CatchDTO catchDTO : userCatchDTO.getCatchDTOs()) {
|
|
|
+ if (node.getName().equals(catchDTO.getNodeName())) {//用户命中了该node
|
|
|
+ double scoreGot = 0;
|
|
|
+ String key = node.getCategory();
|
|
|
+ if (typeScoreMap.containsKey(key)) {
|
|
|
+ scoreGot = typeScoreMap.get(key);
|
|
|
+ }
|
|
|
+ //获取权重
|
|
|
+ double singleNodeWeight = getNodeWeight(basicNode, node.getCategory(), node.getName());
|
|
|
+ typeScoreMap.put(key, scoreGot + singleNodeWeight);
|
|
|
+ break;//一旦找到命中node则跳出,无需继续遍历
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ userScoreMap.put(userCatchDTO.getUserId(), typeScoreMap);
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * 计算一位用户一道题所有type的分数
|
|
|
- * @param caseId 题目id
|
|
|
- * @param userCatchDTOS userCatchDTOS
|
|
|
- * @return <userId, <type,score>>
|
|
|
- */
|
|
|
- private Map<Long,Map<String,Double>> calculateTypeScore(long caseId, List<UserCatchDTO> userCatchDTOS){
|
|
|
- //元node数据
|
|
|
- CaseGraphDTO basicNode = caseGraphService.getCaseGraph(caseId);
|
|
|
- //List<UserCatchDTO> userCatchDTOS = userCatchService.getUserCatchDTOs(userId,taskId,caseId);
|
|
|
+ return userScoreMap;
|
|
|
|
|
|
- if(basicNode == null){
|
|
|
- return null;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
}
|
|
|
|
|
|
|
|
|
- if(userCatchDTOS != null && userCatchDTOS.size() != 0){
|
|
|
- Map<Long,Map<String,Double>> userScoreMap = new HashMap<>();
|
|
|
- for(UserCatchDTO userCatchDTO:userCatchDTOS){
|
|
|
-
|
|
|
- Map<String,Double> typeScoreMap = new HashMap<>();
|
|
|
- for(Node node:basicNode.getNodes()){
|
|
|
- for(CatchDTO catchDTO:userCatchDTO.getCatchDTOs()){
|
|
|
- if(node.getName().equals(catchDTO.getNodeName())){//用户命中了该node
|
|
|
- double scoreGot = 0;
|
|
|
- String key = node.getCategory();
|
|
|
- if(typeScoreMap.containsKey(key)){
|
|
|
- scoreGot = typeScoreMap.get(key);
|
|
|
- }
|
|
|
- //获取权重
|
|
|
- double singleNodeWeight = getNodeWeight(basicNode,node.getCategory(),node.getName());
|
|
|
- typeScoreMap.put(key,scoreGot+singleNodeWeight);
|
|
|
- break;//一旦找到命中node则跳出,无需继续遍历
|
|
|
+ /**
|
|
|
+ * 获取node节点的权重
|
|
|
+ *
|
|
|
+ * @param basicNode 元node
|
|
|
+ * @param nodeName node名称
|
|
|
+ * @return node节点的权重
|
|
|
+ */
|
|
|
+ private double getNodeWeight(CaseGraphDTO basicNode, String category, String nodeName) {
|
|
|
+ int nodeNum = 0;
|
|
|
+ for (Node node : basicNode.getNodes()) {
|
|
|
+ if (node.getCategory().equals(category)) {
|
|
|
+ nodeNum++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ BigDecimal bg = new BigDecimal(100.00 / nodeNum).setScale(10, RoundingMode.HALF_UP);
|
|
|
+
|
|
|
+ double singleNodeWeight = bg.doubleValue(); //同类型的node节点默认权重相等
|
|
|
+
|
|
|
+ for (Node node : basicNode.getNodes()) {
|
|
|
+ if (node.getName().equals(nodeName)) {
|
|
|
+ String description = node.getDescription();
|
|
|
+ if ((!(description == null)) && (description.contains("\"weight\":"))) {//描述中含有权重字段,暂时这样存放单个node的权重
|
|
|
+ NodeExtends nodeExtension = JSONUtil.json2Obj(description, NodeExtends.class);
|
|
|
+ singleNodeWeight = nodeExtension.getWeight();
|
|
|
+ }
|
|
|
+ break;
|
|
|
}
|
|
|
- }
|
|
|
}
|
|
|
- userScoreMap.put(userCatchDTO.getUserId(),typeScoreMap);
|
|
|
- }
|
|
|
-
|
|
|
- return userScoreMap;
|
|
|
|
|
|
+ return singleNodeWeight;
|
|
|
}
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取node节点的权重
|
|
|
- * @param basicNode 元node
|
|
|
- * @param nodeName node名称
|
|
|
- * @return node节点的权重
|
|
|
- */
|
|
|
- private double getNodeWeight(CaseGraphDTO basicNode,String category, String nodeName){
|
|
|
- int nodeNum = 0;
|
|
|
- for(Node node: basicNode.getNodes()){
|
|
|
- if(node.getCategory().equals(category)){
|
|
|
- nodeNum++;
|
|
|
- }
|
|
|
- }
|
|
|
- BigDecimal bg = new BigDecimal(100.00/nodeNum).setScale(10, RoundingMode.HALF_UP);
|
|
|
|
|
|
- double singleNodeWeight = bg.doubleValue(); //同类型的node节点默认权重相等
|
|
|
|
|
|
- for(Node node:basicNode.getNodes()){
|
|
|
- if(node.getName().equals(nodeName)){
|
|
|
- String description = node.getDescription();
|
|
|
- if((!(description==null))&&(description.contains("\"weight\":")))
|
|
|
- {//描述中含有权重字段,暂时这样存放单个node的权重
|
|
|
- NodeExtends nodeExtension = JSONUtil.json2Obj(description, NodeExtends.class);
|
|
|
- singleNodeWeight = nodeExtension.getWeight();
|
|
|
+ /**
|
|
|
+ * 计算用户一个case的分数
|
|
|
+ *
|
|
|
+ * @param taskId 考试id
|
|
|
+ * @param caseId 题目id
|
|
|
+ * @param userId 用户id
|
|
|
+ * @return case的得分
|
|
|
+ */
|
|
|
+ private double calculateCaseScore(long taskId, long caseId, long userId) {
|
|
|
+ CaseGraphDTO basicNode = caseGraphService.getCaseGraph(caseId);
|
|
|
+ double caseScore = 0;
|
|
|
+ for (Category category : basicNode.getCategories()) {
|
|
|
+ int weight = weightGeneralService.getWeight(taskId, caseId, category.getName());
|
|
|
+ double typeScore = generalCalculateScoreService.getTypeScore(userId, taskId, caseId, category.getName());
|
|
|
+ caseScore += (weight * 0.01 * typeScore);
|
|
|
}
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- return singleNodeWeight;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 计算用户一个case的分数
|
|
|
- * @param taskId 考试id
|
|
|
- * @param caseId 题目id
|
|
|
- * @param userId 用户id
|
|
|
- * @return case的得分
|
|
|
- */
|
|
|
- private double calculateCaseScore(long taskId, long caseId, long userId){
|
|
|
- CaseGraphDTO basicNode = caseGraphService.getCaseGraph(caseId);
|
|
|
- double caseScore = 0;
|
|
|
- for(Category category:basicNode.getCategories()){
|
|
|
- int weight = weightGeneralService.getWeight(taskId,caseId,category.getName());
|
|
|
- double typeScore = generalCalculateScoreService.getTypeScore(userId,taskId,caseId,category.getName());
|
|
|
- caseScore += (weight*0.01*typeScore);
|
|
|
+ return caseScore;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- return caseScore;
|
|
|
+ @Async
|
|
|
+ public void saveCaughtDetails(Long examId, Long caseId, Long userId,
|
|
|
+ List<CaughtNodeDTO> caughtNodeDTOs, List<CatchDTO> catchDTOList) {
|
|
|
+
|
|
|
+ List<CaughtNodeDTO> caughtNodeDTOList = caughtNodeService.getCaughtNodeList(examId, caseId);
|
|
|
+ if (caughtNodeDTOList == null) {
|
|
|
+ List<CaughtNodeDTO> cns = new ArrayList<>();
|
|
|
+ for (CaughtNodeDTO cn : caughtNodeDTOs) {
|
|
|
+ List<Long> userIds = new ArrayList<>();
|
|
|
+ userIds.add(userId);
|
|
|
+
|
|
|
+ cn.setNodeName(cn.getNodeName());
|
|
|
+ cn.setExamId(examId);
|
|
|
+ cn.setCaseId(caseId);
|
|
|
+ cn.setIfCatch(cn.getIfCatch());
|
|
|
+
|
|
|
+ if (cn.getIfCatch().equals(Boolean.TRUE)) {
|
|
|
+ cn.setCatchNum(1);
|
|
|
+ cn.setUserIds(userIds);
|
|
|
+ } else {
|
|
|
+ cn.setCatchNum(0);
|
|
|
+ cn.setUserIds(new ArrayList<>());
|
|
|
+ }
|
|
|
+ cn.setTotalNum(1);
|
|
|
+ cn.setCategory(cn.getCategory());
|
|
|
+ cns.add(cn);
|
|
|
+ }
|
|
|
+ caughtNodeService.bulkCreateCaughtNodeDTOs(cns);
|
|
|
+ } else {
|
|
|
+ List<CaughtNodeDTO> savedcnDTOs = caughtNodeService.getCaughtNodeList(examId, caseId);
|
|
|
+ //更新totalNum
|
|
|
+ caughtNodeService.bulkUpdateAllCaughtNode(examId, caseId);
|
|
|
+
|
|
|
+ //更新catch到的node
|
|
|
+ List<String> nodeNameList = new ArrayList<>();
|
|
|
+ for (CaughtNodeDTO caughtNodeDTO : caughtNodeDTOs) {
|
|
|
+ if (caughtNodeDTO.getIfCatch().equals(Boolean.TRUE)) {
|
|
|
+ String nodeName = caughtNodeDTO.getNodeName();
|
|
|
+ nodeNameList.add(nodeName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ caughtNodeService.bulkUpdateCaughtNodes(examId, caseId, nodeNameList, userId);
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ //userCatch
|
|
|
+ List<UserCatchDTO> userCatchDTOs = userCatchService.getUserCatchDTOs(userId, examId, caseId);
|
|
|
+
|
|
|
+ if (userCatchDTOs != null) {
|
|
|
+ UserCatchDTO userCatchDTO = userCatchService.getUserCatchDTOs(userId, examId, caseId).get(0);
|
|
|
+ List<CatchDTO> catchDTOs = userCatchDTO.getCatchDTOs();
|
|
|
+ catchDTOs.addAll(catchDTOList);
|
|
|
+ userCatchDTO.setCatchDTOs(catchDTOs);
|
|
|
+ userCatchService.updateUserCatch(userCatchDTO);
|
|
|
+ } else {
|
|
|
+ UserCatchDTO userCatchDTO = new UserCatchDTO();
|
|
|
+ userCatchDTO.setCaseId(caseId);
|
|
|
+ userCatchDTO.setExamId(examId);
|
|
|
+ userCatchDTO.setUserId(userId);
|
|
|
+ List<CatchDTO> catchDTOs = new ArrayList<>();
|
|
|
+ catchDTOs.addAll(catchDTOList);
|
|
|
+ userCatchDTO.setCatchDTOs(catchDTOs);
|
|
|
+ userCatchService.createUserCatch(userCatchDTO);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|