ソースを参照

添加单独的报告页面

insomniaLee 6 年 前
コミット
787c6cb425

+ 5 - 0
pom.xml

@@ -155,6 +155,11 @@
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
+                <!--<configuration>-->
+                    <!--<fork>-->
+                        <!--true-->
+                    <!--</fork>   &lt;!&ndash;如果没有这个配置的话,,devtools 不会生效&ndash;&gt;-->
+                <!--</configuration>-->
             </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>

+ 9 - 1
src/main/java/com/mooctest/controller/FinalReportController.java

@@ -40,7 +40,15 @@ public class FinalReportController {
         return finalReportService.save(dto);
     }
 
-  @GetMapping("final_reports")
+    @GetMapping("final_reports_export_data")
+    @ResponseBody
+    public List<FinalReportDTO> getFinalReportExports(@RequestParam("examId") long examId,
+                                                      @RequestParam("caseId") long caseId){
+        List<FinalReportDTO> res = finalReportService.getByExamIdAndCaseId(examId,caseId);
+        return res;
+    }
+
+    @GetMapping("final_reports")
     public String getByExamIdAndCaseId(@RequestParam("examId") long examId,
                                        @RequestParam("caseId") long caseId,
                                        Model model) {

+ 50 - 4
src/main/java/com/mooctest/controller/HistoryController.java

@@ -20,6 +20,7 @@ import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 @Controller
 @RequestMapping(value = "/history")
@@ -75,6 +76,52 @@ public class HistoryController {
 		}
 	}
 
+	@GetMapping(value = "/tree_list")
+	public String showTreeList(@RequestParam("caseId") long caseId,@RequestParam("examId")  long examId,
+						Model model){
+		String case_take_id = caseId+"-"+examId;
+		JSONObject result = new JSONObject(); // 用来存放树状结构信息的reuslt;
+		List<String> all = hisservice.getTreeRoots(caseId+"-"+examId); // 获得所有的根结点的id
+		TaskDTO task = taskService.getByExamIdAndCaseId(examId, caseId);
+		List<List<String>> list = new ArrayList<List<String>>();
+		for(String id: all) {
+			list.add(hisservice.getDetail(id));
+		} // 获得树的信息。
+		//获得每份报告的具体信息
+
+
+		List<String> list_bugs = aservice.getValid(case_take_id); // 得到所有的bug报告
+		System.out.println("all :"+all.size());
+		System.out.println("list:"+list.size());
+		System.out.println(list_bugs);
+		List<String> res = list_bugs.stream().filter(s->all.contains(s)).collect(Collectors.toList());
+		System.out.println(res.size());
+		if(all.size()>=0){
+			return "error";
+		}
+
+
+
+
+		List<List<String>> lists = hisservice.getDepth(all.get(0));
+		Set<String> filter = hisservice.filter(lists);
+		result.put("path", new JSONArray(lists));
+		result.put("invalid", new JSONArray(hisservice.getInvalid(filter)));
+		List<String> ids = new ArrayList<String>(filter);
+		result.put("score", new JSONArray(aservice.getScores(ids)));
+		System.out.println("/getPath path = " + result);
+		System.out.println("result.toString() = " + result.toString());
+
+
+		model.addAttribute("master2BugIdsMap", all); //
+		model.addAttribute("bugMap", all); //
+		model.addAttribute("examId", examId);
+		model.addAttribute("caseId", caseId);
+		model.addAttribute("task", task);
+		model.addAttribute("aggNum", all.size());
+		return  "tree_report_list";
+	}
+
     @RequestMapping(value = "/getTrees2")
     public String getTrees2(@RequestParam("case_take_id") String case_take_id) {
 	    return "managerCheck";
@@ -94,11 +141,10 @@ public class HistoryController {
 		long examId =  Long.parseLong(split[1]);
 		try {
 			JSONObject result = new JSONObject();
-
-			List<String> all = hisservice.getTreeRoots(case_take_id);
+			List<String> all = hisservice.getTreeRoots(case_take_id);//获得所有的根结点。
 			System.out.println("all.toString(): " + all.toString());
-			hisservice.pageFilter(all, page);
-			List<String> ids = all.subList(Integer.parseInt(start), Math.min(all.size(), Integer.parseInt(start) + Integer.parseInt(count)));
+			hisservice.pageFilter(all, page);//清洗其他界面的bug报告,只留下本界面的。
+			List<String> ids = all.subList(Integer.parseInt(start), Math.min(all.size(), Integer.parseInt(start) + Integer.parseInt(count))); // 做一个筛选。
 			List<List<String>> list = new ArrayList<List<String>>();
 			System.out.println(ids.toString());
 			for(String id: ids) {

+ 71 - 0
src/main/java/com/mooctest/controller/ReportController.java

@@ -17,6 +17,7 @@ import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.util.ResourceUtils;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 
@@ -111,6 +112,76 @@ public class ReportController {
         return "agg_report_new";
     }
 
+    @GetMapping(value = "/reporttest/{id}")
+    public String showAggrReportTest(@PathVariable("id") String   id,
+                                 @RequestParam("examId") long examId,
+                                 @RequestParam("caseId") long caseId,
+                                 Model model) {
+
+        BugDTO singleReport = bugReportService.getBugById(id,examId, caseId); // 具体的bug的DTO
+
+        MasterReport masterReportSource = masterReportService.getByBugId(id+""); // 找到该报告的master报告报告;
+        String masterId = masterReportSource.getMasterId();
+        Map<String, BugDTO> bugMap = bugReportService.getAllBugsMap(examId, caseId);
+        BugDTO masterReport = bugMap.get(masterId);
+        List<FinalReportDTO> finalReports = finalReportService.getBySourceId(masterId); // 和这份报告suoshu julei baogao de fincal bgoa
+        model.addAttribute("singleReport",singleReport);//
+        model.addAttribute("masterReport", masterReport);
+        model.addAttribute("createTime", new Date(Long.parseLong(singleReport.getCreateTimeMillis())));
+        model.addAttribute("finalReports", finalReports);
+        model.addAttribute("category2String", ReportUtil.category2String);
+        model.addAttribute("recurrent2String", ReportUtil.recurrent2String);
+        model.addAttribute("severity2String", ReportUtil.severity2String);
+        model.addAttribute("masterName","ML-AG-"+masterId.substring(10));
+        model.addAttribute("masterUrl","/report?masterId="+masterId+"&examId="+examId+"&caseId="+caseId);
+        model.addAttribute("examId", examId);
+        model.addAttribute("caseId", caseId);
+        return "single_report";
+    }
+
+    @GetMapping(value = "/report/{id}")
+    public String showSingleReport(@PathVariable("id") String   id,
+                                   @RequestParam("examId") long examId,
+                                   @RequestParam("caseId") long caseId,Model model) {
+        BugDTO bug = bugReportService.getBugById(id,examId, caseId); // 具体的bug的DTO
+
+
+        List<BugDTO> bugs = new LinkedList<>();
+        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> recurrentCounts = sourceReports.stream()
+                .map(BugDTO::getRecurrent)
+                .map((recurrentNum) -> ReportUtil.recurrent2String.get(recurrentNum))
+                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
+        Map<String, Long> severityCounts = sourceReports.stream()
+                .map(BugDTO::getSeverity)
+                .map((severityNum) -> ReportUtil.severity2String.get(severityNum))
+                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
+
+//        List<FinalReportDTO> finalReports = finalReportService.getBySourceId(masterId);
+
+        model.addAttribute("reportId",id);
+        model.addAttribute("report",bug);
+        model.addAttribute("createTime", new Date(Long.parseLong(bug.getCreateTimeMillis())));
+//        model.addAttribute("finalReports", finalReports);
+        model.addAttribute("category2String", ReportUtil.category2String);
+        model.addAttribute("recurrent2String", ReportUtil.recurrent2String);
+        model.addAttribute("severity2String", ReportUtil.severity2String);
+        model.addAttribute("examId", examId);
+        model.addAttribute("caseId", caseId);
+
+//        boolean bugReviewed = bugReviewService.isBugReviewed(masterId);
+//        model.addAttribute("reviewed", bugReviewed);
+//        if (finalReportId != null) {
+//            Optional<FinalReportDTO> finalReportDTO = finalReports.stream().filter(finalReport -> finalReport.getId()==finalReportId).findFirst();
+//            model.addAttribute("finalReportId", finalReportId);
+//            model.addAttribute("editReport", finalReportDTO.get());
+//
+//        }
+        return "single_report";
+    }
+
     @GetMapping("editReportData")
     @ResponseBody
     public FinalReportDTO getEditReportData(@RequestParam("masterId") String masterId,

+ 1 - 1
src/main/java/com/mooctest/model/Bug.java

@@ -25,7 +25,7 @@ public class Bug {
     private String reportId;
 
     private String title;
-
+/**/
     private String description;
 
     @Field("img_url")

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

@@ -38,7 +38,7 @@ public class AnalyzeService {
 	@Autowired
     HistoryService hservice;
 	
-	//获取所有bug
+	//获取所有bug-----
 	public List<String> getValid(String case_take_id) {
 		List<String> result = new ArrayList<String>();
 		List<BugMirror> mirrors = mdao.findValid(case_take_id);

+ 2 - 6
src/main/java/com/mooctest/util/Report2xls.java

@@ -38,13 +38,13 @@ public class Report2xls {
             HSSFSheet sheet1 = wb.createSheet("sheet1");
             for (int i =5;i<maxImgLength;i++){
                 sheet1.setColumnWidth((short)i,(short)60*256);
-
             }
             sheet1.setColumnWidth((short)4,(short)30*256); // 设置描述列的宽度
             desCellStyle = wb.createCellStyle();
             desCellStyle.setWrapText(true);
+            desCellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
             lineCellStyle = wb.createCellStyle();
-            lineCellStyle.setAlignment(HSSFCellStyle.VERTICAL_CENTER);//设置文字居中,垂直居中
+            lineCellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//设置文字居中,垂直居中
             sheet1.setDefaultRowHeight((short)(30*256));
             HSSFPatriarch patriarch = sheet1.createDrawingPatriarch(); // 创建的用来画图的
             HSSFClientAnchor anchor;
@@ -54,16 +54,12 @@ public class Report2xls {
             int tempHeight;
             int fitSize [] ;
             Row thead = sheet1.createRow(0);
-//            thead.setHeight((short)256);
             thead.setHeight((short)480);
             for(int i =0;i<4+maxImgLength&&i<20;i++){
                 thead.createCell(i).setCellValue(theads[i]);
             }
-//            sheet1.setDefaultRowHeight((short)(30*256));
             for (int rowNum = 0; rowNum < data.size(); rowNum++) {
                 Row row = sheet1.createRow(rowNum+1);
-                //row.setHeight((short)(30*256));
-
                 FinalReportDTO dto = data.get(rowNum);
                 cell0 = row.createCell(0);
                 cell0.setCellValue(rowNum+1);

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

@@ -13,6 +13,7 @@ spring:
     encoding: UTF-8
     content-type: text/html
     mode: HTML5
+    cache: false   #避免改了模版还要重启服务器
 ---
 spring:
   profiles: dev

+ 3 - 0
src/main/resources/static/css/main.css

@@ -28,4 +28,7 @@
 }
 .badge-inverse:hover {
   background-color: #1a1a1a;
+}
+.badge-little-green {
+  background-color: #7fd67f;
 }

+ 12 - 7
src/main/resources/templates/agg_report_new.html

@@ -104,10 +104,10 @@
                                 </span>
                             </td>
                         </tr>
+
                         <tr>
                             <td class="attr-title">Bug分类&nbsp;&nbsp;&nbsp;&nbsp;</td>
                             <td class="dup-category" colspan="3">
-
                                 <!--<i class="fa fa-square" style="color: {{ category.category_color  }};"></i>-->
                                 <span th:each="categoryCount : ${categoryCounts}">
                                     <span th:text="${categoryCount.key}"></span>
@@ -205,6 +205,10 @@
                                                 <span class="glyphicon glyphicon-file"
                                                       style="color: #3c8dbc; margin-right: 5px;"></span>
                                                     <a href="#" style="margin-right: 5px;" th:text="${report.id}"></a>
+                                                    <!--查看树状报告-->
+                                                    <span class="glyphicon glyphicon-tree-conifer"
+                                                           style="color: #07b309; margin-right: 5px;" >
+                                                    </span>
 
                                                     <!-- description -->
 
@@ -244,7 +248,7 @@
             </div>
 
             <div class="col-md-4 pull-right" >
-                <div id="my_favorite_latin_words" class="box box-info" style="margin-bottom: 5px; min-height: 182px;"></div>
+                <!--<div id="my_favorite_latin_words" class="box box-info" style="margin-bottom: 5px; min-height: 182px;"></div>-->
 
                 <div th:fragment="create_reports" class="box box-danger source-table" id="new-report-create-block" style="display: none">
                     <div class="box-header" style="border-bottom: 1px #f4f4f4 solid;">
@@ -441,11 +445,12 @@
 
     var images = [];
     $(function () {
-        $("#my_favorite_latin_words").jQCloud(word_list,
-            {
-                shape: "rectangular",
-                autoResize: true
-            });
+        // $("#my_favorite_latin_words").jQCloud(word_list,
+        //     {
+        //         shape: "rectangular",
+        //         autoResize: true
+        //     });
+        //去除掉报告详情界面的词云
         var urlParams = new URLSearchParams(window.location.search);
         if (urlParams.get("finalReportId")) {
             showCreateBlock()

+ 14 - 0
src/main/resources/templates/error.html

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8" />
+    <title>Title</title>
+</head>
+<body>
+
+<h1>
+    访问出错
+</h1>
+
+</body>
+</html>

+ 8 - 0
src/main/resources/templates/final_report_list.html

@@ -43,6 +43,14 @@
                     <span>新增视图</span>
                 </a>
             </li>
+            <li>
+                <a th:href="'/tree_list?examId='+${examId}+'&amp;caseId='+${caseId}">
+                    <!--写死的参数,-->
+                    <!--<a th:href="'/history/getTrees2?examId='+${caseId}+'">-->
+                    <i class="fa fa-sitemap text-warning"></i>
+                    <span>树状视图</span>
+                </a>
+            </li>
         </ul>
     </li>
 </th:block>

+ 468 - 0
src/main/resources/templates/single_report.html

@@ -0,0 +1,468 @@
+<!DOCTYPE html>
+<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"
+      xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
+      layout:decorator="main">
+<head>
+    <link rel="stylesheet" type="text/css" href="/static/css/main.css"/>
+    <link rel="stylesheet" type="text/css" href="/static/css/agg_report_new.css"/>
+    <link rel="stylesheet" type="text/css" href="/static/css/word_cloud.css"/>
+</head>
+<body>
+<th:block layout:fragment="sidebar">
+
+    <li>
+        <a th:href="'/final_reports?examId=' + ${examId} + '&amp;caseId=' + ${caseId}">
+            <i class="fa fa-calendar-check-o"></i>
+            <span>预交付报告</span>
+        </a>
+    </li>
+    <li class="treeview">
+        <a href="#">
+            <i class="fa fa-list"></i>
+            <span>Reports</span>
+            <span class="pull-right-container">
+			<i class="fa fa-angle-left pull-right"></i>
+		</span>
+        </a>
+        <ul class="treeview-menu" style="display: block;">
+            <li>
+                <a th:href="'/task_detail?examId='+${examId}+'&amp;caseId='+${caseId}">
+                    <i class="fa fa-sticky-note text-success"></i>
+                    <span>默认视图</span>
+                </a>
+            </li>
+            <li>
+                <a th:href="'/agg_report_list?examId='+${examId}+'&amp;caseId='+${caseId}">
+                    <i class="fa fa-sitemap text-warning"></i>
+                    <span>聚合视图</span>
+                </a>
+            </li>
+
+
+        </ul>
+    </li>
+</th:block>
+<th:block layout:fragment="maincontent">
+
+    <section class="content-header">
+        <h1>报告详情
+            <small th:text="${singleReport.getId()}"></small>
+        </h1>
+        <!-- <h1>Summary for report 0-5</h1> -->
+        <!-- <small style="font-style: italic;">at 50% report-level and 25% supplementary level</small> -->
+
+        <ol class="breadcrumb">
+            <!-- style="margin-right: 173px;" -->
+            <li>
+                <a href="/home">
+                    <i class="fa fa-dashboard"></i>
+                    全部任务
+                </a>
+            </li>
+            <li>
+                <a th:href="'/agg_report_list?examId='+${examId}+'&amp;caseId='+${caseId}">
+                    审核列表
+                </a>
+            </li>
+            <li class="active" th:text="${singleReport.getId()}">
+
+            </li>
+        </ol>
+    </section>
+    <section class="content container-fluid">
+        <div style="overflow: auto;" class="row">
+            <div class="col-md-8" id="summary">
+                <div class="box box-info detail-table">
+                    <div class="box-header with-border" style="padding: 4px;">
+                        <i class="fa fa-object-group" style="color: #00c0ef;"></i>
+                        <h3 class="box-title" th:text="${singleReport.getId()}">
+
+                        </h3>
+
+                    </div>
+                    <table class="table table-reponsive">
+                        <tbody>
+                        <tr>
+                            <td class="attr-title">创建时间&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
+                            <td class="dup-create-time" th:text="${#dates.format(createTime, 'yyyy-MM-dd')}"></td>
+                            <td class="attr-title">Bug 严重性</td>
+                            <td class="dup-severity">
+                                <span  >
+                                    <span th:text="${severity2String.get(singleReport.getSeverity())}"></span>
+<!--                                    <span class="badge" th:text="${severityCount.value}"></span>-->
+                                </span>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="attr-title">聚合报告</td>
+                            <td class="dup-assignee" colspan="3">
+
+                                <a th:href="@{${masterUrl}}" th:text="${masterName}" style="margin-right: 5px;">
+                                    admin
+                                </a>
+                            </td>
+                        </tr><!-- Attribute -->
+                        <tr>
+                            <td class="attr-title">Bug分类&nbsp;&nbsp;&nbsp;&nbsp;</td>
+                            <td class="dup-category" colspan="3">
+
+                                <!--<i class="fa fa-square" style="color: {{ category.category_color  }};"></i>-->
+                                <span >
+                                    <span th:text="${singleReport.getBugCategory()}"></span>
+                                </span>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="attr-title">三级页面&nbsp;&nbsp;&nbsp;&nbsp;</td>
+                            <td class="dup-category" colspan="3">
+
+                                <!--<i class="fa fa-square" style="color: {{ category.category_color  }};"></i>-->
+                                <span>
+                                    <span th:text="${singleReport.getBug_page()}"></span>
+<!--                                    <span class="badge" th:text="${pageCount.value}"></span>-->
+                                </span>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="attr-title">复现程度&nbsp;&nbsp;&nbsp;&nbsp;</td>
+                            <td class="dup-category" colspan="3">
+
+                                <!--<i class="fa fa-square" style="color: {{ category.category_color  }};"></i>-->
+                                <span >
+                                    <span th:text="${recurrent2String.get(singleReport.getRecurrent())}"></span>
+<!--                                    <span class="badge" th:text="${recurrentCount.value}"></span>-->
+                                </span>
+                            </td>
+                        </tr>
+                        <tr>
+                            <td class="attr-title">审核人</td>
+                            <td class="dup-assignee" colspan="3">
+
+                                <a href="#" style="margin-right: 5px;">
+                                    <i class="fa fa-vcard"></i>
+                                    admin
+                                </a>
+
+
+                            </td>
+                        </tr><!-- Attribute -->
+
+                        <!-- Start Content -->
+                        <tr>
+                            <td class="attr-title">报告内容<span class="glyphicon glyphicon-star"
+                                                            style="margin-left: 5px;"></span></td>
+                            <td class="dup-master" colspan="3">
+                                <span th:text="${masterReport.getDescription()}"></span><br/>
+                                <img class="my-img-thumbnail pointer to-add" th:src="${imgUrl}"
+                                     th:each="imgUrl,iterStat : ${masterReport.getImgUrls()}"
+                                     th:onclick="'javascript:showimage(\''+${imgUrl}+'\');'"/>
+
+                            </td>
+                        </tr>
+                        </tbody>
+                    </table>
+                </div>
+
+            </div>
+
+            <div class="col-md-4 pull-right" >
+                <!--<div id="my_favorite_latin_words" class="box box-info" style="margin-bottom: 5px; min-height: 182px;"></div>-->
+
+
+
+                <div class="box box-info source-table" id="new-report-list-block" >
+                    <div class="box-header">
+                        <h3 class="box-title">
+                            已创建报告
+                        </h3>
+                    </div>
+                    <div th:fragment="ul_reports" id="new-created-reports-panel">
+                        <div  id="new-created-reports" class="box-body"
+                              style="font-size: 12px; max-height: 340px; overflow: scroll;">
+                            <div th:if="${finalReports.size() == 0}" style="font-size: 20px">
+                                暂无 <a onclick="showCreateBlock()" style="cursor: pointer">立即创建报告</a>
+                            </div>
+                            <ul class="list-group">
+
+                                <!-- other reports -->
+                                <th:block th:each="finalReport : ${finalReports}">
+                                    <li class="list-group-item">
+                                        <div style="overflow: auto;">
+                                            <span th:text="${finalReport.id}"></span>
+                                            <span class="pull-right">
+                                            <a href="#" th:onclick="'editReport('+${finalReport.id}+')'" >编辑</a>
+                                            <a href="#" th:onclick="'deleteReport('+ ${finalReport.id} +')'">删除</a>
+                                        </span>
+                                        </div>
+
+                                        <div>
+                                        <span>
+                                            复现程度:<span th:text="${recurrent2String.get(finalReport.recurrent)}"></span>
+                                        </span>
+                                            <span class="pull-right">
+                                            分类:<span th:text="${category2String.get(finalReport.category)}"></span>
+                                        </span>
+                                        </div>
+                                        <div>
+                                            严重程度:<span th:text="${severity2String.get(finalReport.severity)}"></span>
+                                        </div>
+                                        <br/>
+                                        <span th:text="${finalReport.description}"></span>
+                                        <br/>
+                                        <img class="my-img-thumbnail pointer to-add" th:src="${imgUrl}"
+                                             th:each="imgUrl,iterStat : ${finalReport.getImgUrls()}"
+                                             th:onclick="'javascript:showimage(\''+${imgUrl}+'\');'"/>
+                                    </li>
+
+                                </th:block>
+
+                            </ul>
+                        </div>
+
+                    </div>
+                </div>
+
+            </div>
+        </div>
+
+
+
+
+    </section>
+</th:block>
+
+
+</body>
+</html>
+
+
+<div class="modal fade bs-example-modal-lg text-center" id="imgModal" tabindex="-1" role="dialog"
+     aria-labelledby="myLargeModalLabel">
+
+    <div class="modal-dialog modal-lg" style="display: inline-block; max-width: 900px; max-height: 600px">
+        <div class="modal-content" style="background:  transparent">
+            <center>
+                <img id="imgInModalID"
+                     class="carousel-inner img-responsive "
+                     onclick="closeImageViewer()"
+                     onmouseover="this.style.cursor='pointer';this.style.cursor='hand'"
+                     onmouseout="this.style.cursor='default'"
+                     style="max-height: 90vh;
+                     max-width: 90vw;
+                     object-fit: contain;"
+                />
+            </center>
+        </div>
+    </div>
+</div>
+<script type="text/javascript">
+    //显示大图
+    function showimage(source) {
+        $("#imgModal").find("#imgInModalID").attr("src", source);
+        $("#imgModal").modal();
+    }
+
+    //关闭
+    function closeImageViewer() {
+        $("#imgModal").modal('hide');
+    }
+</script>
+<script src="https://d3js.org/d3.v4.min.js"></script>
+<script type="text/javascript" src="/static/js/agg_report_new.js"></script>
+<script type="text/javascript" src="/static/js/jqcloud-1.0.4.min.js"></script>
+<!--<script type="text/javascript" src="/static/js/partload.js"></script>-->
+<script type="text/javascript" xmlns:th="http://www.thymeleaf.org" th:inline="javascript">
+    /*<![CDATA[*/
+    var urlParams = new URLSearchParams(window.location.search);
+    var masterId = urlParams.get('masterId');
+    var examId = urlParams.get('examId');
+    var caseId = urlParams.get('caseId');
+    var finalReportId = urlParams.get('finalReportId');
+    /*]]>*/
+
+
+    var images = [];
+    $(function () {
+
+        var urlParams = new URLSearchParams(window.location.search);
+        if (urlParams.get("finalReportId")) {
+            showCreateBlock()
+            /*<![CDATA[*/
+            var editReport = /*[[${editReport}]]*/;
+            /*]]>*/
+            fillNewReportBlock(editReport);
+        }
+        if(finalReportId == null){
+            $('#create_bug').css('display','block');
+        }
+    });
+
+    function createOrUpdateFinalReport() {
+
+        var report = {
+            'description': $("#bug-description").val(),
+            'severity': $("#severity").val(),
+            'recurrent': $("#recurrent").val(),
+            'category': $("#category").val(),
+            'sourceId': masterId,
+            'reviewerId': 1,
+            'examId': examId,
+            'caseId': caseId,
+            'imgUrls': images
+        }
+        if (finalReportId) {
+            report.id = finalReportId
+            $.ajax({
+                type: "PUT",
+                url: '/final_report/'+finalReportId,
+                data: JSON.stringify(report),
+                contentType: "application/json",
+                success: function (data) {
+                    //修改成功的情况
+                    console.log("修改报告")
+                    loadPartReports();
+
+                    /*<![CDATA[*/
+                    // window.location.href='report?masterId='+masterId+'&examId='+examId+'&caseId='+caseId
+                    /*]]>*/
+                }
+            });
+        } else {
+            //  向服务器新建一个
+            $.ajax({
+                type: "POST",
+                url: '/final_report',
+                data: JSON.stringify(report),
+                contentType: "application/json",
+                success: function (data) {
+                    console.log("新建报告")
+                    // location.reload()
+                    loadPartReports();
+                }
+            });
+        }
+    }
+
+    function showCreateButton() {
+        $("#create_bug").show()
+
+    }
+
+
+    function loadPartReports() {
+        console.log("局部刷新")
+        /*<![CDATA[*/
+        $('#new-created-reports-panel').load("/created_reports?masterId="+ masterId +"&caseId="+ caseId +"&examId="+ examId );
+        //$('#new-report-create-block').load("/created_reports_form");
+        finalReportId = null
+
+        /*]]>*/
+        showCreateButton()
+        $("#new-report-create-block").hide()
+        $("#new-report-list-block").show()
+    }
+
+
+    // function  syncCreatedReports(){
+    //     syncCreatedReportsWithParams(masterId,examId,caseId);
+    // }
+
+
+    function showCreateBlock() {
+        // console.log("show create block")
+        $("#new-report-create-block").show()
+        // console.log("show create yse")
+        $("#new-report-list-block").hide()
+        console.log("show create three")
+
+    }
+    function hideCreateBlock() {
+        if (finalReportId){
+                     /*<![CDATA[*/
+            // window.location.href='report?masterId='+masterId+'&examId='+examId+'&caseId='+caseId
+            // loadPartReports()
+            $("#create_bug").show()
+            $("#bug-description").text("")
+            finalReportId = null
+            /*]]>*/
+        }
+        $("#new-report-create-block").hide()
+        $("#new-report-list-block").show()
+
+    }
+
+
+
+    function fillNewReportBlock(editReport) {
+        console.log(editReport);
+        console.log("开始填充报告页面。")
+        $("#recurrent").val(editReport.recurrent);
+        $("#severity").val(editReport.severity);
+        $("#category").val(editReport.category);
+        $("#bug-description").val(editReport.description);
+        var $new_report_img = $("#new-report-img");
+        $new_report_img.empty()
+        images = [];
+        /*<![CDATA[*/
+        for (var i=0;editReport.imgUrls!=null&&i<editReport.imgUrls.length;i++) {
+            var src = editReport.imgUrls[i]
+            images.push(src);
+            var $img = $('<img />')
+            $img.attr("src", src);
+            $img.attr("class", "my-img-thumbnail pointer to-delete");
+            $img.on("click", function (){
+                showimage(src);
+            });
+            $img.on("dragend", function (e) {
+                var src = $(e.target).attr("src");
+                var idx = images.indexOf(src);
+                if (idx >= 0) {
+                    images.splice(idx, 1);
+                }
+
+                $(e.target).remove();
+            });
+            $new_report_img.append($img)
+        }
+        /*]]>*/
+    }
+    function deleteReport(finalReportId) {
+        $.ajax({
+            url: '/final_report/' + finalReportId,
+            type: 'DELETE',
+            success: function (result) {
+                // Do something with the result
+                alert("删除成功");
+                loadPartReports();
+            }
+        });
+    }
+
+    function editReport (finalId){
+        //填充编辑表单页面。
+        /*<![CDATA[*/
+        $.ajax({
+            url: '/editReportData?masterId='+masterId+'&finalReportId='+finalId,
+            type: 'GET',
+            success: function (result) {
+                console.log(result); //
+                finalReportId = finalId;
+                fillNewReportBlock(result)
+                showCreateBlock();
+            }
+        });
+        /*]]>*/
+
+    }
+
+    function reviewConfirm() {
+        $.ajax({
+            url: '/bug_review?masterId='+masterId,
+            type: 'PUT',
+            success: function (result) {
+                alert("确认审核成功,修改报告状态为已审核");
+                location.reload();
+            }
+        });
+    }
+</script>

+ 2 - 0
src/main/resources/templates/task_detail.html

@@ -148,6 +148,7 @@
                 <th>审核状态</th>
                 <th>审核人</th>
                 <th>所属聚合报告</th>
+                <th>所属树状报告</th>
             </tr>
             </thead>
             <tbody>
@@ -190,6 +191,7 @@
                         <span th:if="${!aggregated}">暂无</span>
                         <a th:if="${aggregated}" th:text="|ML-AG-${report.masterId.substring(10)}|" th:href="'/report?masterId='+${report.masterId}+'&amp;examId='+${examId}+'&amp;caseId='+${caseId}"></a>
                     </td>
+                    <td>暂无</td>
                 </tr>
             </th:block>
             </tbody>

+ 176 - 0
src/main/resources/templates/tree_report_list.html

@@ -0,0 +1,176 @@
+<!DOCTYPE html>
+<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"
+      xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
+      layout:decorator="main">
+<head>
+    <link rel="stylesheet" type="text/css" href="/static/css/main.css" />
+    <link rel="stylesheet" type="text/css" href="/static/css/all_reports.css" />
+
+    <!-- dataTables -->
+    <link rel="stylesheet" type="text/css"
+          href="/static/AdminLTE/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css" />
+</head>
+<body>
+<th:block layout:fragment="sidebar">
+    <li>
+        <a th:href="'/final_reports?examId=' + ${examId} + '&amp;caseId=' + ${caseId}">
+            <i class="fa fa-calendar-check-o"></i>
+            <span>预交付报告</span>
+        </a>
+    </li>
+    <li class="treeview">
+        <a href="#">
+            <i class="fa fa-list"></i>
+            <span>Reports</span>
+            <span class="pull-right-container">
+			<i class="fa fa-angle-left pull-right"></i>
+		</span>
+        </a>
+        <ul class="treeview-menu" style="display: block;">
+            <li class="active">
+                <a th:href="'/agg_report_list?examId='+${examId}+'&amp;caseId='+${caseId}">
+                    <i class="fa fa-circle-o"></i>
+                    <span>全部报告</span>
+                    <span class="badge pull-right all-number" th:text="${task.numOfTotalBug}">199</span>
+                </a>
+            </li>
+            <li>
+                <a th:href="'/agg_report_list?examId='+${examId}+'&amp;caseId='+${caseId}+'&amp;status=1'">
+                    <i class="fa fa-check-circle-o text-success"></i>
+                    <span>已审核报告</span>
+                    <span class="badge badge-success pull-right assigned-number" th:text="${task.numOfTotalBug - task.numOfUndeal}">50</span>
+                </a>
+            </li>
+            <li>
+                <a th:href="'/agg_report_list?examId='+${examId}+'&amp;caseId='+${caseId}+'&amp;status=0'">
+                    <i class="fa fa-clock-o text-danger"></i>
+                    <span>未审核报告</span>
+                    <span class="badge badge-danger pull-right unassign-number" th:text="${task.numOfUndeal}">149</span>
+                </a>
+            </li>
+        </ul>
+    </li>
+</th:block>
+
+<th:block layout:fragment="maincontent">
+    <section class="content-header">
+        <h1>审核列表
+            <small th:text="${task.name}">{{ app.name }}</small>
+        </h1>
+
+        <ol class="breadcrumb">
+            <li>
+                <a href="/home">
+                    <i class="fa fa-dashboard"></i>
+                    全部任务
+                </a>
+            </li>
+            <li class="active" th:text="|${task.name} 审核列表|">
+            </li>
+        </ol>
+    </section>
+
+    <section class="content container-fluid">
+        <div class="box">
+            <div class="box-header with-border">
+                <h3 class="box-title">树状视图 <span class="badge badge-info" th:text="${aggNum}"></span></h3>
+                <div class="box-tools pull-right">
+                    <a class="btn btn-sm btn-primary" th:href="'/task_detail?examId='+${examId}+'&amp;caseId='+${caseId}">
+                        <i class="fa fa-list-alt" style="margin-right: 5px;"></i>
+                        默认视图
+                    </a>
+                </div>
+            </div><!-- /.box-header -->
+
+            <div class="box-body agg-report-list">
+
+                <th:block th:each="masterBug : ${master2BugIdsMap}">
+                    <div class="col-md-4">
+                        <div class="box box-solid box-default">
+
+                            <div class="box-header" id="agg-title-{{aggReport.dup_tag}}">
+                                <div style="overflow: auto;">
+                                    <a th:href="@{'/report?masterId=' + ${masterBug.key} + '&amp;examId=' + ${examId} + '&amp;caseId=' + ${caseId}}"
+                                       class="pull-left agg-title" th:text="|ML-AG-${masterBug.key.substring(10)}|"></a>
+                                    <a th:href="'#dup-list-'+${masterBug.key}"
+                                       class="glyphicon glyphicon-menu-hamburger pull-right agg-title"
+                                       data-toggle="collapse"></a>
+                                    <span class="pull-right" style="margin-right: 5px;">
+
+                                        <label class="badge badge-success" th:if="${bugMap.get(masterBug.key).status == 1}">已审核</label>
+                                        <!--<label class="badge badge-warning" th:if="${bugMap.get(masterBug.key).status == 0}">未审核</label>-->
+                                        <label class="badge badge-little-green" th:if="${bugMap.get(masterBug.key).status == 0}">审核中</label>
+                                    </span>
+                                    <br/>
+                                </div>
+                                <div style="margin-top: 5px;">
+                                    <span class="agg-title">拥有报告数<span class="badge badge-default agg-badge" th:text="${masterBug.value.size()}">10</span></span>
+
+                                </div>
+                            </div>
+                            <div class="sup-title" style="padding: 15px 15px; min-height: 181px;overflow: scroll; max-height: 181px;"
+                            >
+                                <span th:text="${bugMap.get(masterBug.key).description}"></span><br/>
+                                <img class="my-img-thumbnail pointer to-add" th:src="${imgUrl}"
+                                     th:each="imgUrl,iterStat : ${bugMap.get(masterBug.key).getImgUrls()}"
+                                     th:onclick="'javascript:showimage(\''+${imgUrl}+'\');'"/>
+                            </div>
+                            <ul class="list-group collapse" th:id="'dup-list-' + ${masterBug.key}"
+                                style="max-height: 161px; min-height: 161px; overflow: scroll;" >
+                                <li class="list-group-item list-group-item-inner" th:each="bugId : ${masterBug.value}" >
+                                    <div th:id="'report-title-' + ${bugId}">
+                                        <span  th:text="${bugId}">{{ report.print_id
+                                            }}</span>
+                                    </div>
+                                    <div style="margin-top: 5px" th:text="${bugMap.get(bugId).description}">
+                                        {{ report.description }}
+                                    </div>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                </th:block>
+
+
+            </div><!-- /.box-body -->
+        </div>
+    </section>
+
+</th:block>
+</body>
+</html>
+<div class="modal fade bs-example-modal-lg text-center" id="imgModal" tabindex="-1" role="dialog"
+     aria-labelledby="myLargeModalLabel">
+
+    <div class="modal-dialog modal-lg" style="display: inline-block; max-width: 900px; max-height: 600px">
+        <div class="modal-content" style="background:  transparent">
+            <center>
+                <img id="imgInModalID"
+                     class="carousel-inner img-responsive "
+                     onclick="closeImageViewer()"
+                     onmouseover="this.style.cursor='pointer';this.style.cursor='hand'"
+                     onmouseout="this.style.cursor='default'"
+                     style="max-height: 90vh;
+                     max-width: 90vw;
+                     object-fit: contain;"
+                />
+            </center>
+        </div>
+    </div>
+</div>
+<script type="text/javascript">
+    //显示大图
+    function showimage(source) {
+        $("#imgModal").find("#imgInModalID").attr("src", source);
+        $("#imgModal").modal();
+    }
+
+    //关闭
+    function closeImageViewer() {
+        $("#imgModal").modal('hide');
+    }
+</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/js/all_reports.js"></script>