aggr_report.html 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. <!DOCTYPE html>
  2. <html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"
  3. xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
  4. layout:decorator="main">
  5. <head>
  6. <link rel="stylesheet" type="text/css" href="/static/css/main.css"/>
  7. <link rel="stylesheet" type="text/css" href="/static/css/agg_report.css"/>
  8. <link rel="stylesheet" type="text/css" href="/static/css/word_cloud.css"/>
  9. </head>
  10. <body>
  11. <th:block layout:fragment="sidebar">
  12. <li>
  13. <a th:href="'/final_reports?examId=' + ${examId} + '&amp;caseId=' + ${caseId}">
  14. <i class="fa fa-calendar-check-o"></i>
  15. <span>预交付报告</span>
  16. </a>
  17. </li>
  18. <li class="treeview">
  19. <a href="#">
  20. <i class="fa fa-list"></i>
  21. <span>Reports</span>
  22. <span class="pull-right-container">
  23. <i class="fa fa-angle-left pull-right"></i>
  24. </span>
  25. </a>
  26. <ul class="treeview-menu" style="display: block;">
  27. <li>
  28. <a th:href="'/task_detail?examId='+${examId}+'&amp;caseId='+${caseId}">
  29. <i class="fa fa-sticky-note text-success"></i>
  30. <span>默认视图</span>
  31. </a>
  32. </li>
  33. <li>
  34. <a th:href="'/agg_report_list?examId='+${examId}+'&amp;caseId='+${caseId}">
  35. <i class="fa fa-sitemap text-warning"></i>
  36. <span>聚合视图</span>
  37. </a>
  38. </li>
  39. </ul>
  40. </li>
  41. </th:block>
  42. <th:block layout:fragment="maincontent">
  43. <section class="content-header">
  44. <h1>融合报告详情
  45. <small th:text="${aggReportId}"></small>
  46. </h1>
  47. <!-- <h1>Summary for report 0-5</h1> -->
  48. <!-- <small style="font-style: italic;">at 50% report-level and 25% supplementary level</small> -->
  49. <ol class="breadcrumb">
  50. <!-- style="margin-right: 173px;" -->
  51. <li>
  52. <a href="/home">
  53. <i class="fa fa-dashboard"></i>
  54. 全部任务
  55. </a>
  56. </li>
  57. <li>
  58. <a th:href="'/agg_report_list?examId='+${examId}+'&amp;caseId='+${caseId}">
  59. 审核列表
  60. </a>
  61. </li>
  62. <li class="active" th:text="${aggReportId}">
  63. </li>
  64. </ol>
  65. </section>
  66. <section class="content container-fluid">
  67. <div style="overflow: auto;" class="row">
  68. <div class="col-md-8" id="summary">
  69. <div class="box box-info detail-table">
  70. <div class="box-header with-border" style="padding: 4px;">
  71. <i class="fa fa-object-group" style="color: #00c0ef;"></i>
  72. <h3 class="box-title" th:text="${aggReportId}">
  73. </h3>
  74. <button class="btn-xs btn-primary pull-right" id="create_bug" style="margin-left: 5px;" onclick="showCreateBlock()" th:if="${finalReportId == null}">创建缺陷报告
  75. </button>
  76. <button class="btn-xs btn-primary pull-right" id="review_confirm" th:unless="${reviewed}" onclick="reviewConfirm()">确认审核</button>
  77. <span th:if="${reviewed}" class="pull-right label label-success">
  78. <span class="glyphicon glyphicon-ok"></span>
  79. 已审核
  80. </span>
  81. </div>
  82. <table class="table table-reponsive">
  83. <tbody>
  84. <tr>
  85. <td class="attr-title">创建时间&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
  86. <td class="dup-create-time">2017-12-01 ~ 2017-12-05</td>
  87. <td class="attr-title">Bug 严重性</td>
  88. <td class="dup-severity">一般 ~ 严重
  89. </td>
  90. </tr>
  91. <tr>
  92. <td class="attr-title">Bug分类&nbsp;&nbsp;&nbsp;&nbsp;</td>
  93. <td class="dup-category" colspan="3">
  94. <!--<i class="fa fa-square" style="color: {{ category.category_color }};"></i>-->
  95. <span style="margin-right: 10px;" th:if="${categories == null}">暂无</span>
  96. <span style="margin-right: 10px;" th:if="${categories != null}" th:each="ca : ${categories}" th:text="${ca}"></span>
  97. </td>
  98. </tr>
  99. <tr>
  100. <td class="attr-title">审核人</td>
  101. <td class="dup-assignee" colspan="3">
  102. <a href="#" style="margin-right: 5px;">
  103. <i class="fa fa-vcard"></i>
  104. admin
  105. </a>
  106. </td>
  107. </tr><!-- Attribute -->
  108. <!-- Start Content -->
  109. <tr>
  110. <td class="attr-title">主要点<span class="glyphicon glyphicon-star"
  111. style="margin-left: 5px;"></span></td>
  112. <td class="dup-master" colspan="3">
  113. <span th:text="${masterReport.getDescription()}"></span><br/>
  114. <img class="my-img-thumbnail pointer to-add" th:src="${imgUrl}"
  115. th:each="imgUrl,iterStat : ${masterReport.getImgUrls()}"
  116. th:imgUrl="${imgUrl}"
  117. th:onclick="javascript:showimage(this.getAttribute('imgUrl'));"/>
  118. </td>
  119. </tr>
  120. <tr>
  121. <td class="attr-title">补充点</td>
  122. <td class="dup-supplementary" colspan="3">
  123. <ul id="sup-list" class="list-group"
  124. style="max-height: 450px; margin-bottom: 0px; overflow: scroll;">
  125. <li class="list-group-item" style="padding: 3px 3px;"
  126. th:each="supplement, iterStat : ${supplements}">
  127. <p style="border-bottom: 1px solid #ddd; margin: 0 0 1px;">
  128. <b><a href="#" th:text="'Supplementary ' + ${iterStat.count}"> </a></b>
  129. <a th:href="'#sup-' + ${iterStat.count}"
  130. class="glyphicon glyphicon-menu-hamburger pull-right sup-collapse"
  131. data-toggle="collapse" style="color: #000;"></a>
  132. </p>
  133. <div class="sup-title">
  134. <!-- 如果有文字,则仅显示top 1的diff_sentence,并且不展示图片 -->
  135. <span th:if="${supplement.hasTxt}"
  136. th:text="'...' + ${supplement.topTxt} + '...'"></span>
  137. <img th:if="${!supplement.hasTxt}" class="my-img-thumbnail pointer to-add"
  138. th:src="${imgUrl}" th:each="imgUrl,iterStat : ${supplement.top3Img}"
  139. th:imgUrl="${imgUrl}"
  140. th:onclick="javascript:showimage(this.getAttribute('imgUrl'));"/>
  141. </div>
  142. <div th:id="'sup-' + ${iterStat.count}" class="collapse">
  143. <ul class="list-group" style="margin-bottom: 0px;">
  144. <li class="list-group-item" style="padding: 3px 3px;"
  145. th:each="report : ${supplement.bugs}">
  146. <span class="glyphicon glyphicon-file"
  147. style="color: #3c8dbc; margin-right: 5px;"></span>
  148. <a href="#" style="margin-right: 5px;" th:text="${report.id}"></a>
  149. <!-- description -->
  150. <th:block th:each="sent, iterStat : ${report.taggedSentences}">
  151. <span th:if="${sent.isDiff()}" th:text="${sent.sentence}"
  152. style="color: red; font-weight: bold;"></span>
  153. <span th:unless="${sent.isDiff()}"
  154. th:text="${sent.sentence}"></span>
  155. </th:block>
  156. <br/>
  157. <!-- imgs -->
  158. <th:block th:each="img, iterStat : ${report.taggedImgs}">
  159. <img class="my-img-thumbnail pointer to-add"
  160. th:style="${img.isDiff()? 'border: 2px solid red;' : ''}"
  161. th:src="${img.imgUrl}"
  162. th:onclick="javascript:showimage(this.getAttribute('src'));"/>
  163. </th:block>
  164. </li>
  165. </ul>
  166. </div>
  167. </li>
  168. </ul>
  169. </td>
  170. </tr>
  171. </tbody>
  172. </table>
  173. </div>
  174. </div>
  175. <div class="col-md-4 pull-right">
  176. <div id="my_favorite_latin_words" class="box box-info" style="margin-bottom: 5px; min-height: 182px;"></div>
  177. <div class="box box-danger source-table" id="new-report-create-block" style="display: none">
  178. <div class="box-header" style="border-bottom: 1px #f4f4f4 solid;">
  179. <h3 class="box-title">
  180. 编辑报告
  181. </h3>
  182. <button class="btn-xs btn-primary pull-right" style="margin-left: 5px"
  183. onclick="createOrUpdateFinalReport()">保存
  184. </button>
  185. <button class="btn-xs btn-primary pull-right" onclick="hideCreateBlock()">取消</button>
  186. </div>
  187. <div id="new-report" class="box-body"
  188. style="font-size: 12px; max-height: 340px; overflow: scroll;">
  189. <form role="form">
  190. <!-- select -->
  191. <div class="form-group">
  192. <label>Bug 复现程度</label>
  193. <select id="recurrent" name="recurrent" class="form-control">
  194. <option th:each="mapItem : ${recurrent2String}" th:if="${mapItem.key !=0 }"
  195. th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
  196. </select>
  197. </div>
  198. <!-- select -->
  199. <div class="form-group">
  200. <label>Bug 严重性</label>
  201. <select id="severity" name="severity" class="form-control">
  202. <option th:each="mapItem : ${severity2String}" th:if="${mapItem.key !=0 }"
  203. th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
  204. </select>
  205. </div>
  206. <!-- select -->
  207. <div class="form-group">
  208. <label>Bug 分类</label>
  209. <select id="category" class="form-control">
  210. <option th:each="mapItem : ${category2String}" th:if="${mapItem.key !=0 }"
  211. th:value="${mapItem.key}" th:text="${mapItem.value}">必现</option>
  212. </select>
  213. </div>
  214. <!-- textarea -->
  215. <div class="form-group">
  216. <label>Bug 描述</label>
  217. <textarea id="bug-description" name="description" class="form-control" rows="3"
  218. placeholder="Enter ..."></textarea>
  219. </div>
  220. <div class="form-group">
  221. <label>Bug 截图</label>
  222. <div id="new-report-img"></div>
  223. </div>
  224. </form>
  225. </div>
  226. </div>
  227. <div class="box box-info source-table" id="new-report-list-block">
  228. <div class="box-header">
  229. <h3 class="box-title">
  230. 已创建报告
  231. </h3>
  232. </div>
  233. <div id="new-created-reports" class="box-body"
  234. style="font-size: 12px; max-height: 340px; overflow: scroll;">
  235. <div th:if="${finalReports.size() == 0}" style="font-size: 20px">
  236. 暂无 <a onclick="showCreateBlock()" style="cursor: pointer">立即创建报告</a>
  237. </div>
  238. <ul class="list-group">
  239. <!-- other reports -->
  240. <th:block th:each="finalReport : ${finalReports}">
  241. <li class="list-group-item">
  242. <div style="overflow: auto;">
  243. <a href="#" th:text="${finalReport.id}"></a>
  244. <span class="pull-right">
  245. <a th:href="'report?masterId='+${finalReport.sourceId}+'&amp;examId='+${examId}+'&amp;caseId='+${caseId}+'&amp;finalReportId='+${finalReport.id}">编辑</a>
  246. <a href="#" th:finalId="${finalReport.id}" th:onclick="javascript:deleteReport(this.getAttribute('finalId'))">删除</a>
  247. </span>
  248. </div>
  249. <div>
  250. <span>
  251. 复现程度:<span th:text="${recurrent2String.get(finalReport.recurrent)}"></span>
  252. </span>
  253. <span class="pull-right">
  254. 分类:<span th:text="${category2String.get(finalReport.category)}"></span>
  255. </span>
  256. </div>
  257. <div>
  258. 严重程度:<span th:text="${severity2String.get(finalReport.severity)}"></span>
  259. </div>
  260. <br/>
  261. <span th:text="${finalReport.description}"></span>
  262. <br/>
  263. <img class="my-img-thumbnail pointer to-add" th:src="${imgUrl}"
  264. th:each="imgUrl,iterStat : ${finalReport.getImgUrls()}"
  265. th:onclick="javascript:showimage(this.getAttribute('src'));"/>
  266. </li>
  267. </th:block>
  268. </ul>
  269. </div>
  270. </div>
  271. </div>
  272. </div>
  273. <div style="overflow: auto;" class="row">
  274. <div class="col-md-8">
  275. <div class="box box-info pull-left svg-div"
  276. style="background-image: url('static/images/link/dark_opt.jpg'); background-size: cover;">
  277. <h4 style="color: #fff; padding-left: 10px;" class="pull-left">聚合图</h4>
  278. <svg width="660" height="450" style="margin-top: -40px;"></svg>
  279. </div>
  280. </div>
  281. <div class="col-md-4">
  282. <div class="detail-div"
  283. style="height: 459px; max-height: 459px; font-size: 10px; overflow: scroll;">
  284. </div>
  285. </div>
  286. </div>
  287. </section>
  288. </th:block>
  289. </body>
  290. </html>
  291. <div class="modal fade bs-example-modal-lg text-center" id="imgModal" tabindex="-1" role="dialog"
  292. aria-labelledby="myLargeModalLabel">
  293. <div class="modal-dialog modal-lg" style="display: inline-block; width: 300px;">
  294. <div class="modal-content">
  295. <img id="imgInModalID"
  296. class="carousel-inner img-responsive img-rounded"
  297. onclick="closeImageViewer()"
  298. onmouseover="this.style.cursor='pointer';this.style.cursor='hand'"
  299. onmouseout="this.style.cursor='default'"
  300. />
  301. </div>
  302. </div>
  303. </div>
  304. <script type="text/javascript">
  305. //显示大图
  306. function showimage(source) {
  307. $("#imgModal").find("#imgInModalID").attr("src", source);
  308. $("#imgModal").modal();
  309. }
  310. //关闭
  311. function closeImageViewer() {
  312. $("#imgModal").modal('hide');
  313. }
  314. </script>
  315. <script src="https://d3js.org/d3.v4.min.js"></script>
  316. <script type="text/javascript" src="/static/js/agg_report.js"></script>
  317. <script type="text/javascript" src="/static/js/jqcloud-1.0.4.min.js"></script>
  318. <script type="text/javascript" xmlns:th="http://www.thymeleaf.org" th:inline="javascript">
  319. /*<![CDATA[*/
  320. var word_list = /*[[${wordList}]]*/;
  321. var urlParams = new URLSearchParams(window.location.search);
  322. var masterId = urlParams.get('masterId');
  323. var examId = urlParams.get('examId');
  324. var caseId = urlParams.get('caseId');
  325. var finalReportId = urlParams.get('finalReportId');
  326. /*]]>*/
  327. word_list = JSON.parse(word_list)
  328. var images = [];
  329. $(function () {
  330. $("#my_favorite_latin_words").jQCloud(word_list,
  331. {
  332. shape: "rectangular",
  333. autoResize: true
  334. });
  335. var urlParams = new URLSearchParams(window.location.search);
  336. if (urlParams.get("finalReportId")) {
  337. showCreateBlock()
  338. /*<![CDATA[*/
  339. var editReport = /*[[${editReport}]]*/;
  340. /*]]>*/
  341. fillNewReportBlock(editReport);
  342. }
  343. });
  344. function createOrUpdateFinalReport() {
  345. var report = {
  346. 'description': $("#bug-description").val(),
  347. 'severity': $("#severity").val(),
  348. 'recurrent': $("#recurrent").val(),
  349. 'category': $("#category").val(),
  350. 'sourceId': masterId,
  351. 'reviewerId': 1,
  352. 'examId': examId,
  353. 'caseId': caseId,
  354. 'imgUrls': images
  355. }
  356. if (finalReportId) {
  357. report.id = finalReportId
  358. $.ajax({
  359. type: "PUT",
  360. url: '/final_report/'+finalReportId,
  361. data: JSON.stringify(report),
  362. contentType: "application/json",
  363. success: function (data) {
  364. /*<![CDATA[*/
  365. window.location.href='report?masterId='+masterId+'&examId='+examId+'&caseId='+caseId
  366. /*]]>*/ }
  367. });
  368. } else {
  369. $.ajax({
  370. type: "POST",
  371. url: '/final_report',
  372. data: JSON.stringify(report),
  373. contentType: "application/json",
  374. success: function (data) {
  375. location.reload()
  376. }
  377. });
  378. }
  379. }
  380. function showCreateBlock() {
  381. $("#new-report-create-block").show()
  382. $("#new-report-list-block").hide()
  383. }
  384. function hideCreateBlock() {
  385. if (finalReportId){
  386. /*<![CDATA[*/
  387. window.location.href='report?masterId='+masterId+'&examId='+examId+'&caseId='+caseId
  388. /*]]>*/
  389. }
  390. $("#new-report-create-block").hide()
  391. $("#new-report-list-block").show()
  392. }
  393. function fillNewReportBlock(editReport) {
  394. console.log(editReport)
  395. $("#recurrent").val(editReport.recurrent);
  396. $("#severity").val(editReport.severity);
  397. $("#category").val(editReport.category);
  398. $("#bug-description").val(editReport.description);
  399. var $new_report_img = $("#new-report-img");
  400. /*<![CDATA[*/
  401. for (var i=0;i<editReport.imgUrls.length;i++) {
  402. var src = editReport.imgUrls[i]
  403. var $img = $('<img />')
  404. $img.attr("src", src);
  405. $img.attr("class", "my-img-thumbnail pointer to-delete");
  406. $img.on("click", function (){
  407. showimage(src);
  408. });
  409. $img.on("dragend", function (e) {
  410. var src = $(e.target).attr("src");
  411. var idx = images.indexOf(src);
  412. if (idx >= 0) {
  413. images.splice(idx, 1);
  414. }
  415. $(e.target).remove();
  416. });
  417. $new_report_img.append($img)
  418. }
  419. /*]]>*/
  420. $("#new-report-img").val(editReport.description);
  421. }
  422. function deleteReport(finalReportId) {
  423. $.ajax({
  424. url: '/final_report/' + finalReportId,
  425. type: 'DELETE',
  426. success: function (result) {
  427. // Do something with the result
  428. alert("删除成功");
  429. location.reload();
  430. }
  431. });
  432. }
  433. function reviewConfirm() {
  434. $.ajax({
  435. url: '/bug_review?masterId='+masterId,
  436. type: 'PUT',
  437. success: function (result) {
  438. alert("确认审核成功,修改报告状态为已审核");
  439. location.reload();
  440. }
  441. });
  442. }
  443. </script>