Forráskód Böngészése

增加了Excel文件导入bug功能,第一次提交

bigwit11 4 éve
szülő
commit
848f9a3698
26 módosított fájl, 715 hozzáadás és 27 törlés
  1. 12 2
      pom.xml
  2. 18 2
      src/main/java/com/mooctest/controller/HistoryController.java
  3. 28 4
      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. 11 0
      src/main/java/com/mooctest/data/BugDTO.java
  9. 6 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. 176 0
      src/main/java/com/mooctest/service/BugExcelInputService.java
  15. 164 0
      src/main/java/com/mooctest/service/ExcelInputService.java
  16. 1 0
      src/main/java/com/mooctest/service/FinalReportService.java
  17. 3 0
      src/main/java/com/mooctest/service/GraphService.java
  18. 1 1
      src/main/java/com/mooctest/service/HistoryService.java
  19. 3 1
      src/main/java/com/mooctest/service/MasterReportService.java
  20. 87 4
      src/main/java/com/mooctest/service/TaskService.java
  21. 44 2
      src/main/java/com/mooctest/service/impl/BugReportServiceImpl.java
  22. 1 1
      src/main/java/com/mooctest/util/Doc2VecUtil.java
  23. 17 0
      src/main/resources/templates/add_excel.html
  24. 10 0
      src/main/resources/templates/add_excel_ok.html
  25. 9 0
      src/main/resources/templates/paper_list.html
  26. 2 2
      src/main/resources/templates/task_list.html

+ 12 - 2
pom.xml

@@ -172,8 +172,16 @@
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-zookeeper-config</artifactId>
         </dependency>
-
-
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>5.0.12.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tomcat</groupId>
+            <artifactId>tomcat-tribes</artifactId>
+            <version>7.0.47</version>
+        </dependency>
 
 
     </dependencies>
@@ -223,5 +231,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);

+ 28 - 4
src/main/java/com/mooctest/controller/PaperController.java

@@ -3,15 +3,16 @@ package com.mooctest.controller;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.mooctest.service.AuditTaskService;
+import com.mooctest.service.BugExcelInputService;
+import com.mooctest.service.ExcelInputService;
 import com.mooctest.service.PaperService;
+import org.apache.poi.hssf.record.DVALRecord;
 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 java.sql.Timestamp;
 
@@ -23,6 +24,12 @@ public class PaperController {
     @Autowired
     PaperService paperService;
 
+    @Autowired
+    BugExcelInputService bugExcelInputService;
+
+    @Autowired
+    ExcelInputService excelInputService;
+
     private String ITEM_GROUP_NAME = "item_group_list";
 
     @GetMapping("/addPaper")
@@ -36,6 +43,23 @@ public class PaperController {
 //        return "addTask";
 //    }
 
+    @GetMapping("/addExcel")
+    public String addExcel (Model model){
+        return "add_excel";
+    }
+
+    @PostMapping("/excelToMongo")
+    public String excelToMongo (@RequestParam("name")String name, @RequestParam("excelFile") MultipartFile multipartFile){
+        // 从前端接收Excel文件,并返回文件保存的全路径
+//        String fileFullPath = bugExcelInputService.saveMultipartFile(multipartFile, multipartFile.getName());
+        String fileFullPath = excelInputService.saveMultipartFile(multipartFile, name);
+        // 拿取文件,并将文件内容插入到Mongo数据库中
+//        bugExcelInputService.excelToMongo(27017,"localhost","crowd_review","root","root","bug",fileFullPath);
+        excelInputService.excelToMongo(fileFullPath, name);
+        return "add_excel_ok";
+    }
+
+
     @DeleteMapping("/dpaper")
     @ResponseBody
     public JSONObject deletePaper (Model model ,  @RequestParam("id") String id ){

+ 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> {
+}
+

+ 11 - 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

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

@@ -18,4 +18,10 @@ public class TaskDTO {
     private String endTime;
     private long numOfTotalBug;
     private long numOfUndeal;
+
+    public TaskDTO(long examId, long caseId, String name) {
+        this.examId = examId;
+        this.caseId = caseId;
+        this.name = name;
+    }
 }

+ 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->{

+ 176 - 0
src/main/java/com/mooctest/service/BugExcelInputService.java

@@ -0,0 +1,176 @@
+package com.mooctest.service;
+
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+import com.mongodb.MongoClient;
+import com.mongodb.MongoCredential;
+import com.mongodb.ServerAddress;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoDatabase;
+import com.mooctest.dao2.BugDao;
+import com.mooctest.data.BugDTO;
+import com.mooctest.model.Bug;
+import com.mooctest.model.BugData;
+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.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+public class BugExcelInputService {
+
+    public String saveMultipartFile(MultipartFile file, String fileSaveName){
+        OutputStream os = null;
+        InputStream inputStream = null;
+        String fileName = fileSaveName;
+        String fileFullPath = null;
+
+        try {
+            inputStream = file.getInputStream();
+            fileName = file.getOriginalFilename();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        try {
+            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 {
+            // 完毕,关闭所有链接
+            try {
+                os.close();
+                inputStream.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+        }
+
+        return fileFullPath;
+    }
+
+    public void excelToMongo(Integer PORT, String IP, String DATABASE, String USERNAME, String PASSWORD, String COLLECTION, String ADDRESS) {
+        try {
+            // 输入文件
+            FileInputStream inputStream = new FileInputStream(ADDRESS);
+            // 根据输入流导入Excel产生Workbook对象
+            Workbook workbook = null;
+            try {
+                workbook = new HSSFWorkbook(inputStream);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            // IP,端口
+            ServerAddress serverAddress = new ServerAddress(IP, PORT);
+            List<ServerAddress> address = new ArrayList<ServerAddress>();
+            address.add(serverAddress);
+            // 用户名,数据库,密码
+            MongoCredential credential = MongoCredential.createCredential(USERNAME, DATABASE, PASSWORD.toCharArray());
+            List<MongoCredential> credentials = new ArrayList<MongoCredential>();
+            credentials.add(credential);
+            // 通过验证获取连接
+            MongoClient mongoClient = new MongoClient(address, credentials);
+            // 连接到数据库
+            MongoDatabase mongoDatabase = mongoClient.getDatabase(DATABASE);
+
+
+            // 连接文档
+            MongoCollection<Document> collection = mongoDatabase.getCollection(COLLECTION);
+//            MongoCollection<Document> task = mongoDatabase.getCollection("Task");
+
+            System.out.println("连接成功");
+
+            List<Document> documents = new ArrayList<Document>();
+            List<String> fieldList = new ArrayList<String>();
+            // 获取Excel文档中第一个表单
+            Sheet sheet = workbook.getSheetAt(0);
+            // 获取表单第一行作为表头
+            Row topRow = sheet.getRow(0);
+            for (Cell cell : topRow) {
+                fieldList.add(cell.toString());
+            }
+
+            System.out.println("文件列表" + fieldList);
+            // 获得表单的行数
+            int rows = sheet.getLastRowNum() + 1;
+            // 获得每行的列数
+            int colunms = fieldList.size();
+            // 从第二行开始遍历表格
+            for (int i = 1; i < rows; i++) {
+                Row row = sheet.getRow(i);
+                Document document = new Document();
+//                Document taskDocument = new Document();
+                int exam_id = 0;
+                int case_id = 0;
+                String exam_case_id;
+                long data = System.currentTimeMillis();
+                // 每行从第一行开始遍历列
+                for (int j = 0; j < colunms; j++) {
+                    Cell cell = row.getCell(j);
+                    if (j == 0){
+                        exam_id = new Double(Double.parseDouble(cell.toString())).intValue();
+                        exam_id = exam_id + 10000000;
+                        document.append(fieldList.get(j), exam_id);
+//                        taskDocument.append(fieldList.get(j), exam_id);
+
+                    }else if(j == 1){
+                        case_id = new Double(Double.parseDouble(cell.toString())).intValue();
+                        case_id = case_id + 10000000;
+                        document.append(fieldList.get(j), case_id);
+//                        taskDocument.append(fieldList.get(j), case_id);
+
+
+                    }else if (j == 4 || j == 5){
+                        int num = new Double(Double.parseDouble(cell.toString())).intValue();
+                        document.append(fieldList.get(j), num);
+
+
+
+                    }else{
+                        document.append(fieldList.get(j), cell.toString());
+                    }
+                }
+                exam_case_id = exam_id + "-" + case_id;
+                document.append("exam_case_id", exam_case_id);
+                document.append("create_time_millis", data);
+
+                documents.add(document);
+            }
+            System.out.println("documents" + documents);
+            collection.insertMany(documents);
+            System.out.println("插入成功");
+        } catch (FileNotFoundException e) {
+            System.err.println(e.getClass().getName() + ": " + e.getMessage());
+        }
+    }
+
+}

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

@@ -0,0 +1,164 @@
+package com.mooctest.service;
+
+import com.mooctest.dao.ExtendBugDao;
+import com.mooctest.dao.TaskDao;
+import com.mooctest.model.ExtendBug;
+import com.mooctest.model.Task;
+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.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 {
+
+    @Autowired
+    TaskDao taskDao;
+
+    @Autowired
+    ExtendBugDao extendBugDao;
+
+    // 接收前端文件,并将MultipartFile文件转换成File文件,并返回文件路径
+    public String saveMultipartFile(MultipartFile file, String fileSaveName){
+        OutputStream os = null;
+        InputStream inputStream = null;
+        String fileName = fileSaveName;
+        String fileFullPath = null;
+
+        try {
+            inputStream = file.getInputStream();
+            fileName = file.getOriginalFilename();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        try {
+            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 {
+            // 完毕,关闭所有链接
+            try {
+                os.close();
+                inputStream.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+        }
+        return fileFullPath;
+    }
+
+
+    // 解析File文件,并将为数据库表中各字段赋值,并将数据数据插入数据库中
+    public void 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;
+        Task task = new Task(task_id, case_id, task_name);
+        taskDao.save(task);
+
+//        List<ExtendBug> extendBugs = new ArrayList<>();
+        try {
+            // 输入文件
+            FileInputStream inputStream = new FileInputStream(address);
+            // 根据输入流导入Excel产生Workbook对象
+            Workbook workbook = null;
+            try {
+                workbook = new HSSFWorkbook(inputStream);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+            List<Document> documents = new ArrayList<Document>();
+            List<String> fieldList = new ArrayList<String>();
+            // 获取Excel文档中第一个表单
+            Sheet sheet = workbook.getSheetAt(0);
+            // 获取表单第一行作为表头
+            Row topRow = sheet.getRow(0);
+            for (Cell cell : topRow) {
+                fieldList.add(cell.toString());
+            }
+
+            System.out.println("文件列表" + 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.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);
+                    if(j == 0){
+                        String title = cell.toString();
+                        extendBug.setTitle(title);
+                    }else if(j == 1){
+                        String bug_category = cell.toString();
+                        extendBug.setBugCategory(bug_category);
+                    }else if(j == 2){
+                        int num = new Double(Double.parseDouble(cell.toString())).intValue();
+                        short severity = (short)num;
+                        extendBug.setSeverity(severity);
+                    }else if(j == 3){
+                        int num = new Double(Double.parseDouble(cell.toString())).intValue();
+                        short recurrent = (short)num;
+                        extendBug.setRecurrent(recurrent);
+                    }else{
+                        String description = cell.toString();
+                        extendBug.setDescription(description);
+                    }
+
+                }
+                System.out.println(extendBug);
+                extendBugDao.save(extendBug);
+
+            }
+            System.out.println("插入成功");
+        } catch (FileNotFoundException e) {
+            System.err.println(e.getClass().getName() + ": " + e.getMessage());
+        }
+    }
+
+
+}

+ 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 -> {

+ 87 - 4
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,118 @@ 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<>();
+            /*
+             * MongoClient               连接服务器
+             * MongoDatabase             连接数据库
+             * MongoCollection           连接表
+             * FindIterable<Document>    记录型迭代器
+             * MongoCursor               记录游标
+             * 应用顺序: 服务器-->数据库-->表-->记录迭代器-->记录游标
+             */
+//            MongoClient mongoClient = new MongoClient("localhost", 27017);
+//            MongoDatabase mongoDatabase = mongoClient.getDatabase("crowd_review");
+//            MongoCollection<Document> collection = mongoDatabase.getCollection("Task");
+//            FindIterable<Document> findIterable = collection.find();
+//            MongoCursor<Document> mongoCursor = findIterable.iterator();
+        List<Task> tasks = taskDao.findAll();
+        for (Task task: tasks) {
+            TaskDTO taskDTO = new TaskDTO((long) task.getTaskId(), (long) task.getCaseId(), task.getName());
+            taskDTOs.add(taskDTO);
+
+        }
+
+//        while(mongoCursor.hasNext()){
+//                Document  task = mongoCursor.next();
+//                TaskDTO taskDTO = new TaskDTO();
+//                taskDTO.setExamId((long)task.getInteger("task_id"));
+//                taskDTO.setCaseId((long)task.getInteger("case_id"));
+//                taskDTO.setName(task.getString("name"));
+//                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 -> {

+ 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

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

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

+ 17 - 0
src/main/resources/templates/add_excel.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>导入任务</title>
+</head>
+<body>
+<form action="/excelToMongo" method="post" enctype="multipart/form-data">
+    测试名称:<input type="text" name="name"/>
+    <br/>
+    导入Excel文件:<input type="file" name="excelFile">
+    <br/>
+    <input type="submit" value="提交">
+</form>
+
+</body>
+</html>

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

@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Title</title>
+</head>
+<body>
+    提交成功!!!
+</body>
+</html>

+ 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>

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

@@ -98,8 +98,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>