ソースを参照

Merge branch 'Test' into 'Release'

Test



See merge request !909

menduo 6 年 前
コミット
3489bab603
100 ファイル変更1986 行追加882 行削除
  1. 3 0
      mooctest-site-server/.dockerignore
  2. 3 0
      mooctest-site-server/PrivateCloudDockerfile
  3. 15 0
      mooctest-site-server/pom.xml
  4. 13 13
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/acyncTask/McNodeCallBack.java
  5. 17 8
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/acyncTask/MutationCallBack.java
  6. 15 3
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/acyncTask/OnlineJudgeAndCulScoreCallBack.java
  7. 11 2
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/acyncTask/OnlineJudgeCallBack.java
  8. 0 37
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/acyncTask/OnlineJudgeExecuteCallBack.java
  9. 13 7
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/aspect/PointAspect.java
  10. 31 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/enums/EntityType.java
  11. 2 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/enums/OnlineJudgeMode.java
  12. 18 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/enums/TagType.java
  13. 18 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/RedisSessionConfiguration.java
  14. 1 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/ShiroConfiguration.java
  15. 38 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/SwaggerConfiguration.java
  16. 13 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/ApplyUploadRecordDao.java
  17. 26 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/Entity2TagDao.java
  18. 28 24
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/GradeGeneralDao.java
  19. 5 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/QualificationDao.java
  20. 20 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/TagDao.java
  21. 30 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/UploadRecordDao.java
  22. 1 6
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/data/GeneralGradeDTO.java
  23. 34 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/data/UploadRecordDTO.java
  24. 38 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ApplyUploadRecord.java
  25. 3 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/AssistManagerExam.java
  26. 6 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Competition.java
  27. 3 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ContestMentorExam.java
  28. 39 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Entity2Tag.java
  29. 22 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Exam.java
  30. 3 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ExamPythonCommunity.java
  31. 3 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ExamPythonCommunityParticipant.java
  32. 4 79
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/GradeGeneral.java
  33. 3 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ParticipantExam.java
  34. 21 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Tag.java
  35. 43 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/UploadRecord.java
  36. 46 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/Entity2TagService.java
  37. 4 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/ExamService.java
  38. 21 5
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/GeneralCalculateScoreService.java
  39. 22 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/TagService.java
  40. 29 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/enums/ExamStatus.java
  41. 19 4
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CaseServiceImpl.java
  42. 20 3
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CompetitionServiceImpl.java
  43. 136 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/Entity2TagServiceImpl.java
  44. 23 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/ExamServiceImpl.java
  45. 75 23
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/GeneralCalculateScoreServiceImpl.java
  46. 8 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/SearchListComponent.java
  47. 57 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/TagServiceImpl.java
  48. 18 22
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/instancePermission/impl/ExamPermissionServiceImpl.java
  49. 4 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/util/BeanFactory.java
  50. 1 6
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/util/data/CacheUtil.java
  51. 0 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/SessionCounter.java
  52. 1 4
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/CompetitionController.java
  53. 21 4
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ExamController.java
  54. 2 2
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/MutationProgressController.java
  55. 25 10
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/OnlineJudgeController.java
  56. 63 24
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ScoreController.java
  57. 67 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/TagController.java
  58. 6 2
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/UserController.java
  59. 0 31
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromDev/AnalysisController.java
  60. 21 5
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromDev/PluginController.java
  61. 16 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/ApplySignatureVO.java
  62. 3 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/CompetitionVO.java
  63. 28 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/Entity2TagVO.java
  64. 10 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/ExamVO.java
  65. 26 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/OnlineJudgeCustomResultVO.java
  66. 16 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/TagPathVO.java
  67. 20 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/TagVO.java
  68. 21 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/UploadCaughtNodeJson.java
  69. 0 54
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/fromDev/ApfdAllVO.java
  70. 25 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/json/Entity2TagJson.java
  71. 42 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/response/ResponseVO.java
  72. 42 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/response/ServerCode.java
  73. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/ExamVOWrapper.java
  74. 37 10
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/OnlineJudgeResultVOWrapper.java
  75. 0 36
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/OnlineJudgeResultsVOWrapper.java
  76. 44 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/fromDev/TagVOWrapper.java
  77. 11 19
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/exception/ServerException.java
  78. 6 4
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/CalculateSocreLogic.java
  79. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/ExamLogic.java
  80. 6 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/GeneralCalculateScoreLogic.java
  81. 6 7
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/OnlineJudgeLogic.java
  82. 19 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/TagLogic.java
  83. 0 3
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/asyncProgress/OnlineJudgeProcessLogic.java
  84. 29 7
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/asyncProgress/impl/MutationProgressLogicImpl.java
  85. 23 39
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/asyncProgress/impl/OnlineJudgeProcessLogicImpl.java
  86. 0 30
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/fromDev/APFDLogic.java
  87. 12 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/fromDev/UpDownloadLogic.java
  88. 0 238
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/fromDev/impl/APFDLogicImpl.java
  89. 17 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/fromDev/impl/UpDownloadLogicImpl.java
  90. 15 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/fromDev/impl/UpDownloadLogicPCImpl.java
  91. 44 18
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/CalculateScoreLogicImpl.java
  92. 7 3
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/CompetitionLogicImpl.java
  93. 11 3
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/ExamLogicImpl.java
  94. 52 35
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/GeneralCalculateScoreComponent.java
  95. 11 2
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/GeneralCalculateScoreLogicImpl.java
  96. 67 39
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/OnlineJudgeLogicImpl.java
  97. 1 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/ScoreRuleLogicImpl.java
  98. 67 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/TagLogicImpl.java
  99. 12 3
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/UserLogicImpl.java
  100. 4 4
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/strategy/HighestStrategy.java

+ 3 - 0
mooctest-site-server/.dockerignore

@@ -0,0 +1,3 @@
+**
+!target/mooctest-site-server.jar
+!PrivateCloudDockerfile

+ 3 - 0
mooctest-site-server/PrivateCloudDockerfile

@@ -0,0 +1,3 @@
+FROM java
+
+COPY ./target/mooctest-site-server.jar /

+ 15 - 0
mooctest-site-server/pom.xml

@@ -146,6 +146,11 @@
             <version>${spring.boot.version}</version>
         </dependency>
         <dependency>
+            <groupId>org.springframework.session</groupId>
+            <artifactId>spring-session-data-redis</artifactId>
+            <version>1.1.1.RELEASE</version>
+        </dependency>
+        <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-configuration-processor</artifactId>
             <version>${spring.boot.version}</version>
@@ -336,6 +341,16 @@
             <artifactId>commons-math3</artifactId>
             <version>3.6</version>
         </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>2.4.0</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>2.4.0</version>
+        </dependency>
         <!--<dependency>-->
             <!--<groupId>org.springframework.boot</groupId>-->
             <!--<artifactId>spring-boot-devtools</artifactId>-->

+ 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) {

+ 15 - 3
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/acyncTask/OnlineJudgeAndCulScoreCallBack.java

@@ -4,11 +4,17 @@ import cn.iselab.mooctest.site.data.OnlineJudgeResultDTO;
 import cn.iselab.mooctest.site.web.data.OnlineJudgeResultVO;
 import cn.iselab.mooctest.site.web.logic.GeneralCalculateScoreLogic;
 import cn.iselab.mooctest.site.web.logic.OnlineJudgeLogic;
+import com.google.common.collect.Lists;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.math.BigDecimal;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -31,13 +37,19 @@ class OnlineJudgeAndCulScoreCallBack implements AsyncTaskCallBack {
     @Override
     public void onSuccess(Map<String, String> context, String result) throws Exception {
         log.info("submissionId:[{}] 执行成功! result:[{}]",context.get("submissionId"),result);
-        OnlineJudgeResultDTO onlineJudgeResultDTO = onlineJudgeLogic.generalOnlineJudgeResultDTO (result);
-        onlineJudgeLogic.setResultDTOToCache (context.get("submissionId"),onlineJudgeResultDTO);
+        InputStream inputStream = new ByteArrayInputStream(result.getBytes());
+        String tmp = "";
+        List<OnlineJudgeResultDTO> onlineJudgeResultDTOS = Lists.newArrayList();
+        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
+        while ((tmp = br.readLine()) != null) {
+            onlineJudgeResultDTOS.add(onlineJudgeLogic.generalOnlineJudgeResultDTO (tmp));
+        }
+        onlineJudgeLogic.setResultDTOToCache (context.get("submissionId"),onlineJudgeResultDTOS);
         Long examId = Long.parseLong(context.get("examId"));
         Long userId = Long.parseLong(context.get("userId"));
         Long caseId = Long.parseLong(context.get("caseId"));
         //上传分数
-        double score = culScore(onlineJudgeResultDTO.getRightCount(),onlineJudgeResultDTO.getTotalCount());
+        double score = culScore(onlineJudgeResultDTOS.get(0).getRightCount(),onlineJudgeResultDTOS.get(0).getTotalCount());
         generalCalculateScoreLogic.uploadCaseScore(examId,caseId,userId,score);
 
     }

+ 11 - 2
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/acyncTask/OnlineJudgeCallBack.java

@@ -3,10 +3,13 @@ package cn.iselab.mooctest.site.common.acyncTask;
 import cn.iselab.mooctest.site.data.OnlineJudgeResultDTO;
 import cn.iselab.mooctest.site.web.data.OnlineJudgeResultVO;
 import cn.iselab.mooctest.site.web.logic.OnlineJudgeLogic;
+import com.google.common.collect.Lists;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.io.*;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -26,8 +29,14 @@ public class OnlineJudgeCallBack implements AsyncTaskCallBack {
     @Override
     public void onSuccess(Map<String, String> context, String result) throws Exception {
         log.info("submissionId:[{}] 执行成功! result:[{}]",context.get("submissionId"),result);
-        OnlineJudgeResultDTO onlineJudgeResultDTO = onlineJudgeLogic.generalOnlineJudgeResultDTO (result);
-        onlineJudgeLogic.setResultDTOToCache(context.get("submissionId"),onlineJudgeResultDTO);
+        InputStream inputStream = new ByteArrayInputStream(result.getBytes());
+        String tmp = "";
+        List<OnlineJudgeResultDTO> onlineJudgeResultDTOS = Lists.newArrayList();
+        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
+        while ((tmp = br.readLine()) != null) {
+            onlineJudgeResultDTOS.add(onlineJudgeLogic.generalOnlineJudgeResultDTO (tmp));
+        }
+        onlineJudgeLogic.setResultDTOToCache(context.get("submissionId"),onlineJudgeResultDTOS);
     }
 
     @Override

+ 0 - 37
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/acyncTask/OnlineJudgeExecuteCallBack.java

@@ -1,37 +0,0 @@
-package cn.iselab.mooctest.site.common.acyncTask;
-
-import cn.iselab.mooctest.site.data.OnlineJudgeResultDTO;
-import cn.iselab.mooctest.site.web.data.OnlineJudgeResultVO;
-import cn.iselab.mooctest.site.web.data.OnlineJudgeResultsVO;
-import cn.iselab.mooctest.site.web.logic.OnlineJudgeLogic;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import java.util.Map;
-
-/**
- * @program: mooctest-site
- * @email: menduo96@gmail.com
- * @author: menduo
- * @create: 2018/9/25 下午2:22
- **/
-@Slf4j
-@Component
-public class OnlineJudgeExecuteCallBack implements AsyncTaskCallBack{
-    @Autowired
-    private OnlineJudgeLogic onlineJudgeLogic;
-
-    @Override
-    public void onSuccess(Map<String, String> context, String result) throws Exception {
-        log.info("submissionId:[{}] 执行成功! result:[{}]",context.get("submissionId"),result);
-        OnlineJudgeResultDTO onlineJudgeResultDTO = onlineJudgeLogic.generalOnlineJudgeResultDTO (result);
-        //onlineJudgeResultsVO.generalMatched();
-        onlineJudgeLogic.setResultDTOToCache (context.get("submissionId"),onlineJudgeResultDTO);
-    }
-
-    @Override
-    public void onError(Map<String, String> context, String result) {
-        log.error("submissionId:[{}] 执行失败! result:[{}]",context.get("submissionId"),result);
-    }
-}

+ 13 - 7
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/aspect/PointAspect.java

@@ -2,7 +2,9 @@ package cn.iselab.mooctest.site.common.aspect;
 
 import cn.iselab.mooctest.rpc.user.data.AddIntegralDTO;
 import cn.iselab.mooctest.site.common.annotation.PointChange;
+import cn.iselab.mooctest.site.configure.ClientFeatureConfiguration;
 import cn.iselab.mooctest.site.rpc.user.IntegralService;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.shiro.SecurityUtils;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.annotation.AfterReturning;
@@ -20,23 +22,27 @@ import java.lang.reflect.Method;
  */
 @Aspect
 @Component
+@Slf4j
 public class PointAspect {
 
     @Autowired
     IntegralService integralService;
+    @Autowired
+    private ClientFeatureConfiguration clientFeatureConfiguration;
 
     @Pointcut("@annotation(pointChange)")
     private void pointcut(PointChange pointChange){}
 
     @AfterReturning("pointcut(pointChange)")
     public void afterReturning(PointChange pointChange) {
-
-        Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute("userId");
-        AddIntegralDTO dto=new AddIntegralDTO();
-        dto.setUserId(userId);
-        dto.setEvent(pointChange.value());
-        integralService.checkIntegral(dto);
-        System.out.println("Point Change : user="+userId+" event="+pointChange.value());
+        if(clientFeatureConfiguration.isMedal()) {
+            Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute("userId");
+            AddIntegralDTO dto = new AddIntegralDTO();
+            dto.setUserId(userId);
+            dto.setEvent(pointChange.value());
+            integralService.checkIntegral(dto);
+            System.out.println("Point Change : user=" + userId + " event=" + pointChange.value());
+        }
 
     }
 }

+ 31 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/enums/EntityType.java

@@ -0,0 +1,31 @@
+package cn.iselab.mooctest.site.common.enums;
+
+import cn.iselab.mooctest.site.web.exception.ServerException;
+import lombok.Getter;
+
+public enum EntityType {
+
+    Case ("case",1),
+    Target ("target",2);
+
+    @Getter
+    private String typeName;
+    @Getter
+    private int typeNumber;
+
+    private EntityType(String typeName, int typeNumber) {
+        this.typeName = typeName;
+        this.typeNumber = typeNumber;
+    }
+
+    public static EntityType getByTypeName(String typeName){
+        switch (typeName.toLowerCase()){
+            case "case": return Case;
+            case "target": return Target;
+        }
+        throw new ServerException(30000,typeName + " 类型不存在");
+    }
+
+
+
+}

+ 2 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/enums/OnlineJudgeMode.java

@@ -11,7 +11,8 @@ public enum OnlineJudgeMode {
     RUN("run"),
     SUBMIT("submit"),
     RUN_WITH_INPUT("runWithInput"),
-    RUN_WITH_MANY_INPUT("runWithManyInput");
+    RUN_WITH_MANY_INPUT("runWithManyInput"),
+    CUSTOMRUN("customRun");
 
     private String mode;
 

+ 18 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/common/enums/TagType.java

@@ -0,0 +1,18 @@
+package cn.iselab.mooctest.site.common.enums;
+
+/**
+ * Created on 2018/12/17
+ */
+public enum TagType {
+    TAG(1),
+    LABEL(2);
+
+    private int value;
+    private TagType(int value){
+        this.value = value;
+    }
+
+    public int getValue(){
+        return this.value;
+    }
+}

+ 18 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/RedisSessionConfiguration.java

@@ -0,0 +1,18 @@
+package cn.iselab.mooctest.site.configure;
+
+import cn.iselab.mooctest.site.web.SessionCounter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+
+/**
+ * Created by tangshanshan on 2018/6/21.
+ */
+@Configuration
+@EnableRedisHttpSession
+public class RedisSessionConfiguration {
+    @Bean
+    public SessionCounter sessionCounter(){
+        return new SessionCounter();
+    }
+}

+ 1 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/ShiroConfiguration.java

@@ -96,6 +96,7 @@ public class ShiroConfiguration {
         filterChainDefinitionManager.put("/api/test/login", "anon");
         filterChainDefinitionManager.put("/api/test/register", "anon");
         filterChainDefinitionManager.put("/api/featureSwitch", "anon");
+        filterChainDefinitionManager.put("/api/common/tag/**", "authc");
         filterChainDefinitionManager.put("/api/common/**", "anon");
         filterChainDefinitionManager.put("/api/mobileLogin", "anon");
         filterChainDefinitionManager.put("/api/case/nodeList", "anon");

+ 38 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/SwaggerConfiguration.java

@@ -0,0 +1,38 @@
+package cn.iselab.mooctest.site.configure;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+public class SwaggerConfiguration {
+    @Value("${swagger.enable}")
+    private boolean enableSwagger;
+    @Bean
+    public Docket createRestApi() {
+        return new Docket(DocumentationType.SWAGGER_2)
+                .apiInfo(apiInfo())
+                .enable(enableSwagger)
+                .select()
+                .apis(RequestHandlerSelectors.basePackage("cn.iselab.mooctest.site.web.ctrl"))
+                .paths(PathSelectors.any())
+                .build();
+    }
+
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                .title("Mooctest API Doc")
+                .contact(new Contact("Mooctest", "http://www.mooctest.net", "admin@mooctest.edu.cn"))
+                .version("1.0")
+                .build();
+    }
+}

+ 13 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/ApplyUploadRecordDao.java

@@ -0,0 +1,13 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.ApplyUploadRecord;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * Created on 2018/10/22
+ */
+public interface ApplyUploadRecordDao extends JpaRepository<ApplyUploadRecord, Long>{
+
+    ApplyUploadRecord findTopByWorkerIdAndExamIdOrderByIdDesc(long workerId, long examId);
+
+}

+ 26 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/Entity2TagDao.java

@@ -0,0 +1,26 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.common.enums.EntityType;
+import cn.iselab.mooctest.site.models.Entity2Tag;
+import org.springframework.data.repository.CrudRepository;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+/**
+ * @author csc
+ */
+@Transactional
+public interface Entity2TagDao extends CrudRepository<Entity2Tag, Long>{
+
+    List<Entity2Tag> findByEntityIdAndEntityType(long entityId, int entityType);
+
+    List<Entity2Tag> findByEntityIdAndEntityTypeAndTagType(long entityId, int entityType, int
+            tagType);
+
+    List<Entity2Tag> deleteByEntityIdAndEntityType(long entityId, int type);
+
+    List<Entity2Tag> findByTagNameLikeAndEntityType(String tagName, int entityType);
+
+    List<Entity2Tag> findByTagIdAndEntityType(int tagId, int entityType);
+}

+ 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);
 }

+ 5 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/QualificationDao.java

@@ -3,6 +3,7 @@ package cn.iselab.mooctest.site.dao;
 import cn.iselab.mooctest.site.models.Qualification;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.repository.query.Param;
 
 import javax.transaction.Transactional;
 import java.util.List;
@@ -16,4 +17,8 @@ public interface QualificationDao extends CrudRepository<Qualification, Long> {
     List<Qualification> findByCompetitionIdAndStatus(Long competitionId, Integer status);
     Qualification findByCompetitionIdAndUserIdAndStatus(Long competitionId, Long userId, Integer status);
     List<Qualification> findByCompetitionIdAndStatusAndNextRound(Long competitionId, Integer status, boolean nextround);
+
+    //获取状态最新的qualification
+    @Query(value="select * from qualification q where q.competition_id=:competitionId and q.user_id=:userId order by q.status desc limit 1",nativeQuery = true)
+    Qualification findLatestQulificationByCompetitionIdAndUserId(@Param("competitionId")Long competitionId, @Param("userId")Long userId);
 }

+ 20 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/TagDao.java

@@ -0,0 +1,20 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.Tag;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.repository.CrudRepository;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+/**
+ * @author csc
+ */
+@Transactional
+public interface TagDao extends JpaRepository<Tag, Integer> {
+
+    Tag findById(int id);
+    List<Tag> findByParentId(int parentId);
+    List<Tag> findByNameLike(String name);
+    List<Tag> findByParentIdIsNull();
+}

+ 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;
+    }
+}

+ 38 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ApplyUploadRecord.java

@@ -0,0 +1,38 @@
+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/22
+ */
+@Table(name = "apply_upload_record")
+@Entity
+@EqualsAndHashCode
+@Data
+public class ApplyUploadRecord {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    long id;
+
+    @Column(name = "worker_id")
+    long workerId;
+
+    @Column(name = "exam_id")
+    long examId;
+
+    @Column(name = "oss_url")
+    String ossUrl;
+
+    @Column(name = "apply_time")
+    String applyTime;
+
+
+}

+ 3 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/AssistManagerExam.java

@@ -44,4 +44,7 @@ public class AssistManagerExam {
 
     @Column(name = "assist_manager_id")
     private Long assistManagerId;
+
+    @Column(name = "is_deleted")
+    private Boolean isDeleted;
 }

+ 6 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Competition.java

@@ -32,5 +32,11 @@ public class Competition {
     private Boolean allowEnter;
     @Column(name="rank_weight")
     private Integer rankWeight;
+    @Column(name="add_ons_editable")
+    private Boolean addOnsEditable;
+    @Column(name="member_limit")
+    private Integer memberLimit;
+    @Column(name="mentor_limit")
+    private Integer mentorLimit;
 }
 

+ 3 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ContestMentorExam.java

@@ -44,5 +44,8 @@ public class ContestMentorExam {
 
     @Column(name = "contest_mentor_id")
     private Long ContestMentorId;
+
+    @Column(name = "is_deleted")
+    private Boolean isDeleted;
 }
 

+ 39 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Entity2Tag.java

@@ -0,0 +1,39 @@
+package cn.iselab.mooctest.site.models;
+
+import cn.iselab.mooctest.site.common.enums.TagType;
+import javax.persistence.*;
+import java.sql.Timestamp;
+import lombok.Data;
+import org.hibernate.annotations.CreationTimestamp;
+
+@Data
+@Entity
+@Table(name = "entity_2_tag")
+public class Entity2Tag {
+
+    @Id
+    @GeneratedValue
+    private long id;
+
+    @Column(name = "entity_id")
+    private long entityId;
+
+    @Column(name = "entity_type")
+    private int entityType;
+
+    @Column(name = "tag_id")
+    private Integer tagId;
+
+    @Column(name = "tag_name")
+    private String tagName;
+
+    @Column(name = "tag_type")
+    private Integer tagType;
+
+    @CreationTimestamp
+    @Column(name = "create_time")
+    private Timestamp createTime;
+
+
+
+}

+ 22 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Exam.java

@@ -56,6 +56,20 @@ public class Exam {
     inverseJoinColumns = @JoinColumn(name = "group_id"))
     private Set<Group> groupSet;
 
+    @Column(name = "is_deleted")
+    private boolean isDeleted;
+
+    @Column(name = "open_recommend")
+    private boolean openRecommend;
+
+    public boolean isOpenRecommend() {
+        return openRecommend;
+    }
+
+    public void setOpenRecommend(boolean openRecommend) {
+        this.openRecommend = openRecommend;
+    }
+
     public Long getOwnerId() {
         return ownerId;
     }
@@ -132,4 +146,12 @@ public class Exam {
     public void setGroupSet(Set<Group> groupSet) {
         this.groupSet = groupSet;
     }
+
+    public boolean isDeleted() {
+        return isDeleted;
+    }
+
+    public void setDeleted(boolean deleted) {
+        isDeleted = deleted;
+    }
 }

+ 3 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ExamPythonCommunity.java

@@ -39,4 +39,7 @@ public class ExamPythonCommunity {
     @Column(name = "locked")
     private int lock;
 
+    @Column(name = "is_deleted")
+    private Boolean isDeleted;
+
 }

+ 3 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ExamPythonCommunityParticipant.java

@@ -39,4 +39,7 @@ public class ExamPythonCommunityParticipant {
     @Column(name = "participant_id")
     private long participantId;
 
+    @Column(name = "is_deleted")
+    private Boolean isDeleted;
+
 }

+ 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;
-  }
 }

+ 3 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/ParticipantExam.java

@@ -45,4 +45,7 @@ public class ParticipantExam {
 
     @Column(name = "participant_id")
     private Long participantId;
+
+    @Column(name = "is_deleted")
+    private Boolean isDeleted;
 }

+ 21 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Tag.java

@@ -0,0 +1,21 @@
+package cn.iselab.mooctest.site.models;
+
+
+import javax.persistence.*;
+import lombok.Data;
+
+@Data
+@Entity
+@Table(name = "tag")
+public class Tag {
+
+    @Id
+    @GeneratedValue
+    private int id;
+
+    @Column(name = "name")
+    private String name;
+
+    @Column(name = "parent_id")
+    private Integer parentId;
+}

+ 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;
+
+}

+ 46 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/Entity2TagService.java

@@ -0,0 +1,46 @@
+package cn.iselab.mooctest.site.service;
+
+import cn.iselab.mooctest.site.common.enums.EntityType;
+import cn.iselab.mooctest.site.models.Entity2Tag;
+import cn.iselab.mooctest.site.models.Tag;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public interface Entity2TagService {
+
+    /**
+     * 为entity添加标签
+     * @param entityId 实体id
+     * @param type 实体类型
+     * @param tagIds 分类标签id
+     * @param labels 自定义标签labels
+     */
+    void indexTag(long entityId,EntityType type, List<Integer> tagIds, List<String> labels);
+
+    /**
+     * 查找实体对应的分类标签
+     * @param entityId 实体id
+     * @param entityType 实体类型
+     * @return 分类标签id列表
+     */
+    List<Integer> getTagsByEntityIdAndType(long entityId, EntityType entityType);
+
+    /**
+     * 查找实体对应的自定义标签
+     * @param entityId 实体id
+     * @param entityType 实体类型
+     * @return 自定义标签列表
+     */
+    List<String> getLabelsByEntityIdAndType(long entityId, EntityType entityType);
+
+    /**
+     * 给定name,查询相近的标签,并将标签对应的实体id列表返回
+     * @param name 标签关键字
+     * @return 实体id列表
+     */
+    List<Long> queryByNameLike(String name, EntityType type);
+
+    List<Long> getEntitiesByTagId(int tagId, EntityType type);
+
+}

+ 4 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/ExamService.java

@@ -51,4 +51,8 @@ public interface ExamService {
     Weight getWeight(long caseId, long taskId);
 
     boolean isTaskEnd(long taskId) throws Exception;
+
+    boolean canBeDeleted(Long examId);
+
+    Exam deleteExamById(Long examId);
 }

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

@@ -1,6 +1,9 @@
 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.ApplyUploadRecord;
+import cn.iselab.mooctest.site.models.UploadRecord;
 import java.util.List;
 import java.util.Map;
 
@@ -12,15 +15,28 @@ 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);
+
+  ApplyUploadRecord saveApplyUploadRecord(long workerId,long examId,String ossUrl, String
+          applyTime);
+
+  ApplyUploadRecord getLatestApplyUploadRecord(long workerId, long examId);
+
+  ApplyUploadRecord getApplyUploadRecordById(long id);
 }

+ 22 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/TagService.java

@@ -0,0 +1,22 @@
+package cn.iselab.mooctest.site.service;
+
+import cn.iselab.mooctest.site.models.Tag;
+
+import java.util.List;
+
+/**
+ * @author csc
+ */
+public interface TagService {
+
+    List<Tag> getDirectSubTagsByParent(int tagId);
+
+    List<Tag> getAllParentTags();
+
+    Tag getTagById(int tagId);
+
+    List<Tag> getFullPathTagBySon(int sonId);
+
+    List<Tag> getAllSubTags(int tagId);
+
+}

+ 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;
+    }
+}

+ 19 - 4
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CaseServiceImpl.java

@@ -1,8 +1,11 @@
 package cn.iselab.mooctest.site.service.impl;
 
+import cn.iselab.mooctest.site.common.enums.EntityType;
 import cn.iselab.mooctest.site.dao.*;
 import cn.iselab.mooctest.site.models.*;
 import cn.iselab.mooctest.site.service.CaseService;
+import cn.iselab.mooctest.site.service.Entity2TagService;
+import java.util.List;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
@@ -15,6 +18,7 @@ import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
+import java.util.ArrayList;
 import java.util.Map;
 
 /**
@@ -30,6 +34,9 @@ public class CaseServiceImpl implements CaseService {
     @Autowired
     private CaseExtendsDao caseExtendsDao;
 
+    @Autowired
+    private Entity2TagService entity2TagService;
+
     @Override
     public CaseExtends getCaseById(long caseId) {
         return caseDao.findOne(caseId);
@@ -80,9 +87,18 @@ public class CaseServiceImpl implements CaseService {
                     }
                 }
                 if (keyword != null) {
-                    predicate.getExpressions().add(
-                            cb.like(a.<String>get("name"), "%" + StringUtils.trim(keyword) + "%")
-                    );
+                    CriteriaBuilder.In<Long> in = cb.in(a.<Long> get("id"));
+                    List<Long> entitiesHasTag = entity2TagService.queryByNameLike(keyword,
+                            EntityType.Case);
+                    Predicate searchCaseName = cb.like(a.<String>get("name"), "%" + StringUtils.trim(keyword) + "%");
+                    if(entitiesHasTag.size() > 0) {
+                        for(Long entityId: entitiesHasTag) {
+                            in.value(entityId);
+                        }
+                        predicate.getExpressions().add(cb.or(searchCaseName, in));
+                    }else {
+                        predicate.getExpressions().add(searchCaseName);
+                    }
                 }
                 predicate.getExpressions().add(
                         cb.notEqual(a.get("deleted"), 1)
@@ -92,7 +108,6 @@ public class CaseServiceImpl implements CaseService {
         };
     }
 
-
     @Override
     public Page<CaseExtends> getCasesByTargetId(long targetId, String keyword, Pageable pageable){
         Specification<CaseExtends> where=Specifications.where(getWhereTarget(targetId,keyword));

+ 20 - 3
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CompetitionServiceImpl.java

@@ -61,19 +61,36 @@ public class CompetitionServiceImpl implements CompetitionService {
 
     @Override
     public Qualification getQualification(Long competitionId, Long userId) {
-        return qualificationDao.findByCompetitionIdAndUserId(competitionId,userId);
+        return qualificationDao.findLatestQulificationByCompetitionIdAndUserId(competitionId,userId);
     }
 
+    //    @Override
+//    public Qualification createOrUpdateQualification(Qualification qualification) {
+//        Qualification qualification1 = qualificationDao.findByCompetitionIdAndUserIdAndStatus(qualification.getCompetitionId(),
+//                qualification.getUserId(), qualification.getStatus());
+//        if(qualification1 == null) {
+//            return qualificationDao.save(qualification);
+//        }
+//        return qualification1;
+//    }
     @Override
     public Qualification createOrUpdateQualification(Qualification qualification) {
         Qualification qualification1 = qualificationDao.findByCompetitionIdAndUserIdAndStatus(qualification.getCompetitionId(),
                 qualification.getUserId(), qualification.getStatus());
+        //System.out.println(qualification1.toString());
         if(qualification1 == null) {
-            return qualificationDao.save(qualification);
+            //修改原有数据
+
+            //插入新数据
+            qualification1 = new Qualification();
+            qualification1.setCompetitionId(qualification.getCompetitionId());
+            qualification1.setNextRound(qualification.getNextRound());
+            qualification1.setStatus(qualification.getStatus());
+            qualification1.setUserId(qualification.getUserId());
+            return qualificationDao.save(qualification1);
         }
         return qualification1;
     }
-
     @Override
     public List<Qualification> getQualificationByCompetitionIdAndIndex(Long competitionId, Integer status) {
         return qualificationDao.findByCompetitionIdAndStatus(competitionId, status);

+ 136 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/Entity2TagServiceImpl.java

@@ -0,0 +1,136 @@
+package cn.iselab.mooctest.site.service.impl;
+
+import cn.iselab.mooctest.site.common.enums.EntityType;
+import cn.iselab.mooctest.site.common.enums.TagType;
+import cn.iselab.mooctest.site.dao.CaseExtendsDao;
+import cn.iselab.mooctest.site.dao.Entity2TagDao;
+import cn.iselab.mooctest.site.dao.TagDao;
+import cn.iselab.mooctest.site.dao.TargetDao;
+import cn.iselab.mooctest.site.models.Entity2Tag;
+import cn.iselab.mooctest.site.models.Tag;
+import cn.iselab.mooctest.site.service.Entity2TagService;
+import cn.iselab.mooctest.site.service.TagService;
+import cn.iselab.mooctest.site.web.exception.ServerException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * Created on 2018/12/13
+ */
+@Service
+public class Entity2TagServiceImpl implements Entity2TagService{
+
+    @Autowired
+    CaseExtendsDao caseExtendsDao;
+    @Autowired
+    TargetDao targetDao;
+    @Autowired
+    TagDao tagDao;
+    @Autowired
+    Entity2TagDao entity2TagDao;
+    @Autowired
+    TagService tagService;
+
+    @Override
+    public void indexTag(long entityId, EntityType type, List<Integer> tagIds, List<String>
+            labels) {
+        //validate
+        if(type == null){
+            throw new ServerException(30000,"实体类型不能为null!");
+        }
+        if(!isEntityExist(entityId,type)){
+            throw new ServerException(3000,"类型 "+type.getTypeName()+" 实体 "+entityId+" 不存在!");
+        }
+        //delete old tags and labels
+        entity2TagDao.deleteByEntityIdAndEntityType(entityId,type.getTypeNumber());
+
+        //save tags
+        if(!CollectionUtils.isEmpty(tagIds)){
+            for(int id: tagIds) {
+                if(tagDao.findOne(id) == null){
+                    throw new ServerException(30000,"tag "+id+" 不存在!");
+                }
+                Entity2Tag entity2Tag = new Entity2Tag();
+                entity2Tag.setEntityId(entityId);
+                entity2Tag.setEntityType(type.getTypeNumber());
+                entity2Tag.setTagType(TagType.TAG.getValue());
+                entity2Tag.setTagId(id);
+                List<Tag> pathTags = tagService.getFullPathTagBySon(id);
+                List<String> pathStrs = pathTags.stream().map(Tag::getName).collect(Collectors.toList());
+                entity2Tag.setTagName(StringUtils.join(pathStrs.toArray(),","));
+                entity2TagDao.save(entity2Tag);
+            }
+        }
+
+        //save labels
+        if(!CollectionUtils.isEmpty(labels)){
+            labels.forEach(label -> {
+                Entity2Tag entity2Tag = new Entity2Tag();
+                entity2Tag.setEntityId(entityId);
+                entity2Tag.setEntityType(type.getTypeNumber());
+                entity2Tag.setTagType(TagType.LABEL.getValue());
+                entity2Tag.setTagName(label);
+                entity2TagDao.save(entity2Tag);
+            });
+        }
+
+    }
+
+    @Override
+    public List<Integer> getTagsByEntityIdAndType(long entityId, EntityType entityType) {
+        if(!isEntityExist(entityId,entityType)){
+            throw new ServerException(3000,"类型 "+entityType.getTypeName()+" 实体 "+entityId+" 不存在!");
+        }
+        List<Entity2Tag> entity2Tags = entity2TagDao.findByEntityIdAndEntityTypeAndTagType
+                (entityId,entityType.getTypeNumber(),TagType.TAG.getValue());
+        return entity2Tags.stream().map(Entity2Tag::getTagId).collect(
+                Collectors.toList());
+    }
+
+    @Override
+    public List<String> getLabelsByEntityIdAndType(long entityId, EntityType entityType) {
+        if(!isEntityExist(entityId,entityType)){
+            throw new ServerException(3000,"类型 "+entityType.getTypeName()+" 实体 "+entityId+" 不存在!");
+        }
+        List<Entity2Tag> entity2Tags = entity2TagDao.findByEntityIdAndEntityTypeAndTagType
+                (entityId,entityType.getTypeNumber(),TagType.LABEL.getValue());
+        return entity2Tags.stream().map(Entity2Tag::getTagName).collect(Collectors.toList());
+    }
+
+    @Override
+    public List<Long> queryByNameLike(String name, EntityType type) {
+        List<Entity2Tag> entity2Tags = entity2TagDao.findByTagNameLikeAndEntityType
+                ("%"+name+"%", type.getTypeNumber());
+        return entity2Tags.stream().map(Entity2Tag::getEntityId).collect(Collectors.toList());
+
+    }
+
+    @Override
+    public List<Long> getEntitiesByTagId(int tagId, EntityType type) {
+        List<Tag> tags = tagService.getAllSubTags(tagId);
+        List<Entity2Tag> entity2TagList = new ArrayList<>();
+        tags.forEach(tag -> entity2TagList.addAll(entity2TagDao.findByTagIdAndEntityType(tag.getId()
+                ,type.getTypeNumber())));
+        return entity2TagList.stream().map(Entity2Tag::getEntityId).collect(Collectors.toList());
+    }
+
+
+    private boolean isEntityExist(long entityId, EntityType type){
+        switch (type){
+            case Case:
+                return caseExtendsDao.findOne(entityId)!=null;
+            case Target:
+                return targetDao.findOne(entityId)!=null;
+        }
+
+        return false;
+    }
+
+
+
+}

+ 23 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/ExamServiceImpl.java

@@ -6,6 +6,7 @@ import cn.iselab.mooctest.site.models.*;
 import cn.iselab.mooctest.site.service.BaseService;
 import cn.iselab.mooctest.site.service.ExamService;
 import cn.iselab.mooctest.site.util.data.Converter;
+import cn.iselab.mooctest.site.web.exception.HttpBadRequestException;
 import com.google.common.collect.Lists;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.shiro.authz.UnauthenticatedException;
@@ -44,6 +45,8 @@ public class ExamServiceImpl extends BaseService implements ExamService {
     private Paper2CaseDao paper2CaseDao;
     @Autowired
     private WeightDao weightDao;
+    @Autowired
+    private SubmitRecordDao submitRecordDao;
 
     @Autowired
     private SearchListComponent searchListComponent;
@@ -138,6 +141,9 @@ public class ExamServiceImpl extends BaseService implements ExamService {
             public Predicate toPredicate(Root<Exam> a, CriteriaQuery<?> q, CriteriaBuilder cb) {
                 Predicate predicate = cb.conjunction();
                 Join<Exam, Group> t2g = a.join(a.getModel().getSet("groupSet", Group.class), JoinType.LEFT);
+                predicate.getExpressions().add(
+                        cb.equal(a.<Long>get("isDeleted"), 0)
+                );
                 if (ownerId != null) {
                     predicate.getExpressions().add(
                             cb.equal(a.<Long>get("ownerId"), ownerId)
@@ -236,4 +242,21 @@ public class ExamServiceImpl extends BaseService implements ExamService {
         boolean isTaskTimeEnd = System.currentTimeMillis() > exam.getEndTime().getTime();
         return isTaskTimeEnd;
     }
+
+    @Override
+    public boolean canBeDeleted(Long examId) {
+        //check submit
+        List<SubmitRecord> submitRecords = submitRecordDao.findByExamId(examId);
+        return submitRecords == null || submitRecords.size() == 0;
+    }
+
+    @Override
+    public Exam deleteExamById(Long examId) {
+        Exam examToBeDeleted = examDao.findOne(examId);
+        if (examToBeDeleted == null){
+            throw new HttpBadRequestException(String.format("Exam[%d] doesn't exist.", examId));
+        }
+        examToBeDeleted.setDeleted(true);
+        return examDao.save(examToBeDeleted);
+    }
 }

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

@@ -1,13 +1,19 @@
 package cn.iselab.mooctest.site.service.impl;
 
+import cn.iselab.mooctest.site.dao.ApplyUploadRecordDao;
 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.ApplyUploadRecord;
 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 +29,18 @@ public class GeneralCalculateScoreServiceImpl implements GeneralCalculateScoreSe
 
   @Autowired
   GradeGeneralDao gradeGeneralDao;
+  @Autowired
+  UploadRecordDao uploadRecordDao;
+  @Autowired
+  ApplyUploadRecordDao applyUploadRecordDao;
   @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 +48,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 +57,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 +68,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 +78,68 @@ 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);
+  }
+
+  @Override
+  public ApplyUploadRecord saveApplyUploadRecord(long workerId, long examId, String ossUrl,
+          String applyTime) {
+    ApplyUploadRecord applyUploadRecord = new ApplyUploadRecord();
+    applyUploadRecord.setWorkerId(workerId);
+    applyUploadRecord.setExamId(examId);
+    applyUploadRecord.setOssUrl(ossUrl);
+    applyUploadRecord.setApplyTime(applyTime);
+    return applyUploadRecordDao.save(applyUploadRecord);
+  }
+
+  @Override
+  public ApplyUploadRecord getLatestApplyUploadRecord(long workerId, long examId) {
+    return applyUploadRecordDao.findTopByWorkerIdAndExamIdOrderByIdDesc(workerId, examId);
+  }
+
+  @Override
+  public ApplyUploadRecord getApplyUploadRecordById(long id) {
+    return applyUploadRecordDao.findOne(id);
   }
 
 

+ 8 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/SearchListComponent.java

@@ -17,7 +17,14 @@ public class SearchListComponent {
                     String> extraCondition, String keyword) {
         return (root, query, builder) -> {
             Predicate predicate = builder.conjunction();
-
+            try{
+                model.getDeclaredField("isDeleted");
+                predicate.getExpressions().add(
+                        builder.equal(root.<Long>get("isDeleted"), 0)
+                );
+            } catch (NoSuchFieldException e) {
+                //do nothing
+            }
             if (userId != null) {
                 predicate.getExpressions().add(
                         builder.equal(root.<Long>get(joinedColumn), userId)

+ 57 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/TagServiceImpl.java

@@ -0,0 +1,57 @@
+package cn.iselab.mooctest.site.service.impl;
+
+import cn.iselab.mooctest.site.dao.TagDao;
+import cn.iselab.mooctest.site.models.Tag;
+import cn.iselab.mooctest.site.service.TagService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import java.util.*;
+import org.springframework.util.CollectionUtils;
+
+@Service
+public class TagServiceImpl implements TagService{
+
+    @Autowired
+    private TagDao tagDao;
+
+    @Override
+    public List<Tag> getDirectSubTagsByParent(int tagId) {
+        return tagDao.findByParentId(tagId);
+    }
+
+    @Override
+    public List<Tag> getAllParentTags() {
+        return tagDao.findByParentIdIsNull();
+    }
+
+    @Override
+    public Tag getTagById(int tagId) {
+        return tagDao.findOne(tagId);
+    }
+
+    @Override
+    public List<Tag> getFullPathTagBySon(int sonId) {
+        List<Tag> paths = new ArrayList<>();
+        Tag sonTag = tagDao.findById(sonId);
+        paths.add(sonTag);
+        while(sonTag.getParentId()!=null){
+            sonTag = tagDao.findById(sonTag.getParentId());
+            paths.add(sonTag);
+        }
+        Collections.reverse(paths);
+        return paths;
+    }
+
+    @Override
+    public List<Tag> getAllSubTags(int tagId) {
+        List<Tag> subTags = tagDao.findByParentId(tagId);
+        List<Tag> resultTags = new ArrayList<>();
+        if(!CollectionUtils.isEmpty(subTags)){
+            resultTags.addAll(subTags);
+            subTags.forEach(tag -> resultTags.addAll(getAllSubTags(tag.getId())));
+        }
+
+        return resultTags;
+    }
+
+}

+ 18 - 22
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/instancePermission/impl/ExamPermissionServiceImpl.java

@@ -1,12 +1,12 @@
 package cn.iselab.mooctest.site.service.instancePermission.impl;
 
 import cn.iselab.mooctest.site.configure.realm.ShiroAuthorizationHelper;
-import cn.iselab.mooctest.site.dao.ExamDao;
-import cn.iselab.mooctest.site.dao.Group2WorkerDao;
-import cn.iselab.mooctest.site.dao.instancePermission.GroupPermissionDao;
 import cn.iselab.mooctest.site.dao.instancePermission.ExamPermissionDao;
+import cn.iselab.mooctest.site.models.User2Role;
 import cn.iselab.mooctest.site.models.instancePermission.ExamPermission;
 import cn.iselab.mooctest.site.service.BaseService;
+import cn.iselab.mooctest.site.service.RoleService;
+import cn.iselab.mooctest.site.service.User2RoleService;
 import cn.iselab.mooctest.site.service.instancePermission.ExamPermissionService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -26,13 +26,7 @@ public class ExamPermissionServiceImpl extends BaseService implements ExamPermis
     private ExamPermissionDao examPermissionDao;
 
     @Autowired
-    private GroupPermissionDao groupPermissionDao;
-
-    @Autowired
-    private Group2WorkerDao group2WorkerDao;
-
-    @Autowired
-    private ExamDao examDao;
+    private User2RoleService user2RoleService;
 
     @Override
     public List<ExamPermission> getTaskPermissionsByuserId(Long userId) {
@@ -80,18 +74,20 @@ public class ExamPermissionServiceImpl extends BaseService implements ExamPermis
 
     @Override
     public void grantViewPermission(Long userId, List<Long> examIds) {
-        List<ExamPermission> permissions = new ArrayList<>();
-        examIds.stream().forEach(instanceId->{
-            if(examPermissionDao.findByUserIdAndOperationAndInstanceId(userId,"view",instanceId).size()==0){
-                ExamPermission examPermission = new ExamPermission();
-                examPermission.setUserId(userId);
-                examPermission.setInstanceId(instanceId);
-                examPermission.setOperation("view");
-                examPermission.setCreateTime(new Timestamp(System.currentTimeMillis()));
-                permissions.add(examPermission);
-            }
-        });
-        examPermissionDao.save(permissions);
+        if(user2RoleService.checkManagerRole(userId)){
+            List<ExamPermission> permissions = new ArrayList<>();
+            examIds.stream().forEach(instanceId->{
+                if(examPermissionDao.findByUserIdAndOperationAndInstanceId(userId,"view",instanceId).size()==0){
+                    ExamPermission examPermission = new ExamPermission();
+                    examPermission.setUserId(userId);
+                    examPermission.setInstanceId(instanceId);
+                    examPermission.setOperation("view");
+                    examPermission.setCreateTime(new Timestamp(System.currentTimeMillis()));
+                    permissions.add(examPermission);
+                }
+            });
+            examPermissionDao.save(permissions);
+        }
     }
 
     @Override

+ 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

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

@@ -4,7 +4,6 @@ import cn.iselab.mooctest.site.service.CaseGraphService;
 import cn.iselab.mooctest.site.web.data.forMongo.CaseGraphDTO;
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import javax.annotation.PostConstruct;
@@ -13,7 +12,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 /**
- * Created on 2018/10/18
+ * Created on 2018/10/19
  */
 @Component
 public class CacheUtil {
@@ -46,8 +45,4 @@ public class CacheUtil {
     public void removeMetaNodeAll(){
         metaNodeCache.invalidateAll();
     }
-
-
-
-
 }

+ 0 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/SessionCounter.java

@@ -12,7 +12,6 @@ import java.util.Date;
 /**
  * Created by tangshanshan on 2018/1/4.
  */
-@WebListener
 public class SessionCounter  implements HttpSessionListener {
 
     protected final Logger LOG = LoggerFactory.getLogger(getClass());

+ 1 - 4
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/CompetitionController.java

@@ -48,10 +48,7 @@ public class CompetitionController {
     public List<AddonsVO> updateAddons(@PathVariable("qualificationId") Long qualificationId,
                                        @PathVariable("type") Integer type,
                                        @RequestBody List<AddonsVO> addonsVOList) {
-        Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute("userId");
-        if(addonsVOList.size()>3){
-            throw new IllegalArgumentException("list size > 3");
-        }
+        //TODO 校验addonsVOList的大小是否超过上限
         for(int i=0;i<addonsVOList.size();i++){
             if(!addonsVOList.get(i).getAddonsType().equals(type)
                     || !addonsVOList.get(i).getQualificationId().equals(qualificationId)){

+ 21 - 4
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ExamController.java

@@ -384,7 +384,9 @@ public class ExamController extends BaseSearchController {
         public boolean starCase(@RequestParam("caseId") long caseId, @RequestParam("examId") long
                 examId){
             Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute("userId");
-            if(userId == null) throw new HttpBadRequestException("登陆后进行收藏操作");
+            if(userId == null) {
+                throw new HttpBadRequestException("登陆后进行收藏操作");
+            }
         return starCaseLogic.star(userId,caseId,examId);
     }
 
@@ -392,7 +394,9 @@ public class ExamController extends BaseSearchController {
             method=RequestMethod.POST)
     public boolean unStarCase(@PathVariable("caseId") long caseId){
         Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute("userId");
-        if(userId == null) throw new HttpBadRequestException("登陆后进行取消收藏操作");
+        if(userId == null) {
+            throw new HttpBadRequestException("登陆后进行取消收藏操作");
+        }
         return starCaseLogic.unStar(userId,caseId);
     }
 
@@ -400,7 +404,9 @@ public class ExamController extends BaseSearchController {
             method=RequestMethod.GET)
     public Page<ExercisePythonCommunityVO> getStarCases(@PathVariable("activePage") int activePage){
         Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute("userId");
-        if(userId == null) throw new HttpBadRequestException("登陆后查看更多信息");
+        if(userId == null) {
+            throw new HttpBadRequestException("登陆后查看更多信息");
+        }
         return starCaseLogic.getStarList(userId,activePage);
     }
 
@@ -411,6 +417,17 @@ public class ExamController extends BaseSearchController {
         return examLogic.getRecommendExerciseCases(userId);
     }
 
-
+    @RequestMapping(value = UrlConstants.API + "exam/{examId}", method = RequestMethod.DELETE)
+    public ExamVO deleteExamById(@PathVariable("examId") Long examId){
+        Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute("userId");
+        String permissionStr = userId + ":task:delete:" + examId;
+        boolean havePermissionToDelete = SecurityUtils.getSubject().isPermitted(new ExamPermission(permissionStr));
+        boolean isAdmin = SecurityUtils.getSubject().hasRole("admin");
+        if (havePermissionToDelete || isAdmin) {
+            return examLogic.deleteExamById(examId);
+        }else {
+            throw new UnauthenticatedException("Operation forbidden!");
+        }
+    }
 
 }

+ 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")

+ 25 - 10
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/OnlineJudgeController.java

@@ -39,6 +39,17 @@ public class OnlineJudgeController {
         }
     }
 
+    @RequestMapping(value = "custom/run")
+    public String customRun(@RequestBody OnlineJudgeVO onlineJudgeVO ) {
+        log.info("输入参数:{}", onlineJudgeVO.toString());
+        onlineJudgeVO.setMode(OnlineJudgeMode.CUSTOMRUN);
+        return onlineJudgeLogic.postAnOnlineJudgeSubmission(onlineJudgeVO);
+    }
+
+    @RequestMapping(value = "custom/check",method = RequestMethod.GET)
+    public OnlineJudgeCustomResultVO getCustomResult(@RequestParam("submissionId")String submissionId){
+        return onlineJudgeLogic.checkCustomSubmissionById(submissionId);
+    }
     @RequestMapping(value = "check", method = RequestMethod.GET)
     public OnlineJudgeResultVO getResult(@RequestParam("submissionId")String submissionId) {
         return onlineJudgeLogic.checkSubmissionById(submissionId);
@@ -71,26 +82,30 @@ public class OnlineJudgeController {
     //@RequiresRoles(value = {"manager","admin"})
     @RequestMapping(value = "u/execute",method = RequestMethod.POST)
     public String runWithInput(@RequestBody OnlineJudgeVO onlineJudgeVO) {
-        Long userId = (Long)SecurityUtils.getSubject().getSession().getAttribute("userId");
-        if(userId == null) throw new HttpBadRequestException("请登录后操作~");
-        log.info("user:[{}],params:[{}]",userId,onlineJudgeVO);
-
-        onlineJudgeVO.setUserId(userId);
+        userIdMustNotNull(onlineJudgeVO);
         onlineJudgeVO.setMode(OnlineJudgeMode.RUN_WITH_INPUT);
 
         return onlineJudgeLogic.postAnOnlineJudgeSubmission(onlineJudgeVO);
     }
 
     //@RequiresRoles(value = {"manager","admin"})
+
     @RequestMapping(value = "u/pexecute",method = RequestMethod.POST)
     public String runWithManyInput(@RequestBody OnlineJudgeVO onlineJudgeVO) {
-        Long userId = (Long)SecurityUtils.getSubject().getSession().getAttribute("userId");
-        if(userId == null) throw new HttpBadRequestException("请登录后操作~");
-        log.info("user:[{}],params:[{}]",userId,onlineJudgeVO);
-
-        onlineJudgeVO.setUserId(userId);
+        userIdMustNotNull(onlineJudgeVO);
         onlineJudgeVO.setMode(OnlineJudgeMode.RUN_WITH_MANY_INPUT);
 
         return onlineJudgeLogic.postAnOnlineJudgeSubmission(onlineJudgeVO);
     }
+
+    /**
+     * 判断是否可以从shiro中取到userId
+     * @param onlineJudgeVO 参数
+     */
+    private void userIdMustNotNull(@RequestBody OnlineJudgeVO onlineJudgeVO) {
+        Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute("userId");
+        if(userId == null) throw new HttpBadRequestException("请登录后操作~");
+        log.info("user:[{}],params:[{}]",userId,onlineJudgeVO);
+        onlineJudgeVO.setUserId(userId);
+    }
 }

+ 63 - 24
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ScoreController.java

@@ -5,16 +5,24 @@ import cn.iselab.mooctest.site.common.enums.CompeteAnalysisType;
 import cn.iselab.mooctest.site.common.enums.SortOrder;
 import cn.iselab.mooctest.site.data.PageData;
 import cn.iselab.mooctest.site.data.Sort;
+import cn.iselab.mooctest.site.models.ApplyUploadRecord;
+import cn.iselab.mooctest.site.models.Exam;
 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.exception.ServerException;
 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 lombok.extern.slf4j.Slf4j;
 import org.apache.shiro.authz.annotation.RequiresRoles;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -28,7 +36,6 @@ import java.util.Map;
  * Created by HenryLee on 2017/7/10.
  */
 @RestController
-@Slf4j
 public class ScoreController extends BaseController {
 
     @Autowired
@@ -43,6 +50,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 {
@@ -74,6 +84,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,
@@ -84,32 +95,61 @@ public class ScoreController extends BaseController {
     }
 
     //提交node&算分接口
-    @RequestMapping(value = UrlConstants.API_COMMON + "generalCaughtNode/{examId}/{caseId}/{userId}/{uploadTime}", method = RequestMethod.PUT)
-    public void generalCatchNode(@PathVariable("examId") Long examId,
-                                  @PathVariable("caseId") Long caseId,
-                                  @PathVariable("userId") Long userId,
+    @RequestMapping(value = UrlConstants.API_COMMON +
+            "generalCaughtNode/{caseId}/{uploadTime}/{uploadId}", method =
+            RequestMethod.PUT)
+    public ResponseVO generalCatchNode(@PathVariable("caseId") long caseId,
                                   @PathVariable("uploadTime") String uploadTime,
+                                  @PathVariable("uploadId") long uploadId,
                                   @RequestBody List<CaughtNodeDTO> caughtNodeDTOs) throws Exception {
-        log.info(String.format("generalCaughtNode-接口开始--examId:%s,caseId:%s,userId:%s-------------------",examId,caseId,userId));
-        long startTime = System.currentTimeMillis();
-        calculateSocreLogic.recordNode(examId, caseId, userId, uploadTime, null, caughtNodeDTOs);
-        log.info(String.format("generalCaughtNode-接口结束--examId:%s,caseId:%s,userId:%s,time: [%s] ms-------------------"
-                ,examId,caseId,userId,startTime-System.currentTimeMillis()));
+        return generalCatchNode(caseId,uploadTime,uploadId,null,caughtNodeDTOs);
     }
 
     @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 {
-        log.info(String.format("generalUploadCaughtNode-1-接口开始--examId:%s,caseId:%s,userId:%s-------------------",examId,caseId,userId));
-        long startTime = System.currentTimeMillis();
-        calculateSocreLogic.recordNode(examId, caseId, userId, uploadTime, source, caughtNodeDTOs);
-        log.info(String.format("generalUploadCaughtNode-1-接口结束--examId:%s,caseId:%s,userId:%s,time: [%s] ms-------------------"
-                ,examId,caseId,userId,startTime-System.currentTimeMillis()));
+            "generalUploadCaughtNode/{caseId}/{uploadTime}/{uploadId}/{source}", method =
+            RequestMethod.PUT)
+    public ResponseVO generalCatchNode(
+            @PathVariable("caseId") long caseId,
+            @PathVariable("uploadTime") String uploadTime,
+            @PathVariable("uploadId") long uploadId,
+            @PathVariable("source") String source,
+            @RequestBody List<CaughtNodeDTO> caughtNodeDTOs) throws Exception {
+
+        ApplyUploadRecord applyUploadRecord = generalCalculateScoreLogic
+                .getApplyUploadRecord(uploadId);
+        if(applyUploadRecord == null){
+            return new ResponseVO(ServerCode.NO_APPLY_FOUND);
+        }
+
+        ExamVO exam = examLogic.getExamById(applyUploadRecord.getExamId());
+        long endTime = exam.getEndTime();
+        long applyTime = Long.parseLong(applyUploadRecord.getApplyTime());
+        if(applyTime > endTime){
+            return new ResponseVO(ServerCode.EXAM_ENDED);
+        }
+        calculateSocreLogic.recordNode(
+                applyUploadRecord.getExamId(),
+                caseId,
+                applyUploadRecord.getWorkerId(),
+                uploadTime,
+                source,
+                caughtNodeDTOs,applyUploadRecord.getOssUrl());
+        return new ResponseVO(ServerCode.SUCCESS);
+
+    }
+
+    @RequestMapping(value = UrlConstants.API_COMMON +
+            "generalUploadCaughtNode", method = RequestMethod.PUT)
+    public ResponseVO generalCatchNode(@RequestBody UploadCaughtNodeJson uploadCaughtNodeJson)
+            throws Exception {
+
+        return generalCatchNode(
+                uploadCaughtNodeJson.getCaseId(),
+                uploadCaughtNodeJson.getUploadTime(),
+                uploadCaughtNodeJson.getUploadId(),
+                uploadCaughtNodeJson.getSource(),
+                uploadCaughtNodeJson.getCaughtNodeDTOs()
+                );
 
     }
 
@@ -178,7 +218,6 @@ public class ScoreController extends BaseController {
         generalCalculateScoreLogic.expireMetaNodeAll();
     }
 
-
     @RequiresRoles("manager")
     @RequestMapping(value = UrlConstants.API + "competeAnalysis", method = RequestMethod.GET)
     public List<AssignedTaskVO> competeAnalysis(@RequestParam(value = "examId") Long examId) {

+ 67 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/TagController.java

@@ -0,0 +1,67 @@
+package cn.iselab.mooctest.site.web.ctrl;
+
+import cn.iselab.mooctest.site.common.constant.UrlConstants;
+import cn.iselab.mooctest.site.common.enums.EntityType;
+import cn.iselab.mooctest.site.web.data.Entity2TagVO;
+import cn.iselab.mooctest.site.web.data.TagVO;
+import cn.iselab.mooctest.site.web.data.json.Entity2TagJson;
+import cn.iselab.mooctest.site.web.data.response.ResponseVO;
+import cn.iselab.mooctest.site.web.data.response.ServerCode;
+import cn.iselab.mooctest.site.web.exception.ServerException;
+import cn.iselab.mooctest.site.web.logic.TagLogic;
+import java.util.List;
+import org.apache.shiro.authz.annotation.RequiresRoles;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Created on 2018/10/24
+ */
+@RestController
+public class TagController {
+
+    @Autowired
+    TagLogic tagLogic;
+
+    @RequestMapping(value = UrlConstants.API_COMMON+"tags", method = RequestMethod.GET)
+    public ResponseVO<List<TagVO>> getFirstLevelTags(){
+        return new ResponseVO<>(ServerCode.SUCCESS,tagLogic.getFirstLevelTags());
+    }
+
+    @RequiresRoles(value = "manager")
+    @RequestMapping(value = UrlConstants.API_COMMON+"tag/add", method = RequestMethod.PUT)
+    public ResponseVO addTag2Entity(@RequestBody Entity2TagJson entity2TagJson){
+        try{
+            tagLogic.indexTag(entity2TagJson.getEntityId(),entity2TagJson.getType(),
+                    entity2TagJson.getTagIds(),entity2TagJson.getLabels());
+        }catch (ServerException e){
+            return new ResponseVO(e);
+        }
+
+        return new ResponseVO(ServerCode.SUCCESS);
+    }
+
+    @RequestMapping(value = UrlConstants.API_COMMON+"getEntityTags", method = RequestMethod.GET)
+    public ResponseVO<Entity2TagVO> getEntityTags(@RequestParam long entityId, @RequestParam
+            String entityType){
+        try{
+            Entity2TagVO entity2TagVO = tagLogic.getTagsByEntity(
+                    entityId, EntityType.getByTypeName(entityType));
+            return new ResponseVO<>(ServerCode.SUCCESS,entity2TagVO);
+        }catch (ServerException e){
+            return new ResponseVO(e,null);
+        }
+    }
+
+    @RequestMapping(value = UrlConstants.API_COMMON+"getEntitiesByTagId", method = RequestMethod
+            .GET)
+    public ResponseVO<List<Long>> getEntitiesByTagId(@RequestParam int tagId, @RequestParam String
+            entityType){
+        return new ResponseVO<>(ServerCode.SUCCESS,tagLogic.getEntitiesByTagId(tagId, EntityType
+                .getByTypeName(entityType)));
+    }
+}

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

@@ -18,6 +18,7 @@ import cn.iselab.mooctest.site.web.logic.ManagerPropertyLogic;
 import cn.iselab.mooctest.site.web.logic.MenuLogic;
 import cn.iselab.mooctest.site.web.logic.UserLogic;
 import cn.iselab.mooctest.site.util.data.Converter;
+import com.google.common.base.Objects;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authc.AccountException;
 import org.apache.shiro.authz.annotation.Logical;
@@ -178,7 +179,8 @@ public class UserController {
             if (userVO.getMobile() != null) {
                 userVO = userLogic.findUserByMobile(userVO.getMobile());
             }
-            if (userVO.getAvailability() != 1) {
+            //if (userVO.getAvailability() != 1) {
+            if(!Objects.equal(userVO.getAvailability(),1)) {
                 throw new AccountException("user unavailable");
             }
             //如果存在userId但不存在roleId说明是校园版来的账号,对其进行适配企业版的设置
@@ -238,7 +240,7 @@ public class UserController {
         for (Field field : fields) {
             field.setAccessible(true);
             if (field.get(UserVO) != null) {
-                condition.put(field.getName(), (String) field.get(UserVO));
+                condition.put(field.getName(), String.valueOf(field.get(UserVO)) );
             }
         }
         Page<UserVO> userVOPage = userLogic.getUserListOfFuzzySearch(condition, new PageRequest(activePage - 1, rowsOnPage, sort));
@@ -359,4 +361,6 @@ public class UserController {
     public UserVO createUserByAdmin(@RequestBody UserVO userVO) {
         return userLogic.register(userVO);
     }
+
+
 }

+ 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,

+ 21 - 5
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/fromDev/PluginController.java

@@ -1,6 +1,12 @@
 package cn.iselab.mooctest.site.web.ctrl.fromDev;
 
 import cn.iselab.mooctest.site.common.constant.UrlConstants;
+import cn.iselab.mooctest.site.service.enums.ExamStatus;
+import cn.iselab.mooctest.site.web.data.ApplySignatureVO;
+import cn.iselab.mooctest.site.web.data.ExamVO;
+import cn.iselab.mooctest.site.web.data.response.ResponseVO;
+import cn.iselab.mooctest.site.web.data.response.ServerCode;
+import cn.iselab.mooctest.site.web.exception.ServerException;
 import cn.iselab.mooctest.site.web.response.ResponseMessage;
 import cn.iselab.mooctest.site.web.response.SuccessResult;
 import cn.iselab.mooctest.site.util.data.EncryptionUtil;
@@ -65,23 +71,33 @@ public class PluginController extends BaseController{
     }
 
     @RequestMapping(value =UrlConstants.API_DEV + "plugin/submitAnswersSig", method = RequestMethod.GET)
-    public String getSubmitAnswersSignature(HttpServletRequest request) {
+    public ResponseVO<ApplySignatureVO> getSubmitAnswersSignature(HttpServletRequest request) {
         String taskID = request.getParameter("taskID"),
                 workerID = request.getParameter("workerID"),
                 caseName = request.getParameter("caseName");
-        String signature = upDownloadLogic.getSubmitAnswersSignature(taskID, workerID, caseName);
-        if (signature == null) {
-            return StResponse.failure("签名未能生成");
+
+        ExamVO examVO = examLogic.getExamById(Long.parseLong(taskID));
+        if(examVO.getStatus() == ExamStatus.ENDED.getValue()){
+            return new ResponseVO<>(ServerCode.EXAM_ENDED);
+        }
+
+        ApplySignatureVO applySignatureVO = upDownloadLogic.getAndRecordSubmitAnswersSignature(taskID,workerID,
+                caseName);
+        if (applySignatureVO == null || applySignatureVO.getSignature()==null || applySignatureVO
+                .getUploadId() == null) {
+            return new ResponseVO<>(ServerCode.SYSTEM_ERROR);
         } else {
-            return StResponse.success(signature);
+            return new ResponseVO<>(ServerCode.SUCCESS,applySignatureVO);
         }
     }
 
     @RequestMapping(value = UrlConstants.API_DEV+"plugin/downloadAnswer",method = RequestMethod.GET)
     public String getDownloadAnswerUrl(HttpServletRequest request) {
+
         String taskID = request.getParameter("taskID"),
                 workerID = request.getParameter("workerID"),
                 caseName = request.getParameter("caseName");
+
         String url = pluginLogic.getAnalysisSignature(Long.parseLong(taskID),Long.parseLong(workerID),caseName);
         if (url == null) {
             return StResponse.failure("下载url未能生成");

+ 16 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/ApplySignatureVO.java

@@ -0,0 +1,16 @@
+package cn.iselab.mooctest.site.web.data;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Created on 2018/12/7
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ApplySignatureVO {
+    private String signature;
+    private Long uploadId;
+}

+ 3 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/CompetitionVO.java

@@ -20,6 +20,9 @@ public class CompetitionVO {
     private Long qualificationId;
     private Boolean allowEnter;
     private Integer rankWeight;
+    private Boolean addOnsEditable;
+    private Integer memberLimit;
+    private Integer mentorLimit;
 
     private List<AddonsVO> addonsList;
 

+ 28 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/Entity2TagVO.java

@@ -0,0 +1,28 @@
+package cn.iselab.mooctest.site.web.data;
+
+import cn.iselab.mooctest.site.common.enums.EntityType;
+import java.util.List;
+import java.util.Map;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Created on 2018/12/17
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class Entity2TagVO {
+
+    private long entityId;
+    private int entityType;
+    private List<List<TagPathVO>> pathTags;
+    private List<String> labels;
+
+    public void setEntityType(EntityType type){
+        this.entityType = type.getTypeNumber();
+    }
+
+
+}

+ 10 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/ExamVO.java

@@ -31,6 +31,16 @@ public class ExamVO {
     private Integer index;
     private Integer nextIndex;
     private String nextTaskName;
+    private boolean openRecommend;
+
+    public boolean isOpenRecommend() {
+        return openRecommend;
+    }
+    public void setOpenRecommend(boolean openRecommend) {
+        this.openRecommend = openRecommend;
+    }
+
+
 
     private boolean toPythonCommunity;
 

+ 26 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/OnlineJudgeCustomResultVO.java

@@ -0,0 +1,26 @@
+package cn.iselab.mooctest.site.web.data;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @program: mooctest-site
+ * @mail: menduo96@gmail.com
+ * @author: menduo
+ * @create: 2018-12-24 16:04
+ **/
+@Data
+public class OnlineJudgeCustomResultVO {
+    private String state;
+    private int resultCode;
+    private List<String> myResult;
+    private List<String> standardResult;
+
+    public OnlineJudgeCustomResultVO(){}
+
+    public OnlineJudgeCustomResultVO(String state,int resultCode) {
+        this.state = state;
+        this.resultCode = resultCode;
+    }
+}

+ 16 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/TagPathVO.java

@@ -0,0 +1,16 @@
+package cn.iselab.mooctest.site.web.data;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Created on 2018/12/19
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TagPathVO {
+    int id;
+    String name;
+}

+ 20 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/TagVO.java

@@ -0,0 +1,20 @@
+package cn.iselab.mooctest.site.web.data;
+
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Created on 2018/10/25
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TagVO {
+
+    private int id;
+    private String name;
+    private List<TagVO> subTags;
+
+}

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

@@ -0,0 +1,21 @@
+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 caseId;
+    String uploadTime;
+    String source;
+    Long uploadId;
+    List<CaughtNodeDTO> caughtNodeDTOs;
+}

+ 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;
-    }
-}

+ 25 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/json/Entity2TagJson.java

@@ -0,0 +1,25 @@
+package cn.iselab.mooctest.site.web.data.json;
+
+import cn.iselab.mooctest.site.common.enums.EntityType;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Created on 2018/10/30
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Entity2TagJson {
+    String type;
+    long entityId;
+    List<Integer> tagIds;
+    List<String> labels;
+
+    public EntityType getType(){
+        return EntityType.getByTypeName(type.toLowerCase());
+    }
+
+}

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

@@ -0,0 +1,42 @@
+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) {
+        this.code = e.getErrorCode();
+        this.msg = e.getError();
+    }
+
+    public ResponseVO(ServerException e, T data) {
+        this.code = e.getErrorCode();
+        this.msg = e.getError();
+        this.data = data;
+    }
+
+
+}

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

@@ -0,0 +1,42 @@
+package cn.iselab.mooctest.site.web.data.response;
+
+/**
+ * Created on 2018/10/9
+ */
+public enum ServerCode {
+
+    SUCCESS(20000,"OK"),
+
+    //通用错误状态码,30000-39999
+    PARAM_WRONG(30000,"参数错误"),
+
+    //考试相关状态码: 40000-49999
+    EXAM_ENDED(40000,"考试已结束"),
+
+    //分数相关状态码:50000-59999
+    UPLOAD_RECORD_FAIL(50000,"存储提交记录失败"),
+    NO_APPLY_FOUND(50001,"未找到申请提交记录"),
+
+    //系统错误:60000-69999
+    SYSTEM_ERROR(60000,"系统错误"),
+    DATA_NOT_CONSISTENT(60001,"数据不一致"),
+
+    //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;
+    }
+
+}

+ 2 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/ExamVOWrapper.java

@@ -57,6 +57,7 @@ public class ExamVOWrapper extends BaseWrapper<ExamVO, Exam> {
         vo.setType(exam.getType());
         vo.setStatus(exam.getStatus());
         vo.setOwningParty(exam.getOwningParty());
+        vo.setOpenRecommend(exam.isOpenRecommend());
         List<Group> groupList = groupService.getByExamId(vo.getId());
         wrapGroupInfo(vo, groupList);
         return vo;
@@ -156,6 +157,7 @@ public class ExamVOWrapper extends BaseWrapper<ExamVO, Exam> {
         exam.setType(vo.getType());
         exam.setStatus(vo.getStatus());
         exam.setOwningParty(vo.getOwningParty());
+        exam.setOpenRecommend(vo.isOpenRecommend());
 
         return exam;
     }

+ 37 - 10
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/OnlineJudgeResultVOWrapper.java

@@ -1,9 +1,15 @@
 package cn.iselab.mooctest.site.web.data.wrapper;
 
 import cn.iselab.mooctest.site.data.OnlineJudgeResultDTO;
+import cn.iselab.mooctest.site.web.data.OnlineJudgeCustomResultVO;
 import cn.iselab.mooctest.site.web.data.OnlineJudgeResultVO;
+import cn.iselab.mooctest.site.web.data.OnlineJudgeResultsVO;
+import com.google.common.collect.Lists;
+import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 /**
  * @program: mooctest-site
  * @email: menduo96@gmail.com
@@ -11,16 +17,11 @@ import org.springframework.stereotype.Service;
  * @create: 2018/9/27 下午5:12
  **/
 @Service
-public class OnlineJudgeResultVOWrapper extends BaseWrapper<OnlineJudgeResultVO, OnlineJudgeResultDTO> {
+public class OnlineJudgeResultVOWrapper{
 
-    @Override
     public OnlineJudgeResultVO wrap(OnlineJudgeResultDTO onlineJudgeResultDTO) {
         OnlineJudgeResultVO onlineJudgeResultVO = new OnlineJudgeResultVO ();
-        onlineJudgeResultVO.setState (onlineJudgeResultDTO.getState ());
-        onlineJudgeResultVO.setResultCode (onlineJudgeResultDTO.getResultCode ());
-        onlineJudgeResultVO.setResultMsg (onlineJudgeResultDTO.getResultMsg ());
-        onlineJudgeResultVO.setRightCount (onlineJudgeResultDTO.getRightCount ());
-        onlineJudgeResultVO.setTotalCount (onlineJudgeResultDTO.getTotalCount ());
+        BeanUtils.copyProperties(onlineJudgeResultDTO,onlineJudgeResultVO);
         if (onlineJudgeResultDTO.getExpectOutput () != null && onlineJudgeResultDTO.getExpectOutput ().size () > 0)
             onlineJudgeResultVO.setExpectOutput (onlineJudgeResultDTO.getExpectOutput ().get (0));
         else
@@ -39,8 +40,34 @@ public class OnlineJudgeResultVOWrapper extends BaseWrapper<OnlineJudgeResultVO,
         return onlineJudgeResultVO;
     }
 
-    @Override
-    public OnlineJudgeResultDTO unwrap(OnlineJudgeResultVO data) {
-        return null;
+    public OnlineJudgeResultsVO wrap2ResultsVO(OnlineJudgeResultDTO onlineJudgeResultDTO) {
+        return getOnlineJudgeResultsVO(onlineJudgeResultDTO);
+    }
+
+    public OnlineJudgeCustomResultVO wrap2CustomResultVO(List<OnlineJudgeResultDTO> onlineJudgeResultDTOList){
+        if(onlineJudgeResultDTOList!=null && onlineJudgeResultDTOList.size()<2){
+            return new OnlineJudgeCustomResultVO("failed",-2);
+        }
+        OnlineJudgeCustomResultVO onlineJudgeCustomResultVO = new OnlineJudgeCustomResultVO();
+        List<String> myResultList = Lists.newArrayList();
+        List<String> standardList = Lists.newArrayList();
+        for (int i = 0; i < onlineJudgeResultDTOList.get(0).getRealOutput().size() ; i++) {
+            myResultList.add(onlineJudgeResultDTOList.get(0).getRealOutput().get(i)+onlineJudgeResultDTOList.get(0).getErrorLog().get(i));
+            standardList.add(onlineJudgeResultDTOList.get(1).getRealOutput().get(i)+onlineJudgeResultDTOList.get(1).getErrorLog().get(i));
+        }
+            onlineJudgeCustomResultVO.setMyResult(myResultList);
+            onlineJudgeCustomResultVO.setStandardResult(standardList);
+
+        onlineJudgeCustomResultVO.setState("success");
+        onlineJudgeCustomResultVO.setResultCode(0);
+        return onlineJudgeCustomResultVO;
+
+    }
+
+    static OnlineJudgeResultsVO getOnlineJudgeResultsVO(OnlineJudgeResultDTO onlineJudgeResultDTO) {
+        OnlineJudgeResultsVO onlineJudgeResultsVO = new OnlineJudgeResultsVO ();
+        BeanUtils.copyProperties(onlineJudgeResultDTO,onlineJudgeResultsVO);
+        onlineJudgeResultsVO.generalMatched ();
+        return onlineJudgeResultsVO;
     }
 }

+ 0 - 36
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/OnlineJudgeResultsVOWrapper.java

@@ -1,36 +0,0 @@
-package cn.iselab.mooctest.site.web.data.wrapper;
-
-import cn.iselab.mooctest.site.data.OnlineJudgeResultDTO;
-import cn.iselab.mooctest.site.web.data.OnlineJudgeResultsVO;
-import cn.iselab.mooctest.site.web.data.OnlineJudgeResultsVO;
-import org.springframework.stereotype.Service;
-
-/**
- * @program: mooctest-site
- * @email: menduo96@gmail.com
- * @author: menduo
- * @create: 2018/9/27 下午5:12
- **/
-@Service
-public class OnlineJudgeResultsVOWrapper extends BaseWrapper<OnlineJudgeResultsVO, OnlineJudgeResultDTO> {
-
-    @Override
-    public OnlineJudgeResultsVO wrap(OnlineJudgeResultDTO onlineJudgeResultDTO) {
-        OnlineJudgeResultsVO onlineJudgeResultsVO = new OnlineJudgeResultsVO ();
-        onlineJudgeResultsVO.setState (onlineJudgeResultDTO.getState ());
-        onlineJudgeResultsVO.setResultCode (onlineJudgeResultDTO.getResultCode ());
-        onlineJudgeResultsVO.setResultMsg (onlineJudgeResultDTO.getResultMsg ());
-        onlineJudgeResultsVO.setRightCount (onlineJudgeResultDTO.getRightCount ());
-        onlineJudgeResultsVO.setTotalCount (onlineJudgeResultDTO.getTotalCount ());
-        onlineJudgeResultsVO.setExpectOutput (onlineJudgeResultDTO.getExpectOutput ());
-        onlineJudgeResultsVO.setRealOutput (onlineJudgeResultDTO.getRealOutput ());
-        onlineJudgeResultsVO.setErrorLog (onlineJudgeResultDTO.getErrorLog ());
-        onlineJudgeResultsVO.generalMatched ();
-        return onlineJudgeResultsVO;
-    }
-
-    @Override
-    public OnlineJudgeResultDTO unwrap(OnlineJudgeResultsVO data) {
-        return null;
-    }
-}

+ 44 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/fromDev/TagVOWrapper.java

@@ -0,0 +1,44 @@
+package cn.iselab.mooctest.site.web.data.wrapper.fromDev;
+
+import cn.iselab.mooctest.site.models.Tag;
+import cn.iselab.mooctest.site.service.TagService;
+import cn.iselab.mooctest.site.web.data.TagVO;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * Created on 2018/10/25
+ */
+@Component
+public class TagVOWrapper {
+
+    @Autowired
+    TagService tagService;
+
+    public TagVO wrapTag2VORecurse(Tag tag){
+        if(tag == null){
+            return null;
+        }
+
+        TagVO tagVO = new TagVO();
+        BeanUtils.copyProperties(tag,tagVO,"parentId","subTags");
+
+        List<TagVO> subTagVOs = new ArrayList<>();
+        List<Tag> subTags = tagService.getDirectSubTagsByParent(tagVO.getId());
+        if(!CollectionUtils.isEmpty(subTags)){
+            for(Tag subTag: subTags){
+                TagVO subTagVO = wrapTag2VORecurse(subTag);
+                subTagVOs.add(subTagVO);
+            }
+        }
+        tagVO.setSubTags(subTagVOs);
+
+        return tagVO;
+    }
+
+}

+ 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;
 }

+ 2 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/ExamLogic.java

@@ -71,4 +71,6 @@ public interface ExamLogic {
 
     List<ExercisePythonCommunityVO> getRecommendExerciseCases(Long userId);
 
+    ExamVO deleteExamById(Long examId);
+
 }

+ 6 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/GeneralCalculateScoreLogic.java

@@ -1,5 +1,7 @@
 package cn.iselab.mooctest.site.web.logic;
 
+import cn.iselab.mooctest.site.models.ApplyUploadRecord;
+
 /**
  * general calculate score logic
  *
@@ -56,4 +58,8 @@ public interface GeneralCalculateScoreLogic {
     void expireMetaNode(long caseId);
 
     void expireMetaNodeAll();
+
+    ApplyUploadRecord getLatestApplyUploadRecord(long workerId, long examId);
+
+    ApplyUploadRecord getApplyUploadRecord(long id);
 }

+ 6 - 7
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/OnlineJudgeLogic.java

@@ -1,10 +1,9 @@
 package cn.iselab.mooctest.site.web.logic;
 
 import cn.iselab.mooctest.site.data.OnlineJudgeResultDTO;
-import cn.iselab.mooctest.site.web.data.OnlineJudgeResultVO;
-import cn.iselab.mooctest.site.web.data.OnlineJudgeResultsVO;
-import cn.iselab.mooctest.site.web.data.OnlineJudgeVO;
-import cn.iselab.mooctest.site.web.data.SubmissionResultVO;
+import cn.iselab.mooctest.site.web.data.*;
+
+import java.util.List;
 
 /**
  * @program: mooctest-site
@@ -20,13 +19,13 @@ public interface OnlineJudgeLogic {
 
     OnlineJudgeResultVO checkSubmissionById(String submissionId);
     OnlineJudgeResultsVO pcheckSubmissionById(String submissionId);
-
+    OnlineJudgeCustomResultVO checkCustomSubmissionById(String submissinId);
 
     SubmissionResultVO getLatestAnswersForThisCaseAndExam(long examId,long caseId,long userId);
 
 
-    void setResultDTOToCache(String submissionId, OnlineJudgeResultDTO result);
-    OnlineJudgeResultDTO getResultDTOFromCache(String submissionId);
+    void setResultDTOToCache(String submissionId, List<OnlineJudgeResultDTO> result);
+    List<OnlineJudgeResultDTO> getResultDTOFromCache(String submissionId);
     OnlineJudgeResultDTO generalOnlineJudgeResultDTO(String result);
 
 }

+ 19 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/TagLogic.java

@@ -0,0 +1,19 @@
+package cn.iselab.mooctest.site.web.logic;
+
+import cn.iselab.mooctest.site.common.enums.EntityType;
+import cn.iselab.mooctest.site.models.Tag;
+import cn.iselab.mooctest.site.web.data.Entity2TagVO;
+import cn.iselab.mooctest.site.web.data.TagVO;
+import java.util.List;
+
+public interface TagLogic {
+
+    List<TagVO> getFirstLevelTags();
+
+    void indexTag(long entityId, EntityType type, List<Integer> tagId, List<String> labels);
+
+    Entity2TagVO getTagsByEntity(long entityId, EntityType type);
+
+    List<Long> getEntitiesByTagId(int tagId, EntityType type);
+
+}

+ 0 - 3
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/asyncProgress/OnlineJudgeProcessLogic.java

@@ -12,8 +12,5 @@ import java.util.List;
  **/
 public interface OnlineJudgeProcessLogic {
     void triggerRunOnlineJudge(OnlineJudgeVO onlineJudgeVO, List<String> downloadUrl);
-
     void triggerSubmitOnlineJudge(OnlineJudgeVO onlineJudgeVO, List<String> downloadUrl);
-
-    void triggerExecuteOnlineJudge(OnlineJudgeVO onlineJudgeVO, List<String> downloadUrl);
 }

+ 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());
 

+ 23 - 39
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/asyncProgress/impl/OnlineJudgeProcessLogicImpl.java

@@ -2,11 +2,9 @@ package cn.iselab.mooctest.site.web.logic.asyncProgress.impl;
 
 import cn.iselab.mooctest.site.common.acyncTask.OnlineJudgeAndCulScoreCallBack;
 import cn.iselab.mooctest.site.common.acyncTask.OnlineJudgeCallBack;
-import cn.iselab.mooctest.site.common.acyncTask.OnlineJudgeExecuteCallBack;
 import cn.iselab.mooctest.site.common.enums.AsyncJobTool;
 import cn.iselab.mooctest.site.service.AsyncScheduleService;
 import cn.iselab.mooctest.site.service.AsyncTaskService;
-import cn.iselab.mooctest.site.web.data.OnlineJudgeResultsVO;
 import cn.iselab.mooctest.site.web.data.OnlineJudgeVO;
 import cn.iselab.mooctest.site.web.logic.asyncProgress.OnlineJudgeProcessLogic;
 import com.google.common.collect.Lists;
@@ -45,13 +43,18 @@ public class OnlineJudgeProcessLogicImpl implements OnlineJudgeProcessLogic {
 
 
     @Override
-    public void triggerExecuteOnlineJudge(OnlineJudgeVO onlineJudgeVO, List<String> downloadUrl) {
+    public void triggerSubmitOnlineJudge(OnlineJudgeVO onlineJudgeVO, List<String> downloadUrl) {
         List<Map<String, String>> params = prepareParams(onlineJudgeVO,downloadUrl);
-        List<Map<String,String>> contexts = prepareContexts(onlineJudgeVO);
-        asyncScheduleService.start(AsyncJobTool.ONLINEJUDGE, params, contexts, OnlineJudgeExecuteCallBack.class);
-
+        List<Map<String, String>> contexts = prepareContexts(onlineJudgeVO);
+        asyncScheduleService.start(AsyncJobTool.ONLINEJUDGE, params, contexts, OnlineJudgeAndCulScoreCallBack.class);
     }
 
+    /**
+     * 参数准备
+     * @param onlineJudgeVO 原参数
+     * @param downloadUrl 需要celery去下载的所有数据
+     * @return 参数包装List
+     */
     private List<Map<String,String>> prepareParams(OnlineJudgeVO onlineJudgeVO,List<String> downloadUrl) {
         List<Map<String, String>> params = Lists.newArrayList();
 
@@ -65,36 +68,20 @@ public class OnlineJudgeProcessLogicImpl implements OnlineJudgeProcessLogic {
         return params;
     }
 
+    /**
+     * callback
+     * @param onlineJudgeVO
+     * @return
+     */
     private List<Map<String,String>> prepareContexts(OnlineJudgeVO onlineJudgeVO) {
         List<Map<String, String>> contexts = Lists.newArrayList();
         Map<String, String> context = Maps.newHashMap();
         context.put("submissionId", onlineJudgeVO.getSubmissionId());
-        contexts.add(context);
-        return contexts;
-    }
-
-    @Override
-    public void triggerSubmitOnlineJudge(OnlineJudgeVO onlineJudgeVO, List<String> downloadUrl) {
-        List<Map<String, String>> params = Lists.newArrayList();
-
-        Map<String, String> param = Maps.newHashMap();
-        param.put("downloadURL", jointDownloadUrl(downloadUrl));
-        param.put("extraArgs", generateOnlineJudgeExtraArgs(downloadUrl, onlineJudgeVO.getLang(),onlineJudgeVO.getMode().toString()));
-
-        params.add(param);
-
-
-        List<Map<String, String>> contexts = Lists.newArrayList();
-
-        Map<String, String> context = Maps.newHashMap();
-
-        context.put("submissionId", onlineJudgeVO.getSubmissionId());
         context.put("userId", String.valueOf(onlineJudgeVO.getUserId()));
         context.put("examId", String.valueOf(onlineJudgeVO.getExamId()));
         context.put("caseId", String.valueOf(onlineJudgeVO.getCaseId()));
         contexts.add(context);
-
-        asyncScheduleService.start(AsyncJobTool.ONLINEJUDGE, params, contexts, OnlineJudgeAndCulScoreCallBack.class);
+        return contexts;
     }
 
     /**
@@ -120,26 +107,23 @@ public class OnlineJudgeProcessLogicImpl implements OnlineJudgeProcessLogic {
      * @return 参数字符串
      */
     private String generateOnlineJudgeExtraArgs(List<String> downloadUrls, String lang, String mode) {
-        StringBuilder sb = new StringBuilder();
 
         if (downloadUrls.size() < 1) {
             log.error("downloadUrls的长度小于1,参数错误");
             throw new IllegalArgumentException();
         }
-        String codeUrlInOss = downloadUrls.get(0);
-        //code_submissionId_timestamp.txt
-        String codeFileName = codeUrlInOss.split("/")[codeUrlInOss.split("/").length - 1];
-        sb.append("-c ").append(codeFileName);
 
+        String[] array = {" -l "," -m "," -c "," -d "," -s "};
 
-        if (downloadUrls.size() == 2) {
-            String dataUrlInOss = downloadUrls.get(1);
-            String dataFileName = dataUrlInOss.split("/")[dataUrlInOss.split("/").length - 1];
-            sb.append(" -d ").append(dataFileName);
-        }
-
+        StringBuilder sb = new StringBuilder();
         sb.append(" -l ").append(lang);
         sb.append(" -m ").append(mode);
+        int cont = 2;
+        for (String param: downloadUrls) {
+            sb.append(array[cont]).append(param.split("/")[param.split("/").length - 1]);
+            cont++;
+        }
+        log.info("online judge downloadUrls ===> {}",sb.toString());
         return sb.toString();
     }
 }

+ 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);
-}

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

@@ -1,5 +1,7 @@
 package cn.iselab.mooctest.site.web.logic.fromDev;
 
+import cn.iselab.mooctest.site.web.data.ApplySignatureVO;
+
 /**
  * @Author ROKG
  * @Description
@@ -37,4 +39,14 @@ public interface UpDownloadLogic {
      * @return
      */
     String getSubmitAnswersSignature(String examID, String stuID, String examName);
+
+    /**
+     * 获取上传答案的签名并存储记录
+     *
+     * @param examID
+     * @param stuID
+     * @param examName
+     * @return
+     */
+    ApplySignatureVO getAndRecordSubmitAnswersSignature(String examID, String stuID, String examName);
 }

+ 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;
-        }
-    }
-}

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

@@ -1,8 +1,11 @@
 package cn.iselab.mooctest.site.web.logic.fromDev.impl;
 
+import cn.iselab.mooctest.site.models.ApplyUploadRecord;
 import cn.iselab.mooctest.site.models.CaseExtends;
 import cn.iselab.mooctest.site.service.CaseService;
+import cn.iselab.mooctest.site.service.GeneralCalculateScoreService;
 import cn.iselab.mooctest.site.service.TargetService;
+import cn.iselab.mooctest.site.web.data.ApplySignatureVO;
 import cn.iselab.mooctest.site.web.logic.BaseLogic;
 import cn.iselab.mooctest.site.web.logic.fromDev.UpDownloadLogic;
 import com.aliyun.oss.HttpMethod;
@@ -30,6 +33,8 @@ public class UpDownloadLogicImpl extends BaseLogic implements UpDownloadLogic {
     private CaseService caseService;
     @Autowired
     private TargetService targetService;
+    @Autowired
+    private GeneralCalculateScoreService generalCalculateScoreService;
 
     @Value("${oss.endPoint}")
     private String endPoint;
@@ -132,4 +137,16 @@ public class UpDownloadLogicImpl extends BaseLogic implements UpDownloadLogic {
         client.shutdown();
         return signedUrl.toString();
     }
+
+    @Override
+    public ApplySignatureVO getAndRecordSubmitAnswersSignature(String examID, String stuID, String examName) {
+        String applyTime = System.currentTimeMillis()+"";
+        String signature = this.getSubmitAnswersSignature(examID, stuID, examName);
+        ApplyUploadRecord applyUploadRecord = generalCalculateScoreService.saveApplyUploadRecord(
+                Long.parseLong(stuID),
+                Long.parseLong(examID),
+                signature.split("\\?")[0],
+                applyTime);
+        return new ApplySignatureVO(signature,applyUploadRecord.getId());
+    }
 }

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

@@ -1,9 +1,11 @@
 package cn.iselab.mooctest.site.web.logic.fromDev.impl;
 
+import cn.iselab.mooctest.site.models.ApplyUploadRecord;
 import cn.iselab.mooctest.site.models.Target;
 import cn.iselab.mooctest.site.models.CaseExtends;
 import cn.iselab.mooctest.site.service.*;
 import cn.iselab.mooctest.site.service.fromDev.PluginService;
+import cn.iselab.mooctest.site.web.data.ApplySignatureVO;
 import cn.iselab.mooctest.site.web.logic.fromDev.UpDownloadLogic;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@@ -26,6 +28,8 @@ public class UpDownloadLogicPCImpl implements UpDownloadLogic{
     private CaseService caseService;
     @Autowired
     private TargetService targetService;
+    @Autowired
+    private GeneralCalculateScoreService generalCalculateScoreService;
 
     /**
      * 获取下载文件的签名(私有云)
@@ -73,4 +77,15 @@ public class UpDownloadLogicPCImpl implements UpDownloadLogic{
 
         return path;
     }
+
+    @Override
+    public ApplySignatureVO getAndRecordSubmitAnswersSignature(String examID, String stuID, String examName) {
+        String applyTime = System.currentTimeMillis()+"";
+        String path = getSubmitAnswersSignature(examID, stuID, examName);
+        ApplyUploadRecord applyUploadRecord = generalCalculateScoreService.saveApplyUploadRecord
+                (Long.parseLong
+                (stuID),Long.parseLong
+                (examID),path,applyTime);
+        return new ApplySignatureVO(path,applyUploadRecord.getId());
+    }
 }

+ 44 - 18
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,16 +26,17 @@ 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;
 import org.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.convert.converter.Converter;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 import java.io.IOException;
@@ -94,6 +96,9 @@ public class CalculateScoreLogicImpl extends BaseLogic implements CalculateSocre
     GeneralCalculateScoreComponent generalCalculateScoreComponent;
 
     @Autowired
+    GeneralCalculateScoreService generalCalculateScoreService;
+
+    @Autowired
     NodeOperationComponent nodeOperationComponent;
 
     @Override
@@ -101,8 +106,7 @@ public class CalculateScoreLogicImpl extends BaseLogic implements CalculateSocre
         CaseExtends caseExtends = caseService.getCaseExtendsById(caseId);
         Long subsiteId = caseExtends.getAnswerWay();
         if (subsiteId == AnswerWayConstants.APP_ECLIPSE || subsiteId == AnswerWayConstants.WEB_ECLIPSE || subsiteId == AnswerWayConstants.ZHICEYUN
-                || subsiteId == AnswerWayConstants.THIRD_PARTY || subsiteId == AnswerWayConstants.REPORT || subsiteId == AnswerWayConstants.JMETER
-                || subsiteId == AnswerWayConstants.REPORT_RECOMMEND) {
+                || subsiteId == AnswerWayConstants.THIRD_PARTY || subsiteId == AnswerWayConstants.REPORT || subsiteId == AnswerWayConstants.JMETER) {
             calculateScoreService.calculateManual(taskId, caseId);
             calculateScoreService.calculateScript(taskId, caseId);
             List<ScoreRuleItemVO> scoreRule = scoreRuleService.getKibugScoreRule(taskId, caseId);
@@ -117,8 +121,7 @@ public class CalculateScoreLogicImpl extends BaseLogic implements CalculateSocre
         CaseExtends caseExtends = caseService.getCaseExtendsById(caseId);
         Long subsiteId = caseExtends.getAnswerWay();
         if (subsiteId == AnswerWayConstants.APP_ECLIPSE || subsiteId == AnswerWayConstants.WEB_ECLIPSE
-                || subsiteId == AnswerWayConstants.THIRD_PARTY || subsiteId == AnswerWayConstants.REPORT || subsiteId == AnswerWayConstants.JMETER || subsiteId == AnswerWayConstants.ZHICEYUN
-                || subsiteId == AnswerWayConstants.REPORT_RECOMMEND) {
+                || subsiteId == AnswerWayConstants.THIRD_PARTY || subsiteId == AnswerWayConstants.REPORT || subsiteId == AnswerWayConstants.JMETER || subsiteId == AnswerWayConstants.ZHICEYUN) {
             calculateScoreService.calculatePersonalManual(taskId, caseId, userId);
             calculateScoreService.calculatePersonalScript(taskId, caseId, userId);
             List<ScoreRuleItemVO> scoreRule = scoreRuleService.getKibugScoreRule(taskId, caseId);
@@ -480,12 +483,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)) {
@@ -498,21 +495,50 @@ public class CalculateScoreLogicImpl extends BaseLogic implements CalculateSocre
             }
         }
         catchService.postBulkCatchDTOS(catchDTOList);
-
-        generalCalculateScoreComponent.saveCaughtDetails(examId, caseId, userId, source,uploadTime,
-                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);
 
-        nodeOperationComponent.writeNode(examId, caseId, userId, uploadTime,caughtNodeDTOs);
-        //上传caughtNode userCatch结束,调用算分
-        generalCalculateScoreComponent.saveCaughtDetails(examId, caseId, userId, source,uploadTime,
+        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) throws Exception {
+        nodeOperationComponent.writeNode(examId, caseId, userId, uploadTime, caughtNodeDTOs);
+    }
 
 }

+ 7 - 3
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/CompetitionLogicImpl.java

@@ -231,9 +231,13 @@ public class CompetitionLogicImpl implements CompetitionLogic {
         Long groupId = examLogic.getExamById(nextCompetition2Exam.getExamId()).getGroupIds().get(0);
         List<Qualification> list = competitionService.getNextRoundQualificationByCompetitionIdAndIndex(competitionId, index);
         for(Qualification qualification: list) {
-            qualification.setStatus(competition2Exam.getNextIndex());
-            qualification.setNextRound(false);
-            competitionService.createOrUpdateQualification(qualification);
+            Qualification qualification1 = new Qualification();
+            qualification1.setId(qualification.getId());
+            qualification1.setUserId(qualification.getUserId());
+            qualification1.setCompetitionId(qualification.getCompetitionId());
+            qualification1.setStatus(competition2Exam.getNextIndex());
+            qualification1.setNextRound(false);
+            competitionService.createOrUpdateQualification(qualification1);
             if (!groupService.isUserInGroup(qualification.getUserId(), groupId)) {
                 groupService.addUserIntoGroup(qualification.getUserId(), groupId);
             }

+ 11 - 3
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/ExamLogicImpl.java

@@ -144,7 +144,7 @@ public class ExamLogicImpl extends BaseLogic implements ExamLogic {
             @Override
             public ExamVO convert(ParticipantExam examGroupUser) {
                 Exam exam = cn.iselab.mooctest.site.util.data.Converter.convert(Exam.class, examGroupUser);
-                return examVOWrapper.wrap(exam);
+                return examVOWrapper.wrapForList(exam);
             }
         });
         return examVOPage;
@@ -157,7 +157,7 @@ public class ExamLogicImpl extends BaseLogic implements ExamLogic {
             @Override
             public ExamVO convert(AssistManagerExam assistManagerExam) {
                 Exam exam = cn.iselab.mooctest.site.util.data.Converter.convert(Exam.class, assistManagerExam);
-                return examVOWrapper.wrap(exam);
+                return examVOWrapper.wrapForList(exam);
             }
         });
         return examVOPage;
@@ -170,7 +170,7 @@ public class ExamLogicImpl extends BaseLogic implements ExamLogic {
             @Override
             public ExamVO convert(ContestMentorExam contestMentorExam) {
                 Exam exam = cn.iselab.mooctest.site.util.data.Converter.convert(Exam.class, contestMentorExam);
-                return examVOWrapper.wrap(exam);
+                return examVOWrapper.wrapForList(exam);
             }
         });
         return examVOPage;
@@ -458,6 +458,14 @@ public class ExamLogicImpl extends BaseLogic implements ExamLogic {
         return recExerciseList;
     }
 
+    @Override
+    public ExamVO deleteExamById(Long examId) {
+        if (!examService.canBeDeleted(examId)){
+            throw new HttpBadRequestException("Cannot delete this exam.");
+        }
+        return examVOWrapper.wrap(examService.deleteExamById(examId));
+    }
+
 
     @Override
     public void exportExcelByOwner(HttpServletResponse response, Long examId) throws Exception {

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

@@ -2,7 +2,14 @@ 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.service.*;
+import cn.iselab.mooctest.site.data.UploadRecordDTO;
+import cn.iselab.mooctest.site.service.CatchService;
+import cn.iselab.mooctest.site.service.CaughtNodeService;
+import cn.iselab.mooctest.site.service.Exam2CaseService;
+import cn.iselab.mooctest.site.service.GeneralCalculateScoreService;
+import cn.iselab.mooctest.site.service.SubmitRecordService;
+import cn.iselab.mooctest.site.service.UserCatchService;
+import cn.iselab.mooctest.site.service.WeightGeneralService;
 import cn.iselab.mooctest.site.util.data.CacheUtil;
 import cn.iselab.mooctest.site.util.data.JSONUtil;
 import cn.iselab.mooctest.site.web.data.forMongo.CaseGraphDTO;
@@ -10,20 +17,22 @@ 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 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 java.util.stream.Collectors;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
 
 /**
  * asyncTask
@@ -32,6 +41,7 @@ import java.util.Map;
  * @create 2018-03-14 11:18
  */
 @Component
+@Slf4j
 public class GeneralCalculateScoreComponent {
 
     //获取被命中nodes的服务
@@ -56,8 +66,9 @@ public class GeneralCalculateScoreComponent {
     @Autowired
     CacheUtil cacheUtil;
 
-    public void calculateGrade(long examId, long caseId, Long userId, String source) throws Exception {
-        recordTypeScore(examId, caseId, userId, source);
+    public void calculateGrade(long examId, long caseId, Long userId) throws
+            Exception {
+        recordTypeScore(examId, caseId, userId);
         if (userId != null) {
             calculateCaseScore(examId, caseId, userId);
         } else { //计算所有人的分数
@@ -67,25 +78,32 @@ public class GeneralCalculateScoreComponent {
 
     }
 
-    private void calculateGradeCurrent(long examId, long caseId, long userId, String source, String
-            uploadTime, List<CaughtNodeDTO> caughtNodeDTOS) throws Exception {
+    //计算当即提交的node的得分
+    public void calculateGradeCurrent(Long uploadId, long examId, long caseId, long userId,
+            List<CaughtNodeDTO> caughtNodeDTOS)
+            throws Exception {
 
-        CaseGraphDTO basicNode = cacheUtil.getMetaNode(caseId);
+        //过滤没有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 = cacheUtil.getMetaNode(caseId);
         Map<String, Double> typeScoreMap = calculateTypeScore(basicNode,catchDTOS);
         List<GeneralGradeDTO> gradeDTOList = new ArrayList<>();
-        typeScoreMap.forEach((type,score) -> gradeDTOList.add(new GeneralGradeDTO(userId,examId,
-                caseId,type,score,uploadTime,source)));
+        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, String
-            source) throws Exception {
+    //非当即分数记录
+    private void recordTypeScore(long examId, long caseId, Long userId) throws
+            Exception {
 
         List<UserCatchDTO> userCatchDTOList;
         if (userId == null) {
@@ -93,10 +111,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);
         }
 
@@ -115,6 +131,7 @@ public class GeneralCalculateScoreComponent {
                                                      List<UserCatchDTO> userCatchDTOS) throws Exception {
 
         List<GeneralGradeDTO> generalGradeDTOList = new ArrayList<>();
+
         //元node数据
         CaseGraphDTO basicNode = cacheUtil.getMetaNode(caseId);
 
@@ -122,14 +139,16 @@ public class GeneralCalculateScoreComponent {
             for (UserCatchDTO userCatchDTO : userCatchDTOS) {
                 String id = userCatchDTO.getLatestId();
                 List<CatchDTO> catchDTOs = catchService.findById(id);
-
                 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);
                 }
             }
@@ -137,15 +156,14 @@ public class GeneralCalculateScoreComponent {
         return generalGradeDTOList;
     }
 
-    private Map<String, Double> calculateTypeScore(CaseGraphDTO basicNode, List<CatchDTO>
-            catchDTOS){
-        if(basicNode ==null || catchDTOS == null){
-            return new HashMap<>();
-        }
-
+    private Map<String,Double> calculateTypeScore(CaseGraphDTO basicNode, List<CatchDTO>
+            catchDTOs){
         Map<String, Double> typeScoreMap = new HashMap<>();
+        if(basicNode == null || catchDTOs == null){
+            return typeScoreMap;
+        }
         for (Node node : basicNode.getNodes()) {
-            for (CatchDTO catchDTO : catchDTOS) {
+            for (CatchDTO catchDTO : catchDTOs) {
                 if (node.getName().equals(catchDTO.getNodeName())) {//用户命中了该node
                     double scoreGot = 0;
                     String key = node.getCategory();
@@ -161,7 +179,6 @@ public class GeneralCalculateScoreComponent {
         }
 
         return typeScoreMap;
-
     }
 
 
@@ -227,8 +244,8 @@ public class GeneralCalculateScoreComponent {
 
 
     @Async("calculateGradeAsync")
-    public void saveCaughtDetails(Long examId, Long caseId, Long userId, String
-            source,String uploadTime, List<CaughtNodeDTO> caughtNodeDTOs) throws Exception {
+    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) {
@@ -268,8 +285,8 @@ public class GeneralCalculateScoreComponent {
 //            }
 //            caughtNodeService.bulkUpdateCaughtNodes(examId, caseId, nodeNameList, userId);
 //        }
-//        calculateGrade(examId, caseId, userId, source);
-        calculateGradeCurrent(examId,caseId,userId,source,uploadTime, caughtNodeDTOs);
+
+        calculateGradeCurrent(uploadId,examId,caseId,userId,caughtNodeDTOs);
 
     }
 }

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

@@ -1,5 +1,6 @@
 package cn.iselab.mooctest.site.web.logic.impl;
 
+import cn.iselab.mooctest.site.models.ApplyUploadRecord;
 import cn.iselab.mooctest.site.service.Exam2CaseService;
 import cn.iselab.mooctest.site.service.GeneralCalculateScoreService;
 import cn.iselab.mooctest.site.service.SubmitRecordService;
@@ -37,7 +38,6 @@ public class GeneralCalculateScoreLogicImpl implements GeneralCalculateScoreLogi
   @Autowired
   CacheUtil cacheUtil;
 
-
   @Override
   public void calculateExamScoreFromNode(long examId, String source) throws Exception {
     List<Long> caseIds = exam2CaseService.getCaseIdsByExamId(examId);
@@ -58,7 +58,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
@@ -87,5 +87,14 @@ public class GeneralCalculateScoreLogicImpl implements GeneralCalculateScoreLogi
     cacheUtil.removeMetaNodeAll();
   }
 
+  @Override
+  public ApplyUploadRecord getLatestApplyUploadRecord(long workerId, long examId) {
+    return generalCalculateScoreService.getLatestApplyUploadRecord(workerId, examId);
+  }
+
+  @Override
+  public ApplyUploadRecord getApplyUploadRecord(long id) {
+    return generalCalculateScoreService.getApplyUploadRecordById(id);
+  }
 
 }

+ 67 - 39
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/OnlineJudgeLogicImpl.java

@@ -1,7 +1,6 @@
 package cn.iselab.mooctest.site.web.logic.impl;
 
 import cn.iselab.mooctest.site.common.constant.Constants;
-import cn.iselab.mooctest.site.common.enums.OnlineJudgeMode;
 import cn.iselab.mooctest.site.data.OnlineJudgeResultDTO;
 import cn.iselab.mooctest.site.models.Target;
 import cn.iselab.mooctest.site.service.CaseService;
@@ -10,7 +9,6 @@ import cn.iselab.mooctest.site.service.updownload.DownloadService;
 import cn.iselab.mooctest.site.util.data.FileUtils;
 import cn.iselab.mooctest.site.web.data.*;
 import cn.iselab.mooctest.site.web.data.wrapper.OnlineJudgeResultVOWrapper;
-import cn.iselab.mooctest.site.web.data.wrapper.OnlineJudgeResultsVOWrapper;
 import cn.iselab.mooctest.site.web.logic.OSSLogic;
 import cn.iselab.mooctest.site.web.logic.OnlineJudgeLogic;
 import cn.iselab.mooctest.site.web.logic.asyncProgress.OnlineJudgeProcessLogic;
@@ -20,7 +18,6 @@ import com.google.common.cache.CacheBuilder;
 import com.google.common.collect.Lists;
 import com.google.gson.*;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.http.client.utils.URLEncodedUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
@@ -32,6 +29,8 @@ import java.util.List;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 
+import static cn.iselab.mooctest.site.common.enums.OnlineJudgeMode.*;
+
 /**
  * @program: mooctest-site
  * @email: menduo96@gmail.com
@@ -57,8 +56,6 @@ public class OnlineJudgeLogicImpl implements OnlineJudgeLogic {
     private DownloadService downloadService;
     @Autowired
     private OnlineJudgeResultVOWrapper onlineJudgeResultVOWrapper;
-    @Autowired
-    private OnlineJudgeResultsVOWrapper onlineJudgeResultsVOWrapper;
     @Value("${featureSwitch.client.oss}")
     private boolean ossFeatureSwitch;
 
@@ -68,7 +65,7 @@ public class OnlineJudgeLogicImpl implements OnlineJudgeLogic {
             Constants.ANSWER_PATH+File.separator;
 
 
-    private final static Cache<String, OnlineJudgeResultDTO> RESULTDTO_CACHE_FROM_CELERY = CacheBuilder
+    private final static Cache<String, List<OnlineJudgeResultDTO>> RESULTDTO_CACHE_FROM_CELERY = CacheBuilder
             .newBuilder()
             .initialCapacity(50)
             .concurrencyLevel(5)
@@ -80,31 +77,49 @@ public class OnlineJudgeLogicImpl implements OnlineJudgeLogic {
 
         onlineJudgeVO.setSubmissionId(generalSubmissionId());
         // uploadOss策略
-
         // 上传到 {osspath}/{mode}/{userId}/{examId}/{caseId}/code_{submissionId}_{timestamp}.txt
         String codeOssUrl = uploadCodeToOss(onlineJudgeVO);
+        switch (onlineJudgeVO.getMode()) {
+            case RUN: {
+                // 需要有数据文件
+                Target target = targetService.getTargetByCaseId(onlineJudgeVO.getCaseId());
+                //String dataOssUrl = "http://mooctest-site-dev.oss-cn-shanghai.aliyuncs.com/code/data.json";
+                String dataOssUrl = target.getUrl();
+                dataOssUrl = encodeDataUrl(dataOssUrl);
+                List<String> list = Lists.newArrayList(codeOssUrl, dataOssUrl);
+                onlineJudgeProcessLogic.triggerRunOnlineJudge(onlineJudgeVO, list);
+                break;
+            }
+            case ONLYRUN: {
+                List<String> list = Lists.newArrayList(codeOssUrl);
+                onlineJudgeProcessLogic.triggerRunOnlineJudge(onlineJudgeVO, list);
+                break;
+            }
+            case RUN_WITH_INPUT: {
+                //上传数据到 {osspath}/{mode}/{userId}/{examId}/{caseId}/data_{submissionId}_{timestamp}.json
+                String dataOssUrl = uploadDataToOss(onlineJudgeVO);
+                List<String> list = Lists.newArrayList(codeOssUrl, dataOssUrl);
+                onlineJudgeProcessLogic.triggerRunOnlineJudge(onlineJudgeVO, list);
+                break;
+            }
+            case RUN_WITH_MANY_INPUT: {
+                //上传数据到 {osspath}/{mode}/{userId}/{examId}/{caseId}/data_{submissionId}_{timestamp}.json
+                String dataOssUrl = uploadDataToOss(onlineJudgeVO);
+                List<String> list = Lists.newArrayList(codeOssUrl, dataOssUrl);
+                onlineJudgeProcessLogic.triggerRunOnlineJudge(onlineJudgeVO, list);
+                break;
+            }
+            case CUSTOMRUN: {
+                //1. 用户代码和用户的数据 and 2. 标准的代码和用户的数据
+                String userDataOssUrl = uploadDataToOss(onlineJudgeVO); // 用户的数据
 
-        if (OnlineJudgeMode.RUN.equals(onlineJudgeVO.getMode())) {
-            // 需要有数据文件
-            Target target = targetService.getTargetByCaseId(onlineJudgeVO.getCaseId());
-            //String dataOssUrl = "http://mooctest-site-dev.oss-cn-shanghai.aliyuncs.com/code/data.json";
-            String dataOssUrl = target.getUrl();
-            dataOssUrl = encodeDataUrl (dataOssUrl);
-            List<String> list = Lists.newArrayList(codeOssUrl, dataOssUrl);
-            onlineJudgeProcessLogic.triggerRunOnlineJudge(onlineJudgeVO, list);
-        } else if(OnlineJudgeMode.ONLYRUN.equals(onlineJudgeVO.getMode())) {
-            List<String> list = Lists.newArrayList(codeOssUrl);
-            onlineJudgeProcessLogic.triggerRunOnlineJudge(onlineJudgeVO, list);
-        } else if(OnlineJudgeMode.RUN_WITH_INPUT.equals(onlineJudgeVO.getMode())){
-            //上传数据到 {osspath}/{mode}/{userId}/{examId}/{caseId}/data_{submissionId}_{timestamp}.json
-            String dataOssUrl = uploadDataToOss(onlineJudgeVO);
-            List<String> list = Lists.newArrayList(codeOssUrl, dataOssUrl);
-            onlineJudgeProcessLogic.triggerRunOnlineJudge(onlineJudgeVO, list);
-        } else if(OnlineJudgeMode.RUN_WITH_MANY_INPUT.equals(onlineJudgeVO.getMode())){
-            //上传数据到 {osspath}/{mode}/{userId}/{examId}/{caseId}/data_{submissionId}_{timestamp}.json
-            String dataOssUrl = uploadDataToOss(onlineJudgeVO);
-            List<String> list = Lists.newArrayList(codeOssUrl, dataOssUrl);
-            onlineJudgeProcessLogic.triggerExecuteOnlineJudge(onlineJudgeVO, list);
+                Target target = targetService.getTargetByCaseId(onlineJudgeVO.getCaseId());
+                String standardCodeOssUrl = encodeDataUrl(target.getUrl()); // 标准的代码
+
+                List<String> list = Lists.newArrayList(codeOssUrl, userDataOssUrl, standardCodeOssUrl);
+                onlineJudgeProcessLogic.triggerRunOnlineJudge(onlineJudgeVO, list);
+                break;
+            }
         }
 
         return onlineJudgeVO.getSubmissionId();
@@ -205,24 +220,37 @@ public class OnlineJudgeLogicImpl implements OnlineJudgeLogic {
 
     @Override
     public OnlineJudgeResultVO checkSubmissionById(String submissionId) {
-        OnlineJudgeResultDTO result = getResultDTOFromCache (submissionId);
-        if (result == null) {
+        List<OnlineJudgeResultDTO> result = getResultDTOFromCache (submissionId);
+        if (result == null || result.size()==0) {
            return onlineJudgeResultVOWrapper.wrap (new OnlineJudgeResultDTO("started",-1));
         }
-        result.setState("success");
-        return onlineJudgeResultVOWrapper.wrap (result);
+        result.get(0).setState("success");
+        return onlineJudgeResultVOWrapper.wrap (result.get(0));
     }
 
     @Override
     public OnlineJudgeResultsVO pcheckSubmissionById(String submissionId) {
-        OnlineJudgeResultDTO result = getResultDTOFromCache (submissionId);
+        List<OnlineJudgeResultDTO> result = getResultDTOFromCache (submissionId);
+        if (result == null || result.size()==0) {
+            return onlineJudgeResultVOWrapper.wrap2ResultsVO (new OnlineJudgeResultDTO("started",-1));
+        }
+        result.get(0).setState("success");
+
+        return onlineJudgeResultVOWrapper.wrap2ResultsVO (result.get(0));
+    }
+
+    @Override
+    public OnlineJudgeCustomResultVO checkCustomSubmissionById(String submissinId) {
+        List<OnlineJudgeResultDTO> result = getResultDTOFromCache(submissinId);
+
         if (result == null) {
-            return onlineJudgeResultsVOWrapper.wrap (new OnlineJudgeResultDTO("started",-1));
+            return new OnlineJudgeCustomResultVO("started",-1);
         }
-        result.setState("success");
+        OnlineJudgeCustomResultVO onlineJudgeCustomResultVO = onlineJudgeResultVOWrapper.wrap2CustomResultVO(result);
 
-        return onlineJudgeResultsVOWrapper.wrap (result);
+        return onlineJudgeCustomResultVO;
     }
+
     @Override
     public SubmissionResultVO getLatestAnswersForThisCaseAndExam(long examId, long caseId,long userId) {
 
@@ -329,7 +357,7 @@ public class OnlineJudgeLogicImpl implements OnlineJudgeLogic {
 
 
     @Override
-    public OnlineJudgeResultDTO getResultDTOFromCache(String submissionId) {
+    public List<OnlineJudgeResultDTO> getResultDTOFromCache(String submissionId) {
         return RESULTDTO_CACHE_FROM_CELERY.getIfPresent(submissionId);
 
     }
@@ -345,7 +373,7 @@ public class OnlineJudgeLogicImpl implements OnlineJudgeLogic {
     }
 
     @Override
-    public void setResultDTOToCache(String submissionId, OnlineJudgeResultDTO result) {
+    public void setResultDTOToCache(String submissionId, List<OnlineJudgeResultDTO> result) {
         RESULTDTO_CACHE_FROM_CELERY.put(submissionId, result);
     }
 
@@ -402,7 +430,7 @@ public class OnlineJudgeLogicImpl implements OnlineJudgeLogic {
      */
     private String generalFileNameForDownloadFromOss(Long examId, Long caseId, Long userId) {
         StringBuilder sb = new StringBuilder(BASE_DIR);
-        sb.append("/").append(OnlineJudgeMode.SUBMIT.toString()).append("/").append(userId).append("/").append(examId)
+        sb.append("/").append(SUBMIT.toString()).append("/").append(userId).append("/").append(examId)
                 .append("/").append(caseId).append("/");
         return sb.toString();
     }

+ 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()));
     }
 }

+ 67 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/TagLogicImpl.java

@@ -0,0 +1,67 @@
+package cn.iselab.mooctest.site.web.logic.impl;
+
+import cn.iselab.mooctest.site.common.enums.EntityType;
+import cn.iselab.mooctest.site.models.Tag;
+import cn.iselab.mooctest.site.service.Entity2TagService;
+import cn.iselab.mooctest.site.service.TagService;
+import cn.iselab.mooctest.site.web.data.Entity2TagVO;
+import cn.iselab.mooctest.site.web.data.TagPathVO;
+import cn.iselab.mooctest.site.web.data.TagVO;
+import cn.iselab.mooctest.site.web.data.wrapper.fromDev.TagVOWrapper;
+import cn.iselab.mooctest.site.web.exception.ServerException;
+import cn.iselab.mooctest.site.web.logic.TagLogic;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class TagLogicImpl implements TagLogic{
+
+    @Autowired
+    private TagService tagService;
+    @Autowired
+    private TagVOWrapper tagVOWrapper;
+    @Autowired
+    private Entity2TagService entity2TagService;
+
+    @Override
+    public List<TagVO> getFirstLevelTags() {
+        List<Tag> tags =  tagService.getAllParentTags();
+        return tags.stream().map(tag -> tagVOWrapper.wrapTag2VORecurse(tag)).collect(
+                Collectors.toList());
+    }
+
+    @Override
+    public void indexTag(long entityId, EntityType type, List<Integer> tagIds, List<String>
+            labels) {
+        entity2TagService.indexTag(entityId,type,tagIds,labels);
+    }
+
+    @Override
+    public Entity2TagVO getTagsByEntity(long entityId, EntityType type) {
+        if(type == null){
+            throw new ServerException(30000,"实体类型不能为null!");
+        }
+        List<Integer> sonIds = entity2TagService.getTagsByEntityIdAndType(entityId,type);
+        List<List<TagPathVO>> paths = new ArrayList<>();
+        sonIds.forEach(
+                sonId -> paths.add(tagService.getFullPathTagBySon(sonId).stream().
+                        map(pTag -> new TagPathVO(pTag.getId(),pTag.getName())).collect
+                        (Collectors.toList())
+                ));
+        List<String> labels = entity2TagService.getLabelsByEntityIdAndType(entityId,type);
+        return new Entity2TagVO(entityId,type.getTypeNumber(),paths,labels);
+
+    }
+
+    @Override
+    public List<Long> getEntitiesByTagId(int tagId, EntityType type) {
+        return entity2TagService.getEntitiesByTagId(tagId,type);
+    }
+
+
+}

+ 12 - 3
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/UserLogicImpl.java

@@ -5,6 +5,7 @@ import cn.afterturn.easypoi.excel.entity.ExportParams;
 import cn.iselab.mooctest.rpc.user.data.UserIntegralDTO;
 import cn.iselab.mooctest.site.common.annotation.PointChange;
 import cn.iselab.mooctest.site.common.constant.Constants;
+import cn.iselab.mooctest.site.configure.ClientFeatureConfiguration;
 import cn.iselab.mooctest.site.configure.realm.DefaultUsernamepasswordToken;
 import cn.iselab.mooctest.site.dao.UserDao;
 import cn.iselab.mooctest.site.data.UserDTOForMT;
@@ -39,6 +40,7 @@ import org.apache.shiro.SecurityUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
@@ -113,6 +115,9 @@ public class UserLogicImpl extends BaseLogic implements UserLogic {
     @Autowired
     private IntegralService integralService;
 
+    @Autowired
+    private ClientFeatureConfiguration clientFeatureConfiguration;
+
     private UserDTOForMT transfer(UserVO userVO) {
         return Converter.convert(UserDTOForMT.class, userVO);
     }
@@ -759,9 +764,13 @@ public class UserLogicImpl extends BaseLogic implements UserLogic {
         userVO.setMenuVOs(menuVOs);
         userVO.setOpenId(openId2UserIdService.findOpenIdByUserId(userVO.getId()));
         userVO.setPassword("");
-        UserIntegralDTO integralDTO=integralService.getUserIntegral(userVO.getId());
-        if (integralDTO!=null) {
-            userVO.setIntegral(integralDTO.getTotal());
+        if(clientFeatureConfiguration.isMedal()) {
+            UserIntegralDTO integralDTO=integralService.getUserIntegral(userVO.getId());
+            if (integralDTO!=null) {
+                userVO.setIntegral(integralDTO.getTotal());
+            }
+        }else {
+            LOG.info("私有云不进行积分初始化");
         }
 
         if (managerPropertyService.getManagerPropertyByUserId(userVO.getId()) != null) {

+ 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();

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません