Forráskód Böngészése

Merge branch 'DEV' of http://git.mooctest.net/summer/main-site into DEV

tangss 7 éve
szülő
commit
6a74e52e3e
31 módosított fájl, 655 hozzáadás és 652 törlés
  1. 13 13
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/acyncTask/McNodeCallBack.java
  2. 17 8
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/acyncTask/MutationCallBack.java
  3. 28 24
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/GradeGeneralDao.java
  4. 30 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/UploadRecordDao.java
  5. 1 6
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/data/GeneralGradeDTO.java
  6. 34 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/data/UploadRecordDTO.java
  7. 4 79
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/GradeGeneral.java
  8. 43 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/UploadRecord.java
  9. 13 5
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/GeneralCalculateScoreService.java
  10. 29 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/enums/ExamStatus.java
  11. 50 23
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/GeneralCalculateScoreServiceImpl.java
  12. 4 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/util/BeanFactory.java
  13. 2 2
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/MutationProgressController.java
  14. 44 11
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ScoreController.java
  15. 0 31
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromDev/AnalysisController.java
  16. 23 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/UploadCaughtNodeJson.java
  17. 4 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/forMongo/NodeCatch/CatchDTO.java
  18. 0 54
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromDev/ApfdAllVO.java
  19. 37 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/response/ResponseVO.java
  20. 37 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/response/ServerCode.java
  21. 11 19
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/exception/ServerException.java
  22. 6 4
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/CalculateSocreLogic.java
  23. 29 7
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/asyncProgress/impl/MutationProgressLogicImpl.java
  24. 0 30
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/fromDev/APFDLogic.java
  25. 0 238
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/fromDev/impl/APFDLogicImpl.java
  26. 46 13
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/CalculateScoreLogicImpl.java
  27. 128 76
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/GeneralCalculateScoreComponent.java
  28. 1 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/GeneralCalculateScoreLogicImpl.java
  29. 1 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/ScoreRuleLogicImpl.java
  30. 4 4
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/strategy/HighestStrategy.java
  31. 16 3
      mooctest-site-server/src/test/java/cn/iselab/mooctest/site/web/logic/impl/GeneralCalculateScoreComponentTest.java

+ 13 - 13
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/acyncTask/McNodeCallBack.java

@@ -113,21 +113,21 @@ public class McNodeCallBack implements AsyncTaskCallBack {
             long catchNum = dtoList.parallelStream().map(dto -> dto.getIfCatch() == true).count();
             double score = dtoList.size() == 0 ? 0 : (double) catchNum / dtoList.size() * 100;
             GeneralGradeDTO gradeDTO = new GeneralGradeDTO();
-            gradeDTO.setCaseId(caseId);
-            gradeDTO.setScore(score);
-            gradeDTO.setTaskId(examId);
-            gradeDTO.setWorkerId(userId);
-            gradeDTO.setType(category);
-            gradeDTOS.add(gradeDTO);
+//            gradeDTO.setCaseId(caseId);
+//            gradeDTO.setScore(score);
+//            gradeDTO.setTaskId(examId);
+//            gradeDTO.setWorkerId(userId);
+//            gradeDTO.setType(category);
+//            gradeDTOS.add(gradeDTO);
         });
 
-        generalCalculateScoreService.updateTypeGrade(gradeDTOS);
-
-        if (gradeDTOS != null && !gradeDTOS.isEmpty()) {
-            calculateScoreService.calculatePersonalDevScore(examId, caseId, userId);
-            calculateSocreLogic.calculateExamScoreAuto(examId, userId);
-        }
-        calculateSocreLogic.catchNode(examId, caseId, userId, String.valueOf(System.currentTimeMillis()), dtos);
+//        generalCalculateScoreService.updateTypeGrade(gradeDTOS);
+//
+//        if (gradeDTOS != null && !gradeDTOS.isEmpty()) {
+//            calculateScoreService.calculatePersonalDevScore(examId, caseId, userId);
+//            calculateSocreLogic.calculateExamScoreAuto(examId, userId);
+//        }
+//        calculateSocreLogic.catchNode(examId, caseId, userId, String.valueOf(System.currentTimeMillis()), dtos);
 
     }
 

+ 17 - 8
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/acyncTask/MutationCallBack.java

@@ -69,6 +69,7 @@ public class MutationCallBack implements AsyncTaskCallBack {
         Long examId = 0L;
         Long caseId = 0L;
         Long targetId = 0L;
+        Long uploadId = 0L;
         if (context.containsKey("userId")) {
             userId = Long.parseLong(context.get("userId"));
         }
@@ -81,10 +82,13 @@ public class MutationCallBack implements AsyncTaskCallBack {
         if (context.containsKey("targetId")) {
             targetId = Long.parseLong(context.get("targetId"));
         }
+        if (context.containsKey("uploadId")) {
+            uploadId = Long.parseLong(context.get("uploadId"));
+        }
         if (type.equals(MutationResultType.MUTAION_NODE_RESULT)) {
-            processForMutationAndNode(result, userId, examId, caseId);
+            processForMutationAndNode(result, userId, examId, caseId, uploadId);
         } else if (type.equals(MutationResultType.MUTAION_NODE)) {
-            processCaughtNode(result, userId, examId, caseId);
+            processCaughtNode(result, userId, examId, caseId,uploadId);
         } else if (type.equals(MutationResultType.MUTAION_RESULT)) {
             processMutationResult(result, userId, examId, caseId);
         } else if (type.equals(MutationResultType.MUTATION_META_NODE)) {
@@ -97,12 +101,13 @@ public class MutationCallBack implements AsyncTaskCallBack {
         LOG.info("------------------- mutation onError:" + error + " -------------------");
     }
 
-    private void processForMutationAndNode(String result, long userId, long examId, long caseId) throws Exception {
+    private void processForMutationAndNode(String result, long userId, long examId, long caseId,
+            long uploadId) throws Exception {
         JSONObject jsonObject = new JSONObject(result);
         JSONArray arrayNode = jsonObject.getJSONArray("nodes");
         JSONObject objectMutation = jsonObject.getJSONObject("mutation");
         if (arrayNode != null) {
-            processCaughtNode(arrayNode.toString(), userId, examId, caseId);
+            processCaughtNode(arrayNode.toString(), userId, examId, caseId, uploadId);
         }
         if (objectMutation != null) {
             processMutationResult(objectMutation.toString(), userId, examId, caseId);
@@ -126,7 +131,8 @@ public class MutationCallBack implements AsyncTaskCallBack {
         }
     }
 
-    private void processCaughtNode(String result, long userId, long examId, long caseId) throws Exception {
+    private void processCaughtNode(String result, long userId, long examId, long caseId, long
+            uploadId) throws Exception {
         Gson gson = new Gson();
         JSONArray arrayNode = new JSONArray(result);
         List<CaughtNodeDTO> dtos = new ArrayList<>();
@@ -135,9 +141,12 @@ public class MutationCallBack implements AsyncTaskCallBack {
             CaughtNodeDTO dto = gson.fromJson(obj.toString(), CaughtNodeDTO.class);
             dtos.add(dto);
         }
-        calculateSocreLogic.recordNode(examId, caseId, userId, String.valueOf(System.currentTimeMillis()), "m",dtos);
-        generalCalculateScoreLogic.calculateScore(examId, caseId, userId, "m");
-        calculateSocreLogic.calculateExamScoreAuto(examId, userId);
+//        calculateSocreLogic.recordNode(examId, caseId, userId, String.valueOf(System
+//                .currentTimeMillis()), "m",dtos,null);
+//        generalCalculateScoreLogic.calculateScore(examId, caseId, userId, "m");
+//        calculateSocreLogic.calculateExamScoreAuto(examId, userId);
+        calculateSocreLogic.addNode(examId,caseId,userId,String.valueOf(System.currentTimeMillis()),
+                dtos,uploadId);
     }
 
     private void processMetaNode(String result, long targetId) {

+ 28 - 24
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/GradeGeneralDao.java

@@ -18,28 +18,32 @@ import org.springframework.data.repository.query.Param;
 @Transactional
 public interface GradeGeneralDao extends JpaRepository<GradeGeneral,Long> {
 
-  GradeGeneral findByWorkerIdAndExamIdAndCaseIdAndType(long workerId, long examId, long caseId, String type);
-
-  GradeGeneral findByWorkerIdAndExamIdAndCaseIdAndTypeAndUploadTime(long workerId, long examId,
-      long caseId, String type, String uploadTime);
-
-  @Query("select distinct g.workerId from GradeGeneral g "
-      + "where g.examId = :examId and g.caseId = :caseId")
-  List<Long> retrieveUserIdsByExamIdAndCaseId(@Param("examId") long examId, @Param("caseId") long
-      caseId);
-
-  @Query("select g from GradeGeneral g where g.uploadTime="
-      + "(select max(g1.uploadTime) from GradeGeneral g1 where g1.workerId=:workerId and "
-      + "g1.examId=:examId and g1.caseId=:caseId) "
-      + "and g.workerId=:workerId and g.examId=:examId and g.caseId=:caseId")
-  List<GradeGeneral> getLatestScores(@Param("workerId")long workerId, @Param("examId")long
-      examId, @Param("caseId")long caseId);
-
-  @Query("select distinct g.uploadTime from GradeGeneral g where g.workerId=:workerId and "
-      + "g.examId=:examId and g.caseId=:caseId")
-  List<String> getUserUploadTimes(@Param("workerId")long workerId, @Param("examId")long examId,
-      @Param("caseId")long caseId);
-
-  List<GradeGeneral> findByWorkerIdAndExamIdAndCaseIdAndUploadTime(long workerId, long examId,
-      long caseId, String uploadTime);
+//  GradeGeneral findByWorkerIdAndExamIdAndCaseIdAndType(long workerId, long examId, long caseId, String type);
+
+//  GradeGeneral findByWorkerIdAndExamIdAndCaseIdAndTypeAndUploadTime(long workerId, long examId,
+//      long caseId, String type, String uploadTime);
+
+//  @Query("select distinct g.workerId from GradeGeneral g "
+//      + "where g.examId = :examId and g.caseId = :caseId")
+//  List<Long> retrieveUserIdsByExamIdAndCaseId(@Param("examId") long examId, @Param("caseId") long
+//      caseId);
+//
+//  @Query("select g from GradeGeneral g where g.uploadTime="
+//      + "(select max(g1.uploadTime) from GradeGeneral g1 where g1.workerId=:workerId and "
+//      + "g1.examId=:examId and g1.caseId=:caseId) "
+//      + "and g.workerId=:workerId and g.examId=:examId and g.caseId=:caseId")
+//  List<GradeGeneral> getLatestScores(@Param("workerId")long workerId, @Param("examId")long
+//      examId, @Param("caseId")long caseId);
+//
+//  @Query("select distinct g.uploadTime from GradeGeneral g where g.workerId=:workerId and "
+//      + "g.examId=:examId and g.caseId=:caseId")
+//  List<String> getUserUploadTimes(@Param("workerId")long workerId, @Param("examId")long examId,
+//      @Param("caseId")long caseId);
+//
+//  List<GradeGeneral> findByWorkerIdAndExamIdAndCaseIdAndUploadTime(long workerId, long examId,
+//      long caseId, String uploadTime);
+
+  GradeGeneral findByUploadIdAndType(long uploadId, String type);
+
+  List<GradeGeneral> findByUploadId(long uploadId);
 }

+ 30 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/UploadRecordDao.java

@@ -0,0 +1,30 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.UploadRecord;
+import java.util.List;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+/**
+ * Created on 2018/10/10
+ */
+public interface UploadRecordDao extends JpaRepository<UploadRecord, Long> {
+
+    UploadRecord findByWorkerIdAndExamIdAndCaseIdAndUploadTime(long workerId, long examId, long
+            caseId, String uploadTime);
+
+    @Query("select u from UploadRecord u where u.uploadTime="
+      + "(select max(u1.uploadTime) from UploadRecord u1 where u1.workerId=:workerId and "
+      + "u1.examId=:examId and u1.caseId=:caseId) "
+      + "and u.workerId=:workerId and u.examId=:examId and u.caseId=:caseId")
+    UploadRecord getUserLatestRecord(@Param("workerId")long workerId, @Param("examId")long examId,
+            @Param("caseId")long caseId);
+
+    List<UploadRecord> findByWorkerIdAndExamIdAndCaseId(long workerId, long examId, long caseId);
+
+    @Query("select distinct u.workerId from UploadRecord u "
+      + "where u.examId = :examId and u.caseId = :caseId")
+    List<Long> retrieveUserIdsByExamIdAndCaseId(@Param("examId") long examId, @Param("caseId") long
+      caseId);
+}

+ 1 - 6
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/data/GeneralGradeDTO.java

@@ -16,18 +16,13 @@ import org.springframework.beans.BeanUtils;
 @NoArgsConstructor
 @AllArgsConstructor
 public class GeneralGradeDTO {
-    private long workerId;
-    private long taskId;
-    private long caseId;
     private String type;
     private double score;
-    private String uploadTime;
-    private String source;
+    private Long uploadId;
 
     public GradeGeneral toEntity(){
       GradeGeneral entity = new GradeGeneral();
       BeanUtils.copyProperties(this,entity,"id");
-      entity.setExamId(this.taskId);
       return entity;
     }
 }

+ 34 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/data/UploadRecordDTO.java

@@ -0,0 +1,34 @@
+package cn.iselab.mooctest.site.data;
+
+import cn.iselab.mooctest.site.models.UploadRecord;
+import java.util.Optional;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.beans.BeanUtils;
+
+/**
+ * Created on 2018/10/10
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class UploadRecordDTO {
+    long id;
+    long workerId;
+    long examId;
+    long caseId;
+    String OSSUrl;
+    String source;
+    String uploadTime;
+
+    public UploadRecordDTO(UploadRecord uploadRecord) {
+        BeanUtils.copyProperties(uploadRecord, this);
+    }
+
+    public UploadRecord toUploadRecord(){
+        UploadRecord uploadRecord = new UploadRecord();
+        BeanUtils.copyProperties(this,uploadRecord);
+        return uploadRecord;
+    }
+}

+ 4 - 79
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/GradeGeneral.java

@@ -7,6 +7,7 @@ import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.Table;
 import javax.validation.constraints.NotNull;
+import lombok.Data;
 
 /**
  * 通用成绩
@@ -16,6 +17,7 @@ import javax.validation.constraints.NotNull;
  */
 @Entity
 @Table(name = "grade_general")
+@Data
 public class GradeGeneral {
 
   @Id
@@ -23,88 +25,11 @@ public class GradeGeneral {
   private long id;
 
   @NotNull
-  @Column(name = "worker_id")
-  private long workerId;
-
-  @NotNull
-  @Column(name = "exam_id")
-  private long examId;
-
-  @NotNull
-  @Column(name = "case_id")
-  private long caseId;
-
-  @NotNull
   private String type;
 
   private double score;
 
-  @Column(name = "upload_time")
-  private String uploadTime;
-
-  private String source;
-
-  public String getUploadTime() {
-    return uploadTime;
-  }
-
-  public void setUploadTime(String uploadTime) {
-    this.uploadTime = uploadTime;
-  }
-
-  public String getSource() {
-    return source;
-  }
-
-  public void setSource(String source) {
-    this.source = source;
-  }
-
-  public long getId() {
-    return id;
-  }
-
-  public void setId(long id) {
-    this.id = id;
-  }
-
-  public long getWorkerId() {
-    return workerId;
-  }
-
-  public void setWorkerId(long workerId) {
-    this.workerId = workerId;
-  }
-
-  public long getExamId() {
-    return examId;
-  }
-
-  public void setExamId(long examId) {
-    this.examId = examId;
-  }
-
-  public long getCaseId() {
-    return caseId;
-  }
-
-  public void setCaseId(long caseId) {
-    this.caseId = caseId;
-  }
-
-  public String getType() {
-    return type;
-  }
-
-  public void setType(String type) {
-    this.type = type;
-  }
-
-  public double getScore() {
-    return score;
-  }
+  @Column(name = "upload_id")
+  private Long uploadId;
 
-  public void setScore(double score) {
-    this.score = score;
-  }
 }

+ 43 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/UploadRecord.java

@@ -0,0 +1,43 @@
+package cn.iselab.mooctest.site.models;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * Created on 2018/10/9
+ */
+@Table(name = "upload_record")
+@Entity
+@EqualsAndHashCode
+@Data
+public class UploadRecord {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    long id;
+
+    @Column(name = "worker_id")
+    long workerId;
+
+    @Column(name = "exam_id")
+    long examId;
+
+    @Column(name = "case_id")
+    long caseId;
+
+    @Column(name = "oss_url")
+    String OSSUrl;
+
+    @Column(name = "source")
+    String source;
+
+    @Column(name = "upload_time")
+    String uploadTime;
+
+}

+ 13 - 5
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/GeneralCalculateScoreService.java

@@ -1,6 +1,8 @@
 package cn.iselab.mooctest.site.service;
 
 import cn.iselab.mooctest.site.data.GeneralGradeDTO;
+import cn.iselab.mooctest.site.data.UploadRecordDTO;
+import cn.iselab.mooctest.site.models.UploadRecord;
 import java.util.List;
 import java.util.Map;
 
@@ -12,15 +14,21 @@ import java.util.Map;
  */
 public interface GeneralCalculateScoreService {
 
-  void updateTypeGrade(long workerId, long taskId, long caseId, String type, double score);
+  void updateTypeGrade(long uploadId, String type, double score);
 
   void updateTypeGrade(List<GeneralGradeDTO> dtos);
 
-  double getTypeScore(long workerId, long taskId, long caseId, String type);
-
-  List<Long> getUploadUsers(long examId,long caseId);
+  double getTypeScore(long uploadId, String type);
 
   Map<String,Double> getLatestTypeScore(long workerId, long examId, long caseId);
 
-  Map<String,Map<String,Double>> getTimeTypeScore(long workerId, long examId, long caseId);
+  Map<Long,Map<String,Double>> getUidTypeScore(long workerId, long examId, long caseId);
+
+  UploadRecordDTO getLatestUploadRecord(long workerId, long examId, long caseId);
+
+  UploadRecordDTO getUploadRecord(long workerId, long examId, long caseId, String uploadTime);
+
+  UploadRecordDTO saveUploadRecords(UploadRecordDTO record);
+
+  List<Long> getUploadUsers(long examId, long caseId);
 }

+ 29 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/enums/ExamStatus.java

@@ -0,0 +1,29 @@
+package cn.iselab.mooctest.site.service.enums;
+
+/**
+ * Created on 2018/10/9
+ */
+public enum ExamStatus {
+    NOT_START(0),
+    DOING(1),
+    ENDED(2);
+
+    private int value;
+
+    ExamStatus(int value){
+        this.value = value;
+    }
+
+    public int getValue(){
+        return this.value;
+    }
+
+    public static ExamStatus getExamStatus(int value){
+        switch (value){
+            case 0:return NOT_START;
+            case 1:return DOING;
+            case 2:return ENDED;
+        }
+        return null;
+    }
+}

+ 50 - 23
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/GeneralCalculateScoreServiceImpl.java

@@ -1,13 +1,17 @@
 package cn.iselab.mooctest.site.service.impl;
 
 import cn.iselab.mooctest.site.dao.GradeGeneralDao;
+import cn.iselab.mooctest.site.dao.UploadRecordDao;
+import cn.iselab.mooctest.site.data.UploadRecordDTO;
 import cn.iselab.mooctest.site.models.Grade;
 import cn.iselab.mooctest.site.models.GradeGeneral;
+import cn.iselab.mooctest.site.models.UploadRecord;
 import cn.iselab.mooctest.site.service.GeneralCalculateScoreService;
 import cn.iselab.mooctest.site.data.GeneralGradeDTO;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.stream.Collectors;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -23,16 +27,16 @@ public class GeneralCalculateScoreServiceImpl implements GeneralCalculateScoreSe
 
   @Autowired
   GradeGeneralDao gradeGeneralDao;
+  @Autowired
+  UploadRecordDao uploadRecordDao;
   @Override
-  public void updateTypeGrade(long workerId, long taskId, long caseId, String type, double score) {
-    GradeGeneral gradeGeneral = gradeGeneralDao.findByWorkerIdAndExamIdAndCaseIdAndType(workerId,taskId,caseId,type);
+  public void updateTypeGrade(long uploadId, String type, double score) {
+    GradeGeneral gradeGeneral = gradeGeneralDao.findByUploadIdAndType(uploadId,type);
     if(gradeGeneral == null){
       gradeGeneral = new GradeGeneral();
+      gradeGeneral.setUploadId(uploadId);
+      gradeGeneral.setType(type);
     }
-    gradeGeneral.setWorkerId(workerId);
-    gradeGeneral.setExamId(taskId);
-    gradeGeneral.setCaseId(caseId);
-    gradeGeneral.setType(type);
     gradeGeneral.setScore(score);
     gradeGeneralDao.save(gradeGeneral);
   }
@@ -40,8 +44,7 @@ public class GeneralCalculateScoreServiceImpl implements GeneralCalculateScoreSe
   public void updateTypeGrade(List<GeneralGradeDTO> dtos){
     List<GradeGeneral> entities = dtos.stream().map(GeneralGradeDTO::toEntity).collect(Collectors.toList());
     entities.forEach(x->{
-      GradeGeneral entity = gradeGeneralDao.findByWorkerIdAndExamIdAndCaseIdAndTypeAndUploadTime(x
-          .getWorkerId(),x.getExamId(),x.getCaseId(),x.getType(),x.getUploadTime());
+      GradeGeneral entity = gradeGeneralDao.findByUploadIdAndType(x.getUploadId(),x.getType());
       if(entity != null){
         x.setId(entity.getId());
       }
@@ -50,8 +53,8 @@ public class GeneralCalculateScoreServiceImpl implements GeneralCalculateScoreSe
   }
 
   @Override
-  public double getTypeScore(long workerId, long taskId, long caseId, String type) {
-    GradeGeneral grade = gradeGeneralDao.findByWorkerIdAndExamIdAndCaseIdAndType(workerId,taskId,caseId,type);
+  public double getTypeScore(long uploadId, String type) {
+    GradeGeneral grade = gradeGeneralDao.findByUploadIdAndType(uploadId,type);
     if(grade != null){
       return grade.getScore();
     }else{
@@ -61,13 +64,9 @@ public class GeneralCalculateScoreServiceImpl implements GeneralCalculateScoreSe
   }
 
   @Override
-  public List<Long> getUploadUsers(long examId, long caseId) {
-    return gradeGeneralDao.retrieveUserIdsByExamIdAndCaseId(examId,caseId);
-  }
-
-  @Override
   public Map<String,Double> getLatestTypeScore(long workerId, long examId, long caseId) {
-    List<GradeGeneral> gradeGeneralList = gradeGeneralDao.getLatestScores(workerId, examId, caseId);
+    UploadRecord latestRecord = uploadRecordDao.getUserLatestRecord(workerId, examId, caseId);
+    List<GradeGeneral> gradeGeneralList = gradeGeneralDao.findByUploadId(latestRecord.getId());
     Map<String,Double> latestTypeScore = new HashMap<>();
     if(gradeGeneralList != null){
       gradeGeneralList.forEach(gradeGeneral-> latestTypeScore.put(gradeGeneral.getType(),gradeGeneral.getScore()));
@@ -75,19 +74,47 @@ public class GeneralCalculateScoreServiceImpl implements GeneralCalculateScoreSe
     return latestTypeScore;
   }
 
+
+
   @Override
-  public Map<String, Map<String, Double>> getTimeTypeScore(long workerId, long examId,
+  public Map<Long, Map<String, Double>> getUidTypeScore(long workerId, long examId,
       long caseId) {
-    Map<String, Map<String, Double>> timeTypeScoreMap = new HashMap<>();
-    List<String> uploadTimes = gradeGeneralDao.getUserUploadTimes(workerId, examId, caseId);
-    uploadTimes.forEach(uploadTime->{
+    Map<Long, Map<String, Double>> uploadTypeScoreMap = new HashMap<>();
+    List<Long> uploadIdList = uploadRecordDao.findByWorkerIdAndExamIdAndCaseId(workerId,examId,
+            caseId).stream().map(UploadRecord::getId).collect(Collectors.toList());
+    uploadIdList.forEach(uploadId->{
       List<GradeGeneral> gradeGeneralList = gradeGeneralDao
-          .findByWorkerIdAndExamIdAndCaseIdAndUploadTime(workerId,examId,caseId,uploadTime);
+          .findByUploadId(uploadId);
       Map<String,Double> typeScoreMap = new HashMap<>();
       gradeGeneralList.forEach(x->typeScoreMap.put(x.getType(),x.getScore()));
-      timeTypeScoreMap.put(uploadTime,typeScoreMap);
+      uploadTypeScoreMap.put(uploadId,typeScoreMap);
     });
-    return timeTypeScoreMap;
+    return uploadTypeScoreMap;
+  }
+
+  @Override
+  public UploadRecordDTO getLatestUploadRecord(long workerId, long examId, long caseId) {
+    UploadRecord uploadRecord = uploadRecordDao.getUserLatestRecord(workerId, examId, caseId);
+    return uploadRecord==null?null:new UploadRecordDTO(uploadRecord);
+  }
+
+  @Override
+  public UploadRecordDTO getUploadRecord(long workerId, long examId, long caseId,
+          String uploadTime) {
+    UploadRecord uploadRecord = uploadRecordDao.findByWorkerIdAndExamIdAndCaseIdAndUploadTime
+                    (workerId, examId, caseId, uploadTime);
+    return uploadRecord==null?null:new UploadRecordDTO(uploadRecord);
+  }
+
+  @Override
+  public UploadRecordDTO saveUploadRecords(UploadRecordDTO recordDTO) {
+    UploadRecord uploadRecord = uploadRecordDao.save(recordDTO.toUploadRecord());
+    return uploadRecord==null?null:new UploadRecordDTO(uploadRecord);
+  }
+
+  @Override
+  public List<Long> getUploadUsers(long examId, long caseId) {
+    return uploadRecordDao.retrieveUserIdsByExamIdAndCaseId(examId, caseId);
   }
 
 

+ 4 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/util/BeanFactory.java

@@ -17,6 +17,10 @@ public class BeanFactory implements ApplicationContextAware {
         this.applicationContext = applicationContext;
     }
 
+    public static ApplicationContext getApplicationContext(){
+        return applicationContext;
+    }
+
     /**
      * 获取某个Bean的对象
      * @param clazz

+ 2 - 2
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/MutationProgressController.java

@@ -26,8 +26,8 @@ public class MutationProgressController {
 
     @RequiresRoles("admin")
     @RequestMapping(value = UrlConstants.API + "mutationProgress/{examId}", method = RequestMethod.DELETE)
-    public boolean getMutation(@PathVariable String taskId) throws IOException {
-        return mutationProgressLogic.stopMutation(taskId);
+    public boolean getMutation(@PathVariable String examId) throws IOException {
+        return mutationProgressLogic.stopMutation(examId);
     }
 
     @RequiresRoles("admin")

+ 44 - 11
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ScoreController.java

@@ -7,11 +7,17 @@ import cn.iselab.mooctest.site.data.PageData;
 import cn.iselab.mooctest.site.data.Sort;
 import cn.iselab.mooctest.site.service.CaughtNodeService;
 import cn.iselab.mooctest.site.service.CompeteAnalysisAssignedTaskService;
+import cn.iselab.mooctest.site.service.enums.ExamStatus;
 import cn.iselab.mooctest.site.web.data.AssignedTaskVO;
 import cn.iselab.mooctest.site.web.data.CompeteAnalysisVO;
+import cn.iselab.mooctest.site.web.data.ExamVO;
+import cn.iselab.mooctest.site.web.data.UploadCaughtNodeJson;
 import cn.iselab.mooctest.site.web.data.WeightDirtyVO;
 import cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO;
+import cn.iselab.mooctest.site.web.data.response.ResponseVO;
+import cn.iselab.mooctest.site.web.data.response.ServerCode;
 import cn.iselab.mooctest.site.web.logic.CalculateSocreLogic;
+import cn.iselab.mooctest.site.web.logic.ExamLogic;
 import cn.iselab.mooctest.site.web.logic.GeneralCalculateScoreLogic;
 import cn.iselab.mooctest.site.web.response.SuccessResult;
 import org.apache.shiro.authz.annotation.RequiresRoles;
@@ -41,6 +47,9 @@ public class ScoreController extends BaseController {
     @Autowired
     GeneralCalculateScoreLogic generalCalculateScoreLogic;
 
+    @Autowired
+    ExamLogic examLogic;
+
     //一次考试的一道题的所有人的分
     @RequestMapping(value = UrlConstants.API + "score/{examId}/{caseId}", method = RequestMethod.PUT)
     public void CalculateScore(@PathVariable("examId") long taskId, @PathVariable("caseId") long caseId) throws Exception {
@@ -72,6 +81,7 @@ public class ScoreController extends BaseController {
     }
 
     //学生提交结果分析
+    @Deprecated
     @RequestMapping(value = UrlConstants.API_COMMON + "caughtNode/{examId}/{caseId}/{userId}/{uploadTime}", method = RequestMethod.PUT)
     public void catchNode(@PathVariable("examId") Long examId,
                           @PathVariable("caseId") Long caseId,
@@ -88,20 +98,43 @@ public class ScoreController extends BaseController {
                                   @PathVariable("userId") Long userId,
                                   @PathVariable("uploadTime") String uploadTime,
                                   @RequestBody List<CaughtNodeDTO> caughtNodeDTOs) throws Exception {
-        calculateSocreLogic.recordNode(examId, caseId, userId, uploadTime, null, caughtNodeDTOs);
-    }
+        calculateSocreLogic.recordNode(examId, caseId, userId, uploadTime, null, caughtNodeDTOs,
+                null);
+    }
+
+//    @RequestMapping(value = UrlConstants.API_COMMON +
+//            "generalUploadCaughtNode/{examId}/{caseId}/{userId}/{uploadTime}/{source}", method = RequestMethod.PUT)
+//    public void generalCatchNode(@PathVariable("examId") long examId,
+//            @PathVariable("caseId") long caseId,
+//            @PathVariable("userId") long userId,
+//            @PathVariable("uploadTime") String uploadTime,
+//            @PathVariable("source") String source,
+//            @RequestBody List<CaughtNodeDTO> caughtNodeDTOs) throws Exception {
+//
+//        calculateSocreLogic.recordNode(examId, caseId, userId, uploadTime, source,
+//                caughtNodeDTOs,null);
+//
+//    }
 
     @RequestMapping(value = UrlConstants.API_COMMON +
-            "generalUploadCaughtNode/{examId}/{caseId}/{userId}/{uploadTime}/{source}", method = RequestMethod.PUT)
-    public void generalCatchNode(@PathVariable("examId") long examId,
-                                 @PathVariable("caseId") long caseId,
-                                 @PathVariable("userId") long userId,
-                                 @PathVariable("uploadTime") String uploadTime,
-                                 @PathVariable("source") String source,
-                                 @RequestBody List<CaughtNodeDTO> caughtNodeDTOs) throws Exception {
-
-        calculateSocreLogic.recordNode(examId, caseId, userId, uploadTime, source, caughtNodeDTOs);
+            "generalUploadCaughtNode", method = RequestMethod.PUT)
+    public ResponseVO generalCatchNode(@RequestBody UploadCaughtNodeJson uploadCaughtNodeJson)
+            throws Exception {
 
+        ExamVO examVO = examLogic.getExamById(uploadCaughtNodeJson.getExamId());
+        if(examVO.getStatus() == ExamStatus.ENDED.getValue()){
+            return new ResponseVO(ServerCode.EXAM_ENDED);
+        }
+        calculateSocreLogic.recordNode(
+                uploadCaughtNodeJson.getExamId(),
+                uploadCaughtNodeJson.getCaseId(),
+                uploadCaughtNodeJson.getUserId(),
+                uploadCaughtNodeJson.getUploadTime(),
+                uploadCaughtNodeJson.getSource(),
+                uploadCaughtNodeJson.getCaughtNodeDTOs(),
+                uploadCaughtNodeJson.getOssUrl());
+
+        return new ResponseVO(ServerCode.SUCCESS);
     }
 
     @RequestMapping(value = UrlConstants.API_COMMON +

+ 0 - 31
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromDev/AnalysisController.java

@@ -5,7 +5,6 @@ import cn.iselab.mooctest.site.service.common.MongoAPIService;
 import cn.iselab.mooctest.site.web.ctrl.BaseController;
 import cn.iselab.mooctest.site.web.data.forMongo.MutationForMongoDTO;
 import cn.iselab.mooctest.site.web.logic.CalculateSocreLogic;
-import cn.iselab.mooctest.site.web.logic.fromDev.APFDLogic;
 import org.apache.shiro.authz.annotation.RequiresRoles;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
@@ -24,44 +23,14 @@ public class AnalysisController extends BaseController {
     CalculateSocreLogic calculateSocreLogic;
 
     @Autowired
-    APFDLogic apfdLogic;
-
-    @Autowired
     MongoAPIService mongoAPIService;
 
-    /*
-    * 查询重构前数据: workerId
-    * 查询重构后数据: participantId
-    * */
-    @RequiresRoles("admin")
-    @RequestMapping(value = UrlConstants.API + "apfd/{examId}/{caseId}", method = RequestMethod.GET)
-    public String getAPFDAnalyseofCaseInExam(@PathVariable Long examId, @PathVariable Long caseId) {
-        return apfdLogic.getAPFDAnalyseofCaseInExam(examId, caseId, null);
-    }
-
-
-    @RequiresRoles("admin")
-    @RequestMapping(value = UrlConstants.API + "apfd/{examId}/{caseId}/{workerId}", method = RequestMethod.GET)
-    public String getAPFDAnalyseByExamIdAndParticipantId(@PathVariable Long examId, @PathVariable Long caseId,
-                                                               @PathVariable Long workerId) {
-        return apfdLogic.getAPFDAnalyseofCaseInExam(examId, caseId, workerId);
-    }
-
     @RequiresRoles("admin")
     @RequestMapping(value = UrlConstants.API + "score/{examId}", method = RequestMethod.GET)
     public List<Double> recalculateExamScore(@PathVariable Long examId) {
         return calculateSocreLogic.calculateExamScore(examId, null, null, true);
     }
 
-    //admin触发变异分析
-    @Async
-    @RequiresRoles("admin")
-    @RequestMapping(value = UrlConstants.API + "mutation/{examId}/{caseId}", method = RequestMethod.GET)
-    public String getMutationAnalyseofCaseInExam(@PathVariable Long examId, @PathVariable Long caseId,
-                                                 @RequestParam(value = "participantId",required = false)Long participantId) {
-        return apfdLogic.getMutationNodeAnalyseofCaseInExam(examId, caseId, participantId);
-    }
-
     @RequestMapping(value = UrlConstants.API + "mutation", method = RequestMethod.GET)
     public List<MutationForMongoDTO> getMutation(@RequestParam(name = "examId") long examId,
                                                     @RequestParam(name = "stuId", required = false) Long stuId,

+ 23 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/UploadCaughtNodeJson.java

@@ -0,0 +1,23 @@
+package cn.iselab.mooctest.site.web.data;
+
+import cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Created on 2018/10/9
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class UploadCaughtNodeJson {
+    long examId;
+    long caseId;
+    long userId;
+    String uploadTime;
+    String source;
+    String ossUrl;
+    List<CaughtNodeDTO> caughtNodeDTOs;
+}

+ 4 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/forMongo/NodeCatch/CatchDTO.java

@@ -1,6 +1,8 @@
 package cn.iselab.mooctest.site.web.data.forMongo.NodeCatch;
 
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 /**
  * @author sean
@@ -8,6 +10,8 @@ import lombok.Data;
  */
 
 @Data
+@NoArgsConstructor
+@AllArgsConstructor
 public class CatchDTO {
 
     private String nodeName;

+ 0 - 54
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromDev/ApfdAllVO.java

@@ -1,54 +0,0 @@
-package cn.iselab.mooctest.site.web.data.fromDev;
-
-import java.util.List;
-
-/**
- * @author Alan on 2017/4/8
- */
-public class ApfdAllVO {
-    private long taskID;
-    private long caseID;
-    private List<Long> workerID;
-    private long startTime;
-    private long endTime;
-
-    public long getTaskID() {
-        return taskID;
-    }
-
-    public void setTaskID(long taskID) {
-        this.taskID = taskID;
-    }
-
-    public long getCaseID() {
-        return caseID;
-    }
-
-    public void setCaseID(long caseID) {
-        this.caseID = caseID;
-    }
-
-    public List<Long> getWorkerID() {
-        return workerID;
-    }
-
-    public void setWorkerID(List<Long> workerID) {
-        this.workerID = workerID;
-    }
-
-    public long getStartTime() {
-        return startTime;
-    }
-
-    public void setStartTime(long startTime) {
-        this.startTime = startTime;
-    }
-
-    public long getEndTime() {
-        return endTime;
-    }
-
-    public void setEndTime(long endTime) {
-        this.endTime = endTime;
-    }
-}

+ 37 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/response/ResponseVO.java

@@ -0,0 +1,37 @@
+package cn.iselab.mooctest.site.web.data.response;
+
+import cn.iselab.mooctest.site.web.exception.ServerException;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Created on 2018/10/9
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ResponseVO<T> {
+    private int code;
+    private String msg;
+    private T data;
+
+    public ResponseVO(ServerCode serverCode){
+        this.code = serverCode.getCode();
+        this.msg = serverCode.getMsg();
+    }
+
+    public ResponseVO(ServerCode serverCode,T data){
+        this.code = serverCode.getCode();
+        this.msg = serverCode.getMsg();
+        this.data = data;
+    }
+
+    public ResponseVO(ServerException e,T data) {
+        this.code = e.getErrorCode();
+        this.msg = e.getError();
+        this.data = data;
+    }
+
+
+}

+ 37 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/response/ServerCode.java

@@ -0,0 +1,37 @@
+package cn.iselab.mooctest.site.web.data.response;
+
+/**
+ * Created on 2018/10/9
+ */
+public enum ServerCode {
+
+    SUCCESS(20000,"OK"),
+
+    //考试相关状态码: 40000-49999
+    EXAM_ENDED(40000,"考试已结束"),
+
+    //分数相关状态码:50000-59999
+    UPLOAD_RECORD_FAIL(50000,"存储提交记录失败"),
+
+    //系统错误:60000-69999
+    SYSTEM_ERROR(60000,"系统错误"),
+
+    //Node相关错误: 70000-79999
+    META_NODE_NOT_EXIST(70000,"元node不存在");
+
+    private int code;
+    private String msg;
+    ServerCode(int code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+}

+ 11 - 19
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/exception/ServerException.java

@@ -1,5 +1,10 @@
 package cn.iselab.mooctest.site.web.exception;
 
+import cn.iselab.mooctest.site.web.data.response.ServerCode;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
 /**
  * Created with IntelliJ IDEA.
  * User: qgan(qgan@v5.cn)
@@ -7,28 +12,15 @@ package cn.iselab.mooctest.site.web.exception;
  * Time: 下午7:13
  * To change this template use File | Settings | File Templates.
  */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
 public class ServerException extends RuntimeException {
     private int errorCode;
     private String error;
 
-    public ServerException(int errorCode, String error) {
-        this.error = error;
-        this.errorCode = errorCode;
-    }
-
-    public int getErrorCode() {
-        return errorCode;
-    }
-
-    public void setErrorCode(int errorCode) {
-        this.errorCode = errorCode;
-    }
-
-    public String getError() {
-        return error;
-    }
-
-    public void setError(String error) {
-        this.error = error;
+    public ServerException(ServerCode serverCode){
+        this.errorCode = serverCode.getCode();
+        this.error = serverCode.getMsg();
     }
 }

+ 6 - 4
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/CalculateSocreLogic.java

@@ -31,14 +31,16 @@ public interface CalculateSocreLogic {
 
     List<AssignedTaskVO> timeCompeteAnalysis(Long examId);
 
+    @Deprecated
     void catchNode(Long examId, Long caseId, Long userId, String uploadTime, List<CaughtNodeDTO> caughtNodeDTOs) throws Exception;
 
-    void catchNode(Long examId, Long caseId, Long userId, String uploadTime,
-                   String source, List<CaughtNodeDTO> caughtNodeDTOs) throws Exception;
-
 
     PageData<CompeteAnalysisVO> getCompeteAnalysisByPage(Long userId, Long examId, Long caseId, int activePage, int pageSize,
                                                          Sort sort, CompeteAnalysisType competeAnalysisType);
 
-    void recordNode(Long examId, Long caseId, Long userId, String uploadTime, String source, List<CaughtNodeDTO> caughtNodeDTOs) throws Exception;
+    void recordNode(Long examId, Long caseId, Long userId, String uploadTime, String source,
+            List<CaughtNodeDTO> caughtNodeDTOs, String ossUrl) throws Exception;
+
+    void addNode(Long examId, Long caseId, Long userId, String uploadTime,
+            List<CaughtNodeDTO> caughtNodeDTOs, long uploadId) throws Exception;
 }

+ 29 - 7
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/asyncProgress/impl/MutationProgressLogicImpl.java

@@ -5,11 +5,12 @@ import cn.iselab.mooctest.site.common.constant.MutationResultType;
 import cn.iselab.mooctest.site.common.constant.NodeTypeConstants;
 import cn.iselab.mooctest.site.common.enums.AsyncJobTool;
 import cn.iselab.mooctest.site.data.AsyncJobStatus;
+import cn.iselab.mooctest.site.data.UploadRecordDTO;
 import cn.iselab.mooctest.site.data.UserDTOForMT;
 import cn.iselab.mooctest.site.models.SubmitRecord;
 import cn.iselab.mooctest.site.models.WeightGeneral;
 import cn.iselab.mooctest.site.service.*;
-import cn.iselab.mooctest.site.service.updownload.DownloadService;
+//import cn.iselab.mooctest.site.service.updownload.DownloadService;
 import cn.iselab.mooctest.site.web.data.MutationJobVO;
 import cn.iselab.mooctest.site.web.data.MutationProgressVO;
 import cn.iselab.mooctest.site.web.data.forMongo.AsyncTaskDTO;
@@ -50,12 +51,15 @@ public class MutationProgressLogicImpl extends BaseLogic implements MutationProg
     @Autowired
     CaseService caseService;
 
-    @Autowired
-    DownloadService downloadService;
+//    @Autowired
+//    DownloadService downloadService;
 
     @Autowired
     WeightGeneralService weightGeneralService;
 
+    @Autowired
+    GeneralCalculateScoreService generalCalculateScoreService;
+
     @Override
     public MutationProgressVO getMutationProgress(Long examId, Long caseId) {
         AsyncTaskDTO asyncTaskDTO = asyncTaskService.getAsyncTask(AsyncJobTool.MUTATION, examId, caseId);
@@ -169,22 +173,40 @@ public class MutationProgressLogicImpl extends BaseLogic implements MutationProg
         List<Map<String, String>> contexts;
         List<SubmitRecord> submitRecords = submitRecordService.getSubmittedRecordsByExamId(examId);
         params = submitRecords.stream()
-                .filter(assignedTask -> downloadService.generateUrlForDevAnalysis(examId,assignedTask.getParticipantId(),caseService.getCaseById(caseId).getName())!=null)
+//                .filter(assignedTask -> downloadService.generateUrlForDevAnalysis(examId,assignedTask.getParticipantId(),caseService.getCaseById(caseId).getName())!=null)
+                .filter(assignedTask -> {
+                    UploadRecordDTO uploadRecordDTO = generalCalculateScoreService.getLatestUploadRecord
+                        (assignedTask.getParticipantId(),examId,caseId);
+                    return uploadRecordDTO!=null && uploadRecordDTO.getOSSUrl()!=null;
+                    })
                 .map(assignedTask -> {
             Map<String, String> param = new HashedMap();
-            String downloadUrl = downloadService.generateUrlForDevAnalysis(examId,assignedTask.getParticipantId(),caseService.getCaseById(caseId).getName());
-            param.put("downloadURL", downloadUrl);
+//            String downloadUrl = downloadService.generateUrlForDevAnalysis(examId,assignedTask.getParticipantId(),caseService.getCaseById(caseId).getName());
+            UploadRecordDTO uploadRecordDTO = generalCalculateScoreService.getLatestUploadRecord
+                    (assignedTask.getParticipantId(),examId,caseId);
+            String downloadUrl = uploadRecordDTO.getOSSUrl();
+            param.put("downloadURL", uploadRecordDTO.getOSSUrl());
             param.put("extraArgs", generateMutationNodeExtraArgs(downloadUrl));
             return param;
         }).collect(Collectors.toList());
         contexts = submitRecords.stream()
-                .filter(assignedTask -> downloadService.generateUrlForDevAnalysis(examId,assignedTask.getParticipantId(),caseService.getCaseById(caseId).getName())!=null)
+//                .filter(assignedTask -> downloadService.generateUrlForDevAnalysis(examId,assignedTask.getParticipantId(),caseService.getCaseById(caseId).getName())!=null)
+                .filter(assignedTask -> {
+                    UploadRecordDTO uploadRecordDTO = generalCalculateScoreService.getLatestUploadRecord
+                            (assignedTask.getParticipantId(),examId,caseId);
+                    return uploadRecordDTO!=null && uploadRecordDTO.getOSSUrl()!=null;
+                })
                 .map(assignedTask -> {
             Map<String, String> param = new HashedMap();
             param.put("examId", examId.toString());
             param.put("caseId", caseId.toString());
             param.put("userId", assignedTask.getParticipantId().toString());
             param.put("type", MutationResultType.MUTAION_NODE_RESULT);
+
+            UploadRecordDTO uploadRecordDTO = generalCalculateScoreService.getLatestUploadRecord
+                    (assignedTask.getParticipantId(),examId,caseId);
+            param.put("uploadId", uploadRecordDTO.getId()+"");
+
             return param;
         }).collect(Collectors.toList());
 

+ 0 - 30
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/fromDev/APFDLogic.java

@@ -1,30 +0,0 @@
-package cn.iselab.mooctest.site.web.logic.fromDev;
-
-import cn.iselab.mooctest.site.models.Weight;
-import cn.iselab.mooctest.site.rpc.dev.data.ApbcDTO;
-import cn.iselab.mooctest.site.rpc.dev.data.MutationDTO;
-import cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO;
-
-import java.util.List;
-
-/**
- * @author sean
- * @date 2017-09-05.
- */
-public interface APFDLogic {
-
-    String getAPFDAnalyseofCaseInExam(Long examId, Long caseId, Long participantId);
-
-
-    ApbcDTO getAPFDAnalyseByExamIdAndParticipantId(Long examId, Long caseId, Long participantId, Weight weight);
-
-    String getMutationAnalyseofCaseInExam(Long examId, Long caseId, Long participantId);
-
-    MutationDTO getMutationAnalyseByExamIdAndParticipantId(Long examId, Long caseId, Long workerId) throws Exception;
-
-    String getMutationNodeAnalyseofCaseInExam(Long examId, Long caseId, Long participantId);
-
-    List<CaughtNodeDTO> getMutationNodeAnalyseByExamIdAndParticipantId(Long examId, Long caseId, Long workerId);
-
-    void getMutationDTO(Long examId, Long caseId, Long participantId);
-}

+ 0 - 238
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/fromDev/impl/APFDLogicImpl.java

@@ -1,238 +0,0 @@
-package cn.iselab.mooctest.site.web.logic.fromDev.impl;
-
-import cn.iselab.mooctest.site.models.SubmitRecord;
-import cn.iselab.mooctest.site.models.Grade;
-import cn.iselab.mooctest.site.models.Weight;
-import cn.iselab.mooctest.site.rpc.dev.data.ApbcDTO;
-import cn.iselab.mooctest.site.rpc.dev.data.CaughtNodeDTO;
-import cn.iselab.mooctest.site.rpc.dev.data.MutationDTO;
-import cn.iselab.mooctest.site.service.*;
-import cn.iselab.mooctest.site.service.common.MongoAPIService;
-import cn.iselab.mooctest.site.service.fromDev.AnalysisService;
-import cn.iselab.mooctest.site.web.data.forMongo.MutationForMongoDTO;
-import cn.iselab.mooctest.site.web.data.fromDev.StResponse;
-import cn.iselab.mooctest.site.web.exception.HttpBadRequestException;
-import cn.iselab.mooctest.site.web.exception.IllegalOperationException;
-import cn.iselab.mooctest.site.web.logic.BaseLogic;
-import cn.iselab.mooctest.site.web.logic.CalculateSocreLogic;
-import cn.iselab.mooctest.site.web.logic.fromDev.APFDLogic;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * @author sean
- * @date 2017-09-05.
- */
-@Service
-public class APFDLogicImpl extends BaseLogic implements APFDLogic{
-
-    @Autowired
-    CaseService caseService;
-
-    @Autowired
-    WeightService weightService;
-
-    @Autowired
-    AnalysisService analysisService;
-
-    @Autowired
-    SubmitRecordService submitRecordService;
-
-    @Autowired
-    Exam2CaseService exam2CaseService;
-
-    @Autowired
-    CalculateScoreService calculateScoreService;
-
-    @Autowired
-    CalculateSocreLogic calculateSocreLogic;
-
-    @Autowired
-    MongoAPIService mongoAPIService;
-
-    @Override
-    public String getAPFDAnalyseofCaseInExam(Long examId, Long caseId, Long participantId) {
-        if (weightService.getWeightByTidAndCid(examId, caseId) == null) {
-            throw new HttpBadRequestException("unmatched examId and caseId");
-        }
-        Weight weight = weightService.getWeightByTidAndCid(examId, caseId);
-        if (weight.getApfd() == 0) {
-            throw new HttpBadRequestException(caseId + "'s APFD is 0");
-        }
-        if(participantId==null) {
-            List<SubmitRecord> submitRecords = submitRecordService.getSubmittedRecordsByExamId(examId);
-            List<Long> submittedWorkerIds = submitRecords.stream().map(assignedTask -> assignedTask.getParticipantId()).collect(Collectors.toList());
-            LOG.info("---------------------------------start apfd analysis--------------------------------");
-            List<ApbcDTO> apbcDTOList = submittedWorkerIds.stream().map(submittedWorkerId ->
-                    getAPFDAnalyseByExamIdAndParticipantId(examId,caseId,submittedWorkerId,weight)).collect(Collectors.toList());
-            LOG.info("---------------------------------end apfd analysis--------------------------------");
-            if (apbcDTOList.size() != 0 && !apbcDTOList.isEmpty()) {
-                return StResponse.success(apbcDTOList);
-            } else {
-                throw new HttpBadRequestException("获取APFD分析失败");
-            }
-        }else {
-            return StResponse.success(getAPFDAnalyseByExamIdAndParticipantId(examId,caseId,participantId,weight));
-        }
-    }
-    @Override
-    public ApbcDTO getAPFDAnalyseByExamIdAndParticipantId(Long examId, Long caseId, Long participantId, Weight weight) {
-        ApbcDTO apbcDTO = analysisService.apfdAnalyze(examId, participantId, caseId, weight);
-        if (apbcDTO == null) {
-            throw new HttpBadRequestException("Fail to get APFD of No." + caseId);
-        } else {
-            List<Grade> grades = analysisService.saveApfdScore(participantId, examId, caseId, apbcDTO.getApbcScore());
-            if (grades != null && !grades.isEmpty()) {
-                calculateScoreService.calculatePersonalDevScore(examId, caseId, participantId);
-                calculateSocreLogic.calculateExamScore(examId,participantId,null,false);
-            }
-            return apbcDTO;
-        }
-    }
-
-    @Override
-    public String getMutationAnalyseofCaseInExam(Long examId, Long caseId, Long participantId){
-        if (weightService.getWeightByTidAndCid(examId, caseId) == null) {
-            throw new HttpBadRequestException("unmatched examId and caseId");
-        }
-        Weight weight = weightService.getWeightByTidAndCid(examId, caseId);
-        if (weight.getMutation() == 0) {
-            throw new HttpBadRequestException(caseId + "'s 变异分析 is 0");
-        }
-        if(participantId==null) {
-            List<SubmitRecord> submitRecords = submitRecordService.getSubmittedRecordsByExamId(examId);
-            List<Long> submittedWorkerIds = submitRecords.stream().map(assignedTask -> assignedTask.getParticipantId()).collect(Collectors.toList());
-            LOG.info("---------------------------------start mutation analysis--------------------------------");
-            List<MutationDTO> mutationDTOS =submittedWorkerIds.stream().map( submittedWorkerId ->
-                    getMutationAnalyseByExamIdAndParticipantId(examId,caseId,submittedWorkerId)).filter(dTO-> dTO!=null).collect(Collectors.toList());
-            LOG.info("---------------------------------end mutation analysis--------------------------------");
-            if (mutationDTOS.size() != 0 && !mutationDTOS.isEmpty()) {
-                return StResponse.success(mutationDTOS);
-            } else {
-                throw new HttpBadRequestException("获取变异分析失败");
-            }
-        }else {
-            return StResponse.success(getMutationAnalyseByExamIdAndParticipantId(examId, caseId, participantId));
-        }
-    }
-
-    @Override
-    public String getMutationNodeAnalyseofCaseInExam(Long examId, Long caseId, Long participantId){
-        if (weightService.getWeightByTidAndCid(examId, caseId) == null) {
-            throw new HttpBadRequestException("unmatched examId and caseId");
-        }
-        Weight weight = weightService.getWeightByTidAndCid(examId, caseId);
-        if (weight.getMutation() == 0) {
-            throw new HttpBadRequestException(caseId + "'s 变异分析 is 0");
-        }
-        if(participantId==null) {
-            List<SubmitRecord> submitRecords = submitRecordService.getSubmittedRecordsByExamId(examId);
-            List<Long> submittedWorkerIds = submitRecords.stream().map(assignedTask -> assignedTask.getParticipantId()).collect(Collectors.toList());
-            LOG.info("---------------------------------start mutation analysis--------------------------------");
-            List<List<cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO>> mutationDTOS =submittedWorkerIds.stream().map( submittedWorkerId ->
-                    getMutationNodeAnalyseByExamIdAndParticipantId(examId,caseId,submittedWorkerId)).filter(dTO-> dTO!=null).collect(Collectors.toList());
-            LOG.info("---------------------------------end mutation analysis--------------------------------");
-            if (mutationDTOS.size() != 0 && !mutationDTOS.isEmpty()) {
-                return StResponse.success(mutationDTOS);
-            } else {
-                throw new HttpBadRequestException("获取变异分析失败");
-            }
-        }else {
-            return StResponse.success(getMutationNodeAnalyseByExamIdAndParticipantId(examId, caseId, participantId));
-        }
-    }
-
-    @Override
-    public MutationDTO getMutationAnalyseByExamIdAndParticipantId(Long examId, Long caseId, Long participantId){
-        MutationDTO mutationDTO;
-        try {
-            mutationDTO = analysisService.mutationAnalyze(examId, participantId, caseId);
-        }catch (Exception e){
-            e.printStackTrace();
-            return null;
-        }
-        if (mutationDTO == null) {
-            throw new HttpBadRequestException("Fail to get 变异分析 of No." + caseId);
-        } else {
-            double mutationScore= mutationDTO.getTotal()==0?0:(double) mutationDTO.getKilled() / mutationDTO.getTotal() * 100;
-            try {
-                List<Grade> grades = analysisService.saveMutationScore(participantId, examId, caseId, mutationScore);
-                if (grades != null && !grades.isEmpty()) {
-                    calculateScoreService.calculatePersonalDevScore(examId, caseId, participantId);
-                    calculateSocreLogic.calculateExamScoreAuto(examId,participantId);
-                }
-                List<MutationForMongoDTO> list = mongoAPIService.getMutationFromMongo(participantId, examId, caseId);
-                if(list!=null) {
-                    MutationForMongoDTO mutationForMongoDTO = list.get(0);
-                    mutationForMongoDTO.setMutationDTO(mutationDTO);
-                    mongoAPIService.updateMutationToMongo(mutationForMongoDTO);
-                }else {
-                    mongoAPIService.saveMutationToMongo(participantId, examId, caseId, mutationDTO);
-                }
-            }catch (IOException e){
-                throw new IllegalOperationException("mongo io exception");
-            }
-            return mutationDTO;
-        }
-    }
-
-    @Override
-    public List<cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO> getMutationNodeAnalyseByExamIdAndParticipantId(Long examId, Long caseId, Long workerId){
-        List<CaughtNodeDTO> caughtNodeDTOS;
-        try {
-            caughtNodeDTOS = analysisService.mutationCaughtNodeAnalyze(examId,workerId,caseId);
-        }catch (Exception e){
-            e.printStackTrace();
-            return null;
-        }
-
-        if (caughtNodeDTOS == null) {
-            throw new HttpBadRequestException("Fail to get 变异分析 of No." + caseId);
-        } else {
-            List<cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO> dtos=caughtNodeDTOS.stream().map(dto -> {
-                cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO node=new cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO();
-                BeanUtils.copyProperties(dto,node);
-                return node;
-            }).collect(Collectors.toList());
-            long catchNum=dtos.stream().filter(caughtNodeDTO -> caughtNodeDTO.getIfCatch()==true).count();
-            double mutationScore=dtos.size()==0?0:(double) catchNum/dtos.size() * 100;
-            List<Grade> grades = analysisService.saveMutationScore(workerId, examId, caseId, mutationScore);
-            if (grades != null && !grades.isEmpty()) {
-                calculateScoreService.calculatePersonalDevScore(examId, caseId, workerId);
-                calculateSocreLogic.calculateExamScoreAuto(examId,workerId);
-            }
-            getMutationDTO(examId,caseId,workerId);
-            try {
-                calculateSocreLogic.catchNode(examId, caseId, workerId, String.valueOf(System.currentTimeMillis()), dtos);
-            }catch (Exception e){
-                LOG.info("Fail to save caughtNodeDTO to mongo of caseId:"+caseId+" exception:"+e.getMessage());
-            }
-            return dtos;
-        }
-    }
-
-    @Override
-    public void getMutationDTO(Long examId, Long caseId, Long participantId){
-        MutationDTO mutationDTO;
-        try {
-            mutationDTO = analysisService.mutationAnalyze(examId, participantId, caseId);
-            List<MutationForMongoDTO> list = mongoAPIService.getMutationFromMongo(participantId, examId, caseId);
-            if(list!=null) {
-                MutationForMongoDTO mutationForMongoDTO = list.get(0);
-                mutationForMongoDTO.setMutationDTO(mutationDTO);
-                mongoAPIService.updateMutationToMongo(mutationForMongoDTO);
-            }else {
-                mongoAPIService.saveMutationToMongo(participantId, examId, caseId, mutationDTO);
-            }
-        }catch (Exception e){
-            e.printStackTrace();
-            LOG.info("Fail to save mutationDTO to mongo of caseId:"+caseId+" exception:"+e.getMessage());
-            return;
-        }
-    }
-}

+ 46 - 13
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/CalculateScoreLogicImpl.java

@@ -5,6 +5,7 @@ import cn.iselab.mooctest.site.common.enums.CompeteAnalysisType;
 import cn.iselab.mooctest.site.data.CaseBlock;
 import cn.iselab.mooctest.site.data.PageData;
 import cn.iselab.mooctest.site.data.Sort;
+import cn.iselab.mooctest.site.data.UploadRecordDTO;
 import cn.iselab.mooctest.site.models.CaseExtends;
 import cn.iselab.mooctest.site.models.Exam2Case;
 import cn.iselab.mooctest.site.models.Paper;
@@ -25,9 +26,11 @@ 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.competeAnalysis.CompeteAnalysisResultDTO;
 import cn.iselab.mooctest.site.web.data.fromKibug.ScoreRuleItemVO;
+import cn.iselab.mooctest.site.web.data.response.ServerCode;
 import cn.iselab.mooctest.site.web.data.wrapper.AssignedTaskVOWrapper;
 import cn.iselab.mooctest.site.web.data.wrapper.fromDev.CompeteAnalysisVOWrapper;
 import cn.iselab.mooctest.site.web.exception.HttpNotFoundException;
+import cn.iselab.mooctest.site.web.exception.ServerException;
 import cn.iselab.mooctest.site.web.logic.BaseLogic;
 import cn.iselab.mooctest.site.web.logic.CalculateSocreLogic;
 import cn.iselab.mooctest.site.web.logic.CaseLogic;
@@ -92,6 +95,9 @@ public class CalculateScoreLogicImpl extends BaseLogic implements CalculateSocre
     @Autowired
     GeneralCalculateScoreComponent generalCalculateScoreComponent;
 
+    @Autowired
+    GeneralCalculateScoreService generalCalculateScoreService;
+
     @Override
     public void calculateScore(long taskId, long caseId) {
         CaseExtends caseExtends = caseService.getCaseExtendsById(caseId);
@@ -474,12 +480,6 @@ public class CalculateScoreLogicImpl extends BaseLogic implements CalculateSocre
     @Override
     public void catchNode(Long examId, Long caseId, Long userId, String uploadTime,
                           List<CaughtNodeDTO> caughtNodeDTOs) throws Exception {
-        catchNode(examId, caseId, userId, uploadTime, null, caughtNodeDTOs);
-    }
-
-    @Override
-    public void catchNode(Long examId, Long caseId, Long userId, String uploadTime, String source,
-                          List<CaughtNodeDTO> caughtNodeDTOs) throws Exception {
         List<CatchDTO> catchDTOList = new ArrayList<>();
         for (CaughtNodeDTO caughtNodeDTO : caughtNodeDTOs) {
             if (caughtNodeDTO.getIfCatch().equals(Boolean.TRUE)) {
@@ -492,15 +492,49 @@ public class CalculateScoreLogicImpl extends BaseLogic implements CalculateSocre
             }
         }
         catchService.postBulkCatchDTOS(catchDTOList);
-
-        generalCalculateScoreComponent.saveCaughtDetails(examId, caseId, userId, source,
-                caughtNodeDTOs);
     }
 
 
     @Override
     public void recordNode(Long examId, Long caseId, Long userId, String uploadTime,
-                           String source, List<CaughtNodeDTO> caughtNodeDTOs) throws Exception {
+                           String source, List<CaughtNodeDTO> caughtNodeDTOs, String ossUrl) throws
+            Exception {
+        //上传caughtNode
+        recordNodeOnly(examId,caseId,userId,uploadTime,caughtNodeDTOs);
+        //存储上传记录
+        UploadRecordDTO uploadRecordDTO = generalCalculateScoreService.getUploadRecord(userId,
+                examId,caseId,uploadTime);
+        if(uploadRecordDTO == null){
+            uploadRecordDTO = new UploadRecordDTO();
+            uploadRecordDTO.setExamId(examId);
+            uploadRecordDTO.setCaseId(caseId);
+            uploadRecordDTO.setWorkerId(userId);
+            uploadRecordDTO.setUploadTime(uploadTime);
+        }
+        uploadRecordDTO.setOSSUrl(ossUrl);
+        uploadRecordDTO.setSource(source);
+
+        uploadRecordDTO = generalCalculateScoreService.saveUploadRecords(uploadRecordDTO);
+        if(uploadRecordDTO == null){
+            throw new ServerException(ServerCode.UPLOAD_RECORD_FAIL);
+        }
+        //调用算分
+        generalCalculateScoreComponent.saveCaughtDetails(uploadRecordDTO.getId(),examId, caseId,
+                userId, caughtNodeDTOs);
+    }
+
+    @Override
+    public void addNode(Long examId, Long caseId, Long userId, String uploadTime,
+            List<CaughtNodeDTO> caughtNodeDTOs, long uploadId) throws Exception {
+        //上传node
+        recordNodeOnly(examId,caseId,userId,uploadTime,caughtNodeDTOs);
+        //调用算分
+        generalCalculateScoreComponent.saveCaughtDetails(uploadId, examId, caseId, userId,
+                caughtNodeDTOs);
+    }
+
+    private void recordNodeOnly(Long examId, Long caseId, Long userId, String uploadTime,
+            List<CaughtNodeDTO> caughtNodeDTOs){
         List<CatchDTO> catchDTOList = new ArrayList<>();
         for (CaughtNodeDTO caughtNodeDTO : caughtNodeDTOs) {
             if (caughtNodeDTO.getIfCatch().equals(Boolean.TRUE)) {
@@ -529,8 +563,7 @@ public class CalculateScoreLogicImpl extends BaseLogic implements CalculateSocre
             userCatchDTO.setLatestId(id);
             userCatchService.createUserCatch(userCatchDTO);
         }
-        //上传caughtNode userCatch结束,调用算分
-        generalCalculateScoreComponent.saveCaughtDetails(examId, caseId, userId, source,
-                caughtNodeDTOs);
     }
+
+
 }

+ 128 - 76
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/GeneralCalculateScoreComponent.java

@@ -2,17 +2,26 @@ package cn.iselab.mooctest.site.web.logic.impl;
 
 import cn.iselab.mooctest.site.data.GeneralGradeDTO;
 import cn.iselab.mooctest.site.data.NodeExtends;
+import cn.iselab.mooctest.site.data.UploadRecordDTO;
+import cn.iselab.mooctest.site.models.UploadRecord;
 import cn.iselab.mooctest.site.service.*;
+import cn.iselab.mooctest.site.util.BeanFactory;
 import cn.iselab.mooctest.site.util.data.JSONUtil;
 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.Node;
+import cn.iselab.mooctest.site.web.data.response.ServerCode;
+import cn.iselab.mooctest.site.web.exception.ServerException;
 import cn.iselab.mooctest.site.web.logic.strategy.HighestStrategy;
 import cn.iselab.mooctest.site.web.logic.strategy.LatestStrategy;
 import cn.iselab.mooctest.site.web.logic.strategy.ScoreStrategy;
+import java.util.stream.Collectors;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Scope;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
@@ -30,9 +39,10 @@ import java.util.Map;
  * @create 2018-03-14 11:18
  */
 @Component
+@Slf4j
 public class GeneralCalculateScoreComponent {
 
-    //获取元node服务
+//    获取元node服务
     @Autowired
     CaseGraphService caseGraphService;
     //获取被命中nodes的服务
@@ -55,8 +65,11 @@ public class GeneralCalculateScoreComponent {
     @Autowired
     CatchService catchService;
 
-    public void calculateGrade(long examId, long caseId, Long userId, String source) throws Exception {
-        recordTypeScore(examId, caseId, userId, source);
+    private static Map<Long, CaseGraphDTO> basicNodeMap = new HashMap<>();
+
+    public void calculateGrade(long examId, long caseId, Long userId) throws
+            Exception {
+        recordTypeScore(examId, caseId, userId);
         if (userId != null) {
             calculateCaseScore(examId, caseId, userId);
         } else { //计算所有人的分数
@@ -66,8 +79,32 @@ public class GeneralCalculateScoreComponent {
 
     }
 
-    private void recordTypeScore(long examId, long caseId, Long userId, String
-            source) throws Exception {
+    //计算当即提交的node的得分
+    public void calculateGradeCurrent(Long uploadId, long examId, long caseId, long userId,
+            List<CaughtNodeDTO> caughtNodeDTOS)
+            throws Exception {
+
+        //过滤没有catch的node,并将catch住的node转换为CatchDTO
+        List<CatchDTO> catchDTOS = caughtNodeDTOS.stream().filter
+                (CaughtNodeDTO::getIfCatch).map(x -> new CatchDTO(x.getNodeName(),x.getCategory()
+                ,null)).collect(Collectors.toList());
+
+        //通过元node和CatchDTOs计算每种类型的得分
+        CaseGraphDTO basicNode = getBasicNode(caseId);
+        Map<String, Double> typeScoreMap = calculateTypeScore(basicNode,catchDTOS);
+        List<GeneralGradeDTO> gradeDTOList = new ArrayList<>();
+        typeScoreMap.forEach((type,score) -> gradeDTOList.add(new GeneralGradeDTO(type,score,uploadId)));
+
+        //记录每种类型的得分
+        generalCalculateScoreService.updateTypeGrade(gradeDTOList);
+
+        //计算该case的得分
+        calculateCaseScore(examId, caseId, userId);
+    }
+
+    //非当即分数记录
+    private void recordTypeScore(long examId, long caseId, Long userId) throws
+            Exception {
 
         List<UserCatchDTO> userCatchDTOList;
         if (userId == null) {
@@ -75,10 +112,8 @@ public class GeneralCalculateScoreComponent {
         } else {
             userCatchDTOList = userCatchService.getUserCatchDTOs(userId, examId, caseId);
         }
-
         List<GeneralGradeDTO> gradeDTOList = calculateTypeScore(caseId, userCatchDTOList);
         if (gradeDTOList != null) {
-            gradeDTOList.forEach(x -> x.setSource(source));
             generalCalculateScoreService.updateTypeGrade(gradeDTOList);
         }
 
@@ -97,49 +132,53 @@ public class GeneralCalculateScoreComponent {
                                                      List<UserCatchDTO> userCatchDTOS) throws Exception {
 
         List<GeneralGradeDTO> generalGradeDTOList = new ArrayList<>();
+
         //元node数据
-        CaseGraphDTO basicNode = caseGraphService.getCaseGraph(caseId);
+        CaseGraphDTO basicNode = getBasicNode(caseId);
 
         if (basicNode != null && userCatchDTOS != null && userCatchDTOS.size() != 0) {
             for (UserCatchDTO userCatchDTO : userCatchDTOS) {
                 String id = userCatchDTO.getLatestId();
                 List<CatchDTO> catchDTOs = catchService.findById(id);
-                Map<String, Double> typeScoreMap = new HashMap<>();
-                for (Node node : basicNode.getNodes()) {
-                    for (CatchDTO catchDTO : catchDTOs) {
-                        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);
-                            typeScoreMap.put(key, scoreGot + singleNodeWeight);
-                            break;//一旦找到命中node则跳出,无需继续遍历
-                        }
-                    }
+                Map<String, Double> typeScoreMap = calculateTypeScore(basicNode,catchDTOs);
+                UploadRecordDTO uploadRecordDTO = generalCalculateScoreService.getUploadRecord
+                        (userCatchDTO.getUserId(),userCatchDTO.getExamId(),userCatchDTO.getCaseId
+                                (),catchDTOs.get(0).getUploadTime());
+                if(uploadRecordDTO == null){
+                    throw new ServerException(ServerCode.SYSTEM_ERROR.getCode(),"上传记录不存在");
                 }
-
                 for (String key : typeScoreMap.keySet()) {
-                    String uploadTime = catchDTOs.get(0).getUploadTime();
-                    GeneralGradeDTO generalGradeDTO = new GeneralGradeDTO(userCatchDTO.getUserId
-                            (), userCatchDTO.getExamId(), userCatchDTO.getCaseId(), key, typeScoreMap
-                            .get(key), uploadTime, "");
+                    GeneralGradeDTO generalGradeDTO = new GeneralGradeDTO(key,typeScoreMap.get
+                            (key),uploadRecordDTO.getId());
                     generalGradeDTOList.add(generalGradeDTO);
                 }
-
-//                typeScoreMap.keySet().forEach(type -> {
-//                    GeneralGradeDTO generalGradeDTO = new GeneralGradeDTO(userCatchDTO.getUserId
-//                            (), userCatchDTO.getExamId(), userCatchDTO.getCaseId(), type, typeScoreMap
-//                            .get(type), userCatchDTO.getLatestDTOS().get(0).getUploadTime(), "");
-//                    generalGradeDTOList.add(generalGradeDTO);
-//                });
             }
         }
         return generalGradeDTOList;
     }
 
+    private Map<String,Double> calculateTypeScore(CaseGraphDTO basicNode, List<CatchDTO>
+            catchDTOs){
+        Map<String, Double> typeScoreMap = new HashMap<>();
+        for (Node node : basicNode.getNodes()) {
+            for (CatchDTO catchDTO : catchDTOs) {
+                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);
+                    typeScoreMap.put(key, scoreGot + singleNodeWeight);
+                    break;//一旦找到命中node则跳出,无需继续遍历
+                }
+            }
+        }
+
+        return typeScoreMap;
+    }
+
 
     /**
      * 获取node节点的权重
@@ -203,48 +242,61 @@ public class GeneralCalculateScoreComponent {
 
 
     @Async("calculateGradeAsync")
-    public void saveCaughtDetails(Long examId, Long caseId, Long userId, String
-            source, List<CaughtNodeDTO> caughtNodeDTOs) throws Exception {
-
-        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 {
-            //更新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);
-                }
+    public void saveCaughtDetails(long uploadId, Long examId, Long caseId, Long userId,
+            List<CaughtNodeDTO> caughtNodeDTOs) throws Exception {
+
+//        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 {
+//            //更新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);
+//        }
+
+        calculateGradeCurrent(uploadId,examId,caseId,userId,caughtNodeDTOs);
+
+    }
+
+    private CaseGraphDTO getBasicNode(long caseId){
+        CaseGraphDTO basicNode = basicNodeMap.get(caseId);
+        if(basicNode == null){
+            basicNode = caseGraphService.getCaseGraph(caseId);
+            if(basicNode == null){
+                throw new ServerException(ServerCode.META_NODE_NOT_EXIST);
             }
-            caughtNodeService.bulkUpdateCaughtNodes(examId, caseId, nodeNameList, userId);
+            basicNodeMap.put(caseId,basicNode);
         }
-        calculateGrade(examId, caseId, userId, source);
-
+        return  basicNode;
     }
 }

+ 1 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/GeneralCalculateScoreLogicImpl.java

@@ -54,7 +54,7 @@ public class GeneralCalculateScoreLogicImpl implements GeneralCalculateScoreLogi
 
   @Override
   public void calculateScore(long examId, long caseId, Long userId, String source) throws Exception{
-    generalCalculateScoreComponent.calculateGrade(examId, caseId, userId, source);
+    generalCalculateScoreComponent.calculateGrade(examId, caseId, userId);
   }
 
   @Override

+ 1 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/ScoreRuleLogicImpl.java

@@ -45,6 +45,6 @@ public class ScoreRuleLogicImpl implements ScoreRuleLogic {
         newWeightMap.forEach( (k, v) -> {
             weightGeneralService.setWeight(vo.getTaskId(), vo.getCaseId(), k, v);
         });
-        //eventUtil.post(new ScoreRuleChangeEvent(vo.getExamId(), vo.getCaseId()));
+        eventUtil.post(new ScoreRuleChangeEvent(vo.getTaskId(), vo.getCaseId()));
     }
 }

+ 4 - 4
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/strategy/HighestStrategy.java

@@ -25,14 +25,14 @@ public class HighestStrategy implements ScoreStrategy {
 
   @Override
   public double getCaseScore(long examId, long caseId, Long userId) {
-    Map<String,Map<String,Double>> timeTypeScoreMap = generalCalculateScoreService
-        .getTimeTypeScore(userId,examId,caseId);
+    Map<Long,Map<String,Double>> uidTypeScoreMap = generalCalculateScoreService
+        .getUidTypeScore(userId,examId,caseId);
     List<WeightGeneral> weightGeneralList = weightGeneralService.get(examId,caseId);
     List<Double> caseScores = new ArrayList<>();
 
-    timeTypeScoreMap.keySet().forEach(key->{
+    uidTypeScoreMap.keySet().forEach(key->{
       double caseScore = 0.0;
-      Map<String,Double> scoreMap = timeTypeScoreMap.get(key);
+      Map<String,Double> scoreMap = uidTypeScoreMap.get(key);
       for(WeightGeneral weightGeneral:weightGeneralList){
         int weight = weightGeneral.getWeight();
         String category = weightGeneral.getType();

+ 16 - 3
mooctest-site-server/src/test/java/cn/iselab/mooctest/site/web/logic/impl/GeneralCalculateScoreComponentTest.java

@@ -2,12 +2,14 @@ package cn.iselab.mooctest.site.web.logic.impl;
 
 
 import cn.iselab.mooctest.site.data.GeneralGradeDTO;
+import cn.iselab.mooctest.site.data.UploadRecordDTO;
 import cn.iselab.mooctest.site.service.*;
 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.UserCatchDTO;
 import cn.iselab.mooctest.site.web.data.forMongo.graph.Category;
 import cn.iselab.mooctest.site.web.data.forMongo.graph.Node;
+import cn.iselab.mooctest.site.web.exception.ServerException;
 import cn.iselab.mooctest.site.web.logic.strategy.HighestStrategy;
 import cn.iselab.mooctest.site.web.logic.strategy.LatestStrategy;
 import org.junit.Before;
@@ -63,6 +65,8 @@ public class GeneralCalculateScoreComponentTest {
             GeneralCalculateScoreComponent.class;
     Object instance;
 
+    UploadRecordDTO uploadRecordDTO;
+
     @Before
     public void setUp() throws Exception {
 
@@ -84,6 +88,10 @@ public class GeneralCalculateScoreComponentTest {
                 ("highestStrategy");
         field2.set(instance, highestStrategy);
 
+        Field field3 = generalCalculateScoreComponentClass.getDeclaredField
+                ("generalCalculateScoreService");
+        field3.set(instance,generalCalculateScoreService);
+
         basicNode.setCaseId(1L);
         Category c1 = new Category("c1", 1);
         Category c2 = new Category("c2", 1);
@@ -144,6 +152,9 @@ public class GeneralCalculateScoreComponentTest {
                         "5b2fc1dcd7fa0b6acb62816"), "5b2fdac0d7fa0b6acb628193");
         userCatchDTOList.add(userCatchDTO);
 
+        uploadRecordDTO = new UploadRecordDTO(1L,1105L,1804L,824L,"xxx","xx","1234567");
+
+
 //    UserCatchDTO userCatchDTO = new UserCatchDTO("1",1L,1L,1L,Arrays.asList(catchDTO1,
 //        catchDTO2,catchDTO1_new,catchDTO11,catchDTO2_new,catchDTO3),
 //        Arrays.asList(catchDTO1_new,catchDTO2_new));
@@ -155,6 +166,8 @@ public class GeneralCalculateScoreComponentTest {
     public void should_calculateTypeScore_when_givenData() throws Exception {
         when(caseGraphService.getCaseGraph(1L)).thenReturn(basicNode);
         when(catchService.findById("5b2fdac0d7fa0b6acb628193")).thenReturn(catchDTOList);
+        when(generalCalculateScoreService.getUploadRecord(1105L, 1804L, 824L,"1234567"))
+                .thenReturn(uploadRecordDTO);
 
         Method method = generalCalculateScoreComponentClass.getDeclaredMethod("calculateTypeScore",
                 new Class[]{long.class, List.class});
@@ -175,14 +188,14 @@ public class GeneralCalculateScoreComponentTest {
 
     }
 
-    @Test
-    public void should_returnNull_when_caseNotHasNode() throws Exception {
+    @Test(expected = Exception.class)
+    public void should_throwException_when_caseNotHasNode() throws Exception {
         when(caseGraphService.getCaseGraph(2L)).thenReturn(null);
         Method method = generalCalculateScoreComponentClass.getDeclaredMethod("calculateTypeScore",
                 long.class, List.class);
         method.setAccessible(true);
         Object result = method.invoke(instance, 1L, userCatchDTOList);
-        assertEquals(0, ((ArrayList) result).size());
+//        assertEquals(0, ((ArrayList) result).size());
     }
 
     @Test