Переглянути джерело

增加了个人证书和任务金额计算的功能

linyk 2 роки тому
батько
коміт
029409b9dd
34 змінених файлів з 816 додано та 143 видалено
  1. 18 1
      core/src/main/java/com/mooctest/crowd/domain/dao/CrowdTestProjectDao.java
  2. 12 0
      core/src/main/java/com/mooctest/crowd/domain/dao/CrowdTestTaskDao.java
  3. 8 0
      core/src/main/java/com/mooctest/crowd/domain/dao/DefectDao.java
  4. 9 0
      core/src/main/java/com/mooctest/crowd/domain/dao/EvaluationAgencyDao.java
  5. 11 0
      core/src/main/java/com/mooctest/crowd/domain/dao/TaskToUserDao.java
  6. 10 0
      core/src/main/java/com/mooctest/crowd/domain/dao/TestCaseDao.java
  7. 6 0
      core/src/main/java/com/mooctest/crowd/domain/dao/UserDao.java
  8. 3 0
      core/src/main/java/com/mooctest/crowd/domain/dao/UserToRoleDao.java
  9. 6 1
      core/src/main/java/com/mooctest/crowd/domain/model/DefectPO.java
  10. 1 1
      core/src/main/java/com/mooctest/crowd/domain/model/ExceptionLogPO.java
  11. 1 1
      core/src/main/java/com/mooctest/crowd/domain/model/TestCasePO.java
  12. 1 1
      core/src/main/java/com/mooctest/crowd/domain/model/TestEnvPO.java
  13. 49 0
      core/src/main/java/com/mooctest/crowd/domain/repository/CrowdTestProjectRepo.java
  14. 15 2
      core/src/main/java/com/mooctest/crowd/domain/repository/DefectRepo.java
  15. 2 0
      core/src/main/java/com/mooctest/crowd/domain/repository/IDefectRepo.java
  16. 2 0
      core/src/main/java/com/mooctest/crowd/domain/repository/ITestCaseRepo.java
  17. 13 1
      core/src/main/java/com/mooctest/crowd/domain/repository/TestCaseRepo.java
  18. 12 0
      site/pom.xml
  19. 28 3
      site/src/main/java/com/mooctest/crowd/site/controller/CrowdProjectController.java
  20. 20 15
      site/src/main/java/com/mooctest/crowd/site/controller/CrowdTaskController.java
  21. 408 0
      site/src/main/java/com/mooctest/crowd/site/controller/TestCaseController.java
  22. 1 1
      site/src/main/java/com/mooctest/crowd/site/controller/TestEnvController.java
  23. 1 1
      site/src/main/java/com/mooctest/crowd/site/controller/TestToolController.java
  24. 1 1
      site/src/main/java/com/mooctest/crowd/site/controller/advice/ExceptionAdvice.java
  25. 1 86
      site/src/main/java/com/mooctest/crowd/site/data/vo/TaskMoreInfoVO.java
  26. 10 6
      site/src/main/java/com/mooctest/crowd/site/service/CrowdProjectService.java
  27. 3 0
      site/src/main/java/com/mooctest/crowd/site/service/CrowdTaskService.java
  28. 2 0
      site/src/main/java/com/mooctest/crowd/site/service/DefectService.java
  29. 4 0
      site/src/main/java/com/mooctest/crowd/site/service/TestCaseService.java
  30. 91 13
      site/src/main/java/com/mooctest/crowd/site/service/impl/CrowdProjectServiceImpl.java
  31. 18 1
      site/src/main/java/com/mooctest/crowd/site/service/impl/CrowdTaskServiceImpl.java
  32. 15 4
      site/src/main/java/com/mooctest/crowd/site/service/impl/DefectServiceImpl.java
  33. 32 2
      site/src/main/java/com/mooctest/crowd/site/service/impl/TestCaseServiceImpl.java
  34. 2 2
      site/src/main/resources/application.yml

+ 18 - 1
core/src/main/java/com/mooctest/crowd/domain/dao/CrowdTestProjectDao.java

@@ -14,6 +14,7 @@ import org.springframework.data.repository.query.Param;
 
 import javax.transaction.Transactional;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author guochao
@@ -82,8 +83,24 @@ public interface CrowdTestProjectDao extends CrudRepository<CrowdTestProjectPO,
     @Override
     <S extends CrowdTestProjectPO> S save(S s);
 
-
     @Modifying
     @Query(nativeQuery = true,value="update crowd_test_project set CTP_STATUS= ?1 where CTP_CODE=?2")
     void updateStatusByCode(@Param("status") int status, @Param("code") String code);
+
+    int countAllByIsDeleted(int isDeleted);
+
+    @Query(value = "select count(*) from crowd_test_project where DATE_FORMAT(ctp_create_time, '%Y-%m') = :yearMonth and ctp_is_deleted = :isDeleted", nativeQuery = true)
+    int countAllByYearMonthAndIsDeleted(@Param("yearMonth") String yearMonth, @Param("isDeleted") int isDeleted);
+
+    @Query(value = "SELECT t2.at_name AS NAME, COUNT(t1.ctp_id) AS COUNT FROM crowd_test_project t1 INNER JOIN application_type t2 ON t1.ctp_platform=t2.at_code GROUP BY t1.ctp_platform", nativeQuery = true)
+    List<Map> countAllGroupByApplicationType();
+
+    @Query(value = "SELECT t2.f_name AS NAME, COUNT(ctp_id) AS COUNT FROM crowd_test_project t1 INNER JOIN field t2 ON t1.ctp_field_type=t2.f_code GROUP BY t1.ctp_field_type", nativeQuery = true)
+    List<Map> countAllGroupByFieldType();
+
+    @Query(value = "SELECT COUNT(t1.ctp_id) AS count, t2.u_province AS province FROM crowd_test_project AS t1 INNER JOIN user AS t2 ON t1.ctp_u_id=t2.u_id WHERE t1.ctp_is_deleted = 0 AND t2.u_province IS NOT NULL GROUP BY t2.u_province", nativeQuery = true)
+    List<Map> countAllByIsDeletedGroupByProvince(@Param("isDeleted") int isDeleted);
+
+    @Query(value = "SELECT COUNT(*) FROM (SELECT ctp_entrust_unit FROM crowd_test_project GROUP BY ctp_entrust_unit) AS t", nativeQuery = true)
+    int countUnitGroupByUnit();
 }

+ 12 - 0
core/src/main/java/com/mooctest/crowd/domain/dao/CrowdTestTaskDao.java

@@ -14,6 +14,7 @@ import org.springframework.data.repository.query.Param;
 import javax.transaction.Transactional;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author guochao
@@ -80,4 +81,15 @@ public interface CrowdTestTaskDao extends CrudRepository<CrowdTestTaskPO, Long>,
 
     @Query("select cttp from CrowdTestTaskPO cttp where cttp.code in (:codes) and cttp.isDeleted=0")
     List<CrowdTestTaskPO> findAllByCodeIn(Collection<String> codes);
+
+    int countAllByIsDeleted(int isDeleted);
+
+    @Query(value = "select count(*) from crowd_test_task where DATE_FORMAT(ctt_create_time, '%Y-%m') = :yearMonth and ctt_is_deleted = :isDeleted", nativeQuery = true)
+    int countAllByYearMonthAndIsDeleted(@Param("yearMonth") String yearMonth, @Param("isDeleted") int isDeleted);
+
+    @Query(value = "SELECT COUNT(t1.ctt_id) AS count, t3.u_province AS province FROM crowd_test_task AS t1 INNER JOIN crowd_test_project AS t2 ON t1.ctt_ctp_code=t2.ctp_code INNER JOIN user AS t3 ON t2.ctp_rm_id=t3.u_id WHERE t1.ctt_is_deleted=:isDeleted AND t2.ctp_is_deleted=:isDeleted AND t3.u_province IS NOT NULL AND t3.u_province !='' GROUP BY t3.u_province", nativeQuery = true)
+    List<Map> countAllByIsDeletedGroupByProvince(@Param("isDeleted") int isDeleted);
+
+    @Query(value = "SELECT COUNT(ctt_id) AS count, DATE_FORMAT(ctt_create_time, '%Y-%m') AS yearMonth FROM crowd_test_task WHERE ctt_create_time >= :createTime AND ctt_is_deleted = :isDeleted GROUP BY yearMonth", nativeQuery = true)
+    List<Map> countAllByTimeAndIsDeletedGroupByYearMonth(@Param("createTime") String createTime, @Param("isDeleted") int isDeleted);
 }

+ 8 - 0
core/src/main/java/com/mooctest/crowd/domain/dao/DefectDao.java

@@ -4,8 +4,10 @@ import com.mooctest.crowd.domain.model.DefectPO;
 import com.mooctest.crowd.domain.model.TestCasePO;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.CrudRepository;
 import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.data.repository.query.Param;
 
 import java.util.Collection;
 import java.util.List;
@@ -18,4 +20,10 @@ public interface DefectDao extends PagingAndSortingRepository<DefectPO, Long>, C
     DefectPO findByTaskCodeAndCommiterIdAndImportCode(String taskCode, Long commiterId, String importCode);
     int countAllByTaskCode(String taskCode);
     List<DefectPO> findAllByTaskCode(String taskCode);
+    @Query(value = "select count(*) from defect where DATE_FORMAT(commiter_time, '%Y-%m') = :yearMonth", nativeQuery = true)
+    int countAllByYearMonth(@Param("yearMonth") String yearMonth);
+    void deleteAllByTaskCodeAndTestCaseCode(String taskCode, String testCaseCode);
+    @Query(value = "select t.id from DefectPO t where t.taskCode=:taskCode")
+    List<Long> findAllIdByTaskCode(@Param("taskCode")String taskCode);
+    List<DefectPO> findAllByTestCaseCodeIn(List<String> testCaseCodes);
 }

+ 9 - 0
core/src/main/java/com/mooctest/crowd/domain/dao/EvaluationAgencyDao.java

@@ -2,10 +2,13 @@ package com.mooctest.crowd.domain.dao;
 
 import com.mooctest.crowd.domain.model.EvaluationAgencyPO;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.data.repository.query.Param;
 
 import javax.transaction.Transactional;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
 @Transactional
@@ -37,4 +40,10 @@ public interface EvaluationAgencyDao extends PagingAndSortingRepository<Evaluati
 
     EvaluationAgencyPO save(EvaluationAgencyPO evaluationAgencyPO);
 
+    int countAllByType(String type);
+
+    int countAllByTypeNot(String type);
+
+    @Query(value = "SELECT COUNT(t1.ea_id) as count, t2.u_province as province FROM evaluation_agency AS t1 INNER JOIN user AS t2 ON t1.ea_u_id=t2.u_id where t1.ea_type=:type and t1.ea_is_deleted=:isDeleted GROUP BY t2.u_province", nativeQuery = true)
+    List<Map> countAllByTypeGroupByProvince(@Param("type") String type, @Param("isDeleted") int isDeleted);
 }

+ 11 - 0
core/src/main/java/com/mooctest/crowd/domain/dao/TaskToUserDao.java

@@ -6,9 +6,11 @@ import com.mooctest.crowd.domain.model.TaskToUserPO;
 import org.springframework.data.domain.Pageable;
 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;
+import java.util.Map;
 import java.util.Optional;
 
 @Transactional
@@ -34,4 +36,13 @@ public interface TaskToUserDao extends CrudRepository<TaskToUserPO,Long> {
     TaskToUserPO findByUserIdAndTaskCode(Long userId, String taskCode);
 
     int countAllByTaskCode(String taskCode);
+
+    @Query(value = "select count(*) from task_to_user where DATE_FORMAT(ttu_accept_time, '%Y-%m') = :yearMonth", nativeQuery = true)
+    int countAllByYearMonth(@Param("yearMonth") String yearMonth);
+
+    @Query(value = "SELECT COUNT(ttu_id) AS count, DATE_FORMAT(ttu_accept_time, '%Y-%m') AS yearMonth FROM task_to_user WHERE ttu_accept_time >= :createTime GROUP BY yearMonth", nativeQuery = true)
+    List<Map> countAllByTimeGroupByYearMonth(@Param("createTime") String createTime);
+
+    @Query(value = "select count(ttu_id) as count, ttu_u_id as userId from task_to_user where ttu_is_committed=1 group by ttu_u_id", nativeQuery = true)
+    List<Map> countAllCommittedGroupByUserId();
 }

+ 10 - 0
core/src/main/java/com/mooctest/crowd/domain/dao/TestCaseDao.java

@@ -10,6 +10,7 @@ import org.springframework.data.repository.PagingAndSortingRepository;
 import org.springframework.data.repository.query.Param;
 
 import java.util.List;
+import java.util.Map;
 
 public interface TestCaseDao extends PagingAndSortingRepository<TestCasePO, Long>, CrudRepository<TestCasePO, Long>,
         JpaRepository<TestCasePO, Long>, JpaSpecificationExecutor<TestCasePO> {
@@ -24,4 +25,13 @@ public interface TestCaseDao extends PagingAndSortingRepository<TestCasePO, Long
     int countAllByTaskCode(String taskCode);
     int countAllByTaskCodeAndExamStatus(String taskCode, Byte examStatus);
     List<TestCasePO> findAllByTaskCode(String taskCode);
+    List<TestCasePO> findAllByTaskCodeAndExamStatusAndTestStatus(String taskCode, Byte examStatus, Byte testStatus);
+    List<TestCasePO> findAllByTaskCodeAndExamStatus(String taskCode, Byte examStatus);
+    @Query(value = "select count(*) from test_case where DATE_FORMAT(design_time, '%Y-%m') = :yearMonth", nativeQuery = true)
+    int countAllByYearMonth(@Param("yearMonth") String yearMonth);
+    @Modifying
+    @Query(value = "update TestCasePO t set t.examStatus=1, t.examDescr='' where t.taskCode=:taskCode and t.designerId=:designerId")
+    void examAllValidByTaskCodeAndDesignerId(@Param("taskCode") String taskCode, @Param("designerId") Long designerId);
+    @Query(value = "select designer_id as userId, count(designer_id) as count from test_case where task_code=:taskCode and exam_status=:examStatus group by designer_id", nativeQuery = true)
+    List<Map> countAllByTaskCodeAndExamStatusGroupByDesignerId(@Param("taskCode") String taskCode, @Param("examStatus") byte examStatus);
 }

+ 6 - 0
core/src/main/java/com/mooctest/crowd/domain/dao/UserDao.java

@@ -2,11 +2,14 @@ package com.mooctest.crowd.domain.dao;
 
 import com.mooctest.crowd.domain.model.UserPO;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.CrudRepository;
 import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.data.repository.query.Param;
 
 import javax.transaction.Transactional;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
 @Transactional
@@ -33,4 +36,7 @@ public interface UserDao extends PagingAndSortingRepository<UserPO, Long>, JpaSp
     long count();
 
     UserPO findByEmail(String email);
+
+    @Query(value = "SELECT COUNT(t1.u_id) AS count, t1.u_province as province FROM user AS t1 INNER JOIN user_to_role AS t2 ON t1.u_id=t2.utr_u_id WHERE t2.utr_r_id=:roleId and t1.u_province is not null and t1.u_province !='' GROUP BY t1.u_province", nativeQuery = true)
+    List<Map> countAllByRoleIdGroupByProvince(@Param("roleId") int roleId);
 }

+ 3 - 0
core/src/main/java/com/mooctest/crowd/domain/dao/UserToRoleDao.java

@@ -23,4 +23,7 @@ public interface UserToRoleDao extends CrudRepository<UserToRolePO,Long> {
 
     @Query(value="SELECT user_to_role.UTR_R_ID from user_to_role WHERE user_to_role.UTR_U_ID=?",nativeQuery = true)
     List<Long> findRoleId(@Param("userId") Long userId);
+
+    @Query(value="SELECT count(t1.utr_id) from user_to_role t1 inner join user t2 on t1.utr_u_id=t2.u_id WHERE t1.utr_r_id = :roleId and t2.u_is_deleted = :isDeleted",nativeQuery = true)
+    int countAllByRoleIdAndIsDeleted(@Param("roleId") long roleId, @Param("isDeleted") int isDeleted);
 }

+ 6 - 1
core/src/main/java/com/mooctest/crowd/domain/model/DefectPO.java

@@ -13,7 +13,12 @@ import java.sql.Timestamp;
 
 @Data
 @Entity
-@Table(name = "defect")
+@Table(name = "defect", indexes = {
+        @Index(columnList = "task_code,commiter_id,import_code", name = "task_code_commiter_id_import_code_idx", unique = true),
+        @Index(columnList = "task_code", name = "task_code_idx"),
+        @Index(columnList = "project_code", name = "project_code_idx"),
+        @Index(columnList = "test_case_code", name = "test_case_code_idx"),
+})
 public class DefectPO {
     @Id
     @Column(name = "id")

+ 1 - 1
core/src/main/java/com/mooctest/crowd/domain/model/ExceptionLogPO.java

@@ -17,7 +17,7 @@ public class ExceptionLogPO {
     private String exception;
     @Column(name = "uri", length = 100, nullable = true)
     private String uri;
-    @Column(name = "params", length = 500, nullable = true)
+    @Column(name = "params", nullable = true)
     private String params;
     @Column(name = "add_time", nullable = false)
     private Timestamp addTime;

+ 1 - 1
core/src/main/java/com/mooctest/crowd/domain/model/TestCasePO.java

@@ -28,7 +28,7 @@ public class TestCasePO {
     private String taskCode;
     @Column(name = "project_code", length = 30, nullable = false)
     private String projectCode;
-    @Column(name = "name", length = 23, nullable = false)
+    @Column(name = "name", length = 60, nullable = false)
     private String name;
     @Column(name = "descr", length = 500, nullable = true)
     private String descr;

+ 1 - 1
core/src/main/java/com/mooctest/crowd/domain/model/TestEnvPO.java

@@ -22,7 +22,7 @@ public class TestEnvPO {
     private String devModel; //设备型号
     @Column(name = "dev_count", nullable = false)
     private Integer devCount; //设备数量
-    @Column(name = "dev_config", length = 100, nullable = false)
+    @Column(name = "dev_config", length = 200, nullable = false)
     private String devConfig; //设备硬件配置
     @Column(name = "ope_sys", length = 50, nullable = false)
     private String opeSys; //操作系统

+ 49 - 0
core/src/main/java/com/mooctest/crowd/domain/repository/CrowdTestProjectRepo.java

@@ -1,11 +1,13 @@
 package com.mooctest.crowd.domain.repository;
 
+import com.alibaba.fastjson.JSONArray;
 import com.mooctest.crowd.domain.dao.*;
 import com.mooctest.crowd.domain.domainobject.*;
 import com.mooctest.crowd.domain.exception.CrowdTestProjectNotExistException;
 import com.mooctest.crowd.domain.exception.HttpBadRequestException;
 import com.mooctest.crowd.domain.model.*;
 import com.mooctest.crowd.domain.util.Converter;
+import com.mooctest.crowd.domain.util.JsonUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -56,6 +58,9 @@ public class CrowdTestProjectRepo implements ICrowdTestProjectRepo {
     @Autowired
     private CommonRepo commonRepo;
 
+    @Autowired
+    private ProjectTypeCountDao projectTypeCountDao;
+
     @Override
     public Page<CrowdTestProjectPO> findAll(Specification specification, Pageable pageable) {
         return crowdTestProjectDao.findAll(specification, pageable);
@@ -138,6 +143,42 @@ public class CrowdTestProjectRepo implements ICrowdTestProjectRepo {
 
     @Override
     public void saveCrowdTestProject(CrowdTestProject crowdTestProject) {
+        if (crowdTestProject.getId() == null) {
+            List<String> types = JsonUtils.toList(crowdTestProject.getType());
+            for(String type: types) {
+                ProjectTypeCountPO projectTypeCountPO = projectTypeCountDao.findByType(type);
+                if (projectTypeCountPO == null) {
+                    projectTypeCountPO = new ProjectTypeCountPO();
+                    projectTypeCountPO.setType(type);
+                    projectTypeCountPO.setCount(1);
+                    projectTypeCountDao.save(projectTypeCountPO);
+                } else {
+                    projectTypeCountDao.modifyCount(type, 1);
+                }
+            }
+        } else {
+            CrowdTestProjectPO oldProject = crowdTestProjectDao.findById(crowdTestProject.getId()).get();
+            List<String> oldTypes = JsonUtils.toList(oldProject.getType());
+            List<String> newTypes = JsonUtils.toList(crowdTestProject.getType());
+            for (String oldType: oldTypes) {
+                if (!newTypes.contains(oldType)) {
+                    projectTypeCountDao.modifyCount(oldType, -1);
+                }
+            }
+            for (String newType: newTypes) {
+                if (!oldTypes.contains(newType)) {
+                    ProjectTypeCountPO projectTypeCountPO = projectTypeCountDao.findByType(newType);
+                    if (projectTypeCountPO != null) {
+                        projectTypeCountDao.modifyCount(newType, 1);
+                    } else {
+                        projectTypeCountPO = new ProjectTypeCountPO();
+                        projectTypeCountPO.setCount(1);
+                        projectTypeCountPO.setType(newType);
+                        projectTypeCountDao.save(projectTypeCountPO);
+                    }
+                }
+            }
+        }
         CrowdTestProjectPO crowdTestProjectPO = Converter.convert(CrowdTestProjectPO.class, crowdTestProject);
         crowdTestProjectDao.save(crowdTestProjectPO);
         List<CrowdTestTask> crowdTestTaskList = crowdTestProject.getCrowdTestTaskList();
@@ -280,6 +321,10 @@ public class CrowdTestProjectRepo implements ICrowdTestProjectRepo {
         for (CrowdTestProject crowdTestProject : crowdTestProjectList) {
             CrowdTestProjectPO crowdTestProjectPO = Converter.convert(CrowdTestProjectPO.class, crowdTestProject);
             crowdTestProjectPOList.add(crowdTestProjectPO);
+            List<String> types = JsonUtils.toList(crowdTestProject.getType());
+            for(String type: types) {
+                projectTypeCountDao.modifyCount(type, -1);
+            }
         }
         crowdTestProjectDao.deleteAll(crowdTestProjectPOList);
     }
@@ -337,6 +382,10 @@ public class CrowdTestProjectRepo implements ICrowdTestProjectRepo {
         if (!project.isPresent())
             throw new CrowdTestProjectNotExistException();
         crowdTestProjectDao.delete(project.get());
+        List<String> types = JsonUtils.toList(project.get().getType());
+        for(String type: types) {
+            projectTypeCountDao.modifyCount(type, -1);
+        }
     }
 
     /**

+ 15 - 2
core/src/main/java/com/mooctest/crowd/domain/repository/DefectRepo.java

@@ -14,7 +14,9 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
 import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
@@ -26,7 +28,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 
-@Service
+@Component
 public class DefectRepo implements IDefectRepo{
     @Autowired
     private DefectDao defectDao;
@@ -53,7 +55,7 @@ public class DefectRepo implements IDefectRepo{
 
     @Override
     public DOPage<Defect> findUserDefects(Long commiterId, String taskCode, Integer pageNo, Integer pageSize) {
-        Pageable pageable = PageRequest.of(pageNo, pageSize);
+        Pageable pageable = PageRequest.of(pageNo, pageSize, Sort.Direction.ASC, "id");
         Specification<DefectPO> specification = (a, q, cb) -> {
             Predicate predicate = cb.conjunction();
             if(commiterId != null) {
@@ -111,6 +113,17 @@ public class DefectRepo implements IDefectRepo{
         return defectPOs.stream().map(defectPO -> poToDO(defectPO)).collect(Collectors.toList());
     }
 
+    @Override
+    public void deleteByTaskCodeAndTestCaseCode(String taskCode, String testCaseCode) {
+        defectDao.deleteAllByTaskCodeAndTestCaseCode(taskCode, testCaseCode);
+    }
+
+    @Override
+    public List<Defect> findAllByTestCaseCodeIn(List<String> testCaseCodes) {
+        List<DefectPO> defectPOs = defectDao.findAllByTestCaseCodeIn(testCaseCodes);
+        return defectPOs.stream().map(defectPO -> poToDO(defectPO)).collect(Collectors.toList());
+    }
+
     private Defect poToDO(DefectPO defectPO) {
         if (defectPO == null) {
             return null;

+ 2 - 0
core/src/main/java/com/mooctest/crowd/domain/repository/IDefectRepo.java

@@ -17,4 +17,6 @@ public interface IDefectRepo {
     List<Defect> findAllByTaskCodeAndTestCaseCodeIn(String taskCode, Collection<String> testCaseCodes);
     Defect findByTaskCodeAndCommiterIdAndImportCode(String taskCode, Long commiterId, String importCode);
     List<Defect> findAllByTaskCode(String taskCode);
+    void deleteByTaskCodeAndTestCaseCode(String taskCode, String testCaseCode);
+    List<Defect> findAllByTestCaseCodeIn(List<String> testCaseCodes);
 }

+ 2 - 0
core/src/main/java/com/mooctest/crowd/domain/repository/ITestCaseRepo.java

@@ -17,4 +17,6 @@ public interface ITestCaseRepo {
     void updateAssociatedCodeById(Long id, String associatedCode);
     TestCase findByTaskCodeAndDesignerIdAndImportCode(String taskCode, Long designerId, String importCode);
     List<TestCase> findAllByTaskCode(String taskCode);
+    List<TestCase> findAllByTaskCodeAndExamStatusAndTestStatus(String taskCode, TestCaseExamStatus testCaseExamStatus, TestStatus testStatus);
+    List<TestCase> findAllByTaskCodeAndExamStatus(String taskCode, TestCaseExamStatus testCaseExamStatus);
 }

+ 13 - 1
core/src/main/java/com/mooctest/crowd/domain/repository/TestCaseRepo.java

@@ -14,6 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
 import org.springframework.data.jpa.domain.Specification;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
@@ -51,7 +52,7 @@ public class TestCaseRepo implements ITestCaseRepo{
 
     @Override
     public DOPage<TestCase> find(Long designerId, String taskCode, Integer pageNo, Integer pageSize, TestStatus testStatus, TestCaseExamStatus examStatus) {
-        Pageable pageable = PageRequest.of(pageNo, pageSize);
+        Pageable pageable = PageRequest.of(pageNo, pageSize, Sort.Direction.ASC, "id");
         Specification<TestCasePO> specification = (a, q, cb) -> {
             Predicate predicate = cb.conjunction();
             if(designerId != null) {
@@ -112,6 +113,17 @@ public class TestCaseRepo implements ITestCaseRepo{
         return testCasePOs.stream().map(testCasePO -> poToDO(testCasePO)).collect(Collectors.toList());
     }
 
+    @Override
+    public List<TestCase> findAllByTaskCodeAndExamStatusAndTestStatus(String taskCode, TestCaseExamStatus testCaseExamStatus, TestStatus testStatus) {
+        List<TestCasePO> testCasePOs = testCaseDao.findAllByTaskCodeAndExamStatusAndTestStatus(taskCode, testCaseExamStatus.getValue(), testStatus.getValue());
+        return testCasePOs.stream().map(testCasePO -> poToDO(testCasePO)).collect(Collectors.toList());
+    }
+
+    @Override
+    public List<TestCase> findAllByTaskCodeAndExamStatus(String taskCode, TestCaseExamStatus testCaseExamStatus) {
+        List<TestCasePO> testCasePOs = testCaseDao.findAllByTaskCodeAndExamStatus(taskCode, testCaseExamStatus.getValue());
+        return testCasePOs.stream().map(testCasePO -> poToDO(testCasePO)).collect(Collectors.toList());    }
+
     private TestCase poToDO(TestCasePO testCasePO) {
         if (testCasePO == null) {
             return null;

+ 12 - 0
site/pom.xml

@@ -201,6 +201,18 @@
 			<artifactId>aho-corasick-double-array-trie</artifactId>
 			<version>1.2.1</version>
 		</dependency>
+
+		<dependency>
+			<groupId>com.github.liuyueyi.media</groupId>
+			<artifactId>qrcode-plugin</artifactId>
+			<version>2.5.2</version>
+		</dependency>
+		<!-- 二维码需要 -->
+		<dependency>
+			<groupId>commons-lang</groupId>
+			<artifactId>commons-lang</artifactId>
+			<version>2.6</version>
+		</dependency>
 	</dependencies>
 	<build>
 		<plugins>

+ 28 - 3
site/src/main/java/com/mooctest/crowd/site/controller/CrowdProjectController.java

@@ -3,7 +3,6 @@ package com.mooctest.crowd.site.controller;
 import com.mooctest.crowd.domain.domainobject.CrowdTestProject;
 import com.mooctest.crowd.domain.exception.BadRequestException;
 import com.mooctest.crowd.domain.exception.BaseException;
-import com.mooctest.crowd.domain.exception.UnauthorizedException;
 import com.mooctest.crowd.site.annotation.LoginRequired;
 import com.mooctest.crowd.site.command.CrowdTestProjectCommand;
 import com.mooctest.crowd.site.command.GenerateProjectCommand;
@@ -11,9 +10,10 @@ import com.mooctest.crowd.site.data.dto.ProjectDetailsDTO;
 import com.mooctest.crowd.site.data.dto.UserProjectDTO;
 import com.mooctest.crowd.site.data.response.ResponseVO;
 import com.mooctest.crowd.site.data.response.ServerCode;
+import com.mooctest.crowd.site.data.vo.ProjectMoreInfoVO;
 import com.mooctest.crowd.site.data.vo.RegionalManagerVO;
 import com.mooctest.crowd.site.data.vo.SimpleTaskDataVO;
-import com.mooctest.crowd.site.service.CrowdProjectService;
+import com.mooctest.crowd.site.service.*;
 import com.mooctest.crowd.site.util.FileUtil;
 import com.mooctest.crowd.site.util.RequestUtils;
 import io.swagger.annotations.Api;
@@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.validation.BindingResult;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.client.RestTemplate;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
@@ -44,6 +45,18 @@ public class CrowdProjectController{
     @Autowired
     private CrowdProjectService projectService;
 
+    @Autowired
+    private FwzlPostDataResultService fwzlPostDataResultService;
+
+    @Autowired
+    private CpzlPostDataResultService cpzlPostDataResultService;
+
+    @Autowired
+    private RypgPostDataResultService rypgPostDataResultService;
+
+    @Autowired
+    private RestTemplate restTemplate;
+
     @Value("${green.manager.id}")
     long unauthManageId;
 
@@ -221,7 +234,18 @@ public class CrowdProjectController{
     @RequestMapping(value = "/api/project/{projectCode}/status/finished", method = RequestMethod.PUT)
     public ProjectDetailsDTO confirmFinished(@PathVariable("projectCode") String projectCode, HttpSession session){
         Long userId = Long.parseLong((String)session.getAttribute("userId"));
-        return projectService.confirmFinished(projectCode, userId);
+        ProjectDetailsDTO projectDetailsDTO = projectService.confirmFinished(projectCode, userId);
+        ProjectMoreInfoVO projectMoreInfoVO = projectService.getProjectMoreInfo(userId, projectCode);
+        new Thread(() -> {
+            fwzlPostDataResultService.post(projectMoreInfoVO);
+        }).start();
+        new Thread(() -> {
+            cpzlPostDataResultService.post(projectMoreInfoVO);
+        }).start();
+        new Thread(() -> {
+            rypgPostDataResultService.post(projectMoreInfoVO);
+        }).start();
+        return projectDetailsDTO;
     }
 
     /**
@@ -281,4 +305,5 @@ public class CrowdProjectController{
     public ResponseVO<List<SimpleTaskDataVO>> getSimpleProjectDatas(HttpServletRequest request){
         return new ResponseVO(ServerCode.SUCCESS, projectService.findSimpleProjectDatasByRegionalManagerId(RequestUtils.getUserId(request)));
     }
+
 }

+ 20 - 15
site/src/main/java/com/mooctest/crowd/site/controller/CrowdTaskController.java

@@ -1,5 +1,6 @@
 package com.mooctest.crowd.site.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.mooctest.crowd.domain.domainobject.TestCase;
 import com.mooctest.crowd.domain.domainobject.TestEnv;
 import com.mooctest.crowd.domain.env.TestStatus;
@@ -24,13 +25,17 @@ import com.mooctest.crowd.site.util.RequestUtils;
 import io.swagger.annotations.Api;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.ResponseEntity;
 import org.springframework.validation.BindingResult;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.client.RestTemplate;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 import java.util.stream.Collectors;
 
@@ -54,7 +59,9 @@ public class CrowdTaskController{
     @Autowired
     private TestToolService testToolService;
     @Autowired
-    private RedisHelper redisHelper;
+    private RestTemplate restTemplate;
+    @Value("${spring.profiles.active}")
+    private String springProfilesActive;
 
     @RequestMapping(value = "/project/{projectCode}/task/{taskCode}", method = RequestMethod.GET)
     public TaskDetailsDTO getTask(@PathVariable("projectCode") String projectCode, @PathVariable("taskCode") String taskCode, HttpSession session){
@@ -201,8 +208,8 @@ public class CrowdTaskController{
     }
 
     @LoginRequired
-    @RequestMapping(value = "/task/{taskCode}/commit", method = RequestMethod.PUT)
-    public ResponseVO commitTask2(HttpServletRequest request, @PathVariable("taskCode") String taskCode){
+    @RequestMapping(value = "/usertask/{taskCode}/commit", method = RequestMethod.PUT)
+    public ResponseVO commitUserTask(HttpServletRequest request, @PathVariable("taskCode") String taskCode){
         Long userId = RequestUtils.getUserId(request);
         DOPage<TestCase> page = testCaseService.find(userId, userId, taskCode, 0, 1000, null);
         if (page.getDatas().size() == 0) {
@@ -230,6 +237,7 @@ public class CrowdTaskController{
         if (testEnvs.size() == 0) {
             return new ResponseVO(ServerCode.ERROR, "请补充测试的环境信息");
         }
+
         taskService.commitTask(page.getDatas().get(0).getProjectCode(), taskCode, userId);
         return new ResponseVO(ServerCode.SUCCESS);
     }
@@ -245,18 +253,15 @@ public class CrowdTaskController{
     @RequestMapping(value = "/task/{taskCode}/completion", method = RequestMethod.GET)
     public ResponseVO<Double> getTaskCompletion(HttpServletRequest request, @PathVariable("taskCode") String taskCode) {
         Long userId = RequestUtils.getUserId(request);
-        String token = UUID.randomUUID().toString();
-        redisHelper.hset("token", token, userId, 360000);
-        System.out.println("token=======" + token);
-        return new ResponseVO(ServerCode.SUCCESS, 0.0d);
-    }
-
-    @RequestMapping(value = "/task/{taskCode}/moreinfo", method = RequestMethod.GET)
-    public ResponseVO<TaskMoreInfoVO> getTaskMoreInfo(String token, @PathVariable("taskCode") String taskCode){
-        Long userId = (Long)redisHelper.hget("token", token);
-        if (userId == null) {
-            throw new BaseException("token无效");
+        TaskMoreInfoVO taskMoreInfoVO = taskService.getTaskMoreInfo(userId, taskCode);
+        String url = "getCompleteRatio";
+        if ("online".equals(springProfilesActive)) {
+            url = "http://8.134.39.104:7486/" + url;
+        } else {
+            url = "http://8.134.39.104:7486/" + url;
         }
-        return new ResponseVO(ServerCode.SUCCESS, taskService.getTaskMoreInfo(userId, taskCode));
+        ResponseEntity<Double> result = restTemplate.postForEntity(url, taskMoreInfoVO, Double.class);
+        return new ResponseVO(ServerCode.SUCCESS, result.getBody());
     }
+
 }

+ 408 - 0
site/src/main/java/com/mooctest/crowd/site/controller/TestCaseController.java

@@ -1,6 +1,7 @@
 package com.mooctest.crowd.site.controller;
 
 import com.alibaba.druid.util.StringUtils;
+import com.mooctest.crowd.domain.domainobject.CrowdTestTask;
 import com.mooctest.crowd.domain.domainobject.Defect;
 import com.mooctest.crowd.domain.domainobject.TestCase;
 import com.mooctest.crowd.domain.env.TestCaseExamStatus;
@@ -15,17 +16,28 @@ import com.mooctest.crowd.site.data.dto.TestCaseExamCommand;
 import com.mooctest.crowd.site.data.dto.TestCaseSearchDTO;
 import com.mooctest.crowd.site.data.response.ResponseVO;
 import com.mooctest.crowd.site.data.response.ServerCode;
+import com.mooctest.crowd.site.service.CrowdTaskService;
 import com.mooctest.crowd.site.service.DefectService;
 import com.mooctest.crowd.site.service.TestCaseService;
+import com.mooctest.crowd.site.service.UserService;
 import com.mooctest.crowd.site.util.RequestUtils;
 import io.swagger.annotations.Api;
+import org.apache.http.client.utils.DateUtils;
+import org.apache.logging.log4j.util.Strings;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.util.*;
 
 @RestController
 @RequestMapping("/api/testcase")
@@ -35,6 +47,10 @@ public class TestCaseController {
     private TestCaseService testCaseService;
     @Autowired
     private DefectService defectService;
+    @Autowired
+    private UserService userService;
+    @Autowired
+    private CrowdTaskService crowdTaskService;
 
     @PostMapping(value = "/")
     @LoginRequired
@@ -139,4 +155,396 @@ public class TestCaseController {
         defectService.importDefects(file.getBytes(), taskCode, userId);
         return new ResponseVO(ServerCode.SUCCESS);
     }
+
+    @PostMapping(value = "/examallvalid/{taskCode}/{designerId}")
+    @LoginRequired
+    public ResponseVO examAllValid(HttpServletRequest request, @PathVariable("taskCode") String taskCode, @PathVariable("designerId") Long designerId) {
+        Long examerId = RequestUtils.getUserId(request);
+        testCaseService.examAllValidByTaskCodeAndDesignerId(taskCode, designerId, examerId);
+        return new ResponseVO(ServerCode.SUCCESS);
+    }
+
+    @GetMapping(value = "/export/{taskCode}")
+    @LoginRequired
+    public void export(HttpServletRequest request, HttpServletResponse response, @PathVariable("taskCode") String taskCode) throws IOException {
+        Workbook wb = new XSSFWorkbook();
+        Long userId = RequestUtils.getUserId(request);
+        createTestCaseSheet(wb, userId, taskCode);
+        createDefectSheet(wb, userId, taskCode);
+        CrowdTestTask task = crowdTaskService.getByTaskCode(taskCode);
+        response.setHeader("Content-Disposition", String.format("attachment;filename=%s.xlsx",
+                URLEncoder.encode(task.getName(), "utf-8")));
+        response.setContentType("application/octet-stream");
+        OutputStream os = response.getOutputStream();
+        wb.write(os);
+    }
+
+    private void createTestCaseSheet (Workbook wb, Long userId, String taskCode) {
+        List<TestCase> testCases = testCaseService.findAllByTaskCode(userId, taskCode);
+        Sheet sheet = wb.createSheet("测试用例");
+        int i = 0;
+        Row row = sheet.createRow(i++);
+        row.setHeightInPoints(row.getHeightInPoints() * (short)2);
+        CellStyle baseStyle = wb.createCellStyle();
+        baseStyle.setAlignment(HorizontalAlignment.CENTER);
+        baseStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+        baseStyle.setBorderBottom(BorderStyle.THIN);
+        baseStyle.setBorderLeft(BorderStyle.THIN);
+        baseStyle.setBorderRight(BorderStyle.THIN);
+        baseStyle.setBorderTop(BorderStyle.THIN);
+        baseStyle.setWrapText(true);
+
+        Font headerFont = wb.createFont();
+        headerFont.setFontHeightInPoints((short)10);
+        headerFont.setFontName("宋体");
+        headerFont.setBold(true);
+
+        Font contentFont = wb.createFont();
+        contentFont.setFontHeightInPoints((short)10);
+        contentFont.setFontName("宋体");
+
+        CellStyle headerStyle = wb.createCellStyle();
+        headerStyle.cloneStyleFrom(baseStyle);
+        headerStyle.setAlignment(HorizontalAlignment.CENTER);
+        headerStyle.setFont(headerFont);
+
+        Cell cell0 = row.createCell(0);
+        Cell cell1 = row.createCell(1);
+        Cell cell2 = row.createCell(2);
+        Cell cell3 = row.createCell(3);
+        Cell cell4 = row.createCell(4);
+        Cell cell5 = row.createCell(5);
+        Cell cell6 = row.createCell(6);
+        Cell cell7 = row.createCell(7);
+        Cell cell8 = row.createCell(8);
+        Cell cell9 = row.createCell(9);
+        Cell cell10 = row.createCell(10);
+        Cell cell11 = row.createCell(11);
+        Cell cell12 = row.createCell(12);
+        Cell cell13 = row.createCell(13);
+        Cell cell14 = row.createCell(14);
+        Cell cell15 = row.createCell(15);
+        Cell cell16 = row.createCell(16);
+        Cell cell17 = row.createCell(17);
+
+        cell0.setCellStyle(headerStyle);
+        cell0.setCellValue("用例编号");
+
+        cell1.setCellStyle(headerStyle);
+        cell1.setCellValue("关联用例编号");
+
+        cell2.setCellStyle(headerStyle);
+        cell2.setCellValue("关联需求");
+        sheet.setColumnWidth(2, sheet.getColumnWidth(2) * 3);
+
+        cell3.setCellStyle(headerStyle);
+        cell3.setCellValue("用例名称");
+        sheet.setColumnWidth(3, sheet.getColumnWidth(3) * 2);
+
+        cell4.setCellStyle(headerStyle);
+        cell4.setCellValue("优先级");
+
+        cell5.setCellStyle(headerStyle);
+        cell5.setCellValue("用例描述");
+        sheet.setColumnWidth(5, sheet.getColumnWidth(5) * 4);
+
+        cell6.setCellStyle(headerStyle);
+        cell6.setCellValue("前置条件");
+        sheet.setColumnWidth(6, sheet.getColumnWidth(6) * 3);
+
+        cell7.setCellStyle(headerStyle);
+        cell7.setCellValue("环境配置");
+        sheet.setColumnWidth(7, sheet.getColumnWidth(7) * 3);
+
+        cell8.setCellStyle(headerStyle);
+        cell8.setCellValue("操作步骤");
+        sheet.setColumnWidth(8, sheet.getColumnWidth(8) * 3);
+
+        cell9.setCellStyle(headerStyle);
+        cell9.setCellValue("输入数据");
+        sheet.setColumnWidth(9, sheet.getColumnWidth(9) * 3);
+
+        cell10.setCellStyle(headerStyle);
+        cell10.setCellValue("预期结果");
+        sheet.setColumnWidth(10, sheet.getColumnWidth(10) * 3);
+
+        cell11.setCellStyle(headerStyle);
+        cell11.setCellValue("评判标准");
+        sheet.setColumnWidth(11, sheet.getColumnWidth(11) * 3);
+
+        cell12.setCellStyle(headerStyle);
+        cell12.setCellValue("其他说明");
+        sheet.setColumnWidth(12, sheet.getColumnWidth(12) * 3);
+
+        cell13.setCellStyle(headerStyle);
+        cell13.setCellValue("设计人员");
+        sheet.setColumnWidth(13, sheet.getColumnWidth(13) * 2);
+
+        cell14.setCellStyle(headerStyle);
+        cell14.setCellValue("设计时间");
+        sheet.setColumnWidth(14, sheet.getColumnWidth(14) * 2);
+
+        cell15.setCellStyle(headerStyle);
+        cell15.setCellValue("测试结果");
+        sheet.setColumnWidth(15, sheet.getColumnWidth(15) * 3);
+
+        cell16.setCellStyle(headerStyle);
+        cell16.setCellValue("测试结论");
+
+        cell17.setCellStyle(headerStyle);
+        cell17.setCellValue("附件");
+        sheet.setColumnWidth(17, sheet.getColumnWidth(17) * 4);
+
+        CellStyle contentStyle = wb.createCellStyle();
+        contentStyle.cloneStyleFrom(baseStyle);
+        contentStyle.setAlignment(HorizontalAlignment.CENTER);
+        contentStyle.setFont(contentFont);
+        Map<Long, String> userIdNameMap = new HashMap();
+
+        for(TestCase testCase: testCases) {
+            if (!userIdNameMap.containsKey(testCase.getDesignerId())) {
+                String realname = userService.getById(testCase.getDesignerId()).getName();
+                userIdNameMap.put(testCase.getDesignerId(), realname);
+            }
+
+            row = sheet.createRow(i++);
+            cell0 = row.createCell(0);
+            cell0.setCellStyle(contentStyle);
+            cell1 = row.createCell(1);
+            cell1.setCellStyle(contentStyle);
+            cell2 = row.createCell(2);
+            cell2.setCellStyle(contentStyle);
+            cell3 = row.createCell(3);
+            CellStyle cellStyle = wb.createCellStyle();
+            cellStyle.cloneStyleFrom(contentStyle);
+            cellStyle.setAlignment(HorizontalAlignment.LEFT);
+            cell3.setCellStyle(cellStyle);
+            cell4 = row.createCell(4);
+            cell4.setCellStyle(cellStyle);
+            cell5 = row.createCell(5);
+            cell5.setCellStyle(cellStyle);
+            cell6 = row.createCell(6);
+            cell6.setCellStyle(cellStyle);
+            cell7 = row.createCell(7);
+            cell7.setCellStyle(contentStyle);
+            cell8 = row.createCell(8);
+            cell8.setCellStyle(contentStyle);
+            cell9 = row.createCell(9);
+            cell9.setCellStyle(contentStyle);
+            cell10 = row.createCell(10);
+            cell10.setCellStyle(contentStyle);
+            cell11 = row.createCell(11);
+            cell11.setCellStyle(contentStyle);
+            cell12 = row.createCell(12);
+            cell12.setCellStyle(contentStyle);
+            cell13 = row.createCell(13);
+            cell13.setCellStyle(contentStyle);
+            cell14 = row.createCell(14);
+            cell14.setCellStyle(contentStyle);
+            cell15 = row.createCell(15);
+            cell15.setCellStyle(contentStyle);
+            cell16 = row.createCell(16);
+            cell16.setCellStyle(contentStyle);
+            cell17 = row.createCell(17);
+            cell17.setCellStyle(contentStyle);
+
+            cell0.setCellValue(testCase.getCode());
+            cell1.setCellValue(testCase.getAssociatedCode() == null ? "" : testCase.getAssociatedCode());
+            cell2.setCellValue(testCase.getDemand() == null ? "" : testCase.getDemand());
+            cell3.setCellValue(testCase.getName());
+            cell4.setCellValue(testCase.getPriority().getName());
+            cell5.setCellValue(testCase.getDescr() == null ? "" : testCase.getDescr());
+            cell6.setCellValue(testCase.getPreconditions() == null ? "" : testCase.getPreconditions());
+            cell7.setCellValue(testCase.getEnvConfig() == null ? "" : testCase.getEnvConfig());
+            cell8.setCellValue(testCase.getOpeSteps() == null ? "" : testCase.getOpeSteps());
+            cell9.setCellValue(testCase.getInputDatas() == null ? "" : testCase.getInputDatas());
+            cell10.setCellValue(testCase.getExpectedResult() == null ? "" : testCase.getExpectedResult());
+            cell11.setCellValue(testCase.getEvaCriteria() == null ? "" : testCase.getEvaCriteria());
+            cell12.setCellValue(testCase.getOthers() == null ? "" : testCase.getOthers());
+            cell13.setCellValue(userIdNameMap.get(testCase.getDesignerId()));
+            cell14.setCellValue(DateUtils.formatDate(new Date(testCase.getDesignTime().getTime()), "yyyy-MM-dd"));
+            cell15.setCellValue(testCase.getTestResult() == null ? "" : testCase.getTestResult());
+            cell16.setCellValue(testCase.getTestStatus().getName());
+            List<String> files = new ArrayList();
+            files.addAll(testCase.getFiles());
+            files.addAll(testCase.getScreenshots());
+            cell17.setCellValue(Strings.join(files, '、'));
+        }
+    }
+
+    private void createDefectSheet (Workbook wb, Long userId, String taskCode) {
+        List<Defect> defects = defectService.findAllByTaskCode(userId, taskCode);
+        Sheet sheet = wb.createSheet("缺陷记录");
+        int i = 0;
+        Row row = sheet.createRow(i++);
+        row.setHeightInPoints(row.getHeightInPoints() * (short)2);
+        CellStyle baseStyle = wb.createCellStyle();
+        baseStyle.setAlignment(HorizontalAlignment.CENTER);
+        baseStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+        baseStyle.setBorderBottom(BorderStyle.THIN);
+        baseStyle.setBorderLeft(BorderStyle.THIN);
+        baseStyle.setBorderRight(BorderStyle.THIN);
+        baseStyle.setBorderTop(BorderStyle.THIN);
+        baseStyle.setWrapText(true);
+
+        Font headerFont = wb.createFont();
+        headerFont.setFontHeightInPoints((short)10);
+        headerFont.setFontName("宋体");
+        headerFont.setBold(true);
+
+        Font contentFont = wb.createFont();
+        contentFont.setFontHeightInPoints((short)10);
+        contentFont.setFontName("宋体");
+
+        CellStyle headerStyle = wb.createCellStyle();
+        headerStyle.cloneStyleFrom(baseStyle);
+        headerStyle.setAlignment(HorizontalAlignment.CENTER);
+        headerStyle.setFont(headerFont);
+
+        Cell cell0 = row.createCell(0);
+        Cell cell1 = row.createCell(1);
+        Cell cell2 = row.createCell(2);
+        Cell cell3 = row.createCell(3);
+        Cell cell4 = row.createCell(4);
+        Cell cell5 = row.createCell(5);
+        Cell cell6 = row.createCell(6);
+        Cell cell7 = row.createCell(7);
+        Cell cell8 = row.createCell(8);
+        Cell cell9 = row.createCell(9);
+        Cell cell10 = row.createCell(10);
+        Cell cell11 = row.createCell(11);
+        Cell cell12 = row.createCell(12);
+        Cell cell13 = row.createCell(13);
+        Cell cell14 = row.createCell(14);
+        Cell cell15 = row.createCell(15);
+
+        cell0.setCellStyle(headerStyle);
+        cell0.setCellValue("缺陷编号");
+
+        cell1.setCellStyle(headerStyle);
+        cell1.setCellValue("用例编号");
+
+        cell2.setCellStyle(headerStyle);
+        cell2.setCellValue("缺陷描述");
+        sheet.setColumnWidth(2, sheet.getColumnWidth(2) * 3);
+
+        cell3.setCellStyle(headerStyle);
+        cell3.setCellValue("严重程度");
+
+        cell4.setCellStyle(headerStyle);
+        cell4.setCellValue("优先级");
+
+        cell5.setCellStyle(headerStyle);
+        cell5.setCellValue("问题类型");
+
+        cell6.setCellStyle(headerStyle);
+        cell6.setCellValue("前置条件");
+        sheet.setColumnWidth(6, sheet.getColumnWidth(6) * 3);
+
+        cell7.setCellStyle(headerStyle);
+        cell7.setCellValue("环境配置");
+        sheet.setColumnWidth(7, sheet.getColumnWidth(7) * 3);
+
+        cell8.setCellStyle(headerStyle);
+        cell8.setCellValue("操作步骤");
+        sheet.setColumnWidth(8, sheet.getColumnWidth(8) * 3);
+
+        cell9.setCellStyle(headerStyle);
+        cell9.setCellValue("输入数据");
+        sheet.setColumnWidth(9, sheet.getColumnWidth(9) * 3);
+
+        cell10.setCellStyle(headerStyle);
+        cell10.setCellValue("预期结果");
+        sheet.setColumnWidth(10, sheet.getColumnWidth(10) * 3);
+
+        cell11.setCellStyle(headerStyle);
+        cell11.setCellValue("实际结果");
+        sheet.setColumnWidth(11, sheet.getColumnWidth(11) * 3);
+
+        cell12.setCellStyle(headerStyle);
+        cell12.setCellValue("其他说明");
+        sheet.setColumnWidth(12, sheet.getColumnWidth(12) * 3);
+
+        cell13.setCellStyle(headerStyle);
+        cell13.setCellValue("提交人员");
+        sheet.setColumnWidth(13, sheet.getColumnWidth(13) * 2);
+
+        cell14.setCellStyle(headerStyle);
+        cell14.setCellValue("提交时间");
+        sheet.setColumnWidth(14, sheet.getColumnWidth(14) * 2);
+
+        cell15.setCellStyle(headerStyle);
+        cell15.setCellValue("附件");
+        sheet.setColumnWidth(15, sheet.getColumnWidth(15) * 4);
+
+        CellStyle contentStyle = wb.createCellStyle();
+        contentStyle.cloneStyleFrom(baseStyle);
+        contentStyle.setAlignment(HorizontalAlignment.CENTER);
+        contentStyle.setFont(contentFont);
+        Map<Long, String> userIdNameMap = new HashMap();
+
+        for(Defect defect: defects) {
+            if (!userIdNameMap.containsKey(defect.getCommiterId())) {
+                String realname = userService.getById(defect.getCommiterId()).getName();
+                userIdNameMap.put(defect.getCommiterId(), realname);
+            }
+
+            row = sheet.createRow(i++);
+            cell0 = row.createCell(0);
+            cell0.setCellStyle(contentStyle);
+            cell1 = row.createCell(1);
+            cell1.setCellStyle(contentStyle);
+            cell2 = row.createCell(2);
+            cell2.setCellStyle(contentStyle);
+            cell3 = row.createCell(3);
+            CellStyle cellStyle = wb.createCellStyle();
+            cellStyle.cloneStyleFrom(contentStyle);
+            cellStyle.setAlignment(HorizontalAlignment.LEFT);
+            cell3.setCellStyle(cellStyle);
+            cell4 = row.createCell(4);
+            cell4.setCellStyle(cellStyle);
+            cell5 = row.createCell(5);
+            cell5.setCellStyle(cellStyle);
+            cell6 = row.createCell(6);
+            cell6.setCellStyle(cellStyle);
+            cell7 = row.createCell(7);
+            cell7.setCellStyle(contentStyle);
+            cell8 = row.createCell(8);
+            cell8.setCellStyle(contentStyle);
+            cell9 = row.createCell(9);
+            cell9.setCellStyle(contentStyle);
+            cell10 = row.createCell(10);
+            cell10.setCellStyle(contentStyle);
+            cell11 = row.createCell(11);
+            cell11.setCellStyle(contentStyle);
+            cell12 = row.createCell(12);
+            cell12.setCellStyle(contentStyle);
+            cell13 = row.createCell(13);
+            cell13.setCellStyle(contentStyle);
+            cell14 = row.createCell(14);
+            cell14.setCellStyle(contentStyle);
+            cell15 = row.createCell(15);
+            cell15.setCellStyle(contentStyle);
+
+            cell0.setCellValue(defect.getCode());
+            cell1.setCellValue(defect.getTestCaseCode());
+            cell2.setCellValue(defect.getDescr());
+            cell3.setCellValue(defect.getSeriousness().getName());
+            cell4.setCellValue(defect.getPriority().getName());
+            cell5.setCellValue(defect.getDefectType().getName());
+            cell6.setCellValue(defect.getPreconditions() == null ? "" : defect.getPreconditions());
+            cell7.setCellValue(defect.getEnvConfig() == null ? "" : defect.getEnvConfig());
+            cell8.setCellValue(defect.getOpeSteps() == null ? "" : defect.getOpeSteps());
+            cell9.setCellValue(defect.getInputDatas() == null ? "" : defect.getInputDatas());
+            cell10.setCellValue(defect.getExpectedResult() == null ? "" : defect.getExpectedResult());
+            cell11.setCellValue(defect.getTestResult());
+            cell12.setCellValue(defect.getOthers() == null ? "" : defect.getOthers());
+            cell13.setCellValue(userIdNameMap.get(defect.getCommiterId()));
+            cell14.setCellValue(DateUtils.formatDate(new Date(defect.getCommitTime().getTime()), "yyyy-MM-dd"));
+            List<String> files = new ArrayList();
+            files.addAll(defect.getFiles());
+            files.addAll(defect.getScreenshots());
+            cell15.setCellValue(Strings.join(files, '、'));
+        }
+    }
 }

+ 1 - 1
site/src/main/java/com/mooctest/crowd/site/controller/TestEnvController.java

@@ -42,7 +42,7 @@ public class TestEnvController {
 
     @PutMapping(value = "/{id:\\d+}")
     @LoginRequired
-    public ResponseVO update(HttpServletRequest request, @PathVariable Long id, @Validated @RequestBody TestEnvUpdatedCommand testEnvUpdatedCommand) {
+    public ResponseVO update(HttpServletRequest request, @PathVariable Long id, @RequestBody TestEnvUpdatedCommand testEnvUpdatedCommand) {
         testEnvUpdatedCommand.setId(id);
         testEnvUpdatedCommand.setUserId(RequestUtils.getUserId(request));
         testEnvService.update(testEnvUpdatedCommand);

+ 1 - 1
site/src/main/java/com/mooctest/crowd/site/controller/TestToolController.java

@@ -37,7 +37,7 @@ public class TestToolController {
 
     @PutMapping(value = "/{id:\\d+}")
     @LoginRequired
-    public ResponseVO update(HttpServletRequest request, @PathVariable Long id, @Validated @RequestBody TestToolUpdatedCommand testToolUpdatedCommand) {
+    public ResponseVO update(HttpServletRequest request, @PathVariable Long id, @RequestBody TestToolUpdatedCommand testToolUpdatedCommand) {
         testToolUpdatedCommand.setId(id);
         testToolUpdatedCommand.setUserId(RequestUtils.getUserId(request));
         testToolService.update(testToolUpdatedCommand);

+ 1 - 1
site/src/main/java/com/mooctest/crowd/site/controller/advice/ExceptionAdvice.java

@@ -117,7 +117,7 @@ public class ExceptionAdvice {
         String uri = request.getRequestURI();
         String contentType = request.getContentType();
         String params = "";
-        if (contentType.toLowerCase().contains("application/json")) {
+        if (!StringUtils.isEmpty(contentType) && contentType.toLowerCase().contains("application/json")) {
 //            params = (String)request.getAttribute("REQ_JSON_BODY");
 //            int index = params.indexOf("password:");
 //            if (index != -1) {

+ 1 - 86
site/src/main/java/com/mooctest/crowd/site/data/vo/TaskMoreInfoVO.java

@@ -7,91 +7,6 @@ import java.sql.Timestamp;
 import java.util.List;
 
 @Data
-public class TaskMoreInfoVO {
-    private ProjectInfoVO project;
+public class TaskMoreInfoVO extends BaseProjectMoreInfoVO {
     private TaskInfoVO task;
-    private ReceivingOrgInfoVO receivingOrg;
-    private DemandUnitInfoVO demandUnit;
-    private List<TesterInfoVO> testers;
-    private List<TestCase> testCases;
-    private List<Defect> defects;
-    private List<TestEnv> testEnvs;
-    private List<TestTool> testTools;
-
-    @Data
-    public static class TaskInfoVO {
-        private Long id;
-        private String name;
-        private String code;
-        private String type;
-        private String description;
-        private String requirementFile;
-        private Long distributionType;
-        private String distributionProvince;
-        private String distributionCity;
-        private Double quotedPrice;
-        private Double fixedPrice;
-        private int status;
-        private Timestamp deadTime;
-        private Timestamp endTime;
-        private Timestamp createTime;
-    }
-
-    @Data
-    public static class ProjectInfoVO {
-        private Long id;
-        private String name;
-        private String code;
-        private Long projectDistributionTypeId;
-        private String fieldType;
-        private String applicationType;
-        private String type;
-        private String description;
-        private String projectFile;
-        private String requirementFile;
-        private String distributionProvince;
-        private String distributionCity;
-        private String valuationStandard;
-        private Double quotedPrice;
-        private Double fixedPrice;
-        private Double restPrice;
-        private String entrustUnit;
-        private int status;
-        private Timestamp deadTime;
-        private Timestamp endTime;
-        private Timestamp createTime;
-    }
-
-    @Data
-    public static class TesterInfoVO {
-        private Long id;
-        private String name;
-        private String gender;
-        private String province;
-        private String city;
-        private String photoUrl;
-        private String unit;
-        private String county;
-        private String address;
-    }
-
-    @Data
-    public static class DemandUnitInfoVO {
-        private Long id;
-        private String name;
-        private String address;
-        private String province;
-        private String city;
-        private String county;
-    }
-
-    @Data
-    public static class ReceivingOrgInfoVO {
-        private Long id;
-        private String name;
-        private String address;
-        private String province;
-        private String city;
-        private String county;
-    }
 }

+ 10 - 6
site/src/main/java/com/mooctest/crowd/site/service/CrowdProjectService.java

@@ -18,11 +18,11 @@ import java.util.List;
  */
 public interface CrowdProjectService {
 
-    List<CrowdTestProjectVO>    findIndexProject();
+    List<CrowdTestProjectVO> findIndexProject();
 
-    List<CrowdTestProjectVO>  findAllMoreHotProjects();
+    List<CrowdTestProjectVO> findAllMoreHotProjects();
 
-    List<CrowdProjectVO>  findAllMoreHotProjectList(String keyword);
+    List<CrowdProjectVO> findAllMoreHotProjectList(String keyword);
 
     List<CrowdTestProjectVO> findByNameLike(String name);
 
@@ -32,7 +32,7 @@ public interface CrowdProjectService {
 
     ProjectDetailsDTO getProjectDetails(String projectCode, Long userId);
 
-    ProjectDetailsDTO createCrowdProject(CrowdTestProjectCommand command,long userId);
+    ProjectDetailsDTO createCrowdProject(CrowdTestProjectCommand command, long userId);
 
     ProjectDetailsDTO updateProject(String projectCode, CrowdTestProjectCommand crowdTestProjectCommand);
 
@@ -44,7 +44,7 @@ public interface CrowdProjectService {
 
     List<CrowdTestProject> generateProjectByExcel(Long userId, MultipartFile file);
 
-    List<CrowdTestProject> generateProjectByExcelAndUserId(Long userId,MultipartFile file);
+    List<CrowdTestProject> generateProjectByExcelAndUserId(Long userId, MultipartFile file);
 
     List<RegionalManagerVO> getRegionalManagerList();
 
@@ -65,4 +65,8 @@ public interface CrowdProjectService {
     UserProjectDTO getProjectByToken(String projectCode, String taskCode, Long userId, String token);
 
     List<SimpleProjectDataVO> findSimpleProjectDatasByRegionalManagerId(Long regionalManagerId);
-}
+
+    ProjectMoreInfoVO getProjectMoreInfo(Long userId, String projectCode);
+
+    CrowdTestProject findByProjectCode(String projectCode);
+}

+ 3 - 0
site/src/main/java/com/mooctest/crowd/site/service/CrowdTaskService.java

@@ -1,5 +1,6 @@
 package com.mooctest.crowd.site.service;
 
+import com.mooctest.crowd.domain.domainobject.CrowdTestTask;
 import com.mooctest.crowd.site.command.CrowdTestTaskCommand;
 import com.mooctest.crowd.site.data.dto.TaskDetailsDTO;
 import com.mooctest.crowd.site.data.dto.TaskSquareDTO;
@@ -54,4 +55,6 @@ public interface CrowdTaskService {
     TaskStatisticsVO getTaskStatistics(Long userId, String taskCode);
 
     TaskMoreInfoVO getTaskMoreInfo(Long userId, String taskCode);
+
+    CrowdTestTask getByTaskCode(String taskCode);
 }

+ 2 - 0
site/src/main/java/com/mooctest/crowd/site/service/DefectService.java

@@ -8,6 +8,7 @@ import org.springframework.validation.annotation.Validated;
 
 import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
+import java.util.List;
 
 @Validated
 public interface DefectService {
@@ -18,4 +19,5 @@ public interface DefectService {
     void importDefects(@NotNull(message = "文件内容不能为空") byte[] bs,
                          @NotEmpty(message = "任务编号不能为空") String taskCode,
                          @NotNull(message = "用户id不能为空") Long userId);
+    List<Defect> findAllByTaskCode(Long readUserId, String taskCode);
 }

+ 4 - 0
site/src/main/java/com/mooctest/crowd/site/service/TestCaseService.java

@@ -9,8 +9,10 @@ import com.mooctest.crowd.site.data.dto.TestCaseExamCommand;
 import com.mooctest.crowd.site.data.dto.TestCaseSearchDTO;
 import org.springframework.validation.annotation.Validated;
 
+import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
+import java.util.List;
 
 @Validated
 public interface TestCaseService {
@@ -22,4 +24,6 @@ public interface TestCaseService {
     void importTestCases(@NotNull(message = "文件内容不能为空") byte[] bs,
                          @NotEmpty(message = "任务编号不能为空") String taskCode,
                          @NotNull(message = "用户id不能为空") Long userId);
+    void examAllValidByTaskCodeAndDesignerId(@NotBlank(message = "任务编号不能为空") String taskCode, @NotNull(message = "设计者id不能为空") Long designerId, @NotNull(message = "审核者id不能为空") Long examerId);
+    List<TestCase> findAllByTaskCode(Long readUserId, String taskCode);
 }

+ 91 - 13
site/src/main/java/com/mooctest/crowd/site/service/impl/CrowdProjectServiceImpl.java

@@ -1,20 +1,13 @@
 package com.mooctest.crowd.site.service.impl;
 
+import com.alibaba.fastjson.JSONArray;
 import com.google.common.collect.Lists;
 import com.mooctest.crowd.domain.dao.*;
 import com.mooctest.crowd.domain.domainobject.*;
-import com.mooctest.crowd.domain.exception.BadRequestException;
-import com.mooctest.crowd.domain.exception.BaseException;
-import com.mooctest.crowd.domain.exception.Excel2ProjectException;
-import com.mooctest.crowd.domain.exception.HaveNotPartAuthException;
+import com.mooctest.crowd.domain.exception.*;
 import com.mooctest.crowd.domain.factory.CrowdTestProjectFactory;
-import com.mooctest.crowd.domain.model.CrowdTestProjectPO;
-import com.mooctest.crowd.domain.model.ResourceTokenPO;
-import com.mooctest.crowd.domain.model.TaskToUserPO;
-import com.mooctest.crowd.domain.model.UserTaskCountPO;
-import com.mooctest.crowd.domain.repository.CommonRepo;
-import com.mooctest.crowd.domain.repository.CrowdTestProjectRepo;
-import com.mooctest.crowd.domain.repository.UserRepo;
+import com.mooctest.crowd.domain.model.*;
+import com.mooctest.crowd.domain.repository.*;
 import com.mooctest.crowd.domain.util.Converter;
 import com.mooctest.crowd.site.command.CrowdTestProjectCommand;
 import com.mooctest.crowd.site.command.GenerateProjectCommand;
@@ -36,6 +29,7 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
@@ -93,6 +87,22 @@ public class CrowdProjectServiceImpl implements CrowdProjectService {
     @Autowired
     private ThemeSchedulerService themeSchedulerService;
 
+    @Autowired
+    private CrowdTestTaskRepo crowdTestTaskRepo;
+
+    @Autowired
+    private TestCaseRepo testCaseRepo;
+
+    @Autowired
+    private DefectRepo defectRepo;
+
+    @Autowired
+    private TestEnvRepo testEnvRepo;
+
+    @Autowired
+    private TestToolRepo testToolRepo;
+
+
     /**
      * 众测广场首页展示的项目
      *
@@ -183,6 +193,7 @@ public class CrowdProjectServiceImpl implements CrowdProjectService {
     }
 
     @Override
+    @Transactional
     public ProjectDetailsDTO createCrowdProject(CrowdTestProjectCommand command, long userId) {
         // 获取用户所有角色
 //        List<UserToRolePO> userToRole = userToRoleDao.findByUserId(userId);
@@ -200,6 +211,7 @@ public class CrowdProjectServiceImpl implements CrowdProjectService {
             projectRepo.saveCrowdTestProject(project);
             projectDetailsDTO.setProjectDetails(new CrowdProjectVO(project));
             themeSchedulerService.createNewThemeScheduler(project);
+
             return projectDetailsDTO;
         } else {
             throw new HaveNotPartAuthException();
@@ -207,8 +219,10 @@ public class CrowdProjectServiceImpl implements CrowdProjectService {
     }
 
     @Override
+    @Transactional
     public ProjectDetailsDTO updateProject(String projectCode, CrowdTestProjectCommand crowdTestProjectCommand) {
         CrowdTestProject project = projectRepo.getByProjectCode(projectCode);
+        List<String> oldTypes = JSONArray.parseArray(project.getType(), String.class);
         if (project.getStatus() == CrowdTestProjectStatus.HAS_FINISHED)
             throw new BaseException("结项项目禁止修改!");
         if (!project.getUserId().equals(crowdTestProjectCommand.getUserId()))
@@ -217,19 +231,24 @@ public class CrowdProjectServiceImpl implements CrowdProjectService {
         if (project.getCreateTime() == null) {
             project.setCreateTime(new Timestamp(System.currentTimeMillis()));
         }
-        projectRepo.saveCrowdTestProject(operationMediator.updateProject(project, crowdTestProjectCommand));
+        CrowdTestProject newProject = operationMediator.updateProject(project, crowdTestProjectCommand);
+        projectRepo.saveCrowdTestProject(newProject);
+
         return getProjectDetails(projectCode, crowdTestProjectCommand.getUserId());
     }
 
     @Override
+    @Transactional
     public void deleteProject(Long projectId, Long userId) {
         //todo 后面需要加入是否有权限进行删除
-        if (!projectRepo.getByID(projectId).getUserId().equals(userId))
+        CrowdTestProject project = projectRepo.getByID(projectId);
+        if (project != null && !project.getUserId().equals(userId))
             throw new BaseException("没有权限");
         projectRepo.deleteByProjectId(projectId);
     }
 
     @Override
+    @Transactional
     public ProjectDetailsDTO generateProjectWithData(GenerateProjectCommand command) {
         CrowdTestProject project = command.toCrowdProject();
         project.setCode(GenerateFlowCodeUtil.generateProjCode());
@@ -259,6 +278,7 @@ public class CrowdProjectServiceImpl implements CrowdProjectService {
     }
 
     @Override
+    @Transactional
     public List<ProjectDetailsDTO> importMultiProjectsByExcel(List<CrowdTestProject> projects) {
         List<ProjectDetailsDTO> dtos = new ArrayList<>();
         projects.forEach(project -> {
@@ -283,6 +303,7 @@ public class CrowdProjectServiceImpl implements CrowdProjectService {
     }
 
     @Override
+    @Transactional
     public List<CrowdTestProject> generateProjectByExcel(Long userId, MultipartFile file) {
         User user = userRepo.getByID(userId);
         List<CrowdTestProject> projects = generateProjectByExcelAndUserId(userId,file);
@@ -531,6 +552,62 @@ public class CrowdProjectServiceImpl implements CrowdProjectService {
         }).collect(Collectors.toList());
     }
 
+    public ProjectMoreInfoVO getProjectMoreInfo(Long userId, String projectCode) {
+        ProjectMoreInfoVO projectMoreInfoVO = new ProjectMoreInfoVO();
+        CrowdTestProject crowdTestProject = projectRepo.getByProjectCode(projectCode);
+        if (crowdTestProject == null) {
+            throw new CrowdTestProjectNotExistException();
+        }
+        if (!crowdTestProject.getRegionalManagerId().equals(userId)) {
+            throw new BaseException("您无权访问该任务!");
+        }
+        TaskMoreInfoVO.ProjectInfoVO projectInfoVO = Converter.convert(TaskMoreInfoVO.ProjectInfoVO.class, crowdTestProject);
+        User demandUnitUser = userRepo.getByID(crowdTestProject.getUserId());
+        User receivingOrgUser = userRepo.getByID(crowdTestProject.getRegionalManagerId());
+        TaskMoreInfoVO.DemandUnitInfoVO demandUnitInfoVO = Converter.convert(TaskMoreInfoVO.DemandUnitInfoVO.class, demandUnitUser);
+        TaskMoreInfoVO.ReceivingOrgInfoVO receivingOrgInfoVO = Converter.convert(TaskMoreInfoVO.ReceivingOrgInfoVO.class, receivingOrgUser);
+        List<CrowdTestTask> tasks = crowdTestTaskRepo.findAllByCrowdTestProjectCode(projectCode);
+        Map<Long, ProjectMoreInfoVO.TesterInfoVO> idTestInfoMap = new HashMap();
+        tasks.forEach(task -> {
+            String taskCode = task.getCode();
+            List<Defect> defects = defectRepo.findAllByTaskCode(taskCode);
+            List<TestCase> testCases = testCaseRepo.findAllByTaskCode(taskCode);
+            List<TestEnv> testEnvs = testEnvRepo.findAllByTaskCode(taskCode);
+            List<TestTool> testTools = testToolRepo.findAllByTaskCode(taskCode);
+            ProjectMoreInfoVO.TaskInfoVO taskInfoVO = Converter.convert(TaskMoreInfoVO.TaskInfoVO.class, task);
+            StringBuilder testerIdSb = new StringBuilder();
+            viewMediator.renderTaskDetails(projectCode, taskCode, userId)
+                    .getAcceptedUserList().stream().forEach(taskToUserVO -> {
+                        testerIdSb.append(taskToUserVO.getUserId()).append(",");
+                        UserVO userVO = taskToUserVO.getUserVO();
+                        TaskMoreInfoVO.TesterInfoVO testerInfoVO = Converter.convert(TaskMoreInfoVO.TesterInfoVO.class, userVO);
+                        idTestInfoMap.put(testerInfoVO.getId(), testerInfoVO);
+                    });
+            String testerIds = "";
+            if (testerIdSb.length() > 0) {
+                testerIds = testerIdSb.substring(0, testerIdSb.length() - 1);
+            }
+            taskInfoVO.setTesterIds(testerIds);
+            projectMoreInfoVO.getDefects().addAll(defects);
+            projectMoreInfoVO.getTestCases().addAll(testCases);
+            projectMoreInfoVO.getTestEnvs().addAll(testEnvs);
+            projectMoreInfoVO.getTestTools().addAll(testTools);
+            projectMoreInfoVO.getTasks().add(taskInfoVO);
+        });
+        projectMoreInfoVO.getTesters().addAll(idTestInfoMap.values());
+
+        projectMoreInfoVO.setProject(projectInfoVO);
+        projectMoreInfoVO.setDemandUnit(demandUnitInfoVO);
+        projectMoreInfoVO.setReceivingOrg(receivingOrgInfoVO);
+
+        return projectMoreInfoVO;
+    }
+
+    @Override
+    public CrowdTestProject findByProjectCode(String projectCode) {
+        return projectRepo.getByProjectCode(projectCode);
+    }
+
     private List<CrowdTestProject> transferExcel2Projects(Long userId,MultipartFile file) {
         List<String> logList = new ArrayList<>();
         List<CrowdTestProject> projects = new ArrayList<>();
@@ -718,4 +795,5 @@ public class CrowdProjectServiceImpl implements CrowdProjectService {
         Matcher m = p.matcher(str);
         return m.matches();
     }
+
 }

+ 18 - 1
site/src/main/java/com/mooctest/crowd/site/service/impl/CrowdTaskServiceImpl.java

@@ -23,6 +23,7 @@ import com.mooctest.crowd.site.data.tfidf.TFIDFAnalyzer;
 import com.mooctest.crowd.site.data.vo.*;
 import com.mooctest.crowd.site.mediator.ViewMediator;
 import com.mooctest.crowd.site.service.CrowdTaskService;
+import com.mooctest.crowd.site.service.TesterCertService;
 import com.mooctest.crowd.site.util.GenerateFlowCodeUtil;
 import com.mooctest.crowd.site.util.RequestUtils;
 import lombok.extern.slf4j.Slf4j;
@@ -95,6 +96,9 @@ public class CrowdTaskServiceImpl implements CrowdTaskService {
     @Autowired
     private ITestToolRepo testToolRepo;
 
+    @Autowired
+    private TesterCertService testerCertService;
+
     @Override
     public List<CrowdTaskVO> findMoreHotTasks() {
         return viewMediator.findMoreHotTasks();
@@ -255,6 +259,7 @@ public class CrowdTaskServiceImpl implements CrowdTaskService {
         } else if (AuthCheckServiceImpl.isAgency(userRepo.getByID(userId))) {
             // 测评机构提交任务
             task.commitByAgency(taskCode, userId);
+            testerCertService.addTaskCount(userId);
         }
 
         projectRepo.saveCrowdTestProject(project);
@@ -477,18 +482,25 @@ public class CrowdTaskServiceImpl implements CrowdTaskService {
         User receivingOrgUser = userRepo.getByID(crowdTestProject.getRegionalManagerId());
         TaskMoreInfoVO.DemandUnitInfoVO demandUnitInfoVO = Converter.convert(TaskMoreInfoVO.DemandUnitInfoVO.class, demandUnitUser);
         TaskMoreInfoVO.ReceivingOrgInfoVO receivingOrgInfoVO = Converter.convert(TaskMoreInfoVO.ReceivingOrgInfoVO.class, receivingOrgUser);
+        StringBuilder testerIdSb = new StringBuilder();
         List<TaskMoreInfoVO.TesterInfoVO> testerInfoVOs = getTaskDetails(task.getCrowdTestProjectCode(), taskCode, userId)
                 .getAcceptedUserList().stream().map(taskToUserVO -> {
+                    testerIdSb.append(taskToUserVO.getUserId()).append(",");
                     UserVO userVO = taskToUserVO.getUserVO();
                     TaskMoreInfoVO.TesterInfoVO testerInfoVO = Converter.convert(TaskMoreInfoVO.TesterInfoVO.class, userVO);
                     return testerInfoVO;
                 }).collect(Collectors.toList());
+        String testerIds = "";
+        if (testerIdSb.length() > 0) {
+            testerIds = testerIdSb.substring(0, testerIdSb.length() - 1);
+        }
+        taskInfoVO.setTesterIds(testerIds);
 
         taskMoreInfoVO.setTestCases(testCases);
         taskMoreInfoVO.setDefects(defects);
         taskMoreInfoVO.setTestEnvs(testEnvs);
         taskMoreInfoVO.setTestTools(testTools);
-        taskMoreInfoVO.setTesters(testerInfoVOs);
+        taskMoreInfoVO.getTesters().addAll(testerInfoVOs);
         taskMoreInfoVO.setTask(taskInfoVO);
         taskMoreInfoVO.setProject(projectInfoVO);
         taskMoreInfoVO.setDemandUnit(demandUnitInfoVO);
@@ -497,5 +509,10 @@ public class CrowdTaskServiceImpl implements CrowdTaskService {
         return taskMoreInfoVO;
     }
 
+    @Override
+    public CrowdTestTask getByTaskCode(String taskCode) {
+        return crowdTestTaskRepo.findByCode(taskCode);
+    }
+
 }
 

+ 15 - 4
site/src/main/java/com/mooctest/crowd/site/service/impl/DefectServiceImpl.java

@@ -2,10 +2,7 @@ package com.mooctest.crowd.site.service.impl;
 
 import com.alibaba.druid.util.StringUtils;
 import com.mooctest.crowd.domain.dao.CrowdTestProjectDao;
-import com.mooctest.crowd.domain.domainobject.CrowdTestTask;
-import com.mooctest.crowd.domain.domainobject.Defect;
-import com.mooctest.crowd.domain.domainobject.DeletedStatus;
-import com.mooctest.crowd.domain.domainobject.TestCase;
+import com.mooctest.crowd.domain.domainobject.*;
 import com.mooctest.crowd.domain.env.DefectType;
 import com.mooctest.crowd.domain.env.Priority;
 import com.mooctest.crowd.domain.env.Seriousness;
@@ -15,6 +12,7 @@ import com.mooctest.crowd.domain.exception.CrowdTestProjectNotExistException;
 import com.mooctest.crowd.domain.exception.CrowdTestTaskNotExistException;
 import com.mooctest.crowd.domain.model.CrowdTestProjectPO;
 import com.mooctest.crowd.domain.page.DOPage;
+import com.mooctest.crowd.domain.repository.CrowdTestProjectRepo;
 import com.mooctest.crowd.domain.repository.ICrowdTaskRepo;
 import com.mooctest.crowd.domain.repository.IDefectRepo;
 import com.mooctest.crowd.domain.repository.ITestCaseRepo;
@@ -40,6 +38,7 @@ import java.io.IOException;
 import java.sql.Timestamp;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 
 @Service
@@ -52,6 +51,8 @@ public class DefectServiceImpl implements DefectService {
     private ICrowdTaskRepo crowdTaskRepo;
     @Autowired
     private CrowdTestProjectDao crowdTestProjectDao;
+    @Autowired
+    private CrowdTestProjectRepo crowdTestProjectRepo;
 
     @Override
     public Defect add(DefectAddedCommand defectAddedCommand) {
@@ -266,4 +267,14 @@ public class DefectServiceImpl implements DefectService {
             throw new RuntimeException(e);
         }
     }
+
+    @Override
+    public List<Defect> findAllByTaskCode(Long readUserId, String taskCode) {
+        CrowdTestTask task = crowdTaskRepo.findByCode(taskCode);
+        CrowdTestProject project = crowdTestProjectRepo.getByProjectCode(task.getCrowdTestProjectCode());
+        if (!project.getRegionalManagerId().equals(readUserId)) {
+            throw new BaseException("您无权限操作该测试用例!");
+        }
+        return defectRepo.findAllByTaskCode(taskCode);
+    }
 }

+ 32 - 2
site/src/main/java/com/mooctest/crowd/site/service/impl/TestCaseServiceImpl.java

@@ -3,6 +3,7 @@ package com.mooctest.crowd.site.service.impl;
 import com.alibaba.druid.util.StringUtils;
 import com.mooctest.crowd.domain.dao.CrowdTestProjectDao;
 import com.mooctest.crowd.domain.dao.TaskToUserDao;
+import com.mooctest.crowd.domain.dao.TestCaseDao;
 import com.mooctest.crowd.domain.domainobject.*;
 import com.mooctest.crowd.domain.env.Priority;
 import com.mooctest.crowd.domain.env.TestCaseExamStatus;
@@ -34,6 +35,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.sql.Timestamp;
@@ -41,8 +44,7 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 @Service
-public class
-TestCaseServiceImpl implements TestCaseService {
+public class TestCaseServiceImpl implements TestCaseService {
     @Autowired
     private ITestCaseRepo testCaseRepo;
     @Autowired
@@ -55,6 +57,10 @@ TestCaseServiceImpl implements TestCaseService {
     private CrowdTestProjectDao crowdTestProjectDao;
     @Autowired
     private TaskToUserDao taskToUserDao;
+    @Autowired
+    private TestCaseDao testCaseDao;
+    @Autowired
+    private CrowdTestProjectRepo crowdTestProjectRepo;
 
     @Override
     @Transactional
@@ -95,12 +101,14 @@ TestCaseServiceImpl implements TestCaseService {
     }
 
     @Override
+    @Transactional
     public void delete(Long designerId, Long id) {
         TestCase testCase = testCaseRepo.findById(id);
         if (!testCase.getDesignerId().equals(designerId)) {
             throw new BaseException("当前用户无权限操作该用例");
         }
         testCaseRepo.deleteById(id);
+        defectRepo.deleteByTaskCodeAndTestCaseCode(testCase.getTaskCode(), testCase.getCode());
     }
 
     @Override
@@ -352,4 +360,26 @@ TestCaseServiceImpl implements TestCaseService {
             throw new RuntimeException(e);
         }
     }
+
+    @Override
+    @Transactional
+    public void examAllValidByTaskCodeAndDesignerId(String taskCode, Long designerId, Long examerId) {
+        CrowdTestTask task = crowdTaskRepo.findByCode(taskCode);
+        CrowdTestProject project = crowdTestProjectRepo.getByProjectCode(task.getCrowdTestProjectCode());
+        if (!project.getRegionalManagerId().equals(examerId)) {
+            throw new BaseException("您无权限操作该测试用例!");
+        }
+        testCaseDao.examAllValidByTaskCodeAndDesignerId(taskCode, designerId);
+    }
+
+    @Override
+    public List<TestCase> findAllByTaskCode(Long readUserId, String taskCode) {
+        CrowdTestTask task = crowdTaskRepo.findByCode(taskCode);
+        CrowdTestProject project = crowdTestProjectRepo.getByProjectCode(task.getCrowdTestProjectCode());
+        if (!project.getRegionalManagerId().equals(readUserId)) {
+            throw new BaseException("您无权限操作该测试用例!");
+        }
+        List<TestCase> testCases = testCaseRepo.findAllByTaskCode(taskCode);
+        return testCases;
+    }
 }

+ 2 - 2
site/src/main/resources/application.yml

@@ -89,7 +89,7 @@ website:
 spring:
   profiles: online
   datasource:
-    url: jdbc:mysql://8.134.32.27:3306/crowd-test-service?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
+    url: jdbc:mysql://8.134.32.27:3306/crowd-test-service?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&sessionVariables=sql_mode=%27STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION%27
     username: root
     password: callfortest_crowd
   redis:
@@ -216,7 +216,7 @@ website:
 spring:
   profiles: localhost
   datasource:
-    url: jdbc:mysql://127.0.0.1:3306/crowd-test-service?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
+    url: jdbc:mysql://127.0.0.1:3306/crowd-test-service?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&sessionVariables=sql_mode=%27STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION%27
     username: root
     password: 123456
   redis: