Pārlūkot izejas kodu

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

chenxz 7 gadi atpakaļ
vecāks
revīzija
1698bdb383
56 mainītis faili ar 880 papildinājumiem un 159 dzēšanām
  1. 6 0
      mooctest-site-server/pom.xml
  2. 0 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/configure/ShiroConfiguration.java
  3. 3 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/GroupDao.java
  4. 1 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/PaperDao.java
  5. 13 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/SalesPackageDao.java
  6. 13 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/SalesServiceDao.java
  7. 17 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/User2SalesPackageDao.java
  8. 11 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Group.java
  9. 6 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Paper.java
  10. 20 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/SalesPackage.java
  11. 20 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/SalesService.java
  12. 26 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/User2SalesPackage.java
  13. 7 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/CaseGraphService.java
  14. 8 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/CaughtNodeService.java
  15. 4 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/GroupService.java
  16. 8 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/UserCatchService.java
  17. 8 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/UserService.java
  18. 6 5
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/application/impl/WechatServiceImpl.java
  19. 45 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CaseGraphServiceImpl.java
  20. 12 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CaughtNodeServiceImpl.java
  21. 27 13
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/GroupServiceImpl.java
  22. 21 21
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/PaperServiceImpl.java
  23. 12 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/UserCatchServiceImpl.java
  24. 34 4
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/UserServiceImpl.java
  25. 7 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/CaseController.java
  26. 35 5
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/GroupController.java
  27. 3 3
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/MessageController.java
  28. 7 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/OSSController.java
  29. 5 4
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/PaperController.java
  30. 9 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ScoreController.java
  31. 14 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/UserController.java
  32. 10 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/AssignedTaskVO.java
  33. 11 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/GroupVO.java
  34. 10 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/MessageVO.java
  35. 16 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/SalesPackageVO.java
  36. 13 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/SalesServiceVO.java
  37. 19 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/UserPackageVO.java
  38. 29 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/forMongo/NodeCatch/CaughtNodeDTO.java
  39. 31 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/forMongo/NodeCatch/UserCatchDTO.java
  40. 2 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/forMongo/caseGraph/Node.java
  41. 2 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/MessageVOWrapper.java
  42. 11 3
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/PaperVOWrapper.java
  43. 51 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/SalesPackageVOWrapper.java
  44. 3 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/CalculateSocreLogic.java
  45. 6 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/GroupLogic.java
  46. 5 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/OSSLogic.java
  47. 5 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/UserLogic.java
  48. 94 65
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/CalculateScoreLogicImpl.java
  49. 11 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/CaseLogicImpl.java
  50. 5 4
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/ExamLogicImpl.java
  51. 44 9
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/GroupLogicImpl.java
  52. 45 7
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/OSSLogicImpl.java
  53. 11 7
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/PaperLogicImpl.java
  54. 3 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/ReportLogicImpl.java
  55. 27 1
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/UserLogicImpl.java
  56. 8 0
      mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/util/mongodb/MongoAPIUtils.java

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

@@ -274,6 +274,12 @@
             <artifactId>requests</artifactId>
             <version>4.7.3</version>
         </dependency>
+        <!-- ZIP -->
+        <dependency>
+            <groupId>net.lingala.zip4j</groupId>
+            <artifactId>zip4j</artifactId>
+            <version>1.3.2</version>
+        </dependency>
     </dependencies>
 
     <build>

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

@@ -92,7 +92,6 @@ public class ShiroConfiguration {
         filterChainDefinitionManager.put("/api/featureSwitch", "anon");
         filterChainDefinitionManager.put("/api/common/**", "anon");
         filterChainDefinitionManager.put("/api/mobileLogin", "anon");
-        filterChainDefinitionManager.put("/api/caseGraph", "anon");
 
         filterChainDefinitionManager.put("/logout", "anon");
         filterChainDefinitionManager.put("/api/dev/**", "anon");

+ 3 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/GroupDao.java

@@ -62,7 +62,7 @@ public interface GroupDao extends PagingAndSortingRepository<Group, Long> {
 
     @Query("SELECT g FROM Group g, Group2Worker g2w " +
             "WHERE g2w.participantId = :participantId " +
-            "AND g.id = g2w.groupId")
+            "AND g.id = g2w.groupId AND g.isActive=1")
     List<Group> findGroupListByParticipant(@Param("participantId") long participantId);
 
     @Query("SELECT g FROM Task2Group t2g, Group g " +
@@ -135,6 +135,8 @@ public interface GroupDao extends PagingAndSortingRepository<Group, Long> {
             "or u.mobile LIKE concat('%',:keyword,'%') " +
             "or u.school LIKE concat('%',:keyword,'%'))")
     Page<User> findByIdAndKeyWord(@Param("groupId")long groupId, @Param("keyword") String keyword, Pageable pageable);
+
+    List<Group> findByOwnerIdAndIsActive(long ownerId,boolean isActive);
 }
 
 

+ 1 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/PaperDao.java

@@ -20,7 +20,7 @@ public interface PaperDao extends PagingAndSortingRepository<Paper, Long>, JpaSp
 
     Paper findById(long paperId);
 
-    @Query("select p from Paper p,Task2Case t2c where t2c.caseId=:caseId and t2c.taskId=p.id")
+    @Query("select p from Paper p,Task2Case t2c where t2c.caseId=:caseId and t2c.taskId=p.id and p.isDeleted=0")
     Page<Paper> findByCaseId(@Param("caseId") Long caseId,Pageable pageable);
 
 //    @Query("select p from Paper p where p.ownerId=:ownerId")

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

@@ -0,0 +1,13 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.SalesPackage;
+import org.springframework.data.repository.CrudRepository;
+
+import javax.transaction.Transactional;
+
+/**
+ * Created by tangshanshan on 2017/12/13.
+ */
+@Transactional
+public interface SalesPackageDao extends CrudRepository<SalesPackage, Long> {
+}

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

@@ -0,0 +1,13 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.SalesService;
+import org.springframework.data.repository.CrudRepository;
+
+import javax.transaction.Transactional;
+
+/**
+ * Created by tangshanshan on 2017/12/13.
+ */
+@Transactional
+public interface SalesServiceDao extends CrudRepository<SalesService, Long> {
+}

+ 17 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/User2SalesPackageDao.java

@@ -0,0 +1,17 @@
+package cn.iselab.mooctest.site.dao;
+
+import cn.iselab.mooctest.site.models.User2SalesPackage;
+import org.springframework.data.repository.CrudRepository;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+/**
+ * Created by tangshanshan on 2017/12/13.
+ */
+@Transactional
+public interface User2SalesPackageDao extends CrudRepository<User2SalesPackage, Long> {
+    List<User2SalesPackage> findByUserId(Long userId);
+
+    User2SalesPackage findByUserIdAndSalesServiceId(Long userId, Long serviceId);
+}

+ 11 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Group.java

@@ -30,6 +30,9 @@ public class Group {
     @Column(name = "owner_id")
     private Long ownerId;
 
+    @Column(name = "is_active")
+    private Boolean isActive = true;
+
     @ManyToMany
     @JoinTable(name = "task_2_group", joinColumns = @JoinColumn(name = "group_id"),
             inverseJoinColumns = @JoinColumn(name = "task_id"))
@@ -90,4 +93,12 @@ public class Group {
     public void setTaskSet(Set<Task> taskSet) {
         this.taskSet = taskSet;
     }
+
+    public void setIsActive(Boolean isActive){
+        this.isActive = isActive;
+    }
+
+    public Boolean getIsActive(){
+        return this.isActive;
+    }
 }

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

@@ -36,4 +36,10 @@ public class Paper {
 
     @Column(name = "is_public")
     private Boolean isPublic;
+
+    @Column(name = "is_deleted")
+    private Boolean isDeleted;
+
+    @Column(name = "create_time")
+    private Timestamp createTime;
 }

+ 20 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/SalesPackage.java

@@ -0,0 +1,20 @@
+package cn.iselab.mooctest.site.models;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * Created by tangshanshan on 2017/12/13.
+ */
+@Data
+@Entity
+@Table(name = "sales_package")
+public class SalesPackage {
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Column(name  = "name")
+    private String name;
+}

+ 20 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/SalesService.java

@@ -0,0 +1,20 @@
+package cn.iselab.mooctest.site.models;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * Created by tangshanshan on 2017/12/13.
+ */
+@Data
+@Entity
+@Table(name = "sales_service")
+public class SalesService {
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Column(name  = "name")
+    private String name;
+}

+ 26 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/User2SalesPackage.java

@@ -0,0 +1,26 @@
+package cn.iselab.mooctest.site.models;
+
+import lombok.Data;
+
+import javax.persistence.*;
+
+/**
+ * Created by tangshanshan on 2017/12/13.
+ */
+@Data
+@Entity
+@Table(name = "user_2_sales_package")
+public class User2SalesPackage {
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Column(name  = "sales_service_id")
+    private Long salesServiceId;
+
+    @Column(name  = "sales_package_id")
+    private Long salesPackageId;
+
+    @Column(name  = "user_id")
+    private Long userId;
+}

+ 7 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/CaseGraphService.java

@@ -1,7 +1,10 @@
 package cn.iselab.mooctest.site.service;
 
+import cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO;
 import cn.iselab.mooctest.site.web.data.forMongo.caseGraph.CaseGraphDTO;
 
+import java.util.Map;
+
 /**
  * Created by tangshanshan on 2017/12/7.
  */
@@ -10,4 +13,8 @@ public interface CaseGraphService {
     CaseGraphDTO saveCaseGraph(CaseGraphDTO caseGraphDTO);
 
     CaseGraphDTO getCaseGraph(Long caseId);
+
+    Map<String,CaughtNodeDTO> getNodeCatchMap(Long caseId);
+
+    Map<String,CaughtNodeDTO> getNodeCatchMapWithExamId(Long caseId, Long examId);
 }

+ 8 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/CaughtNodeService.java

@@ -0,0 +1,8 @@
+package cn.iselab.mooctest.site.service;
+
+/**
+ * @author sean
+ * @date 2017-12-14.
+ */
+public interface CaughtNodeService {
+}

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

@@ -72,4 +72,8 @@ public interface GroupService {
     User addUserIntoGroupForOauth2(long userId, long groupId);
 
     List<Long> getWorkerIdsByGroupId(Long groupId);
+
+    boolean checkManagerGroupSize(long userId);
+
+    int getUserTotalCount(long managerId);
 }

+ 8 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/UserCatchService.java

@@ -0,0 +1,8 @@
+package cn.iselab.mooctest.site.service;
+
+/**
+ * @author sean
+ * @date 2017-12-14.
+ */
+public interface UserCatchService {
+}

+ 8 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/UserService.java

@@ -1,6 +1,8 @@
 package cn.iselab.mooctest.site.service;
 
 import cn.iselab.mooctest.site.models.User;
+import cn.iselab.mooctest.site.models.User2SalesPackage;
+import cn.iselab.mooctest.site.web.data.SalesServiceVO;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 
@@ -34,4 +36,10 @@ public interface UserService {
     Page<User> findByRoleId(Long roleId, Pageable pageable);
 
     Page<User> getUserOfFuzzySearch(String name, String mobile, String email, Pageable pageable);
+
+    List<User2SalesPackage> getUserSalesPackage(Long userId);
+
+    void saveUserSalesPackage(Long userId, SalesServiceVO salesService);
+
+    void deleteUserSalesPackage(Long userId, SalesServiceVO salesService);
 }

+ 6 - 5
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/application/impl/WechatServiceImpl.java

@@ -192,14 +192,15 @@ public class WechatServiceImpl implements WechatService {
             boolean isManager=false;
             List<User2Role> user2Roles=user2RoleService.getByUserId(user.getId());
             for(User2Role user2Role:user2Roles){
-                if(user2Role.getRoleId()==2)
-                    isManager=true;
+                if(user2Role.getRoleId()==2) {
+                    isManager = true;
+                }
             }
-            if(!isManager)
+            if(!isManager) {
                 result.put("message", "manager not found");
-            else {
+            } else {
                 JSONArray groupArr = new JSONArray();
-                List<Group> groups = groupDao.findByOwnerId(user.getId());
+                List<Group> groups = groupDao.findByOwnerIdAndIsActive(user.getId(),true);
                 for (Group group : groups) {
                     JSONObject groupObj = new JSONObject();
                     groupObj.put("id", group.getId());

+ 45 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CaseGraphServiceImpl.java

@@ -1,7 +1,9 @@
 package cn.iselab.mooctest.site.service.impl;
 
 import cn.iselab.mooctest.site.service.CaseGraphService;
+import cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO;
 import cn.iselab.mooctest.site.web.data.forMongo.caseGraph.CaseGraphDTO;
+import cn.iselab.mooctest.site.web.data.forMongo.caseGraph.Node;
 import cn.iselab.mooctest.site.web.util.mongodb.MongoAPIUtils;
 import com.google.gson.Gson;
 import net.sf.json.JSONArray;
@@ -47,6 +49,49 @@ public class CaseGraphServiceImpl implements CaseGraphService {
         return extractCaseGraphDTO(responseEntity);
     }
 
+    @Override
+    public Map<String,CaughtNodeDTO> getNodeCatchMapWithExamId(Long caseId, Long examId) {
+        HttpHeaders headers=MongoAPIUtils.createAuthHeaderForMongo();
+        HttpEntity<String> entity=new HttpEntity<>(headers);
+
+        RestTemplate rt=new RestTemplate();
+        Map queryParams=new HashedMap();
+        queryParams.put("examId",examId);
+        queryParams.put("caseId",caseId);
+
+        String filter= MongoAPIUtils.generateFilterStr(queryParams);
+        String url=MongoAPIUtils.generateFilterUrl(MongoAPIUtils.MONGODB_DB,MongoAPIUtils.MONGODB_COLLECTION_CAUGHT_NODE);
+        ResponseEntity<JSONObject> responseEntity=rt.exchange(url,HttpMethod.GET,entity,JSONObject.class,filter);
+        return extractNodeCatchMap(responseEntity);
+    }
+
+    @Override
+    public Map<String,CaughtNodeDTO> getNodeCatchMap(Long caseId) {
+        HttpHeaders headers=MongoAPIUtils.createAuthHeaderForMongo();
+        HttpEntity<String> entity=new HttpEntity<>(headers);
+
+        RestTemplate rt=new RestTemplate();
+        Map queryParams=new HashedMap();
+        queryParams.put("caseId",caseId);
+
+        String avars= MongoAPIUtils.generateFilterStr(queryParams);
+        String url=MongoAPIUtils.generateAggrUrl(MongoAPIUtils.MONGODB_DB,MongoAPIUtils.MONGODB_COLLECTION_CAUGHT_NODE,
+                MongoAPIUtils.MONGODB_AGGREGATION_SUM_CATCH);
+        ResponseEntity<JSONObject> responseEntity=rt.exchange(url,HttpMethod.GET,entity,JSONObject.class,avars);
+        return extractNodeCatchMap(responseEntity);
+    }
+
+    private Map<String,CaughtNodeDTO> extractNodeCatchMap(ResponseEntity<JSONObject> response){
+        Map<String,CaughtNodeDTO> nodeCatchMap = new HashedMap();
+        JSONArray resultArray = response.getBody().getJSONArray("_embedded");
+        Gson gson = new Gson();
+        resultArray.forEach(result->{
+            CaughtNodeDTO caughtNodeDTO = gson.fromJson(result.toString(),CaughtNodeDTO.class);
+            nodeCatchMap.put(caughtNodeDTO.getNodeName(),caughtNodeDTO);
+        });
+        return nodeCatchMap;
+    }
+
     private CaseGraphDTO extractCaseGraphDTO(ResponseEntity<JSONObject> dto){
         JSONArray resultArray = dto.getBody().getJSONArray("_embedded");
         if(resultArray.size() == 0) {

+ 12 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/CaughtNodeServiceImpl.java

@@ -0,0 +1,12 @@
+package cn.iselab.mooctest.site.service.impl;
+
+import cn.iselab.mooctest.site.service.CaughtNodeService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author sean
+ * @date 2017-12-14.
+ */
+@Service
+public class CaughtNodeServiceImpl implements CaughtNodeService{
+}

+ 27 - 13
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/GroupServiceImpl.java

@@ -1,9 +1,6 @@
 package cn.iselab.mooctest.site.service.impl;
 
-import cn.iselab.mooctest.site.dao.Group2WorkerDao;
-import cn.iselab.mooctest.site.dao.GroupDao;
-import cn.iselab.mooctest.site.dao.Task2CaseDao;
-import cn.iselab.mooctest.site.dao.Task2GroupDao;
+import cn.iselab.mooctest.site.dao.*;
 import cn.iselab.mooctest.site.data.AssignedCase;
 import cn.iselab.mooctest.site.models.*;
 import cn.iselab.mooctest.site.models.instancePermission.GroupPermission;
@@ -38,15 +35,9 @@ import java.util.stream.Collectors;
 public class GroupServiceImpl implements GroupService {
 
     @Autowired
-    private TaskService taskService;
-
-    @Autowired
     private UserService userService;
 
     @Autowired
-    private ManagerService managerService;
-
-    @Autowired
     private WorkerService workerService;
 
     @Autowired
@@ -62,10 +53,10 @@ public class GroupServiceImpl implements GroupService {
     private GroupDao groupDao;
 
     @Autowired
-    private Task2CaseDao paper2CaseDao;
+    private GroupPermissionService groupPermissionService;
 
     @Autowired
-    private GroupPermissionService groupPermissionService;
+    private ManagerPropertyDao managerPropertyDao;
 
     @Override
     public List<Group> getGroupsByWorkerId(long workerId) {
@@ -84,6 +75,7 @@ public class GroupServiceImpl implements GroupService {
         group.setManagerId(managerId);
         group.setName(name);
         group.setInformation(null);
+        group.setIsActive(true);
         groupDao.save(group);
         return group;
     }
@@ -101,7 +93,7 @@ public class GroupServiceImpl implements GroupService {
 
     @Override
     public List<Group> getGroupsByOwnerId(long ownerId) {
-        List<Group> groupList = groupDao.findByOwnerId(ownerId);
+        List<Group> groupList = groupDao.findByOwnerIdAndIsActive(ownerId,true);
         return groupList;
     }
 
@@ -110,6 +102,7 @@ public class GroupServiceImpl implements GroupService {
         return groupDao.findByOwnerId(ownerId, pageable);
     }
 
+    @Override
     public List<Group> getGroupsByExamIdAndParticipantId(long examId, long participantId) {
         return groupDao.findByExamIdAndParticipantId(examId, participantId);
     }
@@ -302,4 +295,25 @@ public class GroupServiceImpl implements GroupService {
         List<Group2Worker> group2Workers = group2WorkerDao.findByGroupId(groupId);
         return group2Workers.stream().map(group2Worker -> group2Worker.getParticipantId()).collect(Collectors.toList());
     }
+
+    @Override
+    public boolean checkManagerGroupSize(long userId) {
+        int userCount = this.getUserTotalCount(userId);
+        int max = managerPropertyDao.findByUserId(userId).getGroupSize();
+        if(userCount<max) {
+            return true;
+        }else {
+            return false;
+        }
+    }
+
+    @Override
+    public int getUserTotalCount(long managerId) {
+        List<Group> groups = this.groupDao.findByOwnerIdAndIsActive(managerId,true);
+        int userCount = 0;
+        for (Group group : groups) {
+            userCount +=  this.getWorkerCount(group.getId());
+        }
+        return userCount;
+    }
 }

+ 21 - 21
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/PaperServiceImpl.java

@@ -60,17 +60,12 @@ public class PaperServiceImpl extends BaseService implements PaperService {
 
     @Override
     public void deletePaper(long paperId) {
-        List<Task2Case> oldCases = task2CaseDao.findByTaskId(paperId);
-        List<Exam2Paper> exam2Papers = exam2PaperDao.findByPaperId(paperId);
-        for(Task2Case task2Case : oldCases){
-            task2CaseDao.delete(task2Case);
-        }
-        for(Exam2Paper exam2Paper : exam2Papers){
-            exam2PaperDao.delete(exam2Paper);
-        }
-        paperDao.delete(paperId);
+        Paper paper = paperDao.findById(paperId);
+        paper.setIsDeleted(true);
+        paperDao.save(paper);
     }
 
+    @Override
     public Page<Paper> findAll(Pageable pageable, String keyword) {
         Specifications<Paper> where =  Specifications.where(getWhereClause(null, keyword));
         return paperDao.findAll(where, pageable);
@@ -121,21 +116,25 @@ public class PaperServiceImpl extends BaseService implements PaperService {
         for(CaseBlockVO caseBlock : caseBlocks) {
             case_num += caseBlock.getCaseIds().size();
         }
-        if(case_num ==0) return;
+        if(case_num ==0) {
+            return;
+        }
         int average = total_score / case_num;
         int remainder = total_score % case_num;
         for (CaseBlockVO caseBlock : caseBlocks) {
             for(Long caseId : caseBlock.getCaseIds()) {
                 Task2Case task2Case = task2CaseDao.findByTaskIdAndCaseId(paperId, caseId);
-                if(task2Case == null)
+                if(task2Case == null) {
                     task2Case = new Task2Case();
+                }
                 task2Case.setCaseId(caseId);
                 task2Case.setTaskId(paperId);
                 if(total_score / average >1){
                     task2Case.setWeight((double)average/100);
                     total_score -= average;
-                } else
-                    task2Case.setWeight((double)(average+remainder)/100);
+                } else {
+                    task2Case.setWeight((double) (average + remainder) / 100);
+                }
                 task2Case.setAutoSelect(caseBlock.getAutoSelect());
                 task2Case.setCaseIndex(maxCaseIndex);
                 task2Case.setCount(0);
@@ -148,24 +147,23 @@ public class PaperServiceImpl extends BaseService implements PaperService {
 
     @Override
     public boolean isUsedByExam(long paperId) {
-        if(this.exam2PaperDao.findByPaperId(paperId).size() == 0)
-            return false;
-        else
-            return true;
+        return this.exam2PaperDao.findByPaperId(paperId).size() != 0;
     }
 
     @Override
     public boolean deletePaperCase(long paperId, long caseId) {
         Task2Case task2Case = task2CaseDao.findByTaskIdAndCaseId(paperId, caseId);
-        if(task2Case == null)
+        if(task2Case == null) {
             throw new IllegalArgumentException("该试卷不存在这道题!");
+        }
         task2CaseDao.delete(task2Case);
         if(task2CaseDao.findOne(task2Case.getId()) == null){
             List<CaseBlockVO> caseBlockVOS = taskService.getCaseBlocks(paperId).stream().map(caseBlock -> caseBlockVOWrapper.wrap(caseBlock)).collect(Collectors.toList());
             updateCaseAndWeight(paperId,caseBlockVOS);
             return true;
-        } else
+        } else {
             return false;
+        }
 
     }
 
@@ -179,6 +177,9 @@ public class PaperServiceImpl extends BaseService implements PaperService {
                     predicate.getExpressions().add(
                             cb.equal(a.<Long>get("ownerId"), ownerId)
                     );
+                    predicate.getExpressions().add(
+                            cb.equal(a.get("isPublic"),0)
+                    );
                 }else {
                     if(thirdUser!=null) {
                         predicate.getExpressions().add(
@@ -193,10 +194,9 @@ public class PaperServiceImpl extends BaseService implements PaperService {
                             cb.like(a.<String>get("name"), "%" + StringUtils.trim(keyword) + "%")
                     );
                 }
+                predicate.getExpressions().add(cb.equal(a.get("isDeleted"),0));
                 return predicate;
             }
         };
     }
-
-
 }

+ 12 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/UserCatchServiceImpl.java

@@ -0,0 +1,12 @@
+package cn.iselab.mooctest.site.service.impl;
+
+import cn.iselab.mooctest.site.service.UserCatchService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author sean
+ * @date 2017-12-14.
+ */
+@Service
+public class UserCatchServiceImpl implements UserCatchService{
+}

+ 34 - 4
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/service/impl/UserServiceImpl.java

@@ -1,13 +1,12 @@
 package cn.iselab.mooctest.site.service.impl;
 
-import cn.iselab.mooctest.site.dao.OpenId2UserIdDao;
-import cn.iselab.mooctest.site.dao.Role2PermissionDao;
-import cn.iselab.mooctest.site.dao.User2RoleDao;
-import cn.iselab.mooctest.site.dao.UserDao;
+import cn.iselab.mooctest.site.dao.*;
 import cn.iselab.mooctest.site.models.OpenId2UserId;
 import cn.iselab.mooctest.site.models.User;
+import cn.iselab.mooctest.site.models.User2SalesPackage;
 import cn.iselab.mooctest.site.service.BaseService;
 import cn.iselab.mooctest.site.service.UserService;
+import cn.iselab.mooctest.site.web.data.SalesServiceVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
@@ -43,6 +42,9 @@ public class UserServiceImpl extends BaseService implements UserService {
     @Autowired
     private OpenId2UserIdDao openId2UserIdDao;
 
+    @Autowired
+    private User2SalesPackageDao user2SalesPackageDao;
+
     @Override
     public User createUser(User user) {
         User result = userDao.save(user);
@@ -116,6 +118,34 @@ public class UserServiceImpl extends BaseService implements UserService {
 //        return null;
     }
 
+    @Override
+    public List<User2SalesPackage> getUserSalesPackage(Long userId) {
+        return user2SalesPackageDao.findByUserId(userId);
+    }
+
+    @Override
+    public void saveUserSalesPackage(Long userId, SalesServiceVO salesService) {
+        User2SalesPackage saveU2p;
+        User2SalesPackage u2p = user2SalesPackageDao.findByUserIdAndSalesServiceId(userId,salesService.getServiceId());
+        if(u2p==null){
+            saveU2p = new User2SalesPackage();
+            saveU2p.setUserId(userId);
+            saveU2p.setSalesPackageId(salesService.getPackageId());
+            saveU2p.setSalesServiceId(salesService.getServiceId());
+        }else{
+            saveU2p = u2p;
+            saveU2p.setSalesPackageId(salesService.getPackageId());
+        }
+        user2SalesPackageDao.save(saveU2p);
+    }
+
+    @Override
+    public void deleteUserSalesPackage(Long userId, SalesServiceVO salesService) {
+        User2SalesPackage u2p = user2SalesPackageDao.findByUserIdAndSalesServiceId(userId,salesService.getServiceId());
+        if(u2p!=null)
+            user2SalesPackageDao.delete(u2p);
+    }
+
     private Specification<User> getUserWhereClause(String name, String mobile, String email) {
         return new Specification<User>() {
             @Override

+ 7 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/CaseController.java

@@ -95,11 +95,18 @@ public class CaseController extends BaseController {
         return caseLogic.create(caseExtendsVO,user.getId());
     }
 
+    @RequiresPermissions("case:update")
     @RequestMapping(value = UrlConstants.API + "caseGraph", method = RequestMethod.POST)
     public CaseGraphDTO saveCaseGraph(@RequestBody CaseGraphDTO caseGraphDTO) throws Exception{
+        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+        String permissionStr = user.getId().toString() + ":case:update:" + caseGraphDTO.getCaseId().toString();
+        if (!SecurityUtils.getSubject().isPermitted(new CasePermission(permissionStr))) {
+            throw new UnauthorizedException("unauthorized");
+        }
         return caseLogic.saveGraph(caseGraphDTO);
     }
 
+    @RequiresPermissions("case:view")
     @RequestMapping(value = UrlConstants.API + "caseGraph", method = RequestMethod.GET)
     public CaseGraphDTO getCaseGraph(@RequestParam(name = "caseId") Long caseId,
                                      @RequestParam(name = "examId", required = false) Long examId) throws Exception{

+ 35 - 5
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/GroupController.java

@@ -95,17 +95,20 @@ public class GroupController extends BaseController {
             throw new UnauthorizedException("unauthorized");
         }
         Sort sort;
-        if(sortOrder== null || sortOrder.equals("desc"))
-            sort = new Sort(Sort.Direction.DESC,sortBy);
-        else
-            sort = new Sort(Sort.Direction.ASC,sortBy);
+        if(sortOrder== null || "desc".equals(sortOrder)) {
+            sort = new Sort(Sort.Direction.DESC, sortBy);
+        }
+        else {
+            sort = new Sort(Sort.Direction.ASC, sortBy);
+        }
         String activePage = request.getHeader("activePage");
         String rowsOnPage = request.getHeader("rowsOnPage");
         if(activePage == null || rowsOnPage == null) {
             throw new IllegalArgumentException("缺少分页信息");
         }
-        if(keyword == null)
+        if(keyword == null) {
             keyword = "";
+        }
         Pageable pageable = new PageRequest(Integer.parseInt(activePage) - 1, Integer.parseInt(rowsOnPage),sort);
         return groupLogic.getManagerWorkersInGroupPageable(groupId,keyword,pageable);
     }
@@ -184,6 +187,19 @@ public class GroupController extends BaseController {
         return groupLogic.updateAllowJoin(groupId);
     }
 
+    @RequiresPermissions("groupInfo:update")
+    @RequiresRoles(value = "manager")
+    @RequestMapping(value = UrlConstants.API + "group/active/{groupId:\\d+}", method = RequestMethod.PUT)
+    public GroupVO updateActive(@PathVariable("groupId") Long groupId){
+        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+        String permission = user.getId() + ":group:update:" + groupId;
+        if(!SecurityUtils.getSubject().isPermitted(new GroupPermission(permission))) {
+            throw new UnauthorizedException("unauthorized");
+        }
+        return groupLogic.updateGroupActive(groupId);
+    }
+
+
     //do not use
     @RequestMapping(value = UrlConstants.API_MANAGER + "group/{id:\\d+}/worker", method = RequestMethod.POST)
     public WorkerVO addWorkerInGroup(HttpServletRequest request, @PathVariable("id") long groupId,
@@ -237,6 +253,20 @@ public class GroupController extends BaseController {
     @RequestMapping(value = UrlConstants.API + "group/user", method = RequestMethod.GET)
     public List<UserVO> getManagerWorkersInGroup(@RequestParam("groupId") long groupId){
         return groupLogic.getManagerWorkersInGroup(groupId);
+    }
+
+    @RequiresRoles(value = "manager")
+    @RequestMapping(value = UrlConstants.API + "group/userCount", method = RequestMethod.GET)
+    public int getUserTotalCount(){
+        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+        return groupLogic.getUserTotalCount(user.getId());
+    }
 
+    @RequiresRoles(value = "manager")
+    @RequestMapping(value = UrlConstants.API + "group/quota", method = RequestMethod.GET)
+    public int getManagerGroupSize(){
+        User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
+        return groupLogic.getManagerGroupSize(user.getId());
     }
+
 }

+ 3 - 3
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/MessageController.java

@@ -92,9 +92,9 @@ public class MessageController {
 
     @RequiresRoles("manager")
     @RequestMapping(value = UrlConstants.API + "sentMessage", method = RequestMethod.GET)
-    public Page<MessageVO> getSentMessageList(@RequestParam(name = "keyword", required = false) String keyword,
-                                              @RequestParam(name = "sortOrder", required = false) String sortOrder,
-                                              @RequestParam(name = "sortBy", required = false) String sortBy,
+    public Page<MessageVO> getSentMessageList(@RequestParam(name = "keyword", required = false, defaultValue = "") String keyword,
+                                              @RequestParam(name = "sortOrder", required = false, defaultValue = "desc") String sortOrder,
+                                              @RequestParam(name = "sortBy", required = false, defaultValue = "createTime") String sortBy,
                                               HttpServletRequest request) {
         User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
         String activePage = request.getHeader("activePage");

+ 7 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/OSSController.java

@@ -82,4 +82,11 @@ public class OSSController extends BaseController {
         successResult.put("path", request.getHeader("Font-Address")+result);
         return successResult;
     }
+
+    @RequestMapping(value = UrlConstants.API_COMMON + "zip/file", method = RequestMethod.GET)
+    public String getZip(@RequestParam(value = "examId")Long examId,
+                         @RequestParam(value = "workerId")Long workerId,
+                         @RequestParam(value = "fileName")String fileName) throws Exception{
+        return ossLogic.zipFile(examId,workerId,fileName);
+    }
 }

+ 5 - 4
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/PaperController.java

@@ -95,10 +95,11 @@ public class PaperController {
                                       @RequestParam(name = "caseId", required = false) Long caseId,
                                       HttpServletRequest request) {
         Sort sort;
-        if(sortOrder.equals("desc"))
-            sort = new Sort(Sort.Direction.DESC,sortBy);
-        else
-            sort = new Sort(Sort.Direction.ASC,sortBy);
+        if(sortOrder.equals("desc")) {
+            sort = new Sort(Sort.Direction.DESC, sortBy);
+        } else {
+            sort = new Sort(Sort.Direction.ASC, sortBy);
+        }
         String activePage = request.getHeader("activePage");
         String rowsOnPage = request.getHeader("rowsOnPage");
         if(activePage == null || rowsOnPage == null) {

+ 9 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ScoreController.java

@@ -3,6 +3,7 @@ package cn.iselab.mooctest.site.web.ctrl;
 import cn.iselab.mooctest.site.common.constant.UrlConstants;
 import cn.iselab.mooctest.site.common.web.SuccessResult;
 import cn.iselab.mooctest.site.web.data.WeightDirtyVO;
+import cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO;
 import cn.iselab.mooctest.site.web.logic.CalculateSocreLogic;
 import org.apache.shiro.authz.annotation.RequiresRoles;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -21,6 +22,7 @@ public class ScoreController extends BaseController{
     @Autowired
     private CalculateSocreLogic calculateSocreLogic;
 
+
     //一次考试的一道题的所有人的分
     @RequestMapping(value= UrlConstants.API+"score/{taskId}/{caseId}", method = RequestMethod.PUT)
     public void CalculateScore(@PathVariable("taskId") long taskId,@PathVariable("caseId") long caseId) throws Exception{
@@ -50,4 +52,11 @@ public class ScoreController extends BaseController{
         calculateSocreLogic.calculateAllMutationScore(examId, caseId);
         return SuccessResult.ok();
     }
+
+    @RequestMapping(value = UrlConstants.API + "caughtNode", method = RequestMethod.POST)
+    public CaughtNodeDTO catchNode(@RequestBody CaughtNodeDTO caughtNodeDTO,
+                                   @RequestParam(name = "userId") Long userId) throws Exception{
+        return calculateSocreLogic.catchNode(caughtNodeDTO, userId);
+    }
+
 }

+ 14 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/UserController.java

@@ -11,6 +11,7 @@ import cn.iselab.mooctest.site.service.OpenId2UserIdService;
 import cn.iselab.mooctest.site.service.RecordService;
 import cn.iselab.mooctest.site.service.UserService;
 import cn.iselab.mooctest.site.web.data.ManagerPropertyVO;
+import cn.iselab.mooctest.site.web.data.UserPackageVO;
 import cn.iselab.mooctest.site.web.data.UserVO;
 import cn.iselab.mooctest.site.web.data.wrapper.UserVOWrapper;
 import cn.iselab.mooctest.site.web.exception.HttpBadRequestException;
@@ -20,7 +21,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 org.apache.shiro.SecurityUtils;
-import org.apache.shiro.authc.*;
+import org.apache.shiro.authz.annotation.Logical;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.apache.shiro.authz.annotation.RequiresRoles;
 import org.apache.shiro.subject.Subject;
@@ -253,4 +254,16 @@ public class UserController {
     public UserVO resetPassword(@RequestBody UserVO userVO) {
         return userLogic.resetPassword(userVO);
     }
+
+    @RequiresRoles(logical = Logical.OR, value={"admin", "manager"})
+    @RequestMapping(value = UrlConstants.API + "userPackage", method = RequestMethod.GET)
+    public UserPackageVO getUserPackage(@RequestParam(name = "email") String email){
+        return userLogic.getUserPackage(email);
+    }
+
+    @RequiresRoles("admin")
+    @RequestMapping(value = UrlConstants.API + "userPackage", method = RequestMethod.POST)
+    public UserPackageVO saveUserPackage(@RequestBody UserPackageVO userPackageVO){
+        return userLogic.saveUserPackage(userPackageVO);
+    }
 }

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

@@ -39,6 +39,8 @@ public class AssignedTaskVO extends BaseVO {
 
     private Integer status;
 
+    private String resultZip;
+
     public Long getId() {
         return id;
     }
@@ -150,4 +152,12 @@ public class AssignedTaskVO extends BaseVO {
     public void setWorkerSchool(String workerSchool) {
         this.workerSchool = workerSchool;
     }
+
+    public String getResultZip() {
+        return resultZip;
+    }
+
+    public void setResultZip(String resultZip) {
+        this.resultZip = resultZip;
+    }
 }

+ 11 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/GroupVO.java

@@ -17,11 +17,14 @@ public class GroupVO extends CaptchaBaseVO {
     private Integer workerCount;
     private Boolean allowJoin;
     private Long ownerId;
+    private Boolean isActive;
 
+    @Override
     public String getCaptcha() {
         return captcha;
     }
 
+    @Override
     public void setCaptcha(String captcha) {
         this.captcha = captcha;
     }
@@ -91,4 +94,12 @@ public class GroupVO extends CaptchaBaseVO {
     public Long getOwnerId(){
         return this.ownerId;
     }
+
+    public Boolean getIsActive() {
+        return isActive;
+    }
+
+    public void setIsActive(Boolean active) {
+        isActive = active;
+    }
 }

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

@@ -17,6 +17,8 @@ public class MessageVO {
 
     private Long participantId;
 
+    private String participantName;
+
     private String message;
 
     private Boolean isPushed;
@@ -88,4 +90,12 @@ public class MessageVO {
     public void setCreateTime(Long createTime) {
         this.createTime = createTime;
     }
+
+    public String getParticipantName() {
+        return participantName;
+    }
+
+    public void setParticipantName(String participantName) {
+        this.participantName = participantName;
+    }
 }

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

@@ -0,0 +1,16 @@
+package cn.iselab.mooctest.site.web.data;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Created by tangshanshan on 2017/12/13.
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class SalesPackageVO {
+    Long id;
+    String name;
+}

+ 13 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/SalesServiceVO.java

@@ -0,0 +1,13 @@
+package cn.iselab.mooctest.site.web.data;
+
+import lombok.Data;
+
+/**
+ * Created by tangshanshan on 2017/12/13.
+ */
+@Data
+public class SalesServiceVO {
+    Long serviceId;
+    String serviceName;
+    Long packageId;
+}

+ 19 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/UserPackageVO.java

@@ -0,0 +1,19 @@
+package cn.iselab.mooctest.site.web.data;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * Created by tangshanshan on 2017/12/13.
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class UserPackageVO {
+    Long userId;
+    List<SalesPackageVO> salesPackages;
+    List<SalesServiceVO> salesServices;
+}

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

@@ -0,0 +1,29 @@
+package cn.iselab.mooctest.site.web.data.forMongo.NodeCatch;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author sean
+ * @date 2017-12-14.
+ */
+@Data
+public class CaughtNodeDTO {
+
+    //unique
+    private Long id;
+
+    private Long examId;
+
+    private Long caseId;
+
+    private String nodeName;
+
+    private List<Long> userIds;
+
+    //default
+    private Integer catchNum = 0;
+
+    private Integer totalNum;
+}

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

@@ -0,0 +1,31 @@
+package cn.iselab.mooctest.site.web.data.forMongo.NodeCatch;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author sean
+ * @date 2017-12-14.
+ */
+@Data
+public class UserCatchDTO {
+
+    //unique
+    private Long id;
+
+    private Long userId;
+
+    private List<String> nodeNames;
+
+    public Boolean checkNodeNameUnique() {
+        long count = nodeNames.size();
+        long distinctCount = nodeNames.stream().distinct().count();
+        Boolean unique = count == distinctCount;
+        if (!unique) {
+            throw new IllegalArgumentException("node name must be unique!");
+        }
+        return unique;
+    }
+
+}

+ 2 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/forMongo/caseGraph/Node.java

@@ -11,5 +11,6 @@ public class Node {
     String description;
     String category;
     String img;
-    Integer catchBy;
+    Integer catchNum;
+    Integer totalNum;
 }

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

@@ -33,6 +33,8 @@ public class MessageVOWrapper extends BaseWrapper<MessageVO, Message> {
 
         User user = userService.findByUserId(message.getOwnerId());
         messageVO.setOwnerName(user.getName());
+        User participant = userService.findByUserId(message.getParticipantId());
+        messageVO.setParticipantName(participant.getName());
         return messageVO;
     }
 

+ 11 - 3
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/wrapper/PaperVOWrapper.java

@@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.stereotype.Service;
 
+import java.sql.Timestamp;
 import java.util.List;
 
 /**
@@ -79,8 +80,17 @@ public class PaperVOWrapper extends BaseWrapper<PaperVO, Paper> {
 
         Paper paper = new Paper();
         paper.setName(vo.getName());
-        if(vo.getId() != null)
+        if(vo.getId() != null) {
             paper.setId(vo.getId());
+            Paper p = paperService.getById(vo.getId());
+            paper.setIsPublic(p.getIsPublic());
+            paper.setIsDeleted(p.getIsDeleted());
+            paper.setCreateTime(p.getCreateTime());
+        }else {
+            paper.setCreateTime(new Timestamp(System.currentTimeMillis()));
+            paper.setIsDeleted(false);
+            paper.setIsPublic(false);
+        }
         paper.setDescription(vo.getDescription());
         paper.setOwnerId(vo.getOwnerId());
         if(vo.getDifficult() == null) {
@@ -88,8 +98,6 @@ public class PaperVOWrapper extends BaseWrapper<PaperVO, Paper> {
         } else {
             paper.setDifficult(vo.getDifficult());
         }
-        paper.setIsPublic(vo.isVisible());
-        paper.setOwnerId(vo.getOwnerId());
         return paper;
     }
 

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

@@ -0,0 +1,51 @@
+package cn.iselab.mooctest.site.web.data.wrapper;
+
+import cn.iselab.mooctest.site.dao.SalesPackageDao;
+import cn.iselab.mooctest.site.dao.SalesServiceDao;
+import cn.iselab.mooctest.site.models.SalesPackage;
+import cn.iselab.mooctest.site.models.SalesService;
+import cn.iselab.mooctest.site.models.User2SalesPackage;
+import cn.iselab.mooctest.site.web.data.SalesPackageVO;
+import cn.iselab.mooctest.site.web.data.UserPackageVO;
+import cn.iselab.mooctest.site.web.data.SalesServiceVO;
+import org.apache.commons.collections.IteratorUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Created by tangshanshan on 2017/12/13.
+ */
+@Service
+public class SalesPackageVOWrapper{
+    @Autowired
+    private SalesServiceDao salesServiceDao;
+    @Autowired
+    private SalesPackageDao salesPackageDao;
+
+    public UserPackageVO wrap(List<User2SalesPackage> user2SalesPackages, Long userId) {
+        List<SalesPackage> packageList = IteratorUtils.toList(salesPackageDao.findAll().iterator());
+        List<SalesService> serviceList = IteratorUtils.toList(salesServiceDao.findAll().iterator());
+
+        List<SalesPackageVO> PackageVOList = packageList.stream().map(salesPackage -> {
+            return new SalesPackageVO(salesPackage.getId(),salesPackage.getName());
+        }).collect(Collectors.toList());
+
+        List<SalesServiceVO> serviceVOList = serviceList.stream().map(salesService -> {
+            SalesServiceVO salesServiceVO = new SalesServiceVO();
+            salesServiceVO.setServiceId(salesService.getId());
+            salesServiceVO.setServiceName(salesService.getName());
+            for(User2SalesPackage u2p:user2SalesPackages){
+                if(u2p.getSalesServiceId().equals(salesService.getId())){
+                    salesServiceVO.setPackageId(u2p.getSalesPackageId());
+                    break;
+                }
+            }
+            return salesServiceVO;
+        }).collect(Collectors.toList());
+
+        return new UserPackageVO(userId,PackageVOList,serviceVOList);
+    }
+}

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

@@ -1,6 +1,7 @@
 package cn.iselab.mooctest.site.web.logic;
 
 import cn.iselab.mooctest.site.web.data.WeightDirtyVO;
+import cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO;
 
 import java.io.IOException;
 import java.util.List;
@@ -17,4 +18,6 @@ public interface CalculateSocreLogic {
     public List<Double> calculateExamScoreAuto(long examId,long participantId);
 
     void calculateAllMutationScore(long examId,long caseId) throws IOException;
+
+    CaughtNodeDTO catchNode(CaughtNodeDTO caughtNodeDTO, Long userId);
 }

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

@@ -54,4 +54,10 @@ public interface GroupLogic {
     GroupVO updateAllowJoin(long managerId, GroupVO groupVO);
 
     GroupVO updateAllowJoin(long groupId);
+
+    GroupVO updateGroupActive(Long groupId);
+
+    int getUserTotalCount(long managerId);
+
+    int getManagerGroupSize(long managerId);
 }

+ 5 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/OSSLogic.java

@@ -30,7 +30,11 @@ public interface OSSLogic {
 
     String getSubmitSiganature(String path,Long examId,Long caseId,Long workerId,String fileName);
 
-    boolean downloadByUrl(String url,String file) throws Exception;
+    boolean downloadByUrl(String url,String file,String fileName) throws Exception;
 
     String saveFile(MultipartFile file, String path) throws IOException;
+
+    String zipFile(Long examId,Long workerId,String fileName) throws Exception;
+
+    String zipFilePath(String fileName);
 }

+ 5 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/UserLogic.java

@@ -1,6 +1,7 @@
 package cn.iselab.mooctest.site.web.logic;
 
 import cn.iselab.mooctest.site.web.data.ManagerPropertyVO;
+import cn.iselab.mooctest.site.web.data.UserPackageVO;
 import cn.iselab.mooctest.site.web.data.UserVO;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
@@ -60,4 +61,8 @@ public interface UserLogic {
     Page<UserVO> getUserListByRoleId(Long roleId, Pageable pageable);
 
     Page<UserVO> getUserListOfFuzzySearch(String name, String mobile, String email, Pageable pageable);
+
+    UserPackageVO getUserPackage(String email);
+
+    UserPackageVO saveUserPackage(UserPackageVO userPackageVO);
 }

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

@@ -2,7 +2,10 @@ package cn.iselab.mooctest.site.web.logic.impl;
 
 import cn.iselab.mooctest.site.common.constant.AnswerWayConstants;
 import cn.iselab.mooctest.site.data.CaseBlock;
-import cn.iselab.mooctest.site.models.*;
+import cn.iselab.mooctest.site.models.AssignedTask;
+import cn.iselab.mooctest.site.models.CaseExtends;
+import cn.iselab.mooctest.site.models.Exam2Case;
+import cn.iselab.mooctest.site.models.Paper;
 import cn.iselab.mooctest.site.rpc.dev.data.CaseMutationDTO;
 import cn.iselab.mooctest.site.rpc.dev.data.LineMutationDTO;
 import cn.iselab.mooctest.site.rpc.dev.data.MutationDTO;
@@ -12,6 +15,7 @@ import cn.iselab.mooctest.site.service.fromDev.AnalysisService;
 import cn.iselab.mooctest.site.service.fromKibug.ScoreRuleService;
 import cn.iselab.mooctest.site.web.data.WeightDirtyVO;
 import cn.iselab.mooctest.site.web.data.forMongo.MutationForMongoDTO;
+import cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO;
 import cn.iselab.mooctest.site.web.data.fromKibug.ScoreRuleItemVO;
 import cn.iselab.mooctest.site.web.exception.HttpNotFoundException;
 import cn.iselab.mooctest.site.web.logic.CalculateSocreLogic;
@@ -46,81 +50,85 @@ public class CalculateScoreLogicImpl implements CalculateSocreLogic {
     MongoAPIService mongoAPIService;
     @Autowired
     AnalysisService analysisService;
+    @Autowired
+    CaughtNodeService caughtNodeService;
+    @Autowired
+    UserCatchService userCatchService;
 
     @Override
     public void calculateScore(long taskId, long caseId) {
-        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){
+        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) {
             calculateScoreService.calculateManual(taskId, caseId);
-            calculateScoreService.calculateScript(taskId,caseId);
-            List<ScoreRuleItemVO> scoreRule = scoreRuleService.getKibugScoreRule(taskId,caseId);
-            calculateScoreService.calculateTotal(taskId,caseId,scoreRule);
-        }else if(subsiteId == AnswerWayConstants.DEV_ECLIPSE){
+            calculateScoreService.calculateScript(taskId, caseId);
+            List<ScoreRuleItemVO> scoreRule = scoreRuleService.getKibugScoreRule(taskId, caseId);
+            calculateScoreService.calculateTotal(taskId, caseId, scoreRule);
+        } else if (subsiteId == AnswerWayConstants.DEV_ECLIPSE) {
             calculateScoreService.calculateDevScore(taskId, caseId);
         }
     }
 
     @Override
     public void calculateScore(long taskId, long caseId, long userId) throws Exception {
-        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){
-            calculateScoreService.calculatePersonalManual(taskId, caseId,userId);
-            calculateScoreService.calculatePersonalScript(taskId,caseId,userId);
-            List<ScoreRuleItemVO> scoreRule = scoreRuleService.getKibugScoreRule(taskId,caseId);
-            calculateScoreService.calculatePersonalTotal(taskId,caseId,userId,scoreRule);
-        }else if(subsiteId == AnswerWayConstants.DEV_ECLIPSE){
-            calculateScoreService.calculatePersonalDevScore(taskId, caseId,userId);
+        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) {
+            calculateScoreService.calculatePersonalManual(taskId, caseId, userId);
+            calculateScoreService.calculatePersonalScript(taskId, caseId, userId);
+            List<ScoreRuleItemVO> scoreRule = scoreRuleService.getKibugScoreRule(taskId, caseId);
+            calculateScoreService.calculatePersonalTotal(taskId, caseId, userId, scoreRule);
+        } else if (subsiteId == AnswerWayConstants.DEV_ECLIPSE) {
+            calculateScoreService.calculatePersonalDevScore(taskId, caseId, userId);
         }
     }
 
     @Override
-    public List<Double> calculateExamScore(long examId, Long participantId,WeightDirtyVO weightDirtyVO, boolean calculateAll){
-        if(calculateAll==false
-                && (weightDirtyVO.getCaseDirty()==null || weightDirtyVO.getCaseDirty().size()==0)
-                && weightDirtyVO.isWeightDirty()==false){
+    public List<Double> calculateExamScore(long examId, Long participantId, WeightDirtyVO weightDirtyVO, boolean calculateAll) {
+        if (calculateAll == false
+                && (weightDirtyVO.getCaseDirty() == null || weightDirtyVO.getCaseDirty().size() == 0)
+                && weightDirtyVO.isWeightDirty() == false) {
             throw new IllegalArgumentException("Illegal Arguments!");
         }
         //获取exam中应有的case
         Paper paper = paperService.getByExamId(examId);
-        if(paper == null) {
+        if (paper == null) {
             throw new IllegalArgumentException("Cannot find paper of this exam.");
         }
         List<CaseBlock> caseBlocks = taskService.getCaseBlocks(paper.getId());
         List<Long> casesId = new ArrayList<>();
-        for(CaseBlock caseBlock :caseBlocks){
-            for(Long caseId : caseBlock.getCaseIds()) {
+        for (CaseBlock caseBlock : caseBlocks) {
+            for (Long caseId : caseBlock.getCaseIds()) {
                 casesId.add(caseId);
             }
         }
 
         //为null表示为发布成绩时,计算所有case的小分,再计算总分
-        if(calculateAll == true) {
-            for(Long caseId:casesId){
-                calculateScore(examId,caseId);
+        if (calculateAll == true) {
+            for (Long caseId : casesId) {
+                calculateScore(examId, caseId);
             }
-        }else if(weightDirtyVO.getCaseDirty() != null && weightDirtyVO.getCaseDirty().size() != 0){
+        } else if (weightDirtyVO.getCaseDirty() != null && weightDirtyVO.getCaseDirty().size() != 0) {
             //如果不为null,并且有小评分规则变动,表示保存评分规则时,需要对更改的评分规则的case进行计算,再计算总分
-            for(Long caseId:weightDirtyVO.getCaseDirty()){
-                if(casesId.contains(caseId))
-                    calculateScore(examId,caseId);
+            for (Long caseId : weightDirtyVO.getCaseDirty()) {
+                if (casesId.contains(caseId))
+                    calculateScore(examId, caseId);
             }
         }
         //最后计算task的总分
         List<Double> scores = new ArrayList<>();
-        if(participantId != null){
-            AssignedTask assignedTask=assignedTaskService.getAssignedTask(examId,participantId);
-            double score = calculateOneScore(assignedTask,examId);
+        if (participantId != null) {
+            AssignedTask assignedTask = assignedTaskService.getAssignedTask(examId, participantId);
+            double score = calculateOneScore(assignedTask, examId);
             assignedTask.setScore(score);
             scores.add(score);
             assignedTaskService.saveOrUpdateAssignedTask(assignedTask);
-        }else{
+        } else {
             List<AssignedTask> assignedTasks = assignedTaskService.getAssignedTasks(examId);
-            for(AssignedTask assignedTask : assignedTasks){
-                double score = calculateOneScore(assignedTask,examId);
+            for (AssignedTask assignedTask : assignedTasks) {
+                double score = calculateOneScore(assignedTask, examId);
                 assignedTask.setScore(score);
                 scores.add(score);
             }
@@ -134,7 +142,7 @@ public class CalculateScoreLogicImpl implements CalculateSocreLogic {
         WeightDirtyVO weightDirtyVO = new WeightDirtyVO();
         weightDirtyVO.setWeightDirty(true);
         weightDirtyVO.setCaseDirty(null);
-        return this.calculateExamScore(examId,participantId,weightDirtyVO,false);
+        return this.calculateExamScore(examId, participantId, weightDirtyVO, false);
     }
 
     @Override
@@ -144,7 +152,7 @@ public class CalculateScoreLogicImpl implements CalculateSocreLogic {
         Map<String, Integer> mutationTotalKilledMap = new HashMap<>();
         List<MutationForMongoDTO> mutationForMongoDTOS = mongoAPIService.getMutationFromMongo(null, examId, caseId);
 
-        if(mutationForMongoDTOS == null && mutationForMongoDTOS.size() == 0)
+        if (mutationForMongoDTOS == null && mutationForMongoDTOS.size() == 0)
             throw new HttpNotFoundException("该考试的这道题没有变异成绩。");
         for (MutationForMongoDTO mutationForMongoDTO : mutationForMongoDTOS) {
             statisMutation(mutationTotalKilledMap, mutationForMongoDTO.getMutationDTO());
@@ -168,11 +176,11 @@ public class CalculateScoreLogicImpl implements CalculateSocreLogic {
 
 
     private double calculateMutationScore(MutationForMongoDTO mutationForMongoDTO, Map<String, Double> mutationScoreMap,
-                                    final double baseScore) {
+                                          final double baseScore) {
         double sum = 0;
         for (CaseMutationDTO caseMutation : mutationForMongoDTO.getMutationDTO().getDetailList()) {
             for (LineMutationDTO lineMutation : caseMutation.getEachMutantsResult()) {
-                if(lineMutation.isKilled()) {
+                if (lineMutation.isKilled()) {
                     String key = caseMutation.getClassName() + lineMutation.getMutantId();
                     double score = mutationScoreMap.get(key);
                     sum += score;
@@ -185,15 +193,15 @@ public class CalculateScoreLogicImpl implements CalculateSocreLogic {
     private double calculateBaseScore(Map<String, Double> mutationScoreMap) {
         List<Double> scores = (List<Double>) mutationScoreMap.values();
         double sum = 0;
-        for(Double score : scores) {
+        for (Double score : scores) {
             sum += score;
         }
         return sum;
     }
 
     private Map<String, Double> generatePerMutationScore(Map<String, Integer> mutationTotalKilledMap,
-                                          List<MutationForMongoDTO> mutationForMongoDTOS,
-                                          final double scoreOfPerMutation) {
+                                                         List<MutationForMongoDTO> mutationForMongoDTOS,
+                                                         final double scoreOfPerMutation) {
         Map<String, Double> mutationScoreMap = new HashMap<>();
         MutationForMongoDTO mutationForMongoDTO = mutationForMongoDTOS.get(0);
         mutationForMongoDTO.getMutationDTO().getDetailList().forEach(caseMutation -> {
@@ -212,42 +220,63 @@ public class CalculateScoreLogicImpl implements CalculateSocreLogic {
 
     private void statisMutation(Map<String, Integer> mutationTotalKilledMap, MutationDTO mutationDTO) {
         mutationDTO.getDetailList().forEach(caseMutation -> {
-                caseMutation.getEachMutantsResult().forEach(lineMutation -> {
-                    if(lineMutation.isKilled()) {
-                        String key = caseMutation.getClassName() + lineMutation.getMutantId();
-                        Integer count = mutationTotalKilledMap.get(key);
-                        if(count != null) {
-                            count = 0;
-                        }
-                        count = count + 1;
-                        mutationTotalKilledMap.put(key, count);
+            caseMutation.getEachMutantsResult().forEach(lineMutation -> {
+                if (lineMutation.isKilled()) {
+                    String key = caseMutation.getClassName() + lineMutation.getMutantId();
+                    Integer count = mutationTotalKilledMap.get(key);
+                    if (count != null) {
+                        count = 0;
                     }
-                });
+                    count = count + 1;
+                    mutationTotalKilledMap.put(key, count);
+                }
+            });
 
         });
     }
-    
 
-    private double calculateOneScore(AssignedTask assignedTask,long examId){
-        String result=assignedTask.getResult();
+
+    private double calculateOneScore(AssignedTask assignedTask, long examId) {
+        String result = assignedTask.getResult();
         JSONObject cases = new JSONObject(result).getJSONObject("results");
-        Iterator it=cases.keys();
+        Iterator it = cases.keys();
         double score = 0.0;
-        while(it.hasNext()){
+        while (it.hasNext()) {
             String id = (String) it.next();
             JSONObject caseInfo = cases.getJSONObject(id);
-            if(!caseInfo.has("maxScore")){
+            if (!caseInfo.has("maxScore")) {
                 continue;
             }
             double maxScore = caseInfo.getDouble("maxScore");
             long caseId = caseInfo.getLong("id");
-            List<Exam2Case> exam2Cases = exam2CaseService.findByExamIdAndCaseId(examId,caseId);
-            if(exam2Cases.size() == 0){
-                throw new IllegalArgumentException("Cannot find case's ["+ caseId + "] weight");
+            List<Exam2Case> exam2Cases = exam2CaseService.findByExamIdAndCaseId(examId, caseId);
+            if (exam2Cases.size() == 0) {
+                throw new IllegalArgumentException("Cannot find case's [" + caseId + "] weight");
             }
             double weight = exam2Cases.get(0).getWeight();
             score += weight * maxScore;
         }
         return score;
     }
+
+    @Override
+    public CaughtNodeDTO catchNode(CaughtNodeDTO caughtNodeDTO, Long userId) {
+//        //userCatch
+//        UserCatchDTO userCatchDTO = userCatchService.getUserCatchDTO(userId);
+//        List<String> nodeNames = userCatchDTO.getNodeNames();
+//        nodeNames.add(caughtNodeDTO.getNodeName());
+//        userCatchDTO.setNodeNames(nodeNames);
+//        if (userCatchDTO.checkNodeNameUnique()) {
+//            userCatchService.updateUserCatchDTO(userCatchDTO);
+//        }
+//        return null;
+//        //caughtNode
+//        caughtNodeDTO = caughtNodeService.getCaughtNodeDTO(caughtNodeDTO.getExamId(), caughtNodeDTO.getCaseId(), caughtNodeDTO.getNodeName());
+//        List<Long> userIds = caughtNodeDTO.getUserIds();
+//        userIds.add(userId);
+//        caughtNodeDTO.setUserIds(userIds);
+//        caughtNodeDTO.setCatchNum(caughtNodeDTO.getCatchNum() + 1);
+//        return caughtNodeService.updateCaughtNodeDTO(caughtNodeDTO);
+        return null;
+    }
 }

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

@@ -19,6 +19,7 @@ import cn.iselab.mooctest.site.service.instancePermission.CasePermissionService;
 import cn.iselab.mooctest.site.web.data.CaseExtendsVO;
 import cn.iselab.mooctest.site.web.data.CaseVO;
 import cn.iselab.mooctest.site.web.data.KeyAnalysisVO;
+import cn.iselab.mooctest.site.web.data.forMongo.NodeCatch.CaughtNodeDTO;
 import cn.iselab.mooctest.site.web.data.forMongo.caseGraph.CaseGraphDTO;
 import cn.iselab.mooctest.site.web.data.forMongo.caseGraph.Node;
 import cn.iselab.mooctest.site.web.data.wrapper.AppVOWrapper;
@@ -443,8 +444,17 @@ public class CaseLogicImpl implements CaseLogic {
     public CaseGraphDTO getGraph(Long caseId, Long examId) {
         CaseGraphDTO caseGraphDTO = caseGraphService.getCaseGraph(caseId);
         if(caseGraphDTO!=null) {
+            Map<String, CaughtNodeDTO> nodeCatchMap;
+            if(examId==null){
+                nodeCatchMap = caseGraphService.getNodeCatchMap(caseId);
+            }else{
+                nodeCatchMap = caseGraphService.getNodeCatchMapWithExamId(caseId, examId);
+            }
             List<Node> nodes = caseGraphDTO.getNodes().stream().map(node -> {
-                node.setCatchBy(0);
+                if(nodeCatchMap.containsKey(node.getName())){
+                    node.setCatchNum(nodeCatchMap.get(node.getName()).getCatchNum());
+                    node.setTotalNum(nodeCatchMap.get(node.getName()).getTotalNum());
+                }
                 return node;
             }).collect(Collectors.toList());
             caseGraphDTO.setNodes(nodes);

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

@@ -15,10 +15,7 @@ import cn.iselab.mooctest.site.web.data.wrapper.ScoreVOWrapper;
 import cn.iselab.mooctest.site.web.exception.AssignedTaskNotExistException;
 import cn.iselab.mooctest.site.web.exception.HttpBadRequestException;
 import cn.iselab.mooctest.site.web.exception.HttpNotFoundException;
-import cn.iselab.mooctest.site.web.logic.BaseLogic;
-import cn.iselab.mooctest.site.web.logic.ContestLogic;
-import cn.iselab.mooctest.site.web.logic.ExamLogic;
-import cn.iselab.mooctest.site.web.logic.GroupLogic;
+import cn.iselab.mooctest.site.web.logic.*;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.convert.converter.Converter;
@@ -96,6 +93,9 @@ public class ExamLogicImpl extends BaseLogic implements ExamLogic {
     @Autowired
     ReportPermissionService reportPermissionService;
 
+    @Autowired
+    OSSLogic ossLogic;
+
     @Override
     public ExamVO getExamById(long examId) {
         Task task = taskService.getTask(examId);
@@ -234,6 +234,7 @@ public class ExamLogicImpl extends BaseLogic implements ExamLogic {
                 vo.setWorkerName(participant.getName());
                 vo.setWorkerSchool(participant.getSchool());
                 vo.setAssignedCases(assignedCaseVOWrapper.wrap(assignedTaskService.wrapAssignedCases(assignedTask)));
+                vo.setResultZip(ossLogic.zipFilePath(participant.getName()+"_"+assignedTask.getName()));
                 return vo;
             }
         });

+ 44 - 9
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/GroupLogicImpl.java

@@ -2,10 +2,7 @@ package cn.iselab.mooctest.site.web.logic.impl;
 
 import cn.iselab.mooctest.site.models.*;
 import cn.iselab.mooctest.site.models.instancePermission.GroupPermission;
-import cn.iselab.mooctest.site.service.GroupService;
-import cn.iselab.mooctest.site.service.ManagerService;
-import cn.iselab.mooctest.site.service.UserService;
-import cn.iselab.mooctest.site.service.WorkerService;
+import cn.iselab.mooctest.site.service.*;
 import cn.iselab.mooctest.site.service.instancePermission.GroupPermissionService;
 import cn.iselab.mooctest.site.web.data.GroupVO;
 import cn.iselab.mooctest.site.web.data.UserVO;
@@ -66,6 +63,9 @@ public class GroupLogicImpl extends BaseLogic implements GroupLogic {
     @Autowired
     private UserVOWrapper userVOWrapper;
 
+    @Autowired
+    private ManagerPropertyService managerPropertyService;
+
     @Override
     public List<GroupVO> getManagerGroups(long managerId) {
         List<Group> groups = groupService.getGroupsByManagerId(managerId);
@@ -121,8 +121,9 @@ public class GroupLogicImpl extends BaseLogic implements GroupLogic {
         List<Group> groupList=groupService.getGroupsByParticipantId(participantId);
         List<GroupVO> groupVOList=new ArrayList<GroupVO>();
         groupList.stream().forEach(group -> {
-            if(group.getId()!=0)
-                groupVOList.add(Converter.convert(GroupVO.class,group));
+            if(group.getId()!=0) {
+                groupVOList.add(Converter.convert(GroupVO.class, group));
+            }
         });
         return groupVOList;
     }
@@ -230,8 +231,9 @@ public class GroupLogicImpl extends BaseLogic implements GroupLogic {
         User user = (User) SecurityUtils.getSubject().getSession().getAttribute("User");
         groupVO.setOwnerId(user.getId());
         for(Group group:groupService.getGroupsByOwnerId(groupVO.getOwnerId())){
-            if(name.equals(group.getName()))
+            if(name.equals(group.getName())) {
                 throw new HttpBadRequestException("Group name already created by this manager");
+            }
         }
         if(name.length() > 25){
             throw new HttpBadRequestException("Group name exceed 25 chars");
@@ -250,10 +252,16 @@ public class GroupLogicImpl extends BaseLogic implements GroupLogic {
     //Rewirte by HenryLee 2017.7.15
     @Override
     public GroupVO joinGroup(HttpServletRequest request, long userId, GroupVO groupVO) {
-
+        Group group = groupService.getGroup(groupVO.getId());
+        if(group.getIsActive() == false) {
+            throw new HttpBadRequestException("班级已关闭");
+        }
+        long managerId = group.getOwnerId();
+        if(!groupService.checkManagerGroupSize(managerId)) {
+            throw new HttpBadRequestException("Over max group size");
+        }
         if ( groupVO.getCaptcha()!=null && ( groupVO.getCaptcha().equals("summer") || CaptchaUtils.verifyPictureCaptcha(request, groupVO.getCaptcha()))) {
             String managerName = groupVO.getManagerName();
-            Group group = groupService.getGroup(groupVO.getId());
             User user=userService.findByUserId(group.getOwnerId());
             if(!group.getAllowJoin()){
                 throw new HttpForbiddenException("Group not allowed to join");
@@ -312,6 +320,12 @@ public class GroupLogicImpl extends BaseLogic implements GroupLogic {
         if (group == null) {
             throw new HttpNotFoundException("班级[id=" + groupId + "]不存在!");
         }
+        if(group.getIsActive() == false) {
+            throw new HttpBadRequestException("班级已关闭");
+        }
+        if(!groupService.checkManagerGroupSize(group.getOwnerId())) {
+            throw new HttpBadRequestException("Over max group size");
+        }
         User user=userService.findByUsername(userName);
         if(user==null){
             throw new HttpNotFoundException("用户[" + userName + "]不存在!");
@@ -403,6 +417,27 @@ public class GroupLogicImpl extends BaseLogic implements GroupLogic {
     }
 
     @Override
+    public GroupVO updateGroupActive(Long groupId) {
+        Group group = groupService.getGroup(groupId);
+        group.setIsActive(false);
+        return Converter.convert(GroupVO.class,groupService.save(group));
+    }
+
+    @Override
+    public int getUserTotalCount(long managerId) {
+        return groupService.getUserTotalCount(managerId);
+    }
+
+    @Override
+    public int getManagerGroupSize(long managerId) {
+        ManagerProperty managerProperty = managerPropertyService.getManagerPropertyByUserId(managerId);
+        if(managerProperty == null) {
+            throw new HttpBadRequestException("manager don't exist");
+        }
+        return managerProperty.getGroupSize();
+    }
+
+    @Override
     public GroupVO joinGroupByQrCode(long userId,long groupId){
         Group group = groupService.getGroup(groupId);
 

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

@@ -7,14 +7,16 @@ import cn.iselab.mooctest.site.web.exception.HttpBadRequestException;
 import cn.iselab.mooctest.site.web.logic.OSSLogic;
 import com.aliyun.oss.HttpMethod;
 import com.aliyun.oss.OSSClient;
-import com.aliyun.oss.model.GeneratePresignedUrlRequest;
-import com.aliyun.oss.model.OSSObject;
+import com.aliyun.oss.model.*;
 import com.aliyuncs.DefaultAcsClient;
 import com.aliyuncs.exceptions.ClientException;
 import com.aliyuncs.http.MethodType;
 import com.aliyuncs.http.ProtocolType;
 import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
 import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
+import net.lingala.zip4j.core.ZipFile;
+import net.lingala.zip4j.model.ZipParameters;
+import net.lingala.zip4j.util.Zip4jConstants;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.FilenameUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -22,9 +24,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 import java.net.URL;
 import java.util.Date;
 import java.util.List;
@@ -58,6 +58,8 @@ public class OSSLogicImpl implements OSSLogic {
 
     private long maxUploadSizeInMb = 100 * 1024 * 1204; //100MB
     private String UPLOADED_PATH="/download/";
+    private String SAVE_PATH="/var/www/download/";
+    private String ZIP_PATH="zip/";
 
     @Override
     public String getAppPresignUrl(String appName) {
@@ -160,8 +162,7 @@ public class OSSLogicImpl implements OSSLogic {
     }
 
     @Override
-    public boolean downloadByUrl(String url,String filePath) throws Exception {
-        String fileName = FilenameUtils.getName(url);
+    public boolean downloadByUrl(String url,String filePath,String fileName) throws Exception {
         if (fileName == null)
             return false;
         File directory = new File(filePath);
@@ -202,4 +203,41 @@ public class OSSLogicImpl implements OSSLogic {
         file.transferTo(saveFile);
         return fileName;
     }
+
+    @Override
+    public String zipFile(Long examId,Long workerId,String fileName) throws Exception{
+        File file=new File(SAVE_PATH+ZIP_PATH+fileName+".zip");
+        if(!file.exists()){
+            File folder=new File(FileUtils.getUserDirectory()+"/"+fileName);
+            if(!folder.exists())
+                folder.mkdirs();
+            ossClient = new OSSClient(endPoint, accessKeyId, accessKeySecret);
+            ObjectListing listing=ossClient.listObjects(bucketNameDev,"data/answers"+"/"+examId+"/"+workerId+"/");
+            List<OSSObjectSummary> sums = listing.getObjectSummaries();
+            for (OSSObjectSummary s : sums) {
+                String key=s.getKey();
+                String name=key.split("/")[key.split("/").length - 1];
+                ossClient.getObject(new GetObjectRequest(bucketNameDev, key), new File(FileUtils.getUserDirectory()+"/"+fileName+"/"+name));
+            }
+            ossClient.shutdown();
+            ZipFile zipFile=new ZipFile(file);
+            ZipParameters parameters=new ZipParameters();
+            parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
+            parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
+            zipFile.addFolder(folder,parameters);
+            FileUtils.deleteQuietly(folder);
+        }
+        return UPLOADED_PATH+ZIP_PATH+fileName+".zip";
+    }
+
+    @Override
+    public String zipFilePath(String fileName){
+        File file=new File(SAVE_PATH+ZIP_PATH+fileName+".zip");
+        if(file.exists()){
+            return UPLOADED_PATH+ZIP_PATH+fileName+".zip";
+        }
+        else {
+            return null;
+        }
+    }
 }

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

@@ -74,6 +74,9 @@ public class PaperLogicImpl extends BaseLogic implements PaperLogic {
         if(paperService.isUsedByExam(paperId)){
             throw new IllegalArgumentException("试卷已被使用");
         }
+        if(paper.getIsPublic()==true) {
+            throw new IllegalArgumentException("无法删除公开试卷");
+        }
         paperService.deletePaper(paperId);
         return paperVOWrapper.wrap(paper);
     }
@@ -114,6 +117,9 @@ public class PaperLogicImpl extends BaseLogic implements PaperLogic {
         if(paperService.isUsedByExam(paperVO.getId())){
             throw new IllegalArgumentException("试卷已被使用,不可更改");
         }
+        if(paperService.getById(paperVO.getId()).getIsDeleted()) {
+            throw new IllegalArgumentException("试卷已被删除,不可更改");
+        }
         return savePaperVO(paperVO);
     }
 
@@ -133,11 +139,7 @@ public class PaperLogicImpl extends BaseLogic implements PaperLogic {
     public Page<PaperVO> getPaperList(boolean isPublic,String keyword, Pageable pageable) {
         Page<Paper> papers = paperService.findAll(pageable, keyword);
         if(!isPublic){
-            String email = SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal().toString();
-            User user = userService.findByEmail(email);
-            if(user == null){
-                throw new IllegalArgumentException("Can not find user!");
-            }
+            User user = (User)SecurityUtils.getSubject().getSession().getAttribute("User");
             Long ownerId = user.getId();
             papers = paperService.findAllByOwnerId(ownerId,keyword,pageable);
         }
@@ -154,10 +156,12 @@ public class PaperLogicImpl extends BaseLogic implements PaperLogic {
     @Override
     public PaperVO publicityPaper(Long paperId) throws Exception {
         Paper paper= paperService.getById(paperId);
-        if (paper == null)
+        if (paper == null) {
             throw new IllegalArgumentException("Cannot find the paper");
-        if (paper.getIsPublic() == true)
+        }
+        if (paper.getIsPublic() == true) {
             throw new IllegalArgumentException("该试卷已经被公开。");
+        }
         paper.setIsPublic(true);
         //调用修改target公开状态事件
         List<CaseExtendsVO> caseExtends = caseLogic.getCasesByTaskId(paper.getId());

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

@@ -36,6 +36,8 @@ import cn.iselab.mooctest.site.web.logic.CalculateSocreLogic;
 import cn.iselab.mooctest.site.web.logic.OSSLogic;
 import cn.iselab.mooctest.site.web.logic.ReportLogic;
 import cn.iselab.mooctest.site.web.util.Converter;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authz.UnauthorizedException;
 import org.json.JSONArray;
@@ -200,7 +202,7 @@ public class ReportLogicImpl implements ReportLogic {
             if(report!=null) {
                 this.reportSum++;
                 try {
-                    if(ossLogic.downloadByUrl(report.getScriptLocation(), PathConstants.SCRIPTS+"/"+caseTake.getParticipantId())){
+                    if(ossLogic.downloadByUrl(report.getScriptLocation(), PathConstants.SCRIPTS+"/"+caseTake.getParticipantId(), FilenameUtils.getName(report.getScriptLocation()))){
                         this.fileSum++;
                     }
                 }catch (Exception e){

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

@@ -8,12 +8,15 @@ import cn.iselab.mooctest.site.service.*;
 import cn.iselab.mooctest.site.service.instancePermission.GroupPermissionService;
 import cn.iselab.mooctest.site.util.data.EncryptionUtil;
 import cn.iselab.mooctest.site.web.data.ManagerPropertyVO;
+import cn.iselab.mooctest.site.web.data.UserPackageVO;
 import cn.iselab.mooctest.site.web.data.UserVO;
 import cn.iselab.mooctest.site.web.data.wrapper.ManagerPropertyVOWrapper;
 import cn.iselab.mooctest.site.web.data.wrapper.MenuVOWrapper;
+import cn.iselab.mooctest.site.web.data.wrapper.SalesPackageVOWrapper;
 import cn.iselab.mooctest.site.web.data.wrapper.UserVOWrapper;
 import cn.iselab.mooctest.site.web.exception.HttpBadRequestException;
 import cn.iselab.mooctest.site.web.exception.HttpInternalServerError;
+import cn.iselab.mooctest.site.web.exception.HttpNotFoundException;
 import cn.iselab.mooctest.site.web.logic.BaseLogic;
 import cn.iselab.mooctest.site.web.logic.UserLogic;
 import cn.iselab.mooctest.site.web.util.CaptchaUtils;
@@ -28,7 +31,6 @@ import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 
 import javax.servlet.http.HttpServletRequest;
-import java.io.UnsupportedEncodingException;
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.List;
@@ -79,6 +81,9 @@ public class UserLogicImpl extends BaseLogic implements UserLogic {
     @Autowired
     private ContestMentorService contestMentorService;
 
+    @Autowired
+    private SalesPackageVOWrapper salesPackageVOWrapper;
+
     @Override
     public UserVO register(UserVO userVO) {
         if (userService.getUserByEmail(userVO.getEmail()) != null) {
@@ -503,6 +508,27 @@ public class UserLogicImpl extends BaseLogic implements UserLogic {
         }
         return userVOs;
     }
+
+    @Override
+    public UserPackageVO getUserPackage(String email) {
+        User user = userService.findByEmail(email);
+        if(user==null){
+            throw new HttpNotFoundException("用户不存在");
+        }
+        return salesPackageVOWrapper.wrap(userService.getUserSalesPackage(user.getId()), user.getId());
+    }
+
+    @Override
+    public UserPackageVO saveUserPackage(UserPackageVO userPackageVO) {
+        userPackageVO.getSalesServices().stream().forEach(salesService->{
+            if(salesService.getPackageId()==null){
+                userService.deleteUserSalesPackage(userPackageVO.getUserId(),salesService);
+            }else{
+                userService.saveUserSalesPackage(userPackageVO.getUserId(),salesService);
+            }
+        });
+        return userPackageVO;
+    }
 }
 
 

+ 8 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/util/mongodb/MongoAPIUtils.java

@@ -15,6 +15,10 @@ public class MongoAPIUtils {
     public static final String MONGODB_COLLECTION_REPORT= "report";
     public static final String MONGODB_COLLECTION_MUTATION = "mutation";
     public static final String MONGODB_COLLECTION_CASE_GRAPH = "caseGraph";
+    public static final String MONGODB_COLLECTION_CAUGHT_NODE = "caughtNode";
+    public static final String MONGODB_COLLECTION_USER_CATCH = "userCatch";
+
+    public static final String MONGODB_AGGREGATION_SUM_CATCH = "sumCatch";
 
     public static final String BASE64_AUTH = "Basic YWRtaW46Y2hhbmdlaXQ=";
 
@@ -29,6 +33,10 @@ public class MongoAPIUtils {
         return generateCommonUrl(dbName, collectionName) + "?filter={filter}";
     }
 
+    public static String generateAggrUrl(String dbName, String collectionName, String Aggr) {
+        return generateCommonUrl(dbName, collectionName) + "/_aggrs/"+Aggr+"?avars={avars}";
+    }
+
     public static String generateUrlWithResourceId(String dbName, String collectionName, String resourceId) {
         return generateCommonUrl(dbName, collectionName) + "/" + resourceId;
     }