Quellcode durchsuchen

Merge branch 'independent-crowd' into 'dev'

Independent crowd



See merge request !5

liwl vor 4 Jahren
Ursprung
Commit
ce085fb10a
31 geänderte Dateien mit 970 neuen und 110 gelöschten Zeilen
  1. 2 3
      pom.xml
  2. 18 2
      src/main/java/com/mooctest/controller/HistoryController.java
  3. 29 11
      src/main/java/com/mooctest/controller/PaperController.java
  4. 1 1
      src/main/java/com/mooctest/controller/ReportController.java
  5. 19 3
      src/main/java/com/mooctest/controller/TaskController.java
  6. 14 0
      src/main/java/com/mooctest/dao/ExtendBugDao.java
  7. 9 0
      src/main/java/com/mooctest/dao/TaskDao.java
  8. 12 0
      src/main/java/com/mooctest/data/BugDTO.java
  9. 3 0
      src/main/java/com/mooctest/data/TaskDTO.java
  10. 53 0
      src/main/java/com/mooctest/model/ExtendBug.java
  11. 11 1
      src/main/java/com/mooctest/model/Task.java
  12. 10 2
      src/main/java/com/mooctest/service/AggregationService.java
  13. 5 1
      src/main/java/com/mooctest/service/BugDataService.java
  14. 202 0
      src/main/java/com/mooctest/service/ExcelInputService.java
  15. 1 0
      src/main/java/com/mooctest/service/FinalReportService.java
  16. 3 0
      src/main/java/com/mooctest/service/GraphService.java
  17. 1 1
      src/main/java/com/mooctest/service/HistoryService.java
  18. 3 1
      src/main/java/com/mooctest/service/MasterReportService.java
  19. 66 43
      src/main/java/com/mooctest/service/TaskService.java
  20. 44 2
      src/main/java/com/mooctest/service/impl/BugReportServiceImpl.java
  21. 2 2
      src/main/java/com/mooctest/util/Doc2VecUtil.java
  22. 6 0
      src/main/java/com/mooctest/util/ReportUtil.java
  23. 416 0
      src/main/resources/templates/add_excel_pro.html
  24. 3 4
      src/main/resources/templates/agg_report_new.html
  25. 3 4
      src/main/resources/templates/aggr_report.html
  26. 9 0
      src/main/resources/templates/paper_list.html
  27. 4 4
      src/main/resources/templates/single_report.html
  28. 10 2
      src/main/resources/templates/task_list.html
  29. 2 16
      src/main/resources/templates/thumbnail/raw_report.html
  30. 4 1
      src/main/resources/templates/thumbnail/sup_report.html
  31. 5 6
      src/main/resources/templates/tree_report_new.html

+ 2 - 3
pom.xml

@@ -173,9 +173,6 @@
             <artifactId>spring-cloud-starter-zookeeper-config</artifactId>
         </dependency>
 
-
-
-
     </dependencies>
 
     <dependencyManagement>
@@ -223,5 +220,7 @@
 
             </plugin>
         </plugins>
+
+
     </build>
 </project>

+ 18 - 2
src/main/java/com/mooctest/controller/HistoryController.java

@@ -91,6 +91,9 @@ public class HistoryController {
 		}
 	}
 
+	
+
+
 	@GetMapping(value = "/tree_list")
 	public String showTreeList(@RequestParam("caseId") long caseId,@RequestParam("examId")  long examId,
 						Model model){
@@ -154,13 +157,20 @@ public class HistoryController {
 		Map<String,String> report2master = masterReportService.getBugIds2Master(masterReportService.getAllMasterIdByExamIdAndCaseId(examId, caseId));
 
 		List<FinalReportDTO> finalReports = finalReportService.getBySourceId(treeId);
+		// 3.bug分类
         model.addAttribute("categoryCounts", categoryCounts);
+		// 2.bug严重性
         model.addAttribute("severityCounts", severityCounts);
-        model.addAttribute("pageCounts",pageCounts);
+		// 4.三级页面
+        model.addAttribute("pageCounts", pageCounts);
+		// 5.复现程度
         model.addAttribute("recurrentCounts",recurrentCounts);
         model.addAttribute("aggReportId", "ML-TR-" + treeId.substring(10)); // 树报告的信息
+		// 6.主要点
         model.addAttribute("masterReport", treeReport);
+		// 1.创建时间
         model.addAttribute("createTime", new Date(Long.parseLong(treeReport.getCreateTimeMillis())));
+		// 7.补充点
         model.addAttribute("supplements", childReports);
         model.addAttribute("finalReports", finalReports);
         model.addAttribute("category2String", ReportUtil.category2String);
@@ -201,14 +211,20 @@ public class HistoryController {
 		List<FinalReportDTO> finalReports = new ArrayList<>();// 暂时还没有finalreport的数据
 		//report to master
 		Map<String,String> report2master = masterReportService.getBugIds2Master(masterReportService.getAllMasterIdByExamIdAndCaseId(examId, caseId));
-
+		// 2.bug严重性
 		model.addAttribute("severityCounts", severityCounts);
+		// 3.bug分类
 		model.addAttribute("categoryCounts", categoryCounts);
+		// 4.三级页面
 		model.addAttribute("pageCounts",pageCounts);
+		// 5.复现程度
 		model.addAttribute("recurrentCounts",recurrentCounts);
 		model.addAttribute("aggReportId", "ML-TR-" + treeId.substring(10)); // 树报告的信息
+		// 6.主要点
 		model.addAttribute("masterReport", treeReport);
+		// 1.创建时间
 		model.addAttribute("createTime", new Date(Long.parseLong(treeReport.getCreateTimeMillis())));
+		// 7.补充点
 		model.addAttribute("supplements", childReports);
 		model.addAttribute("finalReports", finalReports);
 		model.addAttribute("category2String", ReportUtil.category2String);

+ 29 - 11
src/main/java/com/mooctest/controller/PaperController.java

@@ -1,19 +1,21 @@
 package com.mooctest.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.mooctest.service.AuditTaskService;
+import com.mooctest.service.ExcelInputService;
 import com.mooctest.service.PaperService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
 import java.sql.Timestamp;
+import java.util.Map;
 
 @Controller
 public class PaperController {
@@ -23,6 +25,9 @@ public class PaperController {
     @Autowired
     PaperService paperService;
 
+    @Autowired
+    ExcelInputService excelInputService;
+
     private String ITEM_GROUP_NAME = "item_group_list";
 
     @GetMapping("/addPaper")
@@ -36,6 +41,25 @@ public class PaperController {
 //        return "addTask";
 //    }
 
+
+    @GetMapping("/addExcel")
+    public String addExcel (Model model){
+        return "add_excel_pro";
+    }
+
+
+    @PostMapping("/add_excel_pro")
+    @ResponseBody
+    public  String excelToMongo (HttpServletResponse response, @RequestParam("name")String name, @RequestParam("excelFile") MultipartFile multipartFile) throws IOException {
+        // 从前端接收Excel文件,并返回文件保存的全路径
+        String fileFullPath = excelInputService.saveMultipartFile(multipartFile, name);
+        // 拿取文件,并将文件内容插入到Mongo数据库中
+        Map<String, Boolean> is_success = excelInputService.excelToMongo(fileFullPath, name);
+        String  insert_success_json= JSON.toJSONString(is_success);
+        return insert_success_json;
+    }
+
+
     @DeleteMapping("/dpaper")
     @ResponseBody
     public JSONObject deletePaper (Model model ,  @RequestParam("id") String id ){
@@ -79,12 +103,6 @@ public class PaperController {
     }
 
 
-//    @GetMapping("/reloadJob")
-//    @ResponseBody
-//    public JSONObject reloadJob ( Model model, @RequestParam("id") String id ){
-//        JSONObject res = auditTaskService.getSingleTask(id);
-//        return res;
-//    }
 private void changeTime2Long ( Object input){
     JSONObject temp = (JSONObject) input;
     temp.put("create_time",new Timestamp(Long.parseLong(temp.get("create_time").toString()))); // 修改创建时间的格式  以便前段展示

+ 1 - 1
src/main/java/com/mooctest/controller/ReportController.java

@@ -81,7 +81,7 @@ public class ReportController {
         List<BugDTO> sourceReports = bugs.stream().distinct().collect(Collectors.toList());
         // 各种类型的报告数量的统计,
         Map<String, Long> categoryCounts = sourceReports.stream().collect(Collectors.groupingBy(BugDTO::getBugCategory, Collectors.counting()));
-        Map<String, Long> pageCounts =  sourceReports.stream().collect(Collectors.groupingBy(BugDTO::getBug_page,Collectors.counting()));
+        Map<String, Long> pageCounts =  sourceReports.stream().filter(e->e.getBug_page()!=null).collect(Collectors.groupingBy(BugDTO::getBug_page,Collectors.counting()));
         Map<String, Long> recurrentCounts = sourceReports.stream()
                 .map(BugDTO::getRecurrent)
                 .map((recurrentNum) -> ReportUtil.recurrent2String.get(recurrentNum))

+ 19 - 3
src/main/java/com/mooctest/controller/TaskController.java

@@ -5,8 +5,10 @@ import com.mooctest.data.BugDTO;
 import com.mooctest.data.TaskDTO;
 import com.mooctest.model.BugData;
 import com.mooctest.model.MasterReport;
+import com.mooctest.model.Task;
 import com.mooctest.service.*;
 import com.mooctest.util.ReportUtil;
+import org.apache.catalina.tribes.util.Arrays;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Controller;
@@ -45,9 +47,13 @@ public class TaskController {
 
     @GetMapping("/home")
     public String home(Model model) {
-
+        // 获得所有taskDTO,包括本地和慕测端
         List<TaskDTO> tasks = taskService.getAllTasks();
+        List<TaskDTO> localTasks = taskService.findTask();
+        tasks.addAll(localTasks);
+        // 将获得任务传给前端
         model.addAttribute("tasks", tasks);
+        // 转到task_list页面
         return "task_list";
     }
 
@@ -80,15 +86,23 @@ public class TaskController {
     public String taskDetail(@RequestParam("examId") long examId,
                              @RequestParam("caseId") long caseId,
                              Model model) {
-        // first check is there some data in bugData document,
+
+        // first check is there some data in bugData document
+        // 将bug表中的信息同步到BugData中
         bugDataService.importBugData(examId, caseId);//  访问任务的时候同步报告信息
         // after import the bug data
-        boolean aggregated = masterReportService.isAggregated(examId, caseId); // 检查时候已经聚合
+        // 在MasterReport表中查找融合报告的数量,若大于0,则认为已经融合
+        boolean aggregated = masterReportService.isAggregated(examId, caseId); // 检查报告是否已经聚合
+        // 在bug表中查找所有的bug报告数
         List<BugDTO> allReports = bugReportService.getAllBugs(examId, caseId); // 得到所有的报告
+        // 在BugData表中查找bug数据,<bugid,BugData>
         Map<String , BugData> bugIds2Data = bugDataService.bugId2BugData(examId, caseId);
+        // 将单一状报告转化成树状
         Map<String,String> single2rootMap = historyService.getSingle2Root(caseId, examId);
+        // 若被融合
         if (aggregated) { // add the information that where present when reports have been aggregated
             List<String> bugIds = allReports.stream().map(BugDTO::getId).collect(Collectors.toList());
+            // MasterReport表中获得所有的报告
             List<MasterReport> mrs = masterReportService.getByBugIds(bugIds);
             Map<String, MasterReport> mrMap = mrs.stream().collect(toMap(MasterReport::getBugId, Function.identity()));
             allReports.forEach(bug -> {
@@ -102,8 +116,10 @@ public class TaskController {
             bug.setReviewerId(bugIds2Data.get(bug.getId()).getReviewerId());
         });
 
+        // 从json中获得的task数据保存到TaskDTO中返回
         TaskDTO task = taskService.getByExamIdAndCaseId(examId, caseId);
         model.addAttribute("aggregated", aggregated);
+        // allReport是ButDTO集合
         model.addAttribute("allReports", allReports);
         model.addAttribute("severity2String", ReportUtil.severity2String);
         model.addAttribute("recurrent2String", ReportUtil.recurrent2String);

+ 14 - 0
src/main/java/com/mooctest/dao/ExtendBugDao.java

@@ -0,0 +1,14 @@
+package com.mooctest.dao;
+
+
+import com.mooctest.cluster.Document;
+import com.mooctest.model.Bug;
+import com.mooctest.model.ExtendBug;
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+import java.util.List;
+
+public interface ExtendBugDao extends MongoRepository<ExtendBug, Long> {
+    List<ExtendBug> findByExamCaseId(String examTakeId);
+
+}

+ 9 - 0
src/main/java/com/mooctest/dao/TaskDao.java

@@ -0,0 +1,9 @@
+package com.mooctest.dao;
+
+import com.mooctest.model.ExtendBug;
+import com.mooctest.model.Task;
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+public interface TaskDao extends MongoRepository<Task, Long> {
+}
+

+ 12 - 0
src/main/java/com/mooctest/data/BugDTO.java

@@ -7,6 +7,17 @@ import lombok.NoArgsConstructor;
 
 import java.util.List;
 
+/**
+ * @Data
+ * 使用这个注解,就不用再去手写Getter,Setter,equals,canEqual,hasCode,toString等方法了,注解后在编译时会自动加进去。
+ * @AllArgsConstructor
+ * 使用后添加一个构造函数,该构造函数含有所有已声明字段属性参数
+ * @NoArgsConstructor
+ * 使用后创建一个无参构造函数
+ * @Builder
+ * 关于Builder较为复杂一些,Builder的作用之一是为了解决在某个类有很多构造函数的情况,也省去写很多构造函数的麻烦,在设计模式中的思想是:用一个内部类去实例化一个对象,避免一个类出现过多构造函数,
+ */
+
 @Builder(toBuilder = true)
 @AllArgsConstructor
 @NoArgsConstructor
@@ -28,4 +39,5 @@ public class BugDTO{
     private String masterId;
     private String treeId;
     private String bug_page;
+    private String title;
 }

+ 3 - 0
src/main/java/com/mooctest/data/TaskDTO.java

@@ -1,10 +1,12 @@
 package com.mooctest.data;
 
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 @Data
+@Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class TaskDTO {
@@ -18,4 +20,5 @@ public class TaskDTO {
     private String endTime;
     private long numOfTotalBug;
     private long numOfUndeal;
+
 }

+ 53 - 0
src/main/java/com/mooctest/model/ExtendBug.java

@@ -0,0 +1,53 @@
+package com.mooctest.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.mongodb.core.mapping.Field;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Document(collection = "ExtendBug")
+public class ExtendBug {
+    @Id
+    private String id;
+
+    @Field("exam_id")
+    private String examId;
+
+    @Field("case_id")
+    private String caseId;
+
+    private String title;
+
+    @Field("report_id")
+    private String reportId;
+
+    @Field("bug_category")
+    private String bugCategory;
+
+    private short severity;
+
+    private short recurrent;
+
+    private String description;
+
+    @Field("img_url")
+    private String imgUrls;
+
+    @Field("exam_case_id")
+    private String examCaseId;
+
+    @Field("create_time_millis")
+    private String createTimeMillis;
+
+    @Field("bug_page")
+    private String bugPage;
+
+
+}

+ 11 - 1
src/main/java/com/mooctest/model/Task.java

@@ -3,13 +3,15 @@ package com.mooctest.model;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.mapping.Document;
 
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
+@Document(collection = "Task")
 public class Task {
 
-    private long examId;
+    private long taskId;
     private long caseId;
     private String name;
     private String icon;
@@ -17,4 +19,12 @@ public class Task {
     private int status;
     private String startTime;
     private String endTime;
+
+    public Task(long taskId, long caseId, String name) {
+        this.taskId = taskId;
+        this.caseId = caseId;
+        this.name = name;
+    }
+
+
 }

+ 10 - 2
src/main/java/com/mooctest/service/AggregationService.java

@@ -22,7 +22,7 @@ import java.util.stream.Collectors;
 import static java.util.stream.Collectors.toMap;
 
 @Service
-public class AggregationService {
+public class  AggregationService {
     @Autowired
     BugReportService bugReportService;
 
@@ -39,20 +39,28 @@ public class AggregationService {
     SupplementService supplementService;
 
     public void aggregate(long examId, long caseId) {
+        // 下载图片
         downImg(examId, caseId);
+        // 获得bug队列
         List<BugDTO> bugs = bugReportService.getAllBugs(examId, caseId);
 
         ClusterAnalyzer<String> analyzer = new ClusterAnalyzer<>();
+        // 获得bugid队列
         List<String> bugIds = bugs.stream().map(BugDTO::getId).collect(Collectors.toList());
+        // 获得分配矩阵
         double[][] distMatrix = DistanceMatrix.genHybridDist(bugs);
+        // 获得聚合队列
         List<Set<String>> clusters = analyzer.HAC(distMatrix, bugIds, 0.23); // H 太大了
-
+        // 构建bug映射
         Map<String, BugDTO> bugMap = bugs.stream().collect(toMap(BugDTO::getId, Function.identity()));
         bugs = null;
+        // 构建主要聚合map映射
         Map<String, Set<String>> masterClusterMap = new HashMap<>();
         masterReportService.deleteAll(examId, caseId);
         for (Set<String> cluster : clusters) {
+            // 主要报告
             String masterReport = masterReportService.findMasterReport(cluster, bugMap);
+            // 储存主要报告
             masterReportService.saveMasterReport(masterReport, examId, caseId, cluster);
             masterClusterMap.put(masterReport, cluster);
         }

+ 5 - 1
src/main/java/com/mooctest/service/BugDataService.java

@@ -14,7 +14,7 @@ import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Service
-public class BugDataService {
+public class    BugDataService {
 
     @Autowired
     BugDataDao bugDataDao ;
@@ -79,13 +79,17 @@ public class BugDataService {
         return bugDataDao.findByExamIdAndCaseId(examId, caseId);
     }
 
+    // 检查bug表中的bug报告数据和BugData数据是否一致,若BugData表中缺少数据,则导入BugData
     public void importBugData ( long examId , long caseId){
+        // 通过Exam_case_id获得bug报告数量
         long count = bugDataDao.countByExamIdAndCaseId(examId, caseId);
+        // 获得所有的bug报告,在bug表中找到相应的bug报告
         List<BugDTO> bugs = bugReportService.getAllBugs(examId, caseId);
 
         if(bugs.size()!=count){
             // 报告数量不一致 , 重新引入
             List<BugData> savedBugs = bugDataDao.findByExamIdAndCaseId( examId,  caseId);
+            // ?
             List<String > bugIds = savedBugs.stream().map(BugData::getBugId).collect(Collectors.toList());
             List<BugData> toSave = new ArrayList<>();
             bugs.forEach(s->{

+ 202 - 0
src/main/java/com/mooctest/service/ExcelInputService.java

@@ -0,0 +1,202 @@
+package com.mooctest.service;
+
+import com.mooctest.dao.ExtendBugDao;
+import com.mooctest.dao.TaskDao;
+import com.mooctest.event.EventUtil;
+import com.mooctest.model.ExtendBug;
+import com.mooctest.model.Task;
+import org.apache.commons.io.IOUtils;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.bson.Document;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+import java.util.*;
+
+@Service
+public class ExcelInputService {
+
+    private static Logger logger = LoggerFactory.getLogger(EventUtil.class);
+
+
+    @Autowired
+    TaskDao taskDao;
+
+    @Autowired
+    ExtendBugDao extendBugDao;
+
+    // 接收前端文件,并将MultipartFile文件转换成File文件,并返回文件路径
+    public String saveMultipartFile(MultipartFile file, String fileSaveName){
+        OutputStream os = null;
+        String fileFullPath = null;
+        String fileName = file.getOriginalFilename();
+        try (
+                InputStream inputStream  = file.getInputStream();
+        ) {
+            String path = System.getProperty("user.dir");
+            // 2、保存到临时文件
+            // 1K的数据缓冲
+            byte[] bs = new byte[1024];
+            // 读取到的数据长度
+            int len;
+            // 输出的文件流保存到本地文件
+            File tempFile = new File(path);
+            if (!tempFile.exists()) {
+                tempFile.mkdirs();
+            }
+            fileFullPath = tempFile.getPath() + File.separator + fileName;
+            os = new FileOutputStream(fileFullPath);
+            // 开始读取
+            while ((len = inputStream.read(bs)) != -1) {
+                os.write(bs, 0, len);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }finally {
+            IOUtils.closeQuietly(os);
+        }
+        return fileFullPath;
+    }
+
+
+    // 解析File文件,并将为数据库表中各字段赋值,并将数据数据插入数据库中
+    public Map<String, Boolean> excelToMongo(String address, String fileSaveName) {
+        Integer orderId=UUID.randomUUID().toString().hashCode();
+        orderId = orderId < 0 ? -orderId : orderId;
+        Long task_id = Long.valueOf(orderId);
+        Long case_id = task_id;
+        String task_name = fileSaveName;
+        List<String> fieldList = null;
+        Task task = new Task(task_id, case_id, task_name);
+        taskDao.save(task);
+        Map<String, Boolean> insert_map = new HashMap<>();
+
+        try {
+            // 输入文件
+            FileInputStream inputStream = new FileInputStream(address);
+            // 根据输入流导入Excel产生Workbook对象
+            Workbook workbook = new HSSFWorkbook(inputStream);
+
+
+            fieldList = new ArrayList<String>();
+            // 获取Excel文档中第一个表单
+            Sheet sheet = workbook.getSheetAt(0);
+            // 获取表单第一行作为表头
+            Row topRow = sheet.getRow(0);
+            if (topRow == null) {
+                insert_map.put("file_is_null", true);
+                insert_map.put("insert_success", false);
+                return insert_map;
+            } else {
+                insert_map.put("file_is_null", false);
+
+            }
+            for (Cell cell : topRow) {
+                fieldList.add(cell.toString());
+            }
+
+            logger.info("文件列表" + fieldList);
+            // 获得表单的行数
+            int rows = sheet.getLastRowNum() + 1;
+
+            // 获得每行的列数
+            int colunms = fieldList.size();
+            // 从第二行开始遍历表格
+            for (int i = 1; i < rows; i++) {
+                ExtendBug extendBug = new ExtendBug();
+                Row row = sheet.getRow(i);
+                String exam_case_id = task_id+"-"+ case_id;
+                long create_time_millis = System.currentTimeMillis();
+                extendBug.setBugCategory("空");
+                extendBug.setSeverity((short) 0);
+                extendBug.setRecurrent((short) 0);
+                extendBug.setTitle("空");
+                extendBug.setDescription("空");
+                extendBug.setExamId(task_id+"");
+                extendBug.setCaseId(case_id+"");
+                extendBug.setExamCaseId(exam_case_id);
+                extendBug.setCreateTimeMillis(create_time_millis+"");
+                // 每行从第一列开始遍历列
+                /**
+                 * 表格中字段的顺序必须是title、bug_category、severity、recurrent、description
+                 */
+                for (int j = 0; j < colunms; j++) {
+                    Cell cell = row.getCell(j);
+                    String topName = fieldList.get(j);
+                    if(topName.equals("title") || topName.equals("题目")){
+                        String title;
+                        if(cell == null || cell.toString().equals("")){
+                            title = "空";
+                        }else{
+                            title = cell.toString();
+                        }
+                        extendBug.setTitle(title);
+                    }else if(topName.equals("bug_category") || topName.equals("分类")){
+                        String bug_category;
+                        if(cell == null || cell.toString().equals("")){
+                            bug_category = "空";
+                        }else{
+                            bug_category = cell.toString();
+                        }
+                        extendBug.setBugCategory(bug_category);
+                    }else if(topName.equals("severity") || topName.equals("严重等级")){
+                        int num;
+                        if(cell == null || cell.toString().equals("")){
+                            num = 0;
+                        }else{
+                            num = new Double(Double.parseDouble(cell.toString())).intValue();
+                        }
+                        short severity = (short)num;
+                        extendBug.setSeverity(severity);
+                    }else if(topName.equals("recurrent") || topName.equals("复现程度")){
+                        int num;
+                        if(cell == null || cell.toString().equals("")){
+                            num = 0;
+                        }else{
+                            num = new Double(Double.parseDouble(cell.toString())).intValue();
+                        }
+                        short recurrent = (short)num;
+                        extendBug.setRecurrent(recurrent);
+                    }else{
+                        String description;
+                        if(cell == null || cell.toString().equals("")){
+                            description = "空";
+                        }else{
+                            description = cell.toString();
+                        }
+
+                        extendBug.setDescription(description);
+                    }
+
+                }
+                System.out.println(extendBug);
+                extendBugDao.save(extendBug);
+            }
+            logger.info("文件导入成功!");
+            // 导入成功后将本地文件夹删除
+            File file = new File(address);
+            file.delete();
+            insert_map.put("insert_success", true);
+            return insert_map;
+        } catch (FileNotFoundException e) {
+            logger.info(e.getMessage());
+            insert_map.put("insert_success", false);
+            return insert_map;
+        } catch (IOException e) {
+            logger.info(e.getMessage());
+            insert_map.put("file_is_null", true);
+            insert_map.put("insert_success", false);
+            return insert_map;
+        }
+    }
+}

+ 1 - 0
src/main/java/com/mooctest/service/FinalReportService.java

@@ -45,6 +45,7 @@ public class FinalReportService {
         BeanUtils.copyProperties(dto, finalReport);
         finalReport.setImgUrls(String.join(",", dto.getImgUrls()));
         finalReport.setCreateTime(new Date());
+        // 将创建的报告保存到FinalReport表中
         finalReport = finalReportDao.save(finalReport);
         BeanUtils.copyProperties(finalReport, dto);
 //        try {

+ 3 - 0
src/main/java/com/mooctest/service/GraphService.java

@@ -153,6 +153,7 @@ public class GraphService {
             JSONObject node = new JSONObject();
 
             //add sup report node
+            // 连续插入元素
             node.fluentPut("id", supId)
                     .fluentPut("group", 2)
                     .fluentPut("name", "Sup-" + idx)
@@ -177,6 +178,7 @@ public class GraphService {
             idx++;
         }
         JSONObject aggReportNode = new JSONObject();
+
         aggReportNode.fluentPut("id", "agg_" + masterId)
                 .fluentPut("group", 1)
                 .fluentPut("name", "ML-AG-" + masterId.substring(10))
@@ -184,6 +186,7 @@ public class GraphService {
         nodes.add(aggReportNode);
 
         JSONObject masterNode = new JSONObject();
+        // 连续插入元素
         masterNode.fluentPut("id", masterId)
                 .fluentPut("group", 2.1)
                 .fluentPut("name", "Master-ML-" + masterId.substring(10))

+ 1 - 1
src/main/java/com/mooctest/service/HistoryService.java

@@ -35,7 +35,7 @@ public class HistoryService {
 	//获得 单一报告对树状报告的map
 	public Map<String,String> getSingle2Root(long caseId,long examId){
 		List<String> treeRootids = getTreeRoots(caseId+"-"+examId); // 获得所有的根结点的id
-		Map<String , List<String >> tree2BugIdsMap = getTree2BugIdsMap(treeRootids);
+		Map< String , List<String> > tree2BugIdsMap = getTree2BugIdsMap(treeRootids);
 		Map<String ,String > res = new HashedMap<>();
 		tree2BugIdsMap.forEach((k,v)->{
 			v.forEach(s->{

+ 3 - 1
src/main/java/com/mooctest/service/MasterReportService.java

@@ -41,7 +41,9 @@ public class MasterReportService {
         DirectedWeightedPseudograph<String, DefaultWeightedEdge> g =
                 new DirectedWeightedPseudograph<>(DefaultWeightedEdge.class);
 
-        cluster.forEach(bugId -> g.addVertex(bugId));
+        cluster.forEach(bugId -> {
+            g.addVertex(bugId);
+        });
 
         cluster.forEach(outBugId -> {
             cluster.forEach(inBugId -> {

+ 66 - 43
src/main/java/com/mooctest/service/TaskService.java

@@ -3,11 +3,17 @@ package com.mooctest.service;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 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.TaskDao;
 import com.mooctest.data.TaskDTO;
-import com.mooctest.model.BugData;
 import com.mooctest.model.Task;
 import com.mooctest.util.TimeUtil;
+import org.bson.Document;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -44,6 +50,9 @@ public class TaskService {
     MasterReportDao masterReportDao;
 
     @Autowired
+    TaskDao taskDao;
+
+    @Autowired
     BugReportService bugReportService;
 
     @Autowired
@@ -60,44 +69,97 @@ public class TaskService {
     private final String HTTP = "http://";
 
 
+    // 获得所有任务
     public List<TaskDTO> getAllTasks() {
+        // 传统情况下在java代码里访问restful服务,一般使用Apache的HttpClient。不过此种方法使用起来太过繁琐。
+        // spring提供了一种简单便捷的模板类来进行操作,这就是RestTemplate。
         RestTemplate rt = new RestTemplate();
+        // springMVC通过StringHttpMessageConverter将Controller的返回对象转为字符串
         StringHttpMessageConverter stringHttpMessageConverter=new StringHttpMessageConverter(Charset.forName("UTF-8"));
         List<HttpMessageConverter<?>> list=new ArrayList<HttpMessageConverter<?>>();
         list.add(stringHttpMessageConverter);
         rt.setMessageConverters(list);
+        // 将获得task字符船以json格式解析
         JSONObject tasksJson = JSON.parseObject(rt.getForObject(taskInfoAddr, String.class));
+        // 获得tasksJson中的“data”字段的迭代器
         ListIterator<Object> tasksIter = tasksJson.getJSONArray("data").listIterator();
-
+        // 新建TaskDTO队列,TaskDTO没有持久化处理
         List<TaskDTO> dtos = new ArrayList<>();
+        // 遍历taskJson中“data“
         while (tasksIter.hasNext()) {
+            // 获得每个”data“对象
             JSONObject taskInfo = (JSONObject) tasksIter.next();
-
             TaskDTO dto = new TaskDTO();
+            // 将获得的每个taskJson的exam_id,case_id,name赋给taskdto
             dto.setExamId(Long.parseLong(taskInfo.getString("task_id")));
             dto.setCaseId(Long.parseLong(taskInfo.getString("case_id")));
             dto.setName(taskInfo.getString("name"));
-
+            // 将taskdto加入taskdtos队列
             dtos.add(dto);
         }
 
+
+        // return中是给taskDTO各个属性赋值的过程
         return dtos.stream()
                 .map(taskDTO -> {
+                    // 获得报告数量
+                    long totalBugs = bugDataService.getReportNum(taskDTO.getExamId(),taskDTO.getCaseId());
+                    // 设没有处理的Bug数为0
+                    long undealBugs = 0;
+                    // 如果总Bug报告数为0(没有初始化),将没有处理的报告数设置为报告总数
+                    if (totalBugs == 0) {
+                        totalBugs = bugReportService.getAllBugs(taskDTO.getExamId(), taskDTO.getCaseId()).size();
+                        undealBugs = totalBugs;
+                    } else {
+                        // 否则将获得没有处理的报告数
+                        undealBugs = bugDataService.getReportUnDealNum(taskDTO.getExamId(),taskDTO.getCaseId());
+                    }
+                    // 给taskDTO的总bug数和为处理的bug数赋值
+                    taskDTO.setNumOfTotalBug(totalBugs);
+                    taskDTO.setNumOfUndeal(undealBugs);
+                    return taskDTO;
+                }).sorted(Comparator.comparing(TaskDTO::getExamId).reversed())
+                .collect(Collectors.toList());
+    }
+
+
+    // 在本地获得task方法
+    public List<TaskDTO> findTask() {
+        List<TaskDTO> taskDTOs = new ArrayList<>();
+
+        List<Task> tasks = taskDao.findAll();
+        for (Task task: tasks) {
+            TaskDTO taskDTO =  TaskDTO.builder().examId((long) task.getTaskId()).caseId( (long) task.getCaseId()).name(task.getName()).build();
+            taskDTOs.add(taskDTO);
+
+        }
+
+
+        return taskDTOs.stream()
+                .map(taskDTO -> {
+                    // 获得报告数量
                     long totalBugs = bugDataService.getReportNum(taskDTO.getExamId(),taskDTO.getCaseId());
+                    // 设没有处理的Bug数为0
                     long undealBugs = 0;
+                    // 如果总Bug报告数为0(没有初始化),将没有处理的报告数设置为报告总数
                     if (totalBugs == 0) {
                         totalBugs = bugReportService.getAllBugs(taskDTO.getExamId(), taskDTO.getCaseId()).size();
                         undealBugs = totalBugs;
                     } else {
+                        // 否则将获得没有处理的报告数
                         undealBugs = bugDataService.getReportUnDealNum(taskDTO.getExamId(),taskDTO.getCaseId());
                     }
+                    // 给taskDTO的总bug数和为处理的bug数赋值
                     taskDTO.setNumOfTotalBug(totalBugs);
                     taskDTO.setNumOfUndeal(undealBugs);
                     return taskDTO;
                 }).sorted(Comparator.comparing(TaskDTO::getExamId).reversed())
                 .collect(Collectors.toList());
+
     }
 
+
+
     public List<TaskDTO> getAllTasks2() {
         return tasks.stream()
                 .map(task -> {
@@ -147,45 +209,6 @@ public class TaskService {
         return  tasksJson;
     }
 
-//    public List<TaskDTO> getAllTasks() {
-//        RestTemplate rt = new RestTemplate();
-//        StringHttpMessageConverter stringHttpMessageConverter=new StringHttpMessageConverter(Charset.forName("UTF-8"));
-//        List<HttpMessageConverter<?>> list=new ArrayList<HttpMessageConverter<?>>();
-//        list.add(stringHttpMessageConverter);
-//        rt.setMessageConverters(list);
-//        JSONObject tasksJson = JSON.parseObject(rt.getForObject(taskInfoAddr, String.class));
-//        ListIterator<Object> tasksIter = tasksJson.getJSONArray("data").listIterator();
-//
-//        List<TaskDTO> dtos = new ArrayList<>();
-//        while (tasksIter.hasNext()) {
-//            JSONObject taskInfo = (JSONObject) tasksIter.next();
-//
-//            TaskDTO dto = new TaskDTO();
-//            dto.setExamId(Long.parseLong(taskInfo.getString("task_id")));
-//            dto.setCaseId(Long.parseLong(taskInfo.getString("case_id")));
-//            dto.setName(taskInfo.getString("name"));
-//
-//            dtos.add(dto);
-//        }
-//
-//        return dtos.stream()
-//                .map(taskDTO -> {
-//                    long totalBugs = masterReportDao.countByExamIdAndCaseId(taskDTO.getExamId(), taskDTO.getCaseId());
-//                    long undealBugs = 0;
-//                    if (totalBugs == 0) {
-//                        totalBugs = bugReportService.getAllBugs(taskDTO.getExamId(), taskDTO.getCaseId()).size();
-//                        undealBugs = totalBugs;
-//                    } else {
-//                        undealBugs = masterReportDao.countByExamIdAndCaseIdAndStatus(taskDTO.getExamId(), taskDTO.getCaseId(), 0);
-//                    }
-//                    taskDTO.setNumOfTotalBug(totalBugs);
-//                    taskDTO.setNumOfUndeal(undealBugs);
-//
-//                    return taskDTO;
-//                }).sorted(Comparator.comparing(TaskDTO::getExamId).reversed())
-//                .collect(Collectors.toList());
-//
-//    }
 
     public boolean distribute(String examId,String caseId){
         RestTemplate template = new RestTemplate();

+ 44 - 2
src/main/java/com/mooctest/service/impl/BugReportServiceImpl.java

@@ -2,10 +2,12 @@ package com.mooctest.service.impl;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.mooctest.dao.ExtendBugDao;
 import com.mooctest.dao2.BugDao;
 import com.mooctest.data.BugDTO;
 import com.mooctest.data.ReportDTO;
 import com.mooctest.model.Bug;
+import com.mooctest.model.ExtendBug;
 import com.mooctest.service.BugReportService;
 import com.mooctest.util.HttpUtil;
 import com.mooctest.util.MongoAPIUtil;
@@ -33,6 +35,9 @@ public class BugReportServiceImpl implements BugReportService {
     @Autowired
     BugDao bugDao;
 
+    @Autowired
+    ExtendBugDao extendBugDao;
+
     public List<ReportDTO> getReports(long examId, long caseId) {
 
         HttpHeaders headers = MongoAPIUtil.createAuthHeaderForMongo();
@@ -74,7 +79,13 @@ public class BugReportServiceImpl implements BugReportService {
     public List<BugDTO> getAllBugs(long examId, long caseId) {
         String caseTakeId = caseId + "-" + examId;
         List<Bug> bugs = bugDao.findByCaseTakeId(caseTakeId);
-        return wrapList(bugs);
+        List<ExtendBug> extendBugs = extendBugDao.findByExamCaseId(caseTakeId);
+        List<BugDTO> extendBugDTOs = wrapListe(extendBugs);
+        List<BugDTO> bugDTOs = wrapList(bugs);
+        extendBugDTOs.addAll(bugDTOs);
+//        bugs.addAll(extendBugs);
+//        return wrapList(bugs);
+        return extendBugDTOs;
     }
 
     private List<BugDTO> wrapList(List<Bug> bugs) {
@@ -84,6 +95,13 @@ public class BugReportServiceImpl implements BugReportService {
                 .collect(Collectors.toList());
     }
 
+    private List<BugDTO> wrapListe(List<ExtendBug> bugs) {
+
+        return bugs.parallelStream()
+                .map(bug -> wrap(bug))
+                .collect(Collectors.toList());
+    }
+
     private BugDTO wrap(Bug bug) {
         String[] imgUrls = new String[0];
         if (bug.getImgUrls() != null && !bug.getImgUrls().equals("")) {
@@ -103,6 +121,25 @@ public class BugReportServiceImpl implements BugReportService {
                 .build();
     }
 
+    private BugDTO wrap(ExtendBug bug) {
+        String[] imgUrls = new String[0];
+        if (bug.getImgUrls() != null && !bug.getImgUrls().equals("")) {
+
+            imgUrls = bug.getImgUrls().split(",");
+        }
+        return BugDTO.builder()
+                .id(bug.getId())
+                .bugCategory(bug.getBugCategory())
+                .caseTakeId(bug.getExamCaseId())
+                .createTimeMillis(bug.getCreateTimeMillis())
+                .description(bug.getDescription())
+                .imgUrls(imgUrls)
+                .recurrent(bug.getRecurrent())
+                .severity(bug.getSeverity())
+                .bug_page(bug.getBugPage())
+                .build();
+    }
+
     public Map<String, BugDTO> getAllBugsMap(long examId, long caseId) {
         List<BugDTO> bugs = getAllBugs(examId, caseId);
         return bugs.stream().collect(toMap(BugDTO::getId, Function.identity()));
@@ -118,7 +155,12 @@ public class BugReportServiceImpl implements BugReportService {
 
     public BugDTO getBugById(String bugId, long examId, long caseId) {
         Bug bug = bugDao.findById(bugId).orElse(null);
-        return wrap(bug);
+        if(bug == null){
+            ExtendBug extendBug = extendBugDao.findById(Long.valueOf(bugId)).orElse(null);
+            return wrap(extendBug);
+        }else {
+            return wrap(bug);
+        }
     }
 
     @Override

+ 2 - 2
src/main/java/com/mooctest/util/Doc2VecUtil.java

@@ -15,8 +15,8 @@ public class Doc2VecUtil {
             synchronized (Doc2VecUtil.class) {
                 if (docVectorModel == null) {
                     try {
-                        docVectorModel = new DocVectorModel(new WordVectorModel("/project/sgns.wiki.word"));
-//                        docVectorModel = new DocVectorModel(new  WordVectorModel("/Users/insomnialee/Desktop/sgns.wiki.word"));
+//                        docVectorModel = new DocVectorModel(new WordVectorModel("D:\\work\\project\\yanbaoronghe\\data\\sgns.wiki.word"));
+                        docVectorModel = new DocVectorModel(new  WordVectorModel("/project/sgns.wiki.word"));
                     } catch (IOException e) {
                         e.printStackTrace();
                     }

+ 6 - 0
src/main/java/com/mooctest/util/ReportUtil.java

@@ -10,6 +10,7 @@ public class ReportUtil {
             put((short)3, "一般");
             put((short)2, "较轻");
             put((short)1, "待定");
+            put((short)0, "空");
     }};
 
     public static Map<Integer, String> category2String = new HashMap<Integer, String>() {{
@@ -20,6 +21,8 @@ public class ReportUtil {
         put(1, "安全");
         put(6, "不正常退出");
         put(7, "其他");
+        put(0, "空");
+
     }};
 
     public static Map<String, Integer> string2Category = new HashMap<String, Integer>() {{
@@ -30,6 +33,7 @@ public class ReportUtil {
         put("安全", 1);
         put("不正常退出", 6);
         put("其他", 7);
+        put("空", 0);
     }};
 
     public static Map<Short, String> recurrent2String = new HashMap<Short, String>() {{
@@ -38,6 +42,8 @@ public class ReportUtil {
         put((short)3, "小概率复现");
         put((short)2, "无规律复现");
         put((short)1, "其他");
+        put((short)0, "空");
+
     }};
 
     public static Map<Long, String> reviewerMap = new HashMap<Long, String>() {{

+ 416 - 0
src/main/resources/templates/add_excel_pro.html

@@ -0,0 +1,416 @@
+<!DOCTYPE html>
+<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"
+      xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
+      layout:decorator="base">
+<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"/>
+
+
+    <style>
+        body {
+            padding-right: 0px !important;
+        }
+        *.modal-open {
+            overflow-y: scroll;
+            padding-right: 0 !important;
+        }
+        .content {
+            padding-left: 45px;
+            padding-right: 45px;
+        }
+        .box {
+            margin-bottom: 50px;
+        }
+        .box-header button{
+            margin-right: 5px;
+        }
+        .table tr td {
+            padding-right: 10px;
+            padding-left: 10px;
+            border-top: 1px solid #f4f4f4;
+            border-right: 1px solid #f4f4f4;
+        }
+
+        td .form-group {
+            margin-bottom: 0px;
+        }
+    </style>
+</head>
+<body>
+<div layout:fragment="mainbody">
+
+
+
+    <aside class="main-sidebar">
+        <section class="sidebar">
+            <div class="user-panel">
+                <div class="pull-left image">
+                    <img src="/static/images/avatar/avatar-admin.jpg" class="img-circle" alt="User Image" />
+                </div>
+                <div class="pull-left info">
+                    <p>Admin</p>
+                    <a href="#">
+                        <i class="fa fa-circle text-success"></i>
+                        Online
+                    </a>
+                </div>
+            </div>
+
+            <!-- Search form -->
+            <form action="#" method="get" class="sidebar-form">
+                <div class="input-group">
+                    <input type="text" name="q" class="form-control" placeholder="Search..." />
+                    <span class="input-group-btn">
+						<button type="submit" name="search" id="search-btn" class="btn btn-flat">
+							<i class="fa fa-search"></i>
+						</button>
+					</span>
+                </div>
+            </form>
+
+            <!-- Sidebar Menu -->
+            <ul class="sidebar-menu tree" data-widget="tree">
+                <li>
+                    <a href="/addPaper">
+                        <i class="glyphicon glyphicon-pencil"></i>
+                        <span>
+                            新建试卷
+                        </span>
+                    </a>
+                </li>
+
+                <li>
+                    <a href="/papers">
+                        <i class="glyphicon glyphicon-tasks"></i>
+                        <span>
+                            试卷列表
+                        </span>
+                    </a>
+                </li>
+                <li>
+                    <a href="/review/jobs">
+                        <i class="glyphicon glyphicon-tasks"></i>
+                        <span>
+                            JOB列表
+                        </span>
+                    </a>
+                </li>
+
+            </ul>
+
+
+        </section>
+    </aside>
+
+
+    <div class="content-wrapper">
+        <!-- Content Header (Page header) -->
+        <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="/addTask">新建试卷</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>
+               </div>
+
+                <div class="box-body">
+                    <form id="form" action="/excelToMongo" class="form-horizontal"  method="post" enctype="multipart/form-data">
+                        <!-- text input -->
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label">名称</label>
+                            <div class="col-sm-10">
+                                <input type="text" class="form-control" id="name" name="name" onblur="checkName()" />
+                                <span name="name_span" style="color: #ff0000"></span>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label   class="col-sm-2 control-label">导入Bug文件</label>
+                            <div class="col-sm-10">
+                                <a  href="http://crowdtest-data.oss-cn-hangzhou.aliyuncs.com/%E6%A8%A1%E6%9D%BF%E6%96%87%E4%BB%B6.xls">文件模板</a>
+                                <input  type="file"  id="excel_file" name="excelFile" onchange="checkFile()" />
+                                <span name="file_span" style="color: #ff0000"></span>
+                            </div>
+                        </div>
+                        <span id="submit_span"></span>
+                        <input class="btn btn-success pull-right" type="button" value="提交" id="submit_file" onmousemove="checkSubmit()" onclick="check_success()">
+                    </form>
+                </div>
+            </div>
+
+
+
+
+        </section>
+
+    </div>
+
+
+    <div class="modal fade" id="modal-default">
+        <div class="modal-dialog">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span></button>
+                    <h4 class="modal-title">预览</h4>
+                </div>
+                <div class="modal-body" id="modalBody">
+                    <form class="form-horizontal" id="formBody">
+
+                    </form>
+
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-default pull-left" data-dismiss="modal">关闭</button>
+                    <!--                    <button type="button" class="btn btn-primary"></button>-->
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="modal fade" id="modal-alert">
+        <div class="modal-dialog">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span></button>
+                    <h4 class="modal-title">预览</h4>
+                </div>
+                <div class="modal-body" id="modalAlertBody">
+                    <form class="form-horizontal" id="formAlertBody">
+
+                    </form>
+
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-default pull-left" data-dismiss="modal">关闭</button>
+                </div>
+            </div>
+        </div>
+    </div>
+
+
+
+
+    <div class="modal fade" id="modal-reload">
+        <div class="modal-dialog">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span></button>
+                    <h4 class="modal-title">从已有任务加载数据</h4>
+                </div>
+                <div class="modal-body" >
+                    <form class="form-horizontal" >
+                        <div class="form-group">
+                            <label class="col-sm-2 control-label">JobId</label>
+                            <div class="col-sm-10">
+                                <input  onchange="checkNull(event)" class="form-control" id="jobid" placeholder="请输入任务名称"/>
+                            </div>
+                        </div>
+                    </form>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-default pull-left" data-dismiss="modal">关闭</button>
+                    <button type="button" class="btn btn-primary" onclick="reloadJob()">确认</button>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+
+</body>
+</html>
+
+<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>
+<!-- AdminLTE App -->
+<!--<script src="/static/AdminLTE/dist/js/adminlte.min.js"></script>-->
+<!-- AdminLTE for demo purposes -->
+<script src="/static/AdminLTE/dist/js/demo.js"></script>
+<!-- add Task js for this file only -->
+<script src="/static/js/add_paper.js"></script>
+<script src="/static/AdminLTE/bower_components/bootstrap-notify/dist/bootstrap-notify.min.js"></script>
+<script type="text/javascript" src="http://www.jq22.com/demo/clipboard.js-master201703170013/dist/clipboard.min.js"></script>
+
+<script  type="text/javascript" xmlns:th="http://www.thymeleaf.org" th:inline="javascript">
+
+
+    var ruleId ;
+    var ratioIndex;
+    /*<![CDATA[*/
+    var reportHost = [[${reportHost}]]
+    /*]]>*/
+
+    var name_flag = false;
+    var file_flag = false;
+
+    $(document).ready(function(){
+        $('[data-toggle="tooltip"]').tooltip();
+        //Initialize Select2 Elements
+        $('.select2').select2()
+        ruleId = 0;
+        ratioIndex =0 ;
+        var taskListTable = $('#task-list').DataTable({
+            searching: true,
+            pageLength: 25
+        });
+    });
+
+
+
+
+
+    function checkFile() {
+        var fileName = document.getElementsByName("excelFile")[0].value;
+        console.info(fileName)
+        var index = fileName.lastIndexOf(".");
+        var file_type = fileName.substr(index+1);
+        var file_span = document.getElementsByName("file_span")[0];
+
+        var file = document.getElementById("excel_file").files[0];
+        var file_size=file.size;//文件的字节数
+
+
+        if(file_type != "xls" && file_type != "xlsx"){
+            file_span.innerText="文件类型错误,请导入excel文件";
+            file_flag = false;
+        }else {
+            file_span.innerText="";
+            if(file_size > 1048576){
+                file_span.innerText="文件大小超过1M,请上传小于1M文件";
+                file_flag = false;
+            }else {
+                file_span.innerText="";
+                file_flag = true;
+            }
+        }
+
+        checkSubmit();
+    }
+
+    function checkSubmit() {
+        var submit_button = document.getElementById("submit_file");
+        if(name_flag && file_flag){
+            submit_button.removeAttribute("disabled");
+        }else{
+            submit_button.setAttribute("disabled", true);
+        }
+
+    }
+
+    function checkName() {
+        var name = document.getElementsByName("name")[0].value;
+        var name_span = document.getElementsByName("name_span")[0];
+        if(name == null || name == "" || name.trim().length == 0){
+            name_span.innerText= "输入字段不能为空";
+            name_flag = false;
+        }else{
+            name_span.innerText= "";
+            name_flag = true;
+        }
+        checkSubmit();
+    }
+
+    function check_success(){
+        var params = new FormData();
+        params.append("name",$("#name").val())
+        params.append("excelFile",document.getElementById('excel_file').files[0])
+        $.ajax({
+            type:"post",
+            url:"/add_excel_pro",
+            processData: false,
+            contentType: false,
+            data:params,
+            dataType:'json',
+            success:function(result){
+                console.info(result);
+                if(result["file_is_null"] == false && result["insert_success"] == true){
+                    $.notify({
+                        message: '导入成功'
+                    },{
+                        // settings
+                        delay: 100,
+                        timer: 1000,
+                        type: 'success'
+                    });
+                }else{
+                    $.notify({
+                        message: '导入失败,请按文件模板样式导入文件'
+                    },{
+                        // settings
+                        delay: 100,
+                        timer: 1000,
+                        type: 'danger'
+                    });
+                }
+
+
+            },
+            error:function(data){
+                $.notify({
+                    message: '网络错误'
+                },{
+                    // settings
+                    delay: 100,
+                    timer: 1000,
+                    type: 'warning'
+                });
+            }
+        })
+    }
+
+
+</script>

+ 3 - 4
src/main/resources/templates/agg_report_new.html

@@ -296,16 +296,15 @@
                             <div class="form-group">
                                 <label>Bug 复现程度</label>
                                 <select id="recurrent" name="recurrent" class="form-control">
-                                    <option th:each="mapItem : ${recurrent2String}"
+                                    <option th:each="mapItem : ${recurrent2String}" th:if="${mapItem.key !=0 }"
                                             th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
-
                                 </select>
                             </div>
                             <!-- select -->
                             <div class="form-group">
                                 <label>Bug 严重性</label>
                                 <select id="severity" name="severity" class="form-control">
-                                    <option th:each="mapItem : ${severity2String}"
+                                    <option th:each="mapItem : ${severity2String}" th:if="${mapItem.key !=0 }"
                                             th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
                                 </select>
                             </div>
@@ -314,7 +313,7 @@
                             <div class="form-group">
                                 <label>Bug 分类</label>
                                 <select id="category" class="form-control">
-                                    <option th:each="mapItem : ${category2String}"
+                                    <option th:each="mapItem : ${category2String}" th:if="${mapItem.key !=0 }"
                                             th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
                                 </select>
                             </div>

+ 3 - 4
src/main/resources/templates/aggr_report.html

@@ -226,16 +226,15 @@
                             <div class="form-group">
                                 <label>Bug 复现程度</label>
                                 <select id="recurrent" name="recurrent" class="form-control">
-                                    <option th:each="mapItem : ${recurrent2String}"
+                                    <option th:each="mapItem : ${recurrent2String}" th:if="${mapItem.key !=0 }"
                                             th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
-
                                 </select>
                             </div>
                             <!-- select -->
                             <div class="form-group">
                                 <label>Bug 严重性</label>
                                 <select id="severity" name="severity" class="form-control">
-                                    <option th:each="mapItem : ${severity2String}"
+                                    <option th:each="mapItem : ${severity2String}" th:if="${mapItem.key !=0 }"
                                             th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
                                 </select>
                             </div>
@@ -244,7 +243,7 @@
                             <div class="form-group">
                                 <label>Bug 分类</label>
                                 <select id="category" class="form-control">
-                                    <option th:each="mapItem : ${category2String}"
+                                    <option th:each="mapItem : ${category2String}" th:if="${mapItem.key !=0 }"
                                             th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
                                 </select>
                             </div>

+ 9 - 0
src/main/resources/templates/paper_list.html

@@ -75,6 +75,15 @@
                         </span>
                     </a>
                 </li>
+                <li>
+                    <a href="/addExcel">
+                        <i class="glyphicon glyphicon-pencil"></i>
+                        <span>
+                            导入Excel项目文件
+                        </span>
+                    </a>
+                </li>
+
             </ul>
         </section>
     </aside>

+ 4 - 4
src/main/resources/templates/single_report.html

@@ -219,16 +219,15 @@
                             <div class="form-group">
                                 <label>Bug 复现程度</label>
                                 <select id="recurrent" name="recurrent" class="form-control">
-                                    <option th:each="mapItem : ${recurrent2String}"
+                                    <option th:each="mapItem : ${recurrent2String}" th:if="${mapItem.key !=0 }"
                                             th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
-
                                 </select>
                             </div>
                             <!-- select -->
                             <div class="form-group">
                                 <label>Bug 严重性</label>
                                 <select id="severity" name="severity" class="form-control">
-                                    <option th:each="mapItem : ${severity2String}"
+                                    <option th:each="mapItem : ${severity2String}" th:if="${mapItem.key !=0 }"
                                             th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
                                 </select>
                             </div>
@@ -237,8 +236,9 @@
                             <div class="form-group">
                                 <label>Bug 分类</label>
                                 <select id="category" class="form-control">
-                                    <option th:each="mapItem : ${category2String}"
+                                    <option th:each="mapItem : ${category2String}" th:if="${mapItem.key !=0 }"
                                             th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
+
                                 </select>
                             </div>
 

+ 10 - 2
src/main/resources/templates/task_list.html

@@ -67,6 +67,14 @@
                         </span>
                     </a>
                 </li>
+                <li>
+                    <a href="/addExcel">
+                        <i class="glyphicon glyphicon-tasks"></i>
+                        <span>
+                            导入Excel项目文件
+                        </span>
+                    </a>
+                </li>
             </ul>
         </section>
     </aside>
@@ -98,8 +106,8 @@
             <table id="task-list" class="table table-striped text-center" style="margin-top: 10px">
                 <thead><tr>
                     <!--<th></th>-->
-                    <th>考试号</th>
-                    <th>题号</th>
+                    <th>测试序号(考试号</th>
+                    <th>任务序号(题号</th>
                     <th>应用名</th>
                     <!--<th>版本</th>-->
                     <th>审核状态</th>

+ 2 - 16
src/main/resources/templates/thumbnail/raw_report.html

@@ -6,26 +6,12 @@
 		<b th:if="${isMaster}" th:text="|Master-${bugReport.id}|"></b>
 		<b th:unless="${isMaster}" th:text="${bugReport.id}"></b>
 	</li>
-<!-- 	<li class="list-group-item">
-		<b>Type:    </b>
-		<label class="label" style="background-color: rgb(244, 172, 7); margin-right: 5px;">
-			<span class="glyphicon glyphicon-file" style="margin-right: 5px;"></span>
-			Raw Report
-		</label>
-		{% if is_master %}
-		<label class="label" style="background-color: rgb(252, 165, 4);">
-			<span class="glyphicon glyphicon-file" style="margin-right: 5px;"></span>
-			Master Report
-		</label>
-		{% endif %}
-	</li> -->
+
 	<li class="list-group-item" style="max-width: 290px; min-height: 363px;">
-		<!-- <b>Content: </b><br> -->
 		<span th:text="${bugReport.description}"></span><br />
-
 		<img class="my-img-thumbnail pointer" th:src="${imgUrl}"
 			 th:each="imgUrl,iterStat : ${bugReport.getImgUrls()}"
-			 th:onclick="'javascript:showimage(\''+${imgUrl}+'\');'"/>
+			 th:onclick="showimage([[${imgUrl}]])"/>
 	</li>
 </ul>
 </html>

+ 4 - 1
src/main/resources/templates/thumbnail/sup_report.html

@@ -38,7 +38,10 @@
                         <img th:if="${img.isDiff()}" class="my-img-thumbnail pointer" style="border: 2px solid red;"
                              th:src="${img.imgUrl}" th:onclick="'javascript:showimage(\''+${img.imgUrl}+'\');'"/>
                         <img th:unless="${img.isDiff()}" class="my-img-thumbnail pointer"
-                             th:src="${img.imgUrl}" th:onclick="'javascript:showimage(\''+${img.imgUrl}+'\');'"/>
+                             th:src="${img.imgUrl}" th:onclick="showimage([[${img.imgUrl}]])"/>
+
+
+
                     </th:block>
 
                 </li>

+ 5 - 6
src/main/resources/templates/tree_report_new.html

@@ -288,16 +288,15 @@
                             <div class="form-group">
                                 <label>Bug 复现程度</label>
                                 <select id="recurrent" name="recurrent" class="form-control">
-                                    <option th:each="mapItem : ${recurrent2String}"
-                                            th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
-
+                                    <option th:each="mapItem : ${recurrent2String}" th:if="${mapItem.key !=0 }"
+                                            th:value="${mapItem.key}" th:text="${mapItem.value}" >必现</option>
                                 </select>
                             </div>
                             <!-- select -->
                             <div class="form-group">
                                 <label>Bug 严重性</label>
                                 <select id="severity" name="severity" class="form-control">
-                                    <option th:each="mapItem : ${severity2String}"
+                                    <option th:each="mapItem : ${severity2String}" th:if="${mapItem.key !=0 }"
                                             th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
                                 </select>
                             </div>
@@ -306,7 +305,7 @@
                             <div class="form-group">
                                 <label>Bug 分类</label>
                                 <select id="category" class="form-control">
-                                    <option th:each="mapItem : ${category2String}"
+                                    <option th:each="mapItem : ${category2String}" th:if="${mapItem.key !=0 }"
                                             th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
                                 </select>
                             </div>
@@ -554,7 +553,7 @@
         $("#new-report-create-block").show()
         // console.log("show create yse")
         $("#new-report-list-block").hide()
-        console.log("show create three")
+        console.log("pshow create three")
 
     }
     function hideCreateBlock() {