Explorar el Código

Merge branch 'withConferTest-noPassword' into dev

# Conflicts:
#	pom.xml
#	src/main/resources/bootstrap.yml
insomniaLee hace 5 años
padre
commit
888bd018d6

+ 5 - 3
Dockerfile

@@ -1,10 +1,12 @@
 FROM openjdk:8-jdk-alpine
 FROM openjdk:8-jdk-alpine
-ADD ./deploy.sh /project/
-RUN chmod 777 /project/deploy.sh
+#ADD ./deploy.sh /project/
+#RUN chmod 777 /project/deploy.sh
 #RUN wget -c -P /project/ http://third-part-tool.oss-cn-shanghai.aliyuncs.com/sgns.wiki.word.zip#RUN unzip -o /project/sgns.wiki.word.zip -d /project/
 #RUN wget -c -P /project/ http://third-part-tool.oss-cn-shanghai.aliyuncs.com/sgns.wiki.word.zip#RUN unzip -o /project/sgns.wiki.word.zip -d /project/
 #ADD ./sgns.wiki.word /project/sgns.wiki.word
 #ADD ./sgns.wiki.word /project/sgns.wiki.word
 ADD ./target/crowd_review-1.0-SNAPSHOT.jar /project/crowd_review.jar
 ADD ./target/crowd_review-1.0-SNAPSHOT.jar /project/crowd_review.jar
 EXPOSE 9004
 EXPOSE 9004
 #RUN unzip -o /project/sgns.wiki.word.zip -d /project/
 #RUN unzip -o /project/sgns.wiki.word.zip -d /project/
 #ENTRYPOINT ["/project/deploy.sh"]
 #ENTRYPOINT ["/project/deploy.sh"]
-ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Xms800m","-Xmx1g","-jar","-Dspring.profiles.active=test","/project/crowd_review.jar"]
+# ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Xms800m","-Xmx1g","-jar","-Dspring.profiles.active=test","/project/crowd_review.jar"]
+
+

+ 19 - 0
pom.xml

@@ -174,6 +174,25 @@
             <artifactId>spring-cloud-starter-zookeeper-config</artifactId>
             <artifactId>spring-cloud-starter-zookeeper-config</artifactId>
         </dependency>
         </dependency>
 
 
+        <!-- Aliyun OSS -->
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>3.10.2</version>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-sts</artifactId>
+            <version>2.1.6</version>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-core</artifactId>
+            <version>2.1.7</version>
+        </dependency>
+        <!-- OSS END -->
+
+
     </dependencies>
     </dependencies>
 
 
     <dependencyManagement>
     <dependencyManagement>

+ 19 - 0
src/main/java/com/mooctest/config/MongoOneConfig.java

@@ -2,6 +2,8 @@ package com.mooctest.config;
 
 
 import com.mongodb.MongoClient;
 import com.mongodb.MongoClient;
 import com.mongodb.MongoClientOptions;
 import com.mongodb.MongoClientOptions;
+import com.mongodb.MongoCredential;
+import com.mongodb.ServerAddress;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
@@ -16,6 +18,9 @@ import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
 import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
 import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
 import org.springframework.core.env.Environment;
 import org.springframework.core.env.Environment;
 
 
+import java.util.ArrayList;
+import java.util.List;
+
 @Configuration
 @Configuration
 @EnableMongoRepositories(
 @EnableMongoRepositories(
         basePackages = "com.mooctest.dao",
         basePackages = "com.mooctest.dao",
@@ -27,13 +32,27 @@ public class MongoOneConfig extends AbstractMongoConfig {
     private String database;
     private String database;
     @Value("${mongodb1.port}")
     @Value("${mongodb1.port}")
     private int port;
     private int port;
+//    @Value("${mongodb1.username}")
+//    private String username;
+//    @Value("${mongodb1.password}")
+//    private String password;
     //Setter methods go here..
     //Setter methods go here..
     /*
     /*
      * 创建MongoDBFactory的方法
      * 创建MongoDBFactory的方法
      * 两个MongoDB连接共用
      * 两个MongoDB连接共用
      */
      */
+
+
     public MongoDbFactory mongoDbFactory() throws Exception {
     public MongoDbFactory mongoDbFactory() throws Exception {
+//        List<ServerAddress> seeds = new ArrayList<>();
+//        ServerAddress serverAddress = new ServerAddress(host, port);
+//        seeds.add(serverAddress);
+//        List<MongoCredential> mongoCredentialList = new ArrayList<>();
+//        mongoCredentialList.add(MongoCredential.createCredential(username, database, password.toCharArray()));
+//        return new SimpleMongoDbFactory(new MongoClient(seeds, mongoCredentialList), database);
         return new SimpleMongoDbFactory(new MongoClient(host, port), database);
         return new SimpleMongoDbFactory(new MongoClient(host, port), database);
+
+
     }
     }
 
 
 
 

+ 15 - 0
src/main/java/com/mooctest/config/MongoTwoConfig.java

@@ -2,6 +2,8 @@ package com.mooctest.config;
 
 
 import com.mongodb.MongoClient;
 import com.mongodb.MongoClient;
 import com.mongodb.MongoClientOptions;
 import com.mongodb.MongoClientOptions;
+import com.mongodb.MongoCredential;
+import com.mongodb.ServerAddress;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
@@ -16,6 +18,9 @@ import org.springframework.data.mongodb.core.MongoTemplate;
 import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
 import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
 import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
 import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
 
 
+import java.util.ArrayList;
+import java.util.List;
+
 
 
 @Configuration
 @Configuration
 @EnableMongoRepositories(
 @EnableMongoRepositories(
@@ -29,12 +34,22 @@ public class MongoTwoConfig{
     private String database;
     private String database;
     @Value("${mongodb2.port}")
     @Value("${mongodb2.port}")
     private int port;
     private int port;
+//    @Value("${mongodb2.username}")
+//    private String username;
+//    @Value("${mongodb2.password}")
+//    private String password;
     //Setter methods go here..
     //Setter methods go here..
     /*
     /*
      * 创建MongoDBFactory的方法
      * 创建MongoDBFactory的方法
      * 两个MongoDB连接共用
      * 两个MongoDB连接共用
      */
      */
     public MongoDbFactory mongoDbFactory2() throws Exception {
     public MongoDbFactory mongoDbFactory2() throws Exception {
+//        List<ServerAddress> seeds = new ArrayList<>();
+//        ServerAddress serverAddress = new ServerAddress(host, port);
+//        seeds.add(serverAddress);
+//        List<MongoCredential> mongoCredentialList = new ArrayList<>();
+//        mongoCredentialList.add(MongoCredential.createCredential(username, database, password.toCharArray()));
+//        return new SimpleMongoDbFactory(new MongoClient(seeds, mongoCredentialList), database);
         return new SimpleMongoDbFactory(new MongoClient(host, port), database);
         return new SimpleMongoDbFactory(new MongoClient(host, port), database);
     }
     }
 
 

+ 45 - 0
src/main/java/com/mooctest/controller/TaskController.java

@@ -3,6 +3,7 @@ package com.mooctest.controller;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import com.mooctest.data.BugDTO;
 import com.mooctest.data.BugDTO;
+import com.mooctest.data.SimpleResponse;
 import com.mooctest.data.TaskDTO;
 import com.mooctest.data.TaskDTO;
 import com.mooctest.model.BugData;
 import com.mooctest.model.BugData;
 import com.mooctest.model.MasterReport;
 import com.mooctest.model.MasterReport;
@@ -14,8 +15,10 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Controller;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
 
 
 import java.sql.Timestamp;
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.ArrayList;
@@ -50,6 +53,11 @@ public class TaskController {
     @Value("${report.host}")
     @Value("${report.host}")
     String reportHost;
     String reportHost;
 
 
+    @Value("${useOss}")
+    boolean useOss;
+    @Value("${urlPath}")
+    String urlPrefix;
+
     @GetMapping("/crowdTask")
     @GetMapping("/crowdTask")
     public String home(Model model) {
     public String home(Model model) {
         // 获得所有taskDTO,包括本地和慕测端
         // 获得所有taskDTO,包括本地和慕测端
@@ -165,4 +173,41 @@ public class TaskController {
         JSONObject temp = (JSONObject) input;
         JSONObject temp = (JSONObject) input;
         temp.put("create_time",new Timestamp(Long.parseLong(temp.get("create_time").toString()))); // 修改创建时间的格式  以便前段展示
         temp.put("create_time",new Timestamp(Long.parseLong(temp.get("create_time").toString()))); // 修改创建时间的格式  以便前段展示
     }
     }
+
+    @GetMapping("/addCrowdTask")
+    public String addCrowdTask(Model model){
+        model.addAttribute("templateUrl",useOss?"http://mooctest-site.oss-cn-shanghai.aliyuncs.com/excel-template.xlsx":urlPrefix+"excel-template.xlsx");
+        return "addCrowdTask";
+    }
+
+    @GetMapping("/importTask")
+    public String importTask(Model model){
+        return "importTask";
+    }
+
+    @PostMapping("/addCrowdTask")
+    @ResponseBody
+    public SimpleResponse addCrowdTask2(@RequestParam("name")String name, @RequestParam("description")String description,
+                                        @RequestParam("time")String time, @RequestParam("type")String type,
+                                        @RequestParam("os")String os, @RequestParam("threePage") MultipartFile threePage,
+                                        Model model){
+        if(true)return  new SimpleResponse(200,"success");
+        return taskService.addCrowdTask(name, description, time, type, os, threePage);
+    }
+
+    @PostMapping("/importTask")
+    @ResponseBody
+    public String importTask2(@RequestParam("number")String number,@RequestParam("number")String originId,
+                              @RequestParam("zipFile") MultipartFile zipFile,@RequestParam("jsonFile") MultipartFile jsonFile){
+        if(true)return  "success";
+
+        return taskService.importTask(number, originId, zipFile, jsonFile)?"success":"导出失败";
+    }
+
+    @PostMapping("/exportTask")
+    @ResponseBody
+    public String exportTask(@RequestParam("caseId") String caseId) {
+
+        return taskService.exportTask(caseId) ? "success" : "导出失败";
+    }
 }
 }

+ 15 - 0
src/main/java/com/mooctest/dao2/CrowdTaskDao.java

@@ -0,0 +1,15 @@
+package com.mooctest.dao2;
+
+import com.mooctest.model.CrowdTask;
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+import java.util.List;
+
+
+public interface CrowdTaskDao extends MongoRepository<CrowdTask, String> {
+
+    CrowdTask findFirstByOrderByIdDesc();
+
+    @Override
+    List<CrowdTask> findAll();
+}

+ 15 - 0
src/main/java/com/mooctest/data/SimpleResponse.java

@@ -0,0 +1,15 @@
+package com.mooctest.data;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@Builder
+@NoArgsConstructor
+public class SimpleResponse {
+    private int status;
+    private String message;
+}

+ 26 - 0
src/main/java/com/mooctest/model/CrowdTask.java

@@ -0,0 +1,26 @@
+package com.mooctest.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Document(collection = "exam")
+public class CrowdTask {
+    @Id
+    private String id;
+
+    private String json;
+
+    private String app_name;
+
+    private String paper_type;
+
+    private String test_type;
+
+    private String description;
+}

+ 10 - 0
src/main/java/com/mooctest/service/FileService.java

@@ -0,0 +1,10 @@
+package com.mooctest.service;
+
+import org.springframework.web.multipart.MultipartFile;
+
+public interface FileService {
+
+    //上传一个file 返回一个String
+    public String uploadFile(MultipartFile file);
+    public String uploadJson(String content,long taskId);
+}

+ 146 - 8
src/main/java/com/mooctest/service/TaskService.java

@@ -3,31 +3,35 @@ package com.mooctest.service;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
-import com.mongodb.MongoClient;
-import com.mongodb.client.FindIterable;
-import com.mongodb.client.MongoCollection;
-import com.mongodb.client.MongoCursor;
-import com.mongodb.client.MongoDatabase;
 import com.mooctest.dao.MasterReportDao;
 import com.mooctest.dao.MasterReportDao;
 import com.mooctest.dao.TaskDao;
 import com.mooctest.dao.TaskDao;
+import com.mooctest.dao2.CrowdTaskDao;
+import com.mooctest.data.SimpleResponse;
 import com.mooctest.data.TaskDTO;
 import com.mooctest.data.TaskDTO;
+import com.mooctest.model.CrowdTask;
 import com.mooctest.model.Task;
 import com.mooctest.model.Task;
 import com.mooctest.util.EncodeUtil;
 import com.mooctest.util.EncodeUtil;
+import com.mooctest.util.TaskUtil;
 import com.mooctest.util.TimeUtil;
 import com.mooctest.util.TimeUtil;
 import org.bson.Document;
 import org.bson.Document;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.ResponseEntity;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.*;
 import org.springframework.http.converter.HttpMessageConverter;
 import org.springframework.http.converter.HttpMessageConverter;
 import org.springframework.http.converter.StringHttpMessageConverter;
 import org.springframework.http.converter.StringHttpMessageConverter;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
 import org.springframework.util.MultiValueMap;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.client.RestTemplate;
 import org.springframework.web.client.RestTemplate;
+import org.springframework.web.multipart.MultipartFile;
 
 
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
 import java.nio.charset.Charset;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.*;
@@ -54,11 +58,17 @@ public class TaskService {
     TaskDao taskDao;
     TaskDao taskDao;
 
 
     @Autowired
     @Autowired
+    CrowdTaskDao crowdTaskDao;
+
+    @Autowired
     BugReportService bugReportService;
     BugReportService bugReportService;
 
 
     @Autowired
     @Autowired
     BugDataService bugDataService;
     BugDataService bugDataService;
 
 
+    @Autowired
+    FileService fileService;
+
     @Value("${task.info.addr}")
     @Value("${task.info.addr}")
     String taskInfoAddr;
     String taskInfoAddr;
 
 
@@ -251,6 +261,49 @@ public class TaskService {
         return res;
         return res;
     }
     }
 
 
+    public String addCrowdTaskPure(String name,String description,String time,String type,MultipartFile threePage){
+        if(threePage ==null || threePage.isEmpty()) return "请提交三级页面";
+        String threePageUrl = fileService.uploadFile(threePage);
+        try {
+            long flag = createCrowdTest(threePageUrl,threePage.getOriginalFilename(),"",getMaxCaseId()+1,type,description,name);
+            return flag!=-1 ?""+flag:"创建失败";
+        } catch (Exception e) {
+            e.printStackTrace();
+            return "创建众测失败";
+        }
+    }
+
+    public SimpleResponse addCrowdTask(String name, String description, String time, String type, String os, MultipartFile threePage){
+        if(threePage ==null || threePage.isEmpty()) return new SimpleResponse(400,"请提交三级页面");
+        String threePageUrl = fileService.uploadFile(threePage);
+        try {
+            long flag = createCrowdTest(threePageUrl,threePage.getOriginalFilename(),generatePaperType(type,os),getMaxCaseId()+1,type,description,name);
+            return flag!=-1 ?new SimpleResponse(200,"创建成功,id为"+flag):new SimpleResponse(400,"创建失败");
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new SimpleResponse(400,"创建众测失败");
+        }
+    }
+
+    public long createCrowdTest(String file, String fileName, String paperType, Long caseId, String testType, String description, String appName) throws Exception {
+        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+        params.add("file", file);
+        params.add("file_name", fileName);
+        params.add("paper_type", paperType);
+        params.add("case_id", caseId + "");
+        params.add("test_type", testType);
+        params.add("description", description);
+        params.add("app_name", appName);
+        RestTemplate restTemplate = new RestTemplate();
+        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
+        ResponseEntity<String> responseEntity = restTemplate.postForEntity
+                ("http://" + reportHost  + "/Bug/api/extra/uploadExamUrl", params, String.class);
+        if (responseEntity.getStatusCode().equals(HttpStatus.OK)){
+            fileService.uploadJson(responseEntity.getBody(),caseId);
+            return caseId;
+        }else return -1;
+    }
+
     public String getEncodeTaskReportUrl(long examId,long caseId){
     public String getEncodeTaskReportUrl(long examId,long caseId){
         String url = HTTP + reportHost + "/report/detail/" + examId +"/" +caseId +"/userId";
         String url = HTTP + reportHost + "/report/detail/" + examId +"/" +caseId +"/userId";
         String encodedUrl = EncodeUtil.strConvertBase(url);
         String encodedUrl = EncodeUtil.strConvertBase(url);
@@ -277,4 +330,89 @@ public class TaskService {
         taskDTO.setNumOfUndeal(undealBugs);
         taskDTO.setNumOfUndeal(undealBugs);
         return taskDTO;
         return taskDTO;
     }
     }
+
+    private long getMaxCaseId(){
+        List<CrowdTask> list = crowdTaskDao.findAll();
+        long max =0;
+        long temp =0;
+        for(CrowdTask task : list){
+            temp=Long.parseLong(task.getId());
+            max=temp>max?temp:max;
+        }
+//        CrowdTask task = crowdTaskDao.findFirstByOrderByIdDesc();
+        return max;
+    }
+
+    public boolean exportTask(String caseId){
+        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+        params.add("caseId", caseId);
+        RestTemplate restTemplate = new RestTemplate();
+        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
+        ResponseEntity<String> responseEntity = restTemplate.postForEntity
+                ("http://" + reportHost  + "/Bug/api/data/outputByCaseId", params, String.class);
+        return responseEntity.getStatusCode().equals(HttpStatus.OK);
+    }
+
+    public boolean importTask(String number,String originId,
+                                  MultipartFile zipFile, MultipartFile jsonFile)  {
+
+        HttpHeaders headers = new HttpHeaders();
+        MediaType type = MediaType.parseMediaType("multipart/form-data");
+        // 设置请求的格式类型
+        headers.setContentType(type);
+        ByteArrayResource zipFileResource = null;
+        ByteArrayResource jsonFileResource  = null;
+        try {
+            zipFileResource= new ByteArrayResource(zipFile.getBytes()) {
+                @Override
+                public String getFilename() {
+                    return zipFile.getOriginalFilename();
+                }
+            };
+            jsonFileResource= new ByteArrayResource(jsonFile.getBytes()) {
+                @Override
+                public String getFilename() {
+                    return jsonFile.getOriginalFilename();
+                }
+            };
+        }catch (IOException e){
+            return false;
+        }
+        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
+        params.add("sourceZipFile", zipFileResource);
+        params.add("sourceJsonFile", jsonFileResource);
+        params.add("originalCaseId", originId);
+        params.add("cpSerialNum", number);
+        HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(params, headers);
+        RestTemplate restTemplate = new RestTemplate();
+        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
+        ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://" + reportHost  + "/Bug/api/data/inputFromFile", files, String.class);
+        return responseEntity.getStatusCode().equals(HttpStatus.OK);
+    }
+
+
+    private static String generatePaperType(String testType ,  String os){
+        String defaultValue = "\"windows\",\"linux\",\"macos\"";
+        StringBuffer value  = new StringBuffer();
+        if(os==null||os.length()==0){
+            if(testType.equals(TaskUtil.TaskType.MOBILE.getTaskType())){
+                value.append("\"Android\",\"ios\"");
+            }else{
+                value.append("\"windows\",\"linux\",\"macos\"");
+            }
+
+        }else{
+            String [] data =  os.split(";");
+            for(int i  =0;i<data.length;i++){
+                if(i!=data.length-1){
+                    value.append("\""+data[i]+"\",");
+                }else{
+                    value.append("\""+data[i]+"\"");
+                }
+            }
+        }
+        return  "{\"title\":\"测试报告名称\",\"subTitles\":[{\"name\":\"设备名称\", \"type\":\"text\"},{\"name\":\"设备品牌\",\"type\":\"text\"},{\"name\":\"操作系统\",\"type\":\"enum\",\"value\":["
+                +value.toString()
+                + "]}],\"caseList\":true,\"bugList\": true,\"testScript\":false,\"suppleReport\":false,\"testLog\":false}";
+    }
 }
 }

+ 64 - 0
src/main/java/com/mooctest/service/impl/NginxFileService.java

@@ -0,0 +1,64 @@
+package com.mooctest.service.impl;
+
+import com.mooctest.service.FileService;
+import org.apache.commons.io.IOUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+
+@Service
+@ConditionalOnExpression("${useOss}==false")
+public class NginxFileService implements FileService {
+
+    @Value("${filePath}")
+    private String filePath;
+    @Value("${urlPath}")
+    private String urlPath;
+
+    @Override
+    public String uploadFile(MultipartFile file) {
+        String fileName = System.currentTimeMillis()+ file.getOriginalFilename();
+        File saveFile = new File(filePath + fileName);
+        //判断文件父目录是否存在
+//        System.out.println(saveFile.getParentFile());
+        if (!saveFile.getParentFile().exists()) {
+            saveFile.getParentFile().mkdirs();
+        }
+        try {
+            file.transferTo(saveFile);
+            return urlPath+fileName;
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static void main(String[] args) {
+        NginxFileService n=new NginxFileService();
+        System.out.println(n.uploadJson("adfasfasdf",324));
+    }
+
+    @Override
+    public String uploadJson(String content,long taskId) {
+        String fileName =  taskId+".json";
+        File saveFile = new File(filePath + fileName);
+        //判断文件父目录是否存在
+//        System.out.println(saveFile.getParentFile());
+        if (!saveFile.getParentFile().exists()) {
+            saveFile.getParentFile().mkdirs();
+        }
+        try {
+            Writer write = new OutputStreamWriter(new FileOutputStream(saveFile), "UTF-8");
+            write.write(content);
+            write.flush();
+            write.close();
+            return urlPath+fileName;
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+}

+ 42 - 0
src/main/java/com/mooctest/service/impl/OssFileService.java

@@ -0,0 +1,42 @@
+package com.mooctest.service.impl;
+
+import com.mooctest.service.FileService;
+import com.mooctest.util.OSSClientUtil;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+
+@Service
+@ConditionalOnExpression("${useOss}==true")
+public class OssFileService implements FileService {
+    @Override
+    public String uploadFile(MultipartFile file) {
+        return OSSClientUtil.uploadSingleFile(file);
+    }
+
+    public static void main(String[] args) {
+        OssFileService o = new OssFileService();
+        System.out.println(o.uploadJson("234",234));
+    }
+
+    @Override
+    public String uploadJson(String content, long taskId) {
+        String filePath = System.getProperty("user.dir")+"/";
+        String fileName =  taskId+".json";
+        File saveFile = new File(filePath + fileName);
+        try {
+            Writer write = new OutputStreamWriter(new FileOutputStream(saveFile), "UTF-8");
+            write.write(content);
+            write.flush();
+            write.close();
+            return OSSClientUtil.uploadSingleFile(saveFile);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
+}

+ 381 - 0
src/main/java/com/mooctest/util/OSSClientUtil.java

@@ -0,0 +1,381 @@
+package com.mooctest.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.model.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.aliyun.oss.OSSClient;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @class:AliyunOSSClientUtil
+ * @descript:java使用阿里云OSS存储对象上传图片
+ *
+ */
+public class OSSClientUtil {
+    //log日志
+    private static Logger logger = LoggerFactory.getLogger(OSSClientUtil.class);
+
+
+    //阿里云API的内或外网域名
+    private static String ENDPOINT = "oss-cn-shanghai.aliyuncs.com";
+    //阿里云API的密钥Access Key ID
+    private static String ACCESS_KEY_ID="LTAI4FdrT3HsfdR5edBVN7ws";
+    //阿里云API的密钥Access Key Secret
+    private static String ACCESS_KEY_SECRET="yroxrpm46DzTyzHrLBZzS3MRNIicP6";
+    //阿里云API的bucket名称
+    private static String BACKET_NAME="mooctest-site";
+    //阿里云API的文件夹名称
+    private static String FOLDER="xinchuangJson";
+
+
+
+
+    /**
+     * 获取阿里云OSS客户端对象
+     * @return ossClient
+     */
+    public static  OSSClient getOSSClient(){
+        return new OSSClient(ENDPOINT,ACCESS_KEY_ID, ACCESS_KEY_SECRET);
+    }
+
+    /**
+     * 创建存储空间
+     * @param ossClient      OSS连接
+     * @param bucketName 存储空间
+     * @return
+     */
+    private  static String createBucketName(OSSClient ossClient,String bucketName){
+        //存储空间
+        final String bucketNames=bucketName;
+        if(!ossClient.doesBucketExist(bucketName)){
+            //创建存储空间
+            Bucket bucket=ossClient.createBucket(bucketName);
+            logger.info("创建存储空间成功");
+            return bucket.getName();
+        }
+        return bucketNames;
+    }
+
+    /**
+     * 创建存储空间
+     * @param ossClient      OSS连接
+     * @param bucketName 存储空间
+     * @return
+     */
+    private  static void putBucketACL(OSSClient ossClient,String bucketName){
+        //存储空间
+        final String bucketNames=bucketName;
+        System.out.println(ossClient.doesBucketExist(bucketName));
+        if(ossClient.doesBucketExist(bucketName)){
+            //修改存储空间的权限
+            ossClient.setBucketAcl(bucketNames, CannedAccessControlList.PublicRead);
+            logger.info("创建存储空间成功");
+        }
+    }
+
+    /**
+     * 删除存储空间buckName
+     * @param ossClient  oss对象
+     * @param bucketName  存储空间
+     */
+    private static  void deleteBucket(OSSClient ossClient, String bucketName){
+        ossClient.deleteBucket(bucketName);
+        logger.info("删除" + bucketName + "Bucket成功");
+    }
+
+    /**
+     * 创建模拟文件夹
+     * @param ossClient oss连接
+     * @param bucketName 存储空间
+     * @param folder   模拟文件夹名如"qj_nanjing/"
+     * @return  文件夹名
+     */
+    private  static String createFolder(OSSClient ossClient,String bucketName,String folder){
+        //文件夹名
+        final String keySuffixWithSlash =folder;
+        //判断文件夹是否存在,不存在则创建
+        if(!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)){
+            //创建文件夹
+            ossClient.putObject(bucketName, keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));
+            logger.info("创建文件夹成功");
+            //得到文件夹名
+            OSSObject object = ossClient.getObject(bucketName, keySuffixWithSlash);
+            String fileDir=object.getKey();
+            return fileDir;
+        }
+        return keySuffixWithSlash;
+    }
+
+    /**
+     * 根据key删除OSS服务器上的文件
+     * @param ossClient  oss连接
+     * @param bucketName  存储空间
+     * @param folder  模拟文件夹名 如"qj_nanjing/"
+     * @param key Bucket下的文件的路径名+文件名 如:"upload/cake.jpg"
+     */
+    private static void deleteFile(OSSClient ossClient, String bucketName, String folder, String key){
+        ossClient.deleteObject(bucketName, folder + key);
+        logger.info("删除" + bucketName + "下的文件" + folder + key + "成功");
+    }
+    /**
+     * 根据key删除OSS服务器上的文件
+     * @param key Bucket下的文件的路径名+文件名 如:"upload/cake.jpg"
+     */
+    private static void deleteFile(String key){
+        OSSClient ossClient = getOSSClient();
+        ossClient.deleteObject(BACKET_NAME,key);
+        logger.info("删除" + BACKET_NAME + "下的文件" + key + "成功");
+    }
+
+    private static void uploadFile2OSS(){
+        // Endpoint以杭州为例,其它Region请按实际情况填写。
+        String endpoint = ENDPOINT;
+        // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
+        String accessKeyId = ACCESS_KEY_ID;
+        String accessKeySecret = ACCESS_KEY_SECRET;
+
+        // 创建OSSClient实例。
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+
+        // 创建PutObjectRequest对象。
+        PutObjectRequest putObjectRequest = new PutObjectRequest(BACKET_NAME,
+                System.currentTimeMillis()+"",
+                new File("/Users/insomnialee/Pictures/五等分/13.png"));
+
+        // 如果需要上传时设置存储类型与访问权限,请参考以下示例代码。
+        // ObjectMetadata metadata = new ObjectMetadata();
+        // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
+        // metadata.setObjectAcl(CannedAccessControlList.Private);
+        // putObjectRequest.setMetadata(metadata);
+
+        // 上传文件。
+        PutObjectResult res = ossClient.putObject(putObjectRequest);
+
+
+        // 关闭OSSClient。
+        ossClient.shutdown();
+    }
+
+    /**
+     * 上传图片至OSS
+     * @param file 上传文件(文件全路径如:D:\\image\\cake.jpg)
+     * @return String 返回访问路径
+     * */
+    private static  String uploadObject2OSS(File file) {
+        OSSClient ossClient = getOSSClient();
+        String resultStr = null;
+        String fileName = null;
+        try {
+            //以输入流的形式上传文件
+            InputStream is = new FileInputStream(file);
+            //文件名  如果出现重复,则重新生成名字,再上传
+            fileName = file.getName();
+//            if(ossClient.doesObjectExist(BACKET_NAME, FOLDER + fileName)){
+//                fileName = getfileName(file.getName());
+//            }
+            //文件大小
+            Long fileSize = file.length();
+            //创建上传Object的Metadata
+            ObjectMetadata metadata = new ObjectMetadata();
+            //上传的文件的长度
+            metadata.setContentLength(is.available());
+            //指定该Object被下载时的网页的缓存行为
+//            metadata.setCacheControl("no-cache");
+            //指定该Object下设置Header
+//            metadata.setHeader("Pragma", "no-cache");
+            //指定该Object被下载时的内容编码格式
+//            metadata.setContentEncoding("utf-8");
+            //文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,
+            //如果没有扩展名则填默认值application/octet-stream
+//            metadata.setContentType(getContentType(fileName));
+            //指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)
+            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
+            //上传文件   (上传文件流的形式)
+            PutObjectResult putResult = ossClient.putObject(BACKET_NAME, FOLDER +"/"+ fileName, is, metadata);
+            resultStr = putResult.getETag();
+            logger.info("上传阿里云OSS服务器成功." +resultStr);
+            //解析结果
+        } catch (Exception e) {
+            e.printStackTrace();
+            logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
+        }
+        return "http://"+BACKET_NAME+"."+ENDPOINT+"/"+FOLDER +"/"+ fileName;
+    }
+    /**
+     * 上传图片至OSS
+     * @param in 上传文件流
+     * @return String 返回访问路径,图片存储KEY
+     * */
+    private static  String uploadObject2OSS(InputStream in,String name,Long size) {
+        OSSClient ossClient = getOSSClient();
+        String resultStr = null;
+        String fileName = null;
+        try {
+            //文件名  如果出现重复,则重新生成名字,再上传
+            fileName = getfileName(name);
+            if(ossClient.doesObjectExist(BACKET_NAME, FOLDER + fileName)){
+                fileName = getfileName(name);
+            }
+            //文件大小
+            Long fileSize = size;
+            //创建上传Object的Metadata
+            ObjectMetadata metadata = new ObjectMetadata();
+            //上传的文件的长度
+            metadata.setContentLength(in.available());
+            //指定该Object被下载时的网页的缓存行为
+            metadata.setCacheControl("no-cache");
+            //指定该Object下设置Header
+            metadata.setHeader("Pragma", "no-cache");
+            //指定该Object被下载时的内容编码格式
+            metadata.setContentEncoding("utf-8");
+            //文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,
+            //如果没有扩展名则填默认值application/octet-stream
+            metadata.setContentType(getContentType(fileName));
+            //指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)
+            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
+            //上传文件   (上传文件流的形式)
+            PutObjectResult putResult = ossClient.putObject(BACKET_NAME, FOLDER + fileName, in, metadata);
+            resultStr = putResult.getETag();
+            logger.info("上传阿里云OSS服务器成功." +resultStr);
+            //解析结果
+        } catch (Exception e) {
+            e.printStackTrace();
+            logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
+        }
+        return BACKET_NAME+"."+ENDPOINT+"/"+FOLDER + fileName;
+    }
+
+    /**
+     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
+     * @param fileName 文件名
+     * @return 文件的contentType
+     */
+    private static  String getContentType(String fileName){
+        //文件的后缀名
+        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
+        if(".bmp".equalsIgnoreCase(fileExtension)) {
+            return "image/bmp";
+        }
+        if(".gif".equalsIgnoreCase(fileExtension)) {
+            return "image/gif";
+        }
+        if(".jpeg".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension)  || ".png".equalsIgnoreCase(fileExtension) ) {
+            return "image/jpeg";
+        }
+        if(".html".equalsIgnoreCase(fileExtension)) {
+            return "text/html";
+        }
+        if(".txt".equalsIgnoreCase(fileExtension)) {
+            return "text/plain";
+        }
+        if(".vsd".equalsIgnoreCase(fileExtension)) {
+            return "application/vnd.visio";
+        }
+        if(".ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) {
+            return "application/vnd.ms-powerpoint";
+        }
+        if(".doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) {
+            return "application/msword";
+        }
+        if(".xml".equalsIgnoreCase(fileExtension)) {
+            return "text/xml";
+        }
+        //默认返回类型
+        return "image/jpeg";
+    }
+
+    /**
+     * 修改文件名
+     * @param fileName 文件名
+     * @return 文件的新名称
+     */
+    private static  String getfileName(String fileName){
+        String fileType = fileName.substring(fileName.lastIndexOf("."), fileName.length());
+        String name = System.currentTimeMillis()+fileType;
+        System.out.println(fileName+"----"+name);
+        return name;
+
+    }
+
+    /**
+     * 上传图片至OSS
+     * @param file 上传文件(文件全路径如:D:\\image\\cake.jpg)
+     * @return String 返回访问路径
+     * */
+    private  static  String uploadMultipartFile2OSS(MultipartFile file) {
+        OSSClient ossClient = getOSSClient();
+        String resultStr = null;
+        String fileName = null;
+        try {
+            //以输入流的形式上传文件
+            InputStream is = file.getInputStream();
+            //文件名  如果出现重复,则重新生成名字,再上传
+            fileName = getfileName(file.getOriginalFilename());
+//            if(ossClient.doesObjectExist(BACKET_NAME, FOLDER + fileName)){
+//                fileName = getfileName(file.getName());
+//            }
+            //文件大小
+            Long fileSize = file.getSize();
+            //创建上传Object的Metadata
+            ObjectMetadata metadata = new ObjectMetadata();
+            //上传的文件的长度
+            metadata.setContentLength(is.available());
+            //指定该Object被下载时的网页的缓存行为
+//            metadata.setCacheControl("no-cache");
+            //指定该Object下设置Header
+//            metadata.setHeader("Pragma", "no-cache");
+            //指定该Object被下载时的内容编码格式
+//            metadata.setContentEncoding("utf-8");
+            //文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,
+            //如果没有扩展名则填默认值application/octet-stream
+//            metadata.setContentType(getContentType(fileName));
+            //指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)
+            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
+            //上传文件   (上传文件流的形式)
+            PutObjectResult putResult = ossClient.putObject(BACKET_NAME, FOLDER + "/"+ fileName, is, metadata);
+            resultStr = putResult.getETag();
+            logger.info("上传阿里云OSS服务器成功." +resultStr);
+            //解析结果
+        } catch (Exception e) {
+            e.printStackTrace();
+            logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
+        }
+        return "http://"+BACKET_NAME+"."+ENDPOINT+"/"+FOLDER + "/" + fileName;
+    }
+
+    public static  String uploadSingleFile(MultipartFile file){
+        OSSClient ossClient=OSSClientUtil.getOSSClient();
+        return uploadMultipartFile2OSS(file);
+    }
+
+    public static  String uploadSingleFile(File file){
+//        OSSClient ossClient=OSSClientUtil.getOSSClient();
+        return uploadObject2OSS(file);
+    }
+
+    //测试
+//    public static void main(String[] args) throws Exception {
+//        uploadFile2OSS();
+//        //初始化OSSClient
+//        OSSClient ossClient=OSSClientUtil.getOSSClient();
+//        //上传文件
+//        String files="/Users/insomnialee/Pictures/五等分/13.png";
+//        String[] file=files.split(",");
+//        for(String filename:file){
+//            //System.out.println("filename:"+filename);
+//            File filess=new File(filename);
+//            String md5key = OSSClientUtil.uploadObject2OSS(filess);
+//            System.out.println("文件地址:" + md5key);
+//        }
+//    }
+
+
+}

+ 25 - 0
src/main/java/com/mooctest/util/TaskUtil.java

@@ -0,0 +1,25 @@
+package com.mooctest.util;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class TaskUtil {
+
+
+    public enum TaskType {
+
+        MOBILE("移动应用"), // 未审核
+        WEB("Web应用"); // 已审核
+
+        private String taskType;
+
+        private TaskType(String taskType) {
+            this.taskType = taskType;
+        }
+
+        public String getTaskType() {
+            return taskType;
+        }
+    }
+
+}

+ 42 - 14
src/main/resources/application.yml

@@ -1,4 +1,4 @@
-spring.profiles.active: test
+spring.profiles.active: private-cloud
 spring:
 spring:
   mvc:
   mvc:
     favicon:
     favicon:
@@ -46,18 +46,6 @@ spring:
   thymeleaf:
   thymeleaf:
     cache: false
     cache: false
 
 
-
-mongodb1.database: ${MONGODB_REVIEW_DB}
-mongodb1.host: ${MONGODB_REVIEW_HOST}
-mongodb1.port: ${MONGODB_REVIEW_PORT}
-
-mongodb2.database: ${MONGODB_REPORT_DB}
-mongodb2.host: ${MONGODB_REPORT_HOST}
-mongodb2.port: ${MONGODB_REPORT_PORT}
-
-report.export.addr: ${EXPORT_ADDR}
-task.info.addr: ${TASK_ADDR}
-
 server:
 server:
   port: 9004
   port: 9004
 #    port: 8090
 #    port: 8090
@@ -65,4 +53,44 @@ logging:
   level:
   level:
     com.mooctest: debug
     com.mooctest: debug
   pattern:
   pattern:
-    console: "%d{yyyy-MM-dd HH:mm:ss} [%p] [%t] [%c] %m%n"
+    console: "%d{yyyy-MM-dd HH:mm:ss} [%p] [%t] [%c] %m%n"
+---
+spring:
+  profiles: private-cloud
+  thymeleaf:
+    cache: false
+
+task:
+  info:
+    addr: http://47.98.174.59:8100/Bug/api/extra/getExamList
+  distribute:
+    url: test
+server:
+  port: 9004
+report.host: 47.98.174.59:8100
+audit:
+  distribute:
+    addr: test
+mooctest:
+  host: http://101.37.175.111:8191
+report.export.addr: http://47.99.140.117:9002/generateReport
+report.export.excel.addr: http://47.98.174.59:8095/generateReport
+mongodb1.database: crowd_review_enterprise
+mongodb1.host: 47.98.174.59
+mongodb1.port: 27017
+mongodb2.database: co-enterprise
+mongodb2.host: 47.98.174.59
+mongodb2.port: 27017
+useOss: false
+filePath: /xinchuang/data/
+urlPath: http://47.98.174.59:8100/resourcesXinchuang/
+logging:
+  level:
+    com:
+      mooctest: debug
+  pattern:
+    console: "%d{yyyy-MM-dd HH:mm:ss} [%p] [%t] [%c] %m%n"
+
+
+
+---

+ 0 - 1
src/main/resources/bootstrap.yml

@@ -1,5 +1,4 @@
 spring.profiles.active: dev
 spring.profiles.active: dev
-
 spring:
 spring:
   application:
   application:
     name: mooctest-crowd-review
     name: mooctest-crowd-review

+ 261 - 0
src/main/resources/templates/addCrowdTask.html

@@ -0,0 +1,261 @@
+<!DOCTYPE html>
+<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"
+      xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
+      layout:decorator="main">
+<head>
+    <link rel="stylesheet" href="/static/css/applications.css" type="text/css"/>
+    <!-- dataTables -->
+    <link rel="stylesheet" type="text/css"
+          href="/static/AdminLTE/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css"/>
+    <!-- Font Awesome -->
+    <link rel="stylesheet" href="/static/AdminLTE/bower_components/font-awesome/css/font-awesome.min.css"/>
+    <!-- Ionicons -->
+    <link rel="stylesheet" href="/static/AdminLTE/bower_components/Ionicons/css/ionicons.min.css"/>
+    <!-- daterange picker -->
+    <link rel="stylesheet" href="/static/AdminLTE/bower_components/bootstrap-daterangepicker/daterangepicker.css"/>
+    <!-- bootstrap datepicker -->
+    <link rel="stylesheet" href="/static/AdminLTE/bower_components/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css"/>
+    <!-- iCheck for checkboxes and radio inputs -->
+    <link rel="stylesheet" href="/static/AdminLTE/plugins/iCheck/all.css"/>
+    <!-- Bootstrap time Picker -->
+    <link rel="stylesheet" href="/static/AdminLTE/plugins/timepicker/bootstrap-timepicker.min.css"/>
+    <!-- Select2 -->
+    <link rel="stylesheet" type="text/css" href="/static/AdminLTE/bower_components/select2/dist/css/select2.min.css"/>
+    <!-- Theme style -->
+    <link rel="stylesheet" href="/static/AdminLTE/dist/css/AdminLTE.min.css"/>
+    <!-- AdminLTE Skins. Choose a skin from the css/skins
+         folder instead of downloading all of them to reduce the load. -->
+    <link rel="stylesheet" href="/static/AdminLTE/dist/css/skins/_all-skins.min.css"/>
+</head>
+<body>
+<th:block layout:fragment="sidebar">
+    <li th:replace="/home::mainSidebar">
+</th:block>
+
+
+
+
+<th:block layout:fragment="maincontent">
+    <section class="content-header">
+        <h1>
+            新建众测任务
+            <small>众包测试</small>
+        </h1>
+        <ol class="breadcrumb">
+            <li><a href="/home"><i class="fa fa-dashboard"></i> 主页</a></li>
+            <li><a href="/addCrowdTask">新建众测任务</a></li>
+        </ol>
+    </section>
+
+    <!-- Main content -->
+    <section class="content" id="maincontent">
+
+        <div class="box box-primary" >
+            <div class="box-header with-border">
+                <h3 class="box-title">基本信息</h3>
+                <button class="btn btn-success pull-right" onclick="addTask()">
+                    生成
+                </button>
+            </div>
+            <!-- /.box-header -->
+            <div class="box-body">
+                <form class="form-horizontal">
+                    <!-- text input -->
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label">名称</label>
+                        <div class="col-sm-4">
+                            <input  onchange="checkNull(event)" class="form-control" id="name" placeholder="请输入任务名称"/>
+                        </div>
+                    </div>
+                    <!-- textarea -->
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label">描述</label>
+                        <div class="col-sm-6">
+                            <textarea onchange="checkNull(event)" id="description" class="form-control" rows="3" placeholder="请输入描述信息"></textarea>
+                        </div>
+                    </div>
+                    <!-- text input -->
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label">操作系统枚举项<br><small>请用逗号分割</small></label>
+                        <div class="col-sm-4">
+                            <input  onchange="checkNull(event)" class="form-control" id="os" placeholder="请输入os枚举项"/>
+                        </div>
+                    </div>
+                    <!-- Date and time range -->
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label" >任务时间</label>
+                        <div class=" col-sm-5">
+                            <!--                                <div class="input-group-addon">-->
+                            <!--                                    <i class="fa fa-clock-o"></i>-->
+                            <!--                                </div>-->
+                            <input type="text" class="form-control pull-right" id="reservationtime"/>
+                        </div>
+                        <!-- /.input group -->
+                    </div>
+
+                    <!-- select -->
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label" >任务类型</label>
+                        <div class=" col-sm-4">
+                            <select class="form-control" id="testType" >
+                                <option >移动应用</option>
+                                <option >Web应用</option>
+                            </select>
+                        </div>
+                    </div>
+
+                    <!-- text input -->
+<!--                    <div class="form-group" id="webUrl" style="display: none">-->
+<!--                        <label class="col-sm-2 control-label">待测网站链接</label>-->
+<!--                        <div class="col-sm-6">-->
+<!--                            <input  onchange="checkNull(event)" class="form-control" id="websiteUrl" placeholder="请输入网站链接"/>-->
+<!--                        </div>-->
+<!--                    </div>-->
+
+<!--                    <div class="form-group" id="apkFile">-->
+<!--                        <label for="testApplication"  class="col-sm-2 control-label">待测应用</label>-->
+<!--                        <div class="col-sm-10">-->
+<!--                            <input  type="file" id="testApplication"/>-->
+<!--                            &lt;!&ndash;                               <p class="help-block">Example block-level help text here.</p>&ndash;&gt;-->
+<!--                        </div>-->
+<!--                    </div>-->
+
+<!--                    <div class="form-group">-->
+<!--                        <label for="testRequirement" class="col-sm-2 control-label">测试需求</label>-->
+<!--                        <div class="col-sm-10">-->
+<!--                            <input  type="file" id="testRequirement"/>-->
+<!--                            &lt;!&ndash;                               <p class="help-block">Example block-level help text here.</p>&ndash;&gt;-->
+<!--                        </div>-->
+<!--                    </div>-->
+
+                    <div class="form-group">
+                        <label for="threePage" class="col-sm-2 control-label">三级页面<br><a th:href="${templateUrl}">示例</a></label>
+                        <div class="col-sm-10">
+                            <input  type="file" id="threePage"/>
+                            <!--                               <p class="help-block">Example block-level help text here.</p>-->
+                        </div>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </section>
+
+</th:block>
+</body>
+</html>
+<!-- jQuery 3 -->
+<!--<script src="/static/AdminLTE/bower_components/jquery/dist/jquery.min.js"></script>-->
+<!-- Bootstrap 3.3.7 -->
+<script src="/static/AdminLTE/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
+<script src="/static/AdminLTE/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
+<script src="/static/AdminLTE/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
+<script src="/static/AdminLTE/bower_components/select2/dist/js/select2.min.js"></script>
+<!-- InputMask -->
+<script src="/static/AdminLTE/plugins/input-mask/jquery.inputmask.js"></script>
+<script src="/static/AdminLTE/plugins/input-mask/jquery.inputmask.date.extensions.js"></script>
+<script src="/static/AdminLTE/plugins/input-mask/jquery.inputmask.extensions.js"></script>
+<!-- date-range-picker -->
+<script src="/static/AdminLTE/bower_components/moment/min/moment.min.js"></script>
+<script src="/static/AdminLTE/bower_components/bootstrap-daterangepicker/daterangepicker.js"></script>
+<!-- bootstrap datepicker -->
+<script src="/static/AdminLTE/bower_components/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js"></script>
+<!-- bootstrap time picker -->
+<script src="/static/AdminLTE/plugins/timepicker/bootstrap-timepicker.min.js"></script>
+<!-- SlimScroll -->
+<script src="/static/AdminLTE/bower_components/jquery-slimscroll/jquery.slimscroll.min.js"></script>
+<!-- iCheck 1.0.1 -->
+<script src="/static/AdminLTE/plugins/iCheck/icheck.min.js"></script>
+<!-- FastClick -->
+<script src="/static/AdminLTE/bower_components/fastclick/lib/fastclick.js"></script>
+
+<script src="/static/AdminLTE/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
+<script src="/static/AdminLTE/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
+<script src="/static/AdminLTE/bower_components/select2/dist/js/select2.min.js"></script>
+<script src="/static/AdminLTE/bower_components/bootstrap-notify/dist/bootstrap-notify.min.js"></script>
+<!--<script src="/static/js/app_info.js"></script>-->
+<script type="text/javascript">
+    $(document).ready(function(){
+        $('#crowdSidebar').addClass('active');
+        $('#crowdSidebarMenu-addCrowdTask').addClass('active');
+        $('#reservationtime').daterangepicker({ timePicker: true, timePickerIncrement: 30, locale: { format: 'MM/DD/YYYY hh:mm A' }})
+    });
+
+    // changeType = function () {
+    //     var type = $('#testType').val();
+    //     if(type == 'Web应用'){
+    //         $('#apkFile').css('display','none');
+    //         $('#webUrl').css('display','block');
+    //     }else{
+    //         //移动应用
+    //         $('#apkFile').css('display','block');
+    //         $('#webUrl').css('display','none');
+    //     }
+    // }
+    
+    addTask = function(){
+        //type  = 0  表示添加
+        // type = 1 表示修改
+        // 遍历页面上的数据,生成json数据。
+        var data = new FormData();
+        data.append('name',$('#name').val());
+        data.append('description',$('#description').val());
+        data.append('time',$('#reservationtime').val());
+        data.append('type',$('#testType').val());
+        data.append('os',$('#os').val());
+        // data.append('webUrl',$('#webUrl').val());
+        // if($('#testType').val() == '移动应用') data.append("apk",document.getElementById('testApplication').files[0])
+        // data.append("requirement",document.getElementById('testRequirement').files[0])
+        data.append("threePage",document.getElementById('threePage').files[0])
+        $.ajax({
+            url: '/addCrowdTask',
+            data:data,
+            type: 'POST',
+            processData: false,
+            contentType: false,
+            success: function (result) {
+                console.log(result);
+                console.log(result.status != '200')
+                if(result.status != '200'){
+                    $.notify({
+                        message: result.message
+                    },{
+                        // settings
+                        delay: 100,
+                        timer: 1000,
+                        type: 'error'
+                    });
+                }else {
+                    $.notify({
+                        message: result.message
+                    },{
+                        delay: 100,
+                        timer: 3000,
+                        type: 'success'
+                    });
+                }
+            }
+        });
+    }
+
+
+    checkNull = function (event) {
+        var num = event.target.value;
+        console.log(num)
+        if(num!=null&&num.length!=0){
+            console.log(event.target.parentElement.parentElement)
+            event.target.parentElement.parentElement.setAttribute("class","form-group has-success")
+            if(event.target.nextSibling!=null){
+                event.target.nextSibling.remove();
+            }
+        }else{
+            var newNode = document.createElement("span");
+            newNode.setAttribute("class","help-block")
+            newNode.innerHTML =" 请填写 ";
+            if(event.target.nextSibling==null){
+                event.target.parentNode.insertBefore(newNode,event.target.nextSibling)
+            }
+            event.target.parentElement.parentElement.setAttribute("class","form-group has-error")
+        }
+    }
+
+</script>

+ 2 - 2
src/main/resources/templates/base.html

@@ -16,7 +16,7 @@
     <!-- AdminLTE Skins. We have chosen the skin-blue for this starter
     <!-- AdminLTE Skins. We have chosen the skin-blue for this starter
       page. However, you can choose any other skin. Make sure you
       page. However, you can choose any other skin. Make sure you
       apply the skin class to the body tag so the changes take effect. -->
       apply the skin class to the body tag so the changes take effect. -->
-    <link rel="stylesheet" href="/static/AdminLTE/dist/css/skins/skin-blue.min.css" />
+    <link rel="stylesheet" href="/static/AdminLTE/dist/css/skins/skin-red.min.css" />
 
 
     <title>报告审核</title>
     <title>报告审核</title>
     <style>
     <style>
@@ -42,7 +42,7 @@
     </style>
     </style>
 
 
 </head>
 </head>
-<body class="skin-blue sidebar-mini" style="height: auto; min-height: 100%;">
+<body class="skin-red sidebar-mini" style="height: auto; min-height: 100%;">
 <div class="wrapper" style="height: auto; min-height: 100%;">
 <div class="wrapper" style="height: auto; min-height: 100%;">
     <header class="main-header">
     <header class="main-header">
         <!-- Logo -->
         <!-- Logo -->

+ 10 - 0
src/main/resources/templates/home.html

@@ -44,11 +44,21 @@
                                 <i class="fa fa-align-justify"></i>任务列表
                                 <i class="fa fa-align-justify"></i>任务列表
                             </a>
                             </a>
                         </li>
                         </li>
+                        <li id="crowdSidebarMenu-addCrowdTask">
+                            <a href="/addCrowdTask">
+                                <i class="fa fa-plus"></i>新建众测任务
+                            </a>
+                        </li>
                         <li id="crowdSidebarMenu-addExcel">
                         <li id="crowdSidebarMenu-addExcel">
                             <a href="/addExcel">
                             <a href="/addExcel">
                                 <i class="fa fa-file-excel-o"></i>导入第三方项目
                                 <i class="fa fa-file-excel-o"></i>导入第三方项目
                             </a>
                             </a>
                         </li>
                         </li>
+                        <li id="crowdSidebarMenu-importTask">
+                            <a href="/importTask">
+                                <i class="fa  fa-object-ungroup"></i>导入任务
+                            </a>
+                        </li>
                     </ul>
                     </ul>
                 </li>
                 </li>
 
 

+ 202 - 0
src/main/resources/templates/importTask.html

@@ -0,0 +1,202 @@
+<!DOCTYPE html>
+<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"
+      xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
+      layout:decorator="main">
+<head>
+    <link rel="stylesheet" href="/static/css/applications.css" type="text/css"/>
+    <!-- dataTables -->
+    <link rel="stylesheet" type="text/css"
+          href="/static/AdminLTE/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css"/>
+    <!-- Font Awesome -->
+    <link rel="stylesheet" href="/static/AdminLTE/bower_components/font-awesome/css/font-awesome.min.css"/>
+    <!-- Ionicons -->
+    <link rel="stylesheet" href="/static/AdminLTE/bower_components/Ionicons/css/ionicons.min.css"/>
+    <!-- daterange picker -->
+    <link rel="stylesheet" href="/static/AdminLTE/bower_components/bootstrap-daterangepicker/daterangepicker.css"/>
+    <!-- bootstrap datepicker -->
+    <link rel="stylesheet" href="/static/AdminLTE/bower_components/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css"/>
+    <!-- iCheck for checkboxes and radio inputs -->
+    <link rel="stylesheet" href="/static/AdminLTE/plugins/iCheck/all.css"/>
+    <!-- Bootstrap time Picker -->
+    <link rel="stylesheet" href="/static/AdminLTE/plugins/timepicker/bootstrap-timepicker.min.css"/>
+    <!-- Select2 -->
+    <link rel="stylesheet" type="text/css" href="/static/AdminLTE/bower_components/select2/dist/css/select2.min.css"/>
+    <!-- Theme style -->
+    <link rel="stylesheet" href="/static/AdminLTE/dist/css/AdminLTE.min.css"/>
+    <!-- AdminLTE Skins. Choose a skin from the css/skins
+         folder instead of downloading all of them to reduce the load. -->
+    <link rel="stylesheet" href="/static/AdminLTE/dist/css/skins/_all-skins.min.css"/>
+</head>
+<body>
+<th:block layout:fragment="sidebar">
+    <li th:replace="/home::mainSidebar">
+</th:block>
+
+
+
+
+<th:block layout:fragment="maincontent">
+    <section class="content-header">
+        <h1>
+            导入众测报告
+            <small>众包测试</small>
+        </h1>
+        <ol class="breadcrumb">
+            <li><a href="/home"><i class="fa fa-dashboard"></i> 主页</a></li>
+            <li><a href="/importTask">导入众测任务</a></li>
+        </ol>
+    </section>
+
+    <!-- Main content -->
+    <section class="content" id="maincontent">
+
+        <div class="box box-primary" >
+            <div class="box-header with-border">
+                <h3 class="box-title">基本信息</h3>
+                <button class="btn btn-success pull-right" onclick="importTask()">
+                    导入
+                </button>
+            </div>
+            <!-- /.box-header -->
+            <div class="box-body">
+                <form class="form-horizontal">
+                    <!-- text input -->
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label">单位序列号</label>
+                        <div class="col-sm-4">
+                            <input  onchange="checkNull(event)" class="form-control" id="number" placeholder="请输入单位名称"/>
+                        </div>
+                    </div>
+                    <!-- text input -->
+                    <div class="form-group">
+                        <label class="col-sm-2 control-label">原始任务id</label>
+                        <div class="col-sm-4">
+                            <input  onchange="checkNull(event)" class="form-control" id="originId" placeholder="请输入原始任务id"/>
+                        </div>
+                    </div>
+
+
+                    <div class="form-group">
+                        <label for="zipFile" class="col-sm-2 control-label">导入zip文件</label>
+                        <div class="col-sm-10">
+                            <input  type="file" id="zipFile"/>
+                            <!--                               <p class="help-block">Example block-level help text here.</p>-->
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="jsonFile" class="col-sm-2 control-label">导入json文件</label>
+                        <div class="col-sm-10">
+                            <input  type="file" id="jsonFile"/>
+                            <!--                               <p class="help-block">Example block-level help text here.</p>-->
+                        </div>
+                    </div>
+
+
+                </form>
+            </div>
+        </div>
+    </section>
+
+</th:block>
+</body>
+</html>
+<!-- jQuery 3 -->
+<!--<script src="/static/AdminLTE/bower_components/jquery/dist/jquery.min.js"></script>-->
+<!-- Bootstrap 3.3.7 -->
+<script src="/static/AdminLTE/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
+<script src="/static/AdminLTE/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
+<script src="/static/AdminLTE/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
+<script src="/static/AdminLTE/bower_components/select2/dist/js/select2.min.js"></script>
+<!-- InputMask -->
+<script src="/static/AdminLTE/plugins/input-mask/jquery.inputmask.js"></script>
+<script src="/static/AdminLTE/plugins/input-mask/jquery.inputmask.date.extensions.js"></script>
+<script src="/static/AdminLTE/plugins/input-mask/jquery.inputmask.extensions.js"></script>
+<!-- date-range-picker -->
+<script src="/static/AdminLTE/bower_components/moment/min/moment.min.js"></script>
+<script src="/static/AdminLTE/bower_components/bootstrap-daterangepicker/daterangepicker.js"></script>
+<!-- bootstrap datepicker -->
+<script src="/static/AdminLTE/bower_components/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js"></script>
+<!-- bootstrap time picker -->
+<script src="/static/AdminLTE/plugins/timepicker/bootstrap-timepicker.min.js"></script>
+<!-- SlimScroll -->
+<script src="/static/AdminLTE/bower_components/jquery-slimscroll/jquery.slimscroll.min.js"></script>
+<!-- iCheck 1.0.1 -->
+<script src="/static/AdminLTE/plugins/iCheck/icheck.min.js"></script>
+<!-- FastClick -->
+<script src="/static/AdminLTE/bower_components/fastclick/lib/fastclick.js"></script>
+
+<script src="/static/AdminLTE/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
+<script src="/static/AdminLTE/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
+<script src="/static/AdminLTE/bower_components/select2/dist/js/select2.min.js"></script>
+<script src="/static/AdminLTE/bower_components/bootstrap-notify/dist/bootstrap-notify.min.js"></script>
+<!--<script src="/static/js/app_info.js"></script>-->
+<script type="text/javascript">
+    $(document).ready(function(){
+        $('#crowdSidebar').addClass('active');
+        $('#crowdSidebarMenu-importTask').addClass('active');
+    });
+
+
+
+    importTask = function(){
+        //type  = 0  表示添加
+        // type = 1 表示修改
+        // 遍历页面上的数据,生成json数据。
+        var data = new FormData();
+        data.append('number',$('#number').val());
+        data.append('originId',$('#originId').val());
+        data.append("zipFile",document.getElementById('zipFile').files[0])
+        data.append("jsonFile",document.getElementById('jsonFile').files[0])
+        $.ajax({
+            url: '/importTask',
+            data:data,
+            type: 'POST',
+            processData: false,
+            contentType: false,
+            success: function (result) {
+
+                if(result != 'success'){
+                    $.notify({
+                        message: result
+                    },{
+                        // settings
+                        delay: 100,
+                        timer: 1000,
+                        type: 'error'
+                    });
+                }else {
+                    $.notify({
+                        message: '导入成功'
+                    },{
+                        // settings
+                        delay: 100,
+                        timer: 3000,
+                        type: 'success'
+                    });
+                }
+            }
+        });
+    }
+
+
+    checkNull = function (event) {
+        var num = event.target.value;
+        console.log(num)
+        if(num!=null&&num.length!=0){
+            console.log(event.target.parentElement.parentElement)
+            event.target.parentElement.parentElement.setAttribute("class","form-group has-success")
+            if(event.target.nextSibling!=null){
+                event.target.nextSibling.remove();
+            }
+        }else{
+            var newNode = document.createElement("span");
+            newNode.setAttribute("class","help-block")
+            newNode.innerHTML =" 请填写 ";
+            if(event.target.nextSibling==null){
+                event.target.parentNode.insertBefore(newNode,event.target.nextSibling)
+            }
+            event.target.parentElement.parentElement.setAttribute("class","form-group has-error")
+        }
+    }
+
+</script>

+ 50 - 1
src/main/resources/templates/task_detail.html

@@ -62,7 +62,7 @@
                             <i class="fa fa-sitemap " style="color: rgba(214,182,27,0.7)"></i>
                             <i class="fa fa-sitemap " style="color: rgba(214,182,27,0.7)"></i>
                             <span>聚合视图</span>
                             <span>聚合视图</span>
                         </a>
                         </a>
-                        <ul class="treeview-menu"  id="crowdSidebar-reportReview-aggrReportMenu">
+                        <ul class="treeview-menu"  id="crowdSidebar-reportReview-aggrReportMenu" th:if="${task!=null}">
                             <li id="crowdSidebar-reportReview-aggrReportMenu-all">
                             <li id="crowdSidebar-reportReview-aggrReportMenu-all">
                                 <a th:href="'/agg_report_list?examId='+${examId}+'&amp;caseId='+${caseId}">
                                 <a th:href="'/agg_report_list?examId='+${examId}+'&amp;caseId='+${caseId}">
                                     <i class="fa fa-circle-o"></i>
                                     <i class="fa fa-circle-o"></i>
@@ -104,11 +104,21 @@
                     </li>
                     </li>
                 </ul>
                 </ul>
             </li>
             </li>
+            <li id="crowdSidebarMenu-addCrowdTask">
+                <a href="/addCrowdTask">
+                    <i class="fa fa-plus"></i>新建众测任务
+                </a>
+            </li>
             <li id="crowdSidebarMenu-addExcel">
             <li id="crowdSidebarMenu-addExcel">
                 <a href="/addExcel">
                 <a href="/addExcel">
                     <i class="fa fa-file-excel-o"></i>导入第三方项目
                     <i class="fa fa-file-excel-o"></i>导入第三方项目
                 </a>
                 </a>
             </li>
             </li>
+            <li id="crowdSidebarMenu-importTask">
+                <a href="/importTask">
+                    <i class="fa  fa-object-ungroup"></i>导入任务
+                </a>
+            </li>
         </ul>
         </ul>
     </li>
     </li>
 
 
@@ -253,6 +263,10 @@
                 <i class="fa fa-coffee" style="margin-right: 3px;"></i>
                 <i class="fa fa-coffee" style="margin-right: 3px;"></i>
                 <span>全部交付</span>
                 <span>全部交付</span>
             </button>
             </button>
+            <button  id="export-btn" onclick="exportTask()" class="btn btn-sm btn-assign pull-right">
+                <i class="fa fa-coffee" style="margin-right: 3px;"></i>
+                <span>导出任务</span>
+            </button>
         </div>
         </div>
         <table id="report-list" class="table table-striped table-bordered" cellpadding="0" width="100%">
         <table id="report-list" class="table table-striped table-bordered" cellpadding="0" width="100%">
             <thead>
             <thead>
@@ -363,6 +377,7 @@
     /*<![CDATA[*/
     /*<![CDATA[*/
     var reportHost = [[${reportHost}]]
     var reportHost = [[${reportHost}]]
     var encodedReportDetailUrl = [[${encodedUrl}]]
     var encodedReportDetailUrl = [[${encodedUrl}]]
+    var caseId = [[${caseId}]]
     /*]]>*/
     /*]]>*/
 
 
 
 
@@ -401,6 +416,40 @@
         });
         });
     });
     });
 
 
+    exportTask  = function(){
+        var data = new FormData();
+        data.append('caseId',caseId);
+        $.ajax({
+            url: '/exportTask',
+            data:data,
+            type: 'POST',
+            processData: false,
+            contentType: false,
+            success: function (result) {
+                if(result != 'success'){
+                    $.notify({
+                        message: result
+                    },{
+                        // settings
+                        delay: 100,
+                        timer: 1000,
+                        type: 'error'
+                    });
+                }else {
+
+                    $.notify({
+                        message: '导出成功'
+                    },{
+                        // settings
+                        delay: 100,
+                        timer: 3000,
+                        type: 'success'
+                    });
+                }
+            }
+        });
+    }
+
 
 
     copyUrl = function(){
     copyUrl = function(){
         var clipboard = new Clipboard('#taskUrl-btn', {
         var clipboard = new Clipboard('#taskUrl-btn', {