Selaa lähdekoodia

Merge branch 'feature-V2.0' into 'Private'

# Conflicts:
#   site/src/main/java/com/mooctest/crowd/site/controller/CommonController.java
郭超 4 vuotta sitten
vanhempi
commit
a478898e3c
28 muutettua tiedostoa jossa 642 lisäystä ja 144 poistoa
  1. 14 15
      core/pom.xml
  2. 2 0
      core/src/main/java/com/mooctest/crowd/domain/dao/CrowdTestTaskDao.java
  3. 0 1
      core/src/main/java/com/mooctest/crowd/domain/domainobject/CrowdTestProject.java
  4. 1 38
      core/src/main/java/com/mooctest/crowd/domain/domainobject/CrowdTestTask.java
  5. 8 0
      core/src/main/java/com/mooctest/crowd/domain/exception/ExportTaskFileDirectoryNotExistException.java
  6. 8 0
      core/src/main/java/com/mooctest/crowd/domain/exception/ExportTaskFileNotExistException.java
  7. 8 0
      core/src/main/java/com/mooctest/crowd/domain/exception/FileIsEmptyException.java
  8. 2 23
      core/src/main/java/com/mooctest/crowd/domain/model/CrowdTestTaskPO.java
  9. 24 14
      core/src/main/java/com/mooctest/crowd/domain/repository/CrowdTestProjectRepo.java
  10. 2 0
      core/src/main/java/com/mooctest/crowd/domain/repository/ICrowdTestProjectRepo.java
  11. 12 0
      site/pom.xml
  12. 1 0
      site/src/main/java/com/mooctest/crowd/site/constants/UploadType.java
  13. 22 0
      site/src/main/java/com/mooctest/crowd/site/controller/CrowdTaskController.java
  14. 5 0
      site/src/main/java/com/mooctest/crowd/site/controller/UploadController.java
  15. 6 0
      site/src/main/java/com/mooctest/crowd/site/controller/advice/ExceptionAdvice.java
  16. 3 0
      site/src/main/java/com/mooctest/crowd/site/data/TaskOperationControl.java
  17. 0 2
      site/src/main/java/com/mooctest/crowd/site/data/vo/ConfigurationVO.java
  18. 29 0
      site/src/main/java/com/mooctest/crowd/site/data/vo/CrowdProjectVO.java
  19. 0 2
      site/src/main/java/com/mooctest/crowd/site/data/vo/CrowdReportVO.java
  20. 21 0
      site/src/main/java/com/mooctest/crowd/site/data/vo/CrowdTaskVO.java
  21. 21 8
      site/src/main/java/com/mooctest/crowd/site/mediator/impl/WebMediatorImpl.java
  22. 6 0
      site/src/main/java/com/mooctest/crowd/site/service/CrowdTaskService.java
  23. 2 3
      site/src/main/java/com/mooctest/crowd/site/service/UploadService.java
  24. 19 14
      site/src/main/java/com/mooctest/crowd/site/service/impl/AgencyServiceImpl.java
  25. 263 9
      site/src/main/java/com/mooctest/crowd/site/service/impl/CrowdTaskServiceImpl.java
  26. 11 1
      site/src/main/java/com/mooctest/crowd/site/service/impl/OSSUploadServiceImpl.java
  27. 4 3
      site/src/main/java/com/mooctest/crowd/site/util/OperationRecordUtil.java
  28. 148 11
      site/src/main/resources/application.yml

+ 14 - 15
core/pom.xml

@@ -101,9 +101,9 @@
         </dependency>
 
         <dependency>
-            <groupId> org.springframework.boot </groupId>
-            <artifactId> spring-boot-configuration-processor</artifactId>
-            <optional> true </optional>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
         </dependency>
 
         <dependency>
@@ -159,19 +159,18 @@
             <version>1.4</version>
         </dependency>
 
-      <dependency>
-        <groupId>com.alibaba</groupId>
-        <artifactId>fastjson</artifactId>
-        <version>1.2.58</version>
-    </dependency>
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
             <version>1.2.58</version>
         </dependency>
-
-
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.58</version>
+        </dependency>
     </dependencies>
+
     <build>
         <plugins>
             <plugin>
@@ -183,11 +182,11 @@
                     <target>1.8</target>
                 </configuration>
             </plugin>
-<!--            <plugin>-->
-<!--                <groupId>org.apache.maven.surefire</groupId>-->
-<!--                <artifactId>surefire-junit4</artifactId>-->
-<!--                <version>2.12.4</version>-->
-<!--            </plugin>-->
+            <!--            <plugin>-->
+            <!--                <groupId>org.apache.maven.surefire</groupId>-->
+            <!--                <artifactId>surefire-junit4</artifactId>-->
+            <!--                <version>2.12.4</version>-->
+            <!--            </plugin>-->
         </plugins>
     </build>
 </project>

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

@@ -55,6 +55,8 @@ public interface CrowdTestTaskDao extends CrudRepository<CrowdTestTaskPO, Long>,
 
     List<CrowdTestTaskPO> findByCrowdTestProjectCodeAndIsDeleted(String crowdTestProjectCode, int isDeleted);
 
+    List<CrowdTestTaskPO> findByCrowdTestProjectCodeAndCodeAndIsDeleted(String crowdTestProjectCode, String taskCode, int isDeleted);
+
     List<CrowdTestTaskPO> findByEvaluationAgencyIdAndIsDeleted(Long evaluationAgencyId, int isDeleted);
 
     List<CrowdTestTaskPO> findAllByIsDeleted(int isDeleted);

+ 0 - 1
core/src/main/java/com/mooctest/crowd/domain/domainobject/CrowdTestProject.java

@@ -714,5 +714,4 @@ public class CrowdTestProject {
         }
         this.setStatus(CrowdTestProjectStatus.HAS_REJECTED);
     }
-
 }

+ 1 - 38
core/src/main/java/com/mooctest/crowd/domain/domainobject/CrowdTestTask.java

@@ -46,44 +46,7 @@ public class CrowdTestTask {
     private int participantHasCommittedCount;
     private List<TaskToUser> acceptedUserList = new ArrayList<>();
     private EndPoint endPoint;
-//    private List<CrowdTestReport> crowdTestReportList = new ArrayList<>();
-
-    @Override
-    public String toString() {
-        return "CrowdTestTask{" +
-                "id=" + id +
-                ", name='" + name + '\'' +
-                ", code='" + code + '\'' +
-                ", crowdTestProjectCode='" + crowdTestProjectCode + '\'' +
-                ", evaluationAgencyId=" + evaluationAgencyId +
-                ", type='" + type + '\'' +
-                ", description='" + description + '\'' +
-                ", requirementFile='" + requirementFile + '\'' +
-                ", distributionType=" + distributionType +
-                ", distributionProvince='" + distributionProvince + '\'' +
-                ", distributionCity='" + distributionCity + '\'' +
-                ", quotedPrice=" + quotedPrice +
-                ", fixedPrice=" + fixedPrice +
-                ", status=" + status +
-                ", deadTime=" + deadTime +
-                ", endTime=" + endTime +
-                ", isDeleted=" + isDeleted +
-                ", createTime=" + createTime +
-                ", participantCount=" + participantCount +
-                ", acceptedCount=" + acceptedCount +
-                ", acceptedUserList=" + acceptedUserList +
-                '}';
-    }
-
-    //    public CrowdTestReport getCrowdTestReportByReportId(CrowdTestTask crowdTestTask, Long reportId) throws CrowdTestTaskNotExistException, CrowdTestReportNotExistException {
-//        List<CrowdTestReport> crowdTestReportList = crowdTestTask.getCrowdTestReportList();
-//        for (CrowdTestReport crowdTestReport : crowdTestReportList) {
-//            if (crowdTestReport.getId().equals(reportId)) {
-//                return crowdTestReport;
-//            }
-//        }
-//        throw new CrowdTestReportNotExistException();
-//    }
+    private String exportUrl;
 
     /**
      * 接收任务(测评机构)

+ 8 - 0
core/src/main/java/com/mooctest/crowd/domain/exception/ExportTaskFileDirectoryNotExistException.java

@@ -0,0 +1,8 @@
+package com.mooctest.crowd.domain.exception;
+
+/**
+ * @author guochao
+ * @date 2021-04-10 11:03
+ */
+public class ExportTaskFileDirectoryNotExistException extends BaseException {
+}

+ 8 - 0
core/src/main/java/com/mooctest/crowd/domain/exception/ExportTaskFileNotExistException.java

@@ -0,0 +1,8 @@
+package com.mooctest.crowd.domain.exception;
+
+/**
+ * @author guochao
+ * @date 2021-04-10 10:51
+ */
+public class ExportTaskFileNotExistException extends BaseException {
+}

+ 8 - 0
core/src/main/java/com/mooctest/crowd/domain/exception/FileIsEmptyException.java

@@ -0,0 +1,8 @@
+package com.mooctest.crowd.domain.exception;
+
+/**
+ * @author guochao
+ * @date 2021-04-10 14:42
+ */
+public class FileIsEmptyException extends BaseException {
+}

+ 2 - 23
core/src/main/java/com/mooctest/crowd/domain/model/CrowdTestTaskPO.java

@@ -82,27 +82,6 @@ CrowdTestTaskPO {
     @Column(name = "CTT_PARTICIPANT_HAS_COMMITTED_COUNT")
     private int participantHasCommittedCount;
 
-    @Override
-    public String toString() {
-        return "CrowdTestTaskPO{" +
-                "id=" + id +
-                ", code='" + code + '\'' +
-                ", name='" + name + '\'' +
-                ", crowdTestProjectCode='" + crowdTestProjectCode + '\'' +
-                ", evaluationAgencyId=" + evaluationAgencyId +
-                ", type=" + type +
-                ", description='" + description + '\'' +
-                ", requirementFile='" + requirementFile + '\'' +
-                ", distributionType=" + distributionType +
-                ", distributionProvince='" + distributionProvince + '\'' +
-                ", distributionCity='" + distributionCity + '\'' +
-                ", quotedPrice=" + quotedPrice +
-                ", fixedPrice=" + fixedPrice +
-                ", status=" + status +
-                ", deadTime=" + deadTime +
-                ", endTime=" + endTime +
-                ", isDeleted='" + isDeleted + '\'' +
-                ", createTime=" + createTime +
-                '}';
-    }
+    @Column(name = "CTT_EXPORT_URL")
+    private String exportUrl;
 }

+ 24 - 14
core/src/main/java/com/mooctest/crowd/domain/repository/CrowdTestProjectRepo.java

@@ -8,6 +8,7 @@ import com.mooctest.crowd.domain.model.*;
 import com.mooctest.crowd.domain.util.Converter;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.NotNull;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
@@ -96,23 +97,26 @@ public class CrowdTestProjectRepo implements ICrowdTestProjectRepo {
 
     @Override
     public CrowdTestProject getByID(Long crowdTestProjectId) throws CrowdTestProjectNotExistException {
-
-        CrowdTestProjectPO crowdTestProjectPO = crowdTestProjectDao.findByIdAndIsDeleted(crowdTestProjectId, DeletedStatus.isNotDeleted);
-        if (crowdTestProjectPO == null) {
-            throw new CrowdTestProjectNotExistException();
-        } else {
-            CrowdTestProject crowdTestProjectResult = getCrowdTestProjectAndTaskAndReportByCrowdTestProjectPO(crowdTestProjectPO);
-            return crowdTestProjectResult;
-        }
+        return getCrowdTestProject(null, crowdTestProjectDao.findByIdAndIsDeleted(crowdTestProjectId, DeletedStatus.isNotDeleted));
     }
 
     @Override
     public CrowdTestProject getByProjectCode(String crowdTestProjectCode) throws CrowdTestProjectNotExistException {
-        CrowdTestProjectPO crowdTestProjectPO = crowdTestProjectDao.findByCodeAndIsDeleted(crowdTestProjectCode, DeletedStatus.isNotDeleted);
+        return getCrowdTestProject(null, crowdTestProjectDao.findByCodeAndIsDeleted(crowdTestProjectCode, DeletedStatus.isNotDeleted));
+    }
+
+    @Override
+    public CrowdTestProject getByProjectCodeAndTaskCode(String crowdTestProjectCode, String taskCode) throws CrowdTestProjectNotExistException {
+        return getCrowdTestProject(taskCode, crowdTestProjectDao.findByCodeAndIsDeleted(crowdTestProjectCode, DeletedStatus.isNotDeleted));
+    }
+
+    @NotNull
+    public CrowdTestProject getCrowdTestProject(String taskCode, CrowdTestProjectPO byCodeAndIsDeleted) {
+        CrowdTestProjectPO crowdTestProjectPO = byCodeAndIsDeleted;
         if (crowdTestProjectPO == null) {
             throw new CrowdTestProjectNotExistException();
         } else {
-            CrowdTestProject crowdTestProjectResult = getCrowdTestProjectAndTaskAndReportByCrowdTestProjectPO(crowdTestProjectPO);
+            CrowdTestProject crowdTestProjectResult = getCrowdTestProjectAndTaskAndReportByCrowdTestProjectPO(crowdTestProjectPO, taskCode);
             return crowdTestProjectResult;
         }
     }
@@ -214,7 +218,7 @@ public class CrowdTestProjectRepo implements ICrowdTestProjectRepo {
             if (crowdTestProjectPO == null) {
                 throw new CrowdTestProjectNotExistException();
             } else {
-                CrowdTestProject crowdTestProjectResult = getCrowdTestProjectAndTaskAndReportByCrowdTestProjectPO(crowdTestProjectPO.get(i));
+                CrowdTestProject crowdTestProjectResult = getCrowdTestProjectAndTaskAndReportByCrowdTestProjectPO(crowdTestProjectPO.get(i), null);
                 crowdTestProjectList.add(crowdTestProjectResult);
             }
         }
@@ -345,9 +349,15 @@ public class CrowdTestProjectRepo implements ICrowdTestProjectRepo {
      * @param crowdTestProjectPO
      * @return
      */
-    private CrowdTestProject getCrowdTestProjectAndTaskAndReportByCrowdTestProjectPO(CrowdTestProjectPO crowdTestProjectPO) {
+    private CrowdTestProject getCrowdTestProjectAndTaskAndReportByCrowdTestProjectPO(CrowdTestProjectPO crowdTestProjectPO, String taskCode) {
         CrowdTestProject crowdTestProjectResult = Converter.convert(CrowdTestProject.class, crowdTestProjectPO);
-        List<CrowdTestTaskPO> crowdTestTaskPOList = crowdTestTaskDao.findByCrowdTestProjectCodeAndIsDeleted(crowdTestProjectPO.getCode(), DeletedStatus.isNotDeleted);
+        List<CrowdTestTaskPO> crowdTestTaskPOList = new ArrayList<>();
+        if(taskCode != null){
+            // 指定任务返回
+            crowdTestTaskPOList = crowdTestTaskDao.findByCrowdTestProjectCodeAndCodeAndIsDeleted(crowdTestProjectPO.getCode(), taskCode, DeletedStatus.isNotDeleted);
+        }else{
+            crowdTestTaskPOList = crowdTestTaskDao.findByCrowdTestProjectCodeAndIsDeleted(crowdTestProjectPO.getCode(), DeletedStatus.isNotDeleted);
+        }
 
         List<CrowdTestTask> crowdTestTaskListResult = new ArrayList<>();
         for (CrowdTestTaskPO crowdTestTaskPO : crowdTestTaskPOList) {
@@ -451,7 +461,7 @@ public class CrowdTestProjectRepo implements ICrowdTestProjectRepo {
     private List<CrowdTestProject> getCrowdTestProjects(List<CrowdTestProjectPO> crowdTestProjectPOList) {
         List<CrowdTestProject> crowdTestProjectListResult = new ArrayList<>();
         for (CrowdTestProjectPO crowdTestProjectPO : crowdTestProjectPOList) {
-            CrowdTestProject crowdTestProjectResult = getCrowdTestProjectAndTaskAndReportByCrowdTestProjectPO(crowdTestProjectPO);
+            CrowdTestProject crowdTestProjectResult = getCrowdTestProjectAndTaskAndReportByCrowdTestProjectPO(crowdTestProjectPO, null);
             crowdTestProjectListResult.add(crowdTestProjectResult);
         }
         return crowdTestProjectListResult;

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

@@ -26,6 +26,8 @@ public interface ICrowdTestProjectRepo {
 
     CrowdTestProject getByProjectCode(String crowdTestProjectCode);
 
+    CrowdTestProject getByProjectCodeAndTaskCode(String crowdTestProjectCode, String taskCode) throws CrowdTestProjectNotExistException;
+
     List<CrowdTestProject> getAllCrowdTestProject();
 
     List<CrowdTestProject> getCrowdListByUserId(Long userId);

+ 12 - 0
site/pom.xml

@@ -57,6 +57,12 @@
 			<artifactId>mockito-all</artifactId>
 			<version>1.10.19</version>
 		</dependency>
+		<!-- ZIP -->
+		<dependency>
+			<groupId>net.lingala.zip4j</groupId>
+			<artifactId>zip4j</artifactId>
+			<version>1.3.2</version>
+		</dependency>
 		<dependency>
 			<groupId>com.mooctest.crowd</groupId>
 			<artifactId>core</artifactId>
@@ -185,6 +191,12 @@
 			<artifactId>aho-corasick-double-array-trie</artifactId>
 			<version>1.2.1</version>
 		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-test</artifactId>
+			<version>5.3.5</version>
+			<scope>compile</scope>
+		</dependency>
 	</dependencies>
 	<build>
 		<plugins>

+ 1 - 0
site/src/main/java/com/mooctest/crowd/site/constants/UploadType.java

@@ -12,5 +12,6 @@ public class UploadType {
     public static final String REPORT = "Report/";
     public static final String IMAGE = "Image/";
     public static final String AUTH_INFO = "AuthInfo/";
+    public static final String EXPORT_TASK_FILE = "ExportTask/";
     public static final String OTHERS = "Others/";
 }

+ 22 - 0
site/src/main/java/com/mooctest/crowd/site/controller/CrowdTaskController.java

@@ -5,6 +5,7 @@ import com.mooctest.crowd.domain.exception.UnauthorizedException;
 import com.mooctest.crowd.site.annotation.LoginRequired;
 import com.mooctest.crowd.site.command.CrowdTestTaskCommand;
 import com.mooctest.crowd.site.command.TaskDataBoardCommand;
+import com.mooctest.crowd.site.data.dto.ProjectDetailsDTO;
 import com.mooctest.crowd.site.data.dto.TaskDetailsDTO;
 import com.mooctest.crowd.site.data.dto.TaskSquareDTO;
 import com.mooctest.crowd.site.data.response.ResponseVO;
@@ -17,6 +18,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.BindingResult;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpSession;
 import java.util.List;
@@ -138,4 +140,24 @@ public class CrowdTaskController{
     public ResponseVO<List<JabaResult>> getTaskWord(@PathVariable("projectCode") String projectCode, @PathVariable("taskCode") String taskCode, HttpSession session){
         return new ResponseVO<>(ServerCode.SUCCESS, taskService.getTaskWord(projectCode, taskCode));
     }
+
+    /**
+     * 任务导出
+     * @param projectCode
+     * @param taskCode
+     * @param session
+     * @return
+     */
+    @RequestMapping(value = "/project/{projectCode}/task/{taskCode}/export", method = RequestMethod.GET)
+    public ResponseVO<String> exportTask(@PathVariable("projectCode") String projectCode, @PathVariable("taskCode") String taskCode, HttpSession session){
+        Long userId = Long.parseLong((String)session.getAttribute("userId"));
+        return new ResponseVO<>(ServerCode.SUCCESS, taskService.exportTask(projectCode, taskCode, userId));
+    }
+
+    // 任务导入
+    @RequestMapping(value = "/project/task/import", method = RequestMethod.POST)
+    public ResponseVO<ProjectDetailsDTO> importTask(MultipartFile file, HttpSession session){
+        Long userId = Long.parseLong((String)session.getAttribute("userId"));
+        return new ResponseVO<>(ServerCode.SUCCESS, taskService.importTask(file, userId));
+    }
 }

+ 5 - 0
site/src/main/java/com/mooctest/crowd/site/controller/UploadController.java

@@ -27,6 +27,11 @@ public class UploadController {
         return uploadService.uploadRequirment(file, userId);
     }
 
+    @RequestMapping(value = "/taskFile/{userId}", method = RequestMethod.POST)
+    public String uploadTaskFile(MultipartFile file, @PathVariable("userId") Long userId){
+        return uploadService.uploadTask(file, userId);
+    }
+
     @RequestMapping(value = "/apk/{userId}", method = RequestMethod.POST)
     public String uploadApk(MultipartFile file, @PathVariable("userId") Long userId){
         return uploadService.uploadAPK(file, userId);

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

@@ -55,6 +55,12 @@ public class ExceptionAdvice {
             return "您未认证为发包用户,请认证后操作。";
         } else if(e instanceof CrowdTestEndPointException){
             return "任务的服务序列号输入有误,不是base64加密后的序列号。";
+        } else if(e instanceof ExportTaskFileNotExistException){
+            return "导出的任务文件不存在。";
+        } else if(e instanceof ExportTaskFileDirectoryNotExistException){
+            return "导出的任务文件所在的文件夹不存在。";
+        } else if(e instanceof FileIsEmptyException){
+            return "文件不存在或文件是空文件,请重新上传。";
         } else {
             return e.getMessage();
         }

+ 3 - 0
site/src/main/java/com/mooctest/crowd/site/data/TaskOperationControl.java

@@ -22,6 +22,7 @@ public class TaskOperationControl {
     private boolean writeReport = false;
     private boolean taskDemonstrate = false;
     private boolean taskRecommend = false;
+    private boolean exportTask = false;
 
     public void hasAll(){
         this.receive = true;
@@ -32,6 +33,7 @@ public class TaskOperationControl {
         this.uploadReport = true;
         this.taskDemonstrate = true;
         this.taskRecommend = true;
+        this.exportTask = true;
     }
 
     public void noAll(){
@@ -44,5 +46,6 @@ public class TaskOperationControl {
         this.writeReport = false;
         this.taskDemonstrate = false;
         this.taskRecommend = false;
+        this.exportTask = false;
     }
 }

+ 0 - 2
site/src/main/java/com/mooctest/crowd/site/data/vo/ConfigurationVO.java

@@ -15,6 +15,4 @@ import java.util.Map;
 @AllArgsConstructor
 public class ConfigurationVO implements Serializable{
     private Map<String, String> configurationList;
-
-
 }

+ 29 - 0
site/src/main/java/com/mooctest/crowd/site/data/vo/CrowdProjectVO.java

@@ -2,12 +2,15 @@ package com.mooctest.crowd.site.data.vo;
 
 
 import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.annotation.JSONField;
 import com.google.common.collect.Lists;
 import com.mooctest.crowd.domain.domainobject.CrowdTestProject;
 import com.mooctest.crowd.domain.domainobject.CrowdTestProjectStatus;
+import com.mooctest.crowd.domain.factory.CrowdTestProjectFactory;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.springframework.beans.BeanUtils;
 
 import java.io.Serializable;
 import java.sql.Timestamp;
@@ -25,6 +28,7 @@ import java.util.Map;
 public class CrowdProjectVO implements Serializable {
 
     private String id;
+    private String code;
     private String name;
     private String contactName;
     private String contactPhone;
@@ -38,6 +42,8 @@ public class CrowdProjectVO implements Serializable {
     private Long userId;
     private Map<String, String> location;
     private String institution;
+
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
     private Timestamp datetime;
     private String valuationStandard;
     private Double price;
@@ -50,10 +56,12 @@ public class CrowdProjectVO implements Serializable {
     private Long regionManagerId;
     private StatusVO statusVO;
     private Boolean needHandle = false; //该项目需要处理
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
     private Timestamp createTime;
 
     public CrowdProjectVO(CrowdTestProject project){
         this.id = project.getCode();
+        this.code = project.getCode();
         this.name = project.getName();
         this.contactName = project.getLinkMan();
         this.contactPhone = project.getLinkManMobile();
@@ -86,6 +94,27 @@ public class CrowdProjectVO implements Serializable {
         this.createTime=project.getCreateTime();
     }
 
+    public CrowdTestProject toCrowdTestProject(){
+        CrowdTestProject crowdTestProject = CrowdTestProjectFactory.createCrowdTestProject();
+        BeanUtils.copyProperties(this, crowdTestProject);
+        crowdTestProject.setDeadTime(this.datetime);
+        crowdTestProject.setLinkMan(this.contactName);
+        crowdTestProject.setLinkManMobile(this.contactPhone);
+        crowdTestProject.setFixedPrice(this.price);
+        crowdTestProject.setQuotedPrice(this.budget);
+        crowdTestProject.setRequirementFile(this.doc);
+        crowdTestProject.setFixedPrice(this.price);
+        crowdTestProject.setDescription(this.desc);
+        crowdTestProject.setCode(this.id);
+        crowdTestProject.setType(this.type.toString());
+        crowdTestProject.setApplicationType(this.platform);
+        crowdTestProject.setFieldType(this.field);
+        crowdTestProject.setProjectFile(this.file);
+        crowdTestProject.setProjectDistributionTypeId(this.resource);
+        crowdTestProject.setRegionalManagerId(this.regionManagerId);
+        return crowdTestProject;
+    }
+
     private void renderStatus(){
         this.statusVO = new StatusVO();
         if (this.status == CrowdTestProjectStatus.HAS_REJECTED){

+ 0 - 2
site/src/main/java/com/mooctest/crowd/site/data/vo/CrowdReportVO.java

@@ -23,8 +23,6 @@ public class CrowdReportVO {
     private String target;
     private  boolean Updated;//是否可以修改
 
-
-
     public CrowdReportVO(CrowdTestReport report){
         BeanUtils.copyProperties(report, this);
         this.target = report.getTestObject();

+ 21 - 0
site/src/main/java/com/mooctest/crowd/site/data/vo/CrowdTaskVO.java

@@ -1,17 +1,21 @@
 package com.mooctest.crowd.site.data.vo;
 
+import com.alibaba.fastjson.annotation.JSONField;
 import com.mooctest.crowd.domain.domainobject.CrowdTestTask;
 import com.mooctest.crowd.domain.domainobject.CrowdTestTaskAcceptStatus;
 import com.mooctest.crowd.domain.domainobject.CrowdTestTaskStatus;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.springframework.beans.BeanUtils;
+
 import java.io.Serializable;
 import java.sql.Timestamp;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
+
 import static com.mooctest.crowd.site.data.vo.CrowdTestProjectVO.getDistanceTimes;
 
 /**
@@ -38,6 +42,7 @@ public class CrowdTaskVO implements Serializable{
     private int status;
     private Long distributionType;
     private int fullStatus;
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
     private Timestamp datetime;
     private int participantCount;
     private int acceptedCount;
@@ -45,11 +50,13 @@ public class CrowdTaskVO implements Serializable{
     private int participantHasCommittedCount;
     private StatusVO statusVO;
     private FullStatusVO fullStatusVO;
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
     private Timestamp createTime;
     private List<TaskToUserVO> taskToUserVOS = new ArrayList<>();
     private String time_interval;
     private EndPointVO endPointVO;
     private String writeReportUrl;
+    private String exportUrl;
 
     public CrowdTaskVO(CrowdTestTask task){
         id = task.getCode();
@@ -75,6 +82,7 @@ public class CrowdTaskVO implements Serializable{
         joinCount = task.getAcceptedCount();
         createTime = task.getCreateTime();
         participantHasCommittedCount = task.getParticipantHasCommittedCount();
+        exportUrl = task.getExportUrl();
         DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         try {
             Date date = df.parse(df.format(task.getCreateTime()));
@@ -94,6 +102,19 @@ public class CrowdTaskVO implements Serializable{
         this.renderStatus();
     }
 
+    public CrowdTestTask toCrowdTestTask(){
+        CrowdTestTask crowdTestTask = new CrowdTestTask();
+        BeanUtils.copyProperties(this, crowdTestTask);
+        crowdTestTask.setCrowdTestProjectCode(this.projectId);
+        crowdTestTask.setName(this.title);
+        crowdTestTask.setDistributionType(this.resource);
+        crowdTestTask.setQuotedPrice(this.quotePrice);
+        crowdTestTask.setType(this.serviceType);
+        crowdTestTask.setEvaluationAgencyId(this.agencyId);
+        crowdTestTask.setDeadTime(this.datetime);
+        return crowdTestTask;
+    }
+
     private void renderStatus(){
         this.statusVO = new StatusVO();
         if (this.status == CrowdTestTaskStatus.HAS_REJECTED){

+ 21 - 8
site/src/main/java/com/mooctest/crowd/site/mediator/impl/WebMediatorImpl.java

@@ -130,7 +130,6 @@ public class WebMediatorImpl implements ViewMediator {
     @Autowired
     private EndPointDao endPointDao;
 
-
     @Value("${file.save.path}")
     private String fileSaveRootPath;
 
@@ -235,7 +234,7 @@ public class WebMediatorImpl implements ViewMediator {
 //            return null;
 //        }).filter(Objects::nonNull).collect(Collectors.toList());
         List<UserVO> userVOS = userTaskCountDao.findByType(RoleType.EVALUATION_USER.getId())
-                .stream().sorted(Comparator.comparing(UserTaskCountPO::getCount)).collect(Collectors.toList())
+                .stream().sorted(Comparator.comparing(UserTaskCountPO::getCount).reversed()).collect(Collectors.toList())
                 .stream().map(userTaskCountPO -> {
                     User user = userRepo.getByIDJustInfo(userTaskCountPO.getUserId());
                     UserVO userVO = new UserVO(user);
@@ -975,7 +974,7 @@ public class WebMediatorImpl implements ViewMediator {
 //        String typeName = commonRepo.getTypeNameByCode(taskVO.getServiceType());
 //        taskVO.setServiceType(typeName);
 
-        System.out.println("renderTaskDetails userId:" + userId);
+        log.info("renderTaskDetails userId:" + userId);
         if (userId == null) {
             taskDetailsDTO.setTaskOperationControl(this.initTaskPermission(project, task.get(), null));
         } else {
@@ -1732,6 +1731,9 @@ public class WebMediatorImpl implements ViewMediator {
             //区域管理员或系统管理员视角
             if (user.getRoleList().stream().anyMatch(role -> role.getName().equals("SystemAdministrator"))
                     || (user.getRegionalManager() != null && user.getId().equals(project.getRegionalManagerId()))) {
+                // 不管何时都可以导出任务
+                taskOperationControl.setExportTask(true);
+                // 刚发布时,可修改,可查看推荐,可跳转看报告链接是否正确
                 if (task.getStatus() < CrowdTestTaskStatus.HAS_RECEIVED) {
                     taskOperationControl.setUpdate(true);
                     taskOperationControl.setTaskRecommend(true);
@@ -1740,8 +1742,10 @@ public class WebMediatorImpl implements ViewMediator {
                         taskOperationControl.setWriteReport(true);
                     }
                 }
+                // 任务已发布
                 else{
                     taskOperationControl.setTaskRecommend(true);
+                    // 已被接收,分两种:1、为平台填写报告,此时提交人数和接收人数一致,则可以确认结束任务;2、为众测任务,已提交了报告,可以确认结束任务
                     if ((task.getParticipantHasCommittedCount() == task.getAcceptedCount() && task.getStatus() == CrowdTestTaskStatus.HAS_RECEIVED) || (task.getParticipantHasCommittedCount() == task.getParticipantCount() && task.getStatus() == CrowdTestTaskStatus.HAS_COMMITED)) {
                         taskOperationControl.setConfirmFinish(true);
                     }
@@ -1751,7 +1755,7 @@ public class WebMediatorImpl implements ViewMediator {
                         taskOperationControl.setConfirmFinish(false);
                         taskOperationControl.setTaskRecommend(false);
                     }
-                    // 具有配置项,需要在第三方进行填写报告
+                    // 具有配置项,需要在第三方进行填写报告;可以填写报告、上传报告、确认结束
                     if(endPointPOOptional.isPresent()){
                         taskOperationControl.setWriteReport(true);
                         taskOperationControl.setUploadReport(true);
@@ -1763,7 +1767,7 @@ public class WebMediatorImpl implements ViewMediator {
                 }
             }
             // TODO 已拒绝视图
-            //评测机构和测评人员视角
+            // 评测机构和测评人员视角
             else if (AuthCheckServiceImpl.isAgency(user) && task.getStatus() != CrowdTestTaskStatus.HAS_REJECTED) {
                 if ((task.getDistributionType() == 0 && task.getEvaluationAgencyId().equals(user.getId()))
                         || (task.getDistributionType() == 2 && task.getStatus() >= CrowdTestTaskStatus.HAS_RECEIVED)) {
@@ -1771,19 +1775,28 @@ public class WebMediatorImpl implements ViewMediator {
                     Optional<TaskToUser> taskToUserOptional = acceptedUserList.stream().filter(taskToUser -> taskToUser.getUserId().equals(user.getId())).findFirst();
 
                     if (taskToUserOptional.isPresent()) {
-                        // 已接收用户
+                        // 任务已发布
                         if (task.getStatus() == CrowdTestTaskStatus.HAS_RELEASED) {
+                            // 已发布:具有接收功能
                             taskOperationControl.setReceive(true);
+                            // 定向发布:具有拒绝功能
                             if (task.getDistributionType() == 0) {
                                 taskOperationControl.setReject(true);
                             }
-                        } else if (task.getStatus() == CrowdTestTaskStatus.HAS_RECEIVED) {
+                        }
+                        // 已接收用户
+                        else if (task.getStatus() == CrowdTestTaskStatus.HAS_RECEIVED) {
+                            // 具有任务导出和上次报告功能
+                            taskOperationControl.setExportTask(true);
                             taskOperationControl.setUploadReport(true);
                             if (taskToUserOptional.get().getHasReport() == 1 && taskToUserOptional.get().getIsCommitted() == 0) {
                                 taskOperationControl.setFinish(true);
-                            } else if (taskToUserOptional.get().getHasReport() == 1 && taskToUserOptional.get().getIsCommitted() == 1) {
+                            }
+                            // 用户已上传报告并已提交任务:取消提交、上传报告、导出任务功能
+                            else if (taskToUserOptional.get().getHasReport() == 1 && taskToUserOptional.get().getIsCommitted() == 1) {
                                 taskOperationControl.setFinish(false);
                                 taskOperationControl.setUploadReport(false);
+                                taskOperationControl.setExportTask(false);
                             }
 
                             // 具有配置项,需要在第三方进行填写报告

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

@@ -1,10 +1,12 @@
 package com.mooctest.crowd.site.service;
 
 import com.mooctest.crowd.site.command.CrowdTestTaskCommand;
+import com.mooctest.crowd.site.data.dto.ProjectDetailsDTO;
 import com.mooctest.crowd.site.data.dto.TaskDetailsDTO;
 import com.mooctest.crowd.site.data.dto.TaskSquareDTO;
 import com.mooctest.crowd.site.data.tfidf.JabaResult;
 import com.mooctest.crowd.site.data.vo.CrowdTaskVO;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
 
@@ -46,4 +48,8 @@ public interface CrowdTaskService {
     TaskDetailsDTO addToken(String projectCode, String taskCode, Long userId, String token);
 
     List<JabaResult> getTaskWord(String projectCode, String taskCode);
+
+    String exportTask(String projectCode, String taskCode, Long userId);
+
+    ProjectDetailsDTO importTask(MultipartFile file, Long userId);
 }

+ 2 - 3
site/src/main/java/com/mooctest/crowd/site/service/UploadService.java

@@ -2,9 +2,6 @@ package com.mooctest.crowd.site.service;
 
 import org.springframework.web.multipart.MultipartFile;
 
-import java.awt.*;
-import java.io.IOException;
-
 /**
  * @author: Diors.Po
  * @Email: 171256175@qq.com
@@ -13,6 +10,8 @@ import java.io.IOException;
 public interface UploadService {
     String uploadImage(MultipartFile file, Long userId);
 
+    String uploadTask(MultipartFile file, Long userId);
+
     String uploadReport(MultipartFile file, Long userId);
 
     String uploadRequirment(MultipartFile file, Long userId);

+ 19 - 14
site/src/main/java/com/mooctest/crowd/site/service/impl/AgencyServiceImpl.java

@@ -5,7 +5,6 @@ import com.mooctest.crowd.domain.domainobject.*;
 import com.mooctest.crowd.domain.exception.BaseException;
 import com.mooctest.crowd.domain.exception.EvaluationAgencyNotExistException;
 import com.mooctest.crowd.domain.exception.UserNotExistException;
-import com.mooctest.crowd.domain.model.EvaluationAgencyPO;
 import com.mooctest.crowd.domain.model.UserTaskCountPO;
 import com.mooctest.crowd.domain.repository.EvaluationAgencyRepo;
 import com.mooctest.crowd.domain.repository.UserRepo;
@@ -137,19 +136,25 @@ public class AgencyServiceImpl implements AgencyService {
      */
     @Override
     public List<EvaluationAgencyVO> findMoreAgencyVO(String keyword) {
-        List<EvaluationAgencyVO> list = userTaskCountDao.findByType(RoleType.AGENCY.getId())
-                .stream().sorted(Comparator.comparing(UserTaskCountPO::getCount)).collect(Collectors.toList())
-                .stream().map(userTaskCountPO -> {
-                    EvaluationAgencyPO agency = agencyDao.findByUserId(userTaskCountPO.getUserId());
-                    EvaluationAgencyVO agencyVO = new EvaluationAgencyVO();
-                    agencyVO.setAgencyPhoto(agency.getAgencyPhoto());
-                    agencyVO.setTaskCount(userTaskCountPO.getCount());
-                    agencyVO.setId(agency.getId());
-                    agencyVO.setUserId(agency.getUserId());
-                    agencyVO.setEvaluationAgencyName(agency.getEvaluationAgencyName());
-                    agencyVO.setAddress(agency.getAddress());
-                    return agencyVO;
-                }).collect(Collectors.toList());
+        List<UserTaskCountPO> userTaskCountPOList = userTaskCountDao.findByType(RoleType.AGENCY.getId());
+        List<Long> agencyIdList = userTaskCountPOList.stream().map(UserTaskCountPO::getUserId).collect(Collectors.toList());
+
+        List<EvaluationAgency> evaluationAgencyList = evaluationAgencyRepo.findAll();
+        List<EvaluationAgencyVO> list = evaluationAgencyList.stream().map(agency -> {
+            EvaluationAgencyVO agencyVO = new EvaluationAgencyVO();
+            if(agencyIdList.indexOf(agency.getUserId()) != -1){
+                agencyVO.setTaskCount(userTaskCountPOList.get(agencyIdList.indexOf(agency.getUserId())).getCount());
+            }else{
+                agencyVO.setTaskCount(0L);
+            }
+            agencyVO.setAgencyPhoto(agency.getAgencyPhoto());
+            agencyVO.setId(agency.getId());
+            agencyVO.setUserId(agency.getUserId());
+            agencyVO.setEvaluationAgencyName(agency.getEvaluationAgencyName());
+            agencyVO.setAddress(agency.getAddress());
+            return agencyVO;
+        }).collect(Collectors.toList());
+
         if (keyword == null) {
             return list.stream().sorted(Comparator.comparing(EvaluationAgencyVO::getTaskCount).reversed()).collect(Collectors.toList());
         } else {

+ 263 - 9
site/src/main/java/com/mooctest/crowd/site/service/impl/CrowdTaskServiceImpl.java

@@ -1,20 +1,20 @@
 package com.mooctest.crowd.site.service.impl;
 
-import com.mooctest.crowd.domain.dao.CrowdTestTaskDao;
-import com.mooctest.crowd.domain.dao.EndPointDao;
-import com.mooctest.crowd.domain.domainobject.CrowdTestProject;
-import com.mooctest.crowd.domain.domainobject.CrowdTestTask;
-import com.mooctest.crowd.domain.domainobject.CrowdTestTaskStatus;
-import com.mooctest.crowd.domain.domainobject.DistributeType;
-import com.mooctest.crowd.domain.exception.BaseException;
-import com.mooctest.crowd.domain.exception.CrowdTestTaskNotExistException;
-import com.mooctest.crowd.domain.exception.UnauthorizedException;
+import com.alibaba.fastjson.JSON;
+import com.google.gson.Gson;
+import com.mooctest.crowd.domain.dao.*;
+import com.mooctest.crowd.domain.domainobject.*;
+import com.mooctest.crowd.domain.exception.*;
+import com.mooctest.crowd.domain.model.ApplicationTypePO;
 import com.mooctest.crowd.domain.model.EndPointPO;
+import com.mooctest.crowd.domain.model.FieldPO;
 import com.mooctest.crowd.domain.repository.CommonRepo;
 import com.mooctest.crowd.domain.repository.CrowdTestProjectRepo;
 import com.mooctest.crowd.domain.repository.CrowdTestTaskRepo;
 import com.mooctest.crowd.domain.repository.UserRepo;
 import com.mooctest.crowd.site.command.CrowdTestTaskCommand;
+import com.mooctest.crowd.site.constants.UploadType;
+import com.mooctest.crowd.site.data.dto.ProjectDetailsDTO;
 import com.mooctest.crowd.site.data.dto.TaskDetailsDTO;
 import com.mooctest.crowd.site.data.dto.TaskSquareDTO;
 import com.mooctest.crowd.site.data.enums.ProjectType;
@@ -23,12 +23,21 @@ import com.mooctest.crowd.site.data.tfidf.TFIDFAnalyzer;
 import com.mooctest.crowd.site.data.vo.CrowdTaskVO;
 import com.mooctest.crowd.site.mediator.ViewMediator;
 import com.mooctest.crowd.site.service.CrowdTaskService;
+import com.mooctest.crowd.site.service.UploadService;
 import com.mooctest.crowd.site.util.GenerateFlowCodeUtil;
 import lombok.extern.slf4j.Slf4j;
+import net.lingala.zip4j.exception.ZipException;
+import net.lingala.zip4j.model.ZipParameters;
+import net.lingala.zip4j.util.Zip4jConstants;
+import org.jetbrains.annotations.NotNull;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
 
+import java.io.*;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -56,6 +65,15 @@ public class CrowdTaskServiceImpl implements CrowdTaskService {
     CrowdTestTaskDao taskDao;
 
     @Autowired
+    FieldDao fieldDao;
+
+    @Autowired
+    ApplicationTypeDao applicationTypeDao;
+
+    @Autowired
+    TestTypeDao testTypeDao;
+
+    @Autowired
     private UserRepo userRepo;
 
     @Autowired
@@ -64,6 +82,24 @@ public class CrowdTaskServiceImpl implements CrowdTaskService {
     @Autowired
     private CommonRepo commonRepo;
 
+    @Autowired
+    private UploadService uploadService;
+
+    @Value("${file.save.path}")
+    private String fileSaveRootPath;
+
+    @Value("${private.cloud.master}")
+    private String masterName;
+
+    @Value("${private.cloud.publish.project.id}")
+    private String publishProjectUserId;
+
+    @Value("${private.cloud.task.type.code}")
+    private String taskTypeCode;
+
+    @Value("${feature.client.oss}")
+    private Boolean usingOss;
+
     @Override
     public List<CrowdTaskVO> findMoreHotTasks() {
         return viewMediator.findMoreHotTasks();
@@ -126,6 +162,10 @@ public class CrowdTaskServiceImpl implements CrowdTaskService {
         task.create(taskCode);
         project.addTask(task);
         projectRepo.saveCrowdTestProject(project);
+
+//        // 生成任务导出链接
+//        String exportTaskUrl = this.exportTask(projectCode, task.getCode(), userId);
+//        task.setExportUrl(exportTaskUrl);
         return getTaskDetails(projectCode, taskCode, userId);
     }
 
@@ -150,6 +190,11 @@ public class CrowdTaskServiceImpl implements CrowdTaskService {
         updateTask.setStatus(CrowdTestTaskStatus.HAS_RELEASED);
         updateTask.update();
         project.removeTask(task.get());
+
+//        // 重新生成任务导出链接
+//        String exportTaskUrl = this.exportTask(projectCode, updateTask.getCode(), userId);
+//        updateTask.setExportUrl(exportTaskUrl);
+
         project.addTask(updateTask);
         projectRepo.saveCrowdTestProject(project);
         return getTaskDetails(projectCode, taskCode, userId);
@@ -241,5 +286,214 @@ public class CrowdTaskServiceImpl implements CrowdTaskService {
         return TFIDFAnalyzer.getInstance().extractTagsList(taskDetails.getCrowdTaskVO().getDescription(), 20);
     }
 
+    @Override
+    public String exportTask(String projectCode, String taskCode, Long userId) {
+        // 获取项目和任务的详细信息,特定任务的信息
+        ProjectDetailsDTO projectDetailsDTO = viewMediator.renderProjectDetails(projectRepo.getByProjectCodeAndTaskCode(projectCode, taskCode), userRepo.getByID(userId));
+
+        // 文件夹路径
+        String fileDirectoryPath = fileSaveRootPath + UploadType.EXPORT_TASK_FILE;
+        File fileDirectory = new File(fileDirectoryPath);
+        // 如果文件夹不存在,则新建一个
+        if(!fileDirectory.exists()){
+            fileDirectory.mkdirs();
+        }
+
+        // 文件路径
+        String fileNameCode = projectCode + "-" + taskCode;
+        String filePath = fileDirectoryPath + fileNameCode + ".json";
+        log.info("文件路径为:" + filePath);
+        File file = new File(filePath);
+        // 如果文件不存在,则新建一个
+        if(!file.exists()){
+            try {
+                file.createNewFile();
+            } catch (IOException e) {
+                throw new ExportTaskFileNotExistException();
+            }
+        }
+
+        // 将对象转成json字符串
+        String projectAndTaskJsonData = JSON.toJSONString(projectDetailsDTO);
+        // 将json字符串写入文件中
+        writerStringToFile(file, projectAndTaskJsonData);
+
+        // file是json文件,需要进行zip压缩
+        String downloadPath = fileDirectoryPath + fileNameCode + ".zip";
+        File downloadFile = new File(downloadPath);
+        String downloadUrl = downloadPath;
+        try{
+            log.info("----------------开始压缩文件----------------");
+            net.lingala.zip4j.core.ZipFile zipFile = new net.lingala.zip4j.core.ZipFile(downloadFile);
+            ZipParameters parameters = new ZipParameters();
+            parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
+            parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
+            zipFile.addFile(file, parameters);
+            log.info("----------------压缩结束-------------------");
+
+            // 将File类型转成MultipartFile类型
+            FileInputStream inputStream = new FileInputStream(downloadFile);
+            MultipartFile multipartFile = new MockMultipartFile(downloadFile.getName(), downloadFile.getName(), "", inputStream);
+            // 文件上传至oss
+            if(usingOss){
+                downloadUrl = uploadService.uploadTask(multipartFile, userId);
+            }
+        } catch (IOException e) {
+            log.info("----------copy error{}---------", e);
+        } catch (ZipException e) {
+            log.info("----------copy error{}---------", e);
+        }
+        log.info("下载链接:" + downloadUrl);
+        return downloadUrl;
+    }
+
+    /**
+     * 将json字符串写入文件中
+     * @param file
+     * @param projectAndTaskJsonData
+     */
+    public void writerStringToFile(File file, String projectAndTaskJsonData) {
+        //写入
+        BufferedWriter writer = null;
+        try {
+            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, false), "UTF-8"));
+            writer.write(projectAndTaskJsonData);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }finally {
+            try {
+                if(writer != null){
+                    writer.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        log.info("文件生成成功!");
+    }
+
+    @Override
+    public ProjectDetailsDTO importTask(MultipartFile file, Long userId) {
+        log.info("导入的文件为:" + file.getOriginalFilename());
+        // 将文件内容读出变成字符串
+        String fileString = fileToString(file);
+        Gson gson = new Gson();
+        // 将字符串序列化成对象
+        ProjectDetailsDTO projectDetailsDTO = gson.fromJson(fileString, ProjectDetailsDTO.class);
+
+        // 将对象VO转成CrowdTestProject
+        CrowdTestProject crowdTestProject = projectDetailsDTO.getProjectDetails().toCrowdTestProject();
+        User user = userRepo.getByIDJustInfo(userId);
+
+        // 为项目信息赋予导入的默认值
+        setProjectDefaultValueToPrivateCloud(crowdTestProject, user);
+        // 项目的剩余预算需要重新计算,根据任务报价
+
+        List<CrowdTestTask> crowdTestTaskList = projectDetailsDTO.getTaskList().stream().map(CrowdTaskVO::toCrowdTestTask).collect(Collectors.toList());
+        // 为任务信息赋予导入的默认值
+        crowdTestTaskList.forEach(crowdTestTask -> setTaskDefaultValueToPrivateCloud(crowdTestProject.getCode(), crowdTestTask));
+        // 所有任务花费的金额
+        double costPrice = crowdTestTaskList.stream().mapToDouble(CrowdTestTask::getQuotedPrice).sum();
+        // 为测试项目赋予测试类型、以及剩余预算
+        crowdTestProject.setType(crowdTestTaskList.get(0).getType());
+        crowdTestProject.setRestPrice(crowdTestProject.getQuotedPrice() - costPrice);
+        // 将任务添加到项目中
+        crowdTestProject.setCrowdTestTaskList(crowdTestTaskList);
+
+        projectRepo.saveCrowdTestProject(crowdTestProject);
+        return viewMediator.renderProjectDetails(projectRepo.getByProjectCode(crowdTestProject.getCode()), userRepo.getByID(userId));
+    }
+
+    /**
+     * 为项目信息赋予导入的默认值
+     * @param crowdTestProject
+     * @param user
+     */
+    private void setProjectDefaultValueToPrivateCloud(CrowdTestProject crowdTestProject, User user) {
+        // 导入私有云的项目名称以Master开头
+        crowdTestProject.setCode(masterName + "-" + System.currentTimeMillis() + "-" + crowdTestProject.getCode());
+
+        // 使用默认的发包用户进行发包
+        User publishUser = userRepo.getByIDJustInfo(Long.parseLong(publishProjectUserId));
+
+        crowdTestProject.setUserId(publishUser.getId());
+        crowdTestProject.setRegionalManagerId(user.getId());
+        crowdTestProject.setJoinCount(0);
+        crowdTestProject.setLinkManMobile(publishUser.getMobile());
+        crowdTestProject.setLinkMan(publishUser.getName());
+        crowdTestProject.setProjectDistributionTypeId(DistributeType.SQUARE.getId());
+        // 判断领域类型是否存在
+        Optional<FieldPO> fieldPO = fieldDao.findByName(crowdTestProject.getFieldType());
+        if(fieldPO.isPresent()){
+            crowdTestProject.setFieldType(fieldPO.get().getCode());
+        }else{
+            // 如果没有赋值为第一种测试类型
+            crowdTestProject.setFieldType(fieldDao.findAll().get(0).getCode());
+        }
+        // 判断应用类型是否存在
+        Optional<ApplicationTypePO> applicationTypePO = applicationTypeDao.findByName(crowdTestProject.getApplicationType());
+        if(applicationTypePO.isPresent()){
+            crowdTestProject.setApplicationType(applicationTypePO.get().getCode());
+        }else{
+            // 如果没有赋值为第一种测试类型
+            crowdTestProject.setApplicationType(applicationTypeDao.findAll().get(0).getCode());
+        }
+    }
+
+    /**
+     * 为任务信息赋予导入的默认值
+     * @param projectCode
+     * @param crowdTestTask
+     */
+    private void setTaskDefaultValueToPrivateCloud(String projectCode, CrowdTestTask crowdTestTask) {
+        crowdTestTask.setCode(masterName + "-" + System.currentTimeMillis() + "-" + crowdTestTask.getCode());
+        crowdTestTask.setCrowdTestProjectCode(projectCode);
+        crowdTestTask.setEvaluationAgencyId(null);
+        crowdTestTask.setDistributionType(DistributeType.SQUARE.getId());
+        crowdTestTask.setAcceptedCount(0);
+        crowdTestTask.setParticipantHasCommittedCount(0);
+        crowdTestTask.setFullStatus(0);
+        crowdTestTask.setStatus(CrowdTestTaskStatus.HAS_RELEASED);
+        // 判断默认的测试类型MCZC是否存在
+        if(testTypeDao.findByCode(taskTypeCode).isPresent()){
+            crowdTestTask.setType(taskTypeCode);
+        }else{
+            // 如果没有赋值为第一种测试类型
+            crowdTestTask.setType(testTypeDao.findAll().get(0).getCode());
+        }
+    }
+
+    /**
+     * 将文件内容读出变成字符串
+     * @param file
+     * @return
+     */
+    @NotNull
+    public String fileToString(MultipartFile file) {
+        if(file.isEmpty()){
+            throw new FileIsEmptyException();
+        }
+
+        // 读取文件内容
+        BufferedReader reader = null;
+        StringBuffer stringBuffer = new StringBuffer();
+        try {
+            reader = new BufferedReader(new InputStreamReader(file.getInputStream(), "UTF-8"));
+            String lineString;
+            while((lineString = reader.readLine()) != null){
+                stringBuffer.append(lineString);
+            }
+            if(reader != null){
+                reader.close();
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return stringBuffer.toString();
+    }
 }
 

+ 11 - 1
site/src/main/java/com/mooctest/crowd/site/service/impl/OSSUploadServiceImpl.java

@@ -47,7 +47,17 @@ public class OSSUploadServiceImpl implements UploadService {
                 +userId+"_"
                 +System.currentTimeMillis()+""
                 +file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."), file.getOriginalFilename().length());
-        return doUpload(fileName, file);    }
+        return doUpload(fileName, file);
+    }
+
+    @Override
+    public String uploadTask(MultipartFile file, Long userId) {
+        String fileName = UploadType.EXPORT_TASK_FILE+file.getOriginalFilename().substring(0,file.getOriginalFilename().lastIndexOf("."))+"_"
+                +userId+"_"
+                +System.currentTimeMillis()+""
+                +file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."), file.getOriginalFilename().length());
+        return doUpload(fileName, file);
+    }
 
     @Override
     public String uploadAPK(MultipartFile file, Long userId) {

+ 4 - 3
site/src/main/java/com/mooctest/crowd/site/util/OperationRecordUtil.java

@@ -1,11 +1,12 @@
 package com.mooctest.crowd.site.util;
 
 import com.alibaba.fastjson.JSONObject;
-import com.mooctest.crowd.site.anticorruption.impl.data.UserInfo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.http.*;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
 import org.springframework.stereotype.Component;
 import org.springframework.web.client.RestTemplate;
 
@@ -45,7 +46,7 @@ public class OperationRecordUtil {
         params.put("operation", operation);
         params.put("resource", "crowd-service");
         HttpEntity<String> entity = new HttpEntity<>(params.toString() , httpHeaders);
-        restTemplate.exchange(userServiceUrl + "/api/operation_record", HttpMethod.POST, entity, Object.class);
+//        restTemplate.exchange(userServiceUrl + "/api/operation_record", HttpMethod.POST, entity, Object.class);
         Timestamp current = new Timestamp(System.currentTimeMillis());
         log.info(String.format("IP:[%s] - User[%d] logout at [%s]", ip, userId, current.toString()));
     }

+ 148 - 11
site/src/main/resources/application.yml

@@ -1,6 +1,6 @@
 spring:
   profiles:
-     active: dev-localhost
+     active: dev-online
   cache:
     guava:
       spec: expireAfterWrite=30s
@@ -17,8 +17,11 @@ spring:
   servlet:
     multipart:
       enabled: true
-      max-file-size: 100MB
-      max-request-size: 100MB
+      max-file-size: 3024MB
+      max-request-size: 3024MB
+file:
+  save:
+    path: /var/www/
 
 oss:
   accessKeyId: LTAI4FdrT3HsfdR5edBVN7ws
@@ -38,6 +41,16 @@ green:
   agency:
     id: 99231
 
+private:
+  cloud:
+    # 导入私有云的项目code以此开头
+    master: MASTER
+    task:
+      type:
+        code: MzZC
+    publish:
+      project:
+        id: 20471
 ---
 spring:
   profiles: private-cloud
@@ -80,6 +93,48 @@ user:
     baseUrl: http://crowd_user:8081
 #    baseUrl: http://59.42.10.53:8081
 
+---
+spring:
+  profiles: private-cloud-mutil-mysql-redis
+  datasource:
+    url: jdbc:mysql://mysql:13306/crowd-test-service?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
+    username: root
+    password: Customs2019
+  redis:
+    host: redis
+    port: 16379
+    password:
+    jedis:
+      pool:
+        max-active: 8
+        max-idle: 8
+        max-wait: -1
+        min-idle: 0
+    database: 0
+
+#  redis:
+#    host: redis
+#    password:
+#    pool:
+#      max-active: 8
+#      max-idle: 8
+#      max-wait: -1
+#      min-idle: 0
+#    port: 6379
+
+feature:
+  client:
+    oss: false
+
+file:
+  save:
+    path: /var/www/
+
+user:
+  service:
+    baseUrl: http://crowd_user:8081
+#    baseUrl: http://59.42.10.53:8081
+
 website:
   domain: 127.0.0.1
 
@@ -137,7 +192,7 @@ spring:
     password: secr3t!
   redis:
     host: 59.42.10.53
-    pool: 6379
+    port: 6379
     password: '#2019@callforttest@!'
     jedis:
       pool:
@@ -157,7 +212,7 @@ file:
 
 user:
   service:
-    #    baseUrl: http://127.0.0.1:8081
+#    baseUrl: http://127.0.0.1:8081
     baseUrl: http://59.42.10.53:8081
 
 website:
@@ -172,7 +227,7 @@ spring:
     password: secr3t!
   redis:
     host: 10.18.18.50
-    pool: 6379
+    port: 6379
     password: '#2019@callforttest@!'
     jedis:
       pool:
@@ -194,6 +249,39 @@ website:
 
 ---
 spring:
+  profiles: dev-online-localhost
+  datasource:
+    url: jdbc:mysql://101.37.175.111:3306/crowd-test-service-online?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
+    username: mooctest
+    password: secr3t!
+  redis:
+    host: 114.55.91.27
+    port: 6379
+    password: '#03#05@ise@mooctest'
+    jedis:
+      pool:
+        max-active: 8
+        max-idle: 8
+        max-wait: -1
+        min-idle: 0
+    database: 6
+user:
+  service:
+    baseUrl: http://127.0.0.1:8081
+
+file:
+  save:
+    path: /var/www/
+
+feature:
+  client:
+    oss: true
+
+website:
+  domain: mooctest.net
+
+---
+spring:
   profiles: dev-online
   datasource:
     url: jdbc:mysql://101.37.175.111:3306/crowd-test-service-online?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
@@ -201,7 +289,7 @@ spring:
     password: secr3t!
   redis:
     host: 59.42.10.53
-    pool: 6379
+    port: 6379
     password: '#2019@callforttest@!'
     jedis:
       pool:
@@ -214,23 +302,68 @@ user:
   service:
     baseUrl: http://59.42.10.53:8081
 
+#file:
+#  save:
+#    path: /var/www/
+
+file:
+  save:
+    path: /Users/guochao/Desktop/project/data/cofortest/
+
+#feature:
+#  client:
+#    oss: true
 feature:
   client:
-    oss: true
+    oss: false
+
 
 website:
   domain: mooctest.net
 
 ---
 spring:
-  profiles: online
+  profiles: pre-online
   datasource:
     url: jdbc:mysql://10.18.18.50:3306/crowd-test-service?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
     username: root
     password: callfortest_crowd
   redis:
     host: 10.18.18.50
-    pool: 6379
+    port: 6379
+    password: '#2019@callforttest@!'
+    jedis:
+      pool:
+        max-active: 8
+        max-idle: 8
+        max-wait: -1
+        min-idle: 0
+    database: 0
+
+feature:
+  client:
+    oss: true
+
+file:
+  save:
+    path: /var/www/
+
+user:
+  service:
+    baseUrl: http://user.cofortest.com:8081
+website:
+  domain: cofortest.com
+
+---
+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
+    username: root
+    password: callfortest_crowd
+  redis:
+    host: 8.134.32.27
+    port: 6379
     password: '#2019@callforttest@!'
     jedis:
       pool:
@@ -244,8 +377,12 @@ feature:
   client:
     oss: true
 
+file:
+  save:
+    path: /var/www/
 user:
   service:
-    baseUrl: http://user.cofortest.com
+#    baseUrl: http://59.42.10.53
+    baseUrl: http://user.cofortest.com:8081
 website:
   domain: cofortest.com