DataService.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. package edu.nju.service;
  2. import com.alibaba.fastjson.JSON;
  3. import edu.nju.dao.*;
  4. import edu.nju.entities.*;
  5. import edu.nju.util.TransUtil;
  6. import org.json.JSONArray;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.stereotype.Service;
  9. import java.io.*;
  10. import java.lang.reflect.Field;
  11. import java.net.HttpURLConnection;
  12. import java.net.URL;
  13. import java.net.URLConnection;
  14. import java.nio.charset.StandardCharsets;
  15. import java.util.ArrayList;
  16. import java.util.HashSet;
  17. import java.util.List;
  18. import java.util.Set;
  19. import java.util.zip.ZipEntry;
  20. import java.util.zip.ZipOutputStream;
  21. /**
  22. * @Author JiaWei Xu
  23. * @Date 2020-12-25 10:45
  24. * @Email xjwhhh233@outlook.com
  25. */
  26. @Service
  27. public class DataService {
  28. private static final int BUFFER_SIZE = 2 * 1024;
  29. private static final String imageUrlPrefix="https://mooctest-site.oss-cn-shanghai.aliyuncs.com/xinchuang/image/";
  30. @Autowired
  31. ExamDao examDao;
  32. @Autowired
  33. BugDao bugDao;
  34. @Autowired
  35. ReportDao reportDao;
  36. @Autowired
  37. TestCaseDao testCaseDao;
  38. @Autowired
  39. CaseToBugDao caseToBugDao;
  40. @Autowired
  41. BugScoreDao bugScoreDao;
  42. @Autowired
  43. BugMirrorDao bugMirrorDao;
  44. @Autowired
  45. BugHistoryDao bugHistoryDao;
  46. @Autowired
  47. BugDetailDao bugDetailDao;
  48. private String cpSerialNum = "cp_ent_dev";
  49. /**
  50. * 根据caseId获取对应bug信息
  51. *
  52. * @param caseId
  53. * @return
  54. */
  55. public List<BugDetail> getBugDetailByCaseId(String caseId) {
  56. List<BugDetail> bugDetailList = new ArrayList<>();
  57. Exam crowdCase = examDao.findById(caseId);
  58. if (crowdCase != null) {
  59. List<Report> reportList = reportDao.findByCaseId(caseId);
  60. for (Report report : reportList) {
  61. String reportId = report.getId();
  62. List<TestCase> testCaseList = testCaseDao.findByReport(reportId);
  63. for (TestCase testCase : testCaseList) {
  64. String testCaseId = testCase.getId();
  65. CaseToBug caseToBug = caseToBugDao.findById(testCaseId);
  66. if (caseToBug != null) {
  67. List<String> bugIdList = caseToBug.getBug_id();
  68. for (String bugId : bugIdList) {
  69. BugDetail bugDetail = new BugDetail();
  70. bugDetail.setId(bugId);
  71. //bug基本属性
  72. Bug bug = bugDao.findByid(bugId);
  73. if (bug != null) {
  74. bugDetail.setBugCategory(bug.getBug_category());
  75. bugDetail.setSeverity(TransUtil.severityTransFromInt(bug.getSeverity()));
  76. bugDetail.setRecurrent(TransUtil.recurrentTransFromInt(bug.getRecurrent()));
  77. bugDetail.setBugCreateTime(TransUtil.formatTimeMillis(bug.getCreate_time_millis()));
  78. bugDetail.setBugPage(bug.getBug_page());
  79. bugDetail.setTitle(bug.getTitle());
  80. bugDetail.setBugDescription(bug.getDescription());
  81. bugDetail.setImgUrl(bug.getImg_url());
  82. }
  83. //bugScore属性
  84. BugScore bugScore = bugScoreDao.findById(bugId);
  85. if (bugScore != null) {
  86. bugDetail.setScore(bugScore.getGrade());
  87. }
  88. //bugMirror属性
  89. BugMirror bugMirror = bugMirrorDao.findById(bugId);
  90. if (bugMirror != null) {
  91. Set<String> goodWorkerIdSet = new HashSet<>();
  92. Set<String> badWorkerIdSet = new HashSet<>();
  93. Set<String> goodReportIdSet = bugMirror.getGood();
  94. Set<String> badReportIdSet = bugMirror.getBad();
  95. int goodNum = 0;
  96. int badNum = 0;
  97. for (String goodReportId : goodReportIdSet) {
  98. Report goodReport = reportDao.findById(goodReportId);
  99. if (goodReport != null) {
  100. goodNum++;
  101. goodWorkerIdSet.add(goodReport.getWorker_id());
  102. }
  103. }
  104. for (String badReportId : badReportIdSet) {
  105. Report badReport = reportDao.findById(badReportId);
  106. if (badReport != null) {
  107. badNum++;
  108. badWorkerIdSet.add(badReport.getWorker_id());
  109. }
  110. }
  111. bugDetail.setGoodNum(goodNum);
  112. bugDetail.setBadNum(badNum);
  113. bugDetail.setGoodWorkerId(goodWorkerIdSet);
  114. bugDetail.setBadWorkerId(badWorkerIdSet);
  115. }
  116. //bugHistory属性
  117. BugHistory bugHistory = bugHistoryDao.findByid(bugId);
  118. if (bugHistory != null) {
  119. bugDetail.setParent(bugHistory.getParent());
  120. bugDetail.setChildren(bugHistory.getChildren());
  121. bugDetail.setRoot(bugHistory.getRoot());
  122. }
  123. //testCase属性
  124. bugDetail.setTestCaseId(testCase.getId());
  125. bugDetail.setTestCaseName(testCase.getName());
  126. bugDetail.setTestCaseFront(testCase.getFront());
  127. bugDetail.setTestCaseBehind(testCase.getBehind());
  128. bugDetail.setTestCaseDescription(testCase.getDescription());
  129. bugDetail.setTestCaseCreateTime(TransUtil.formatTimeMillis(testCase.getCreate_time_millis()));
  130. //report属性
  131. bugDetail.setReportId(report.getId());
  132. bugDetail.setReportName(report.getName());
  133. bugDetail.setScriptLocation(report.getScript_location());
  134. bugDetail.setReportLocation(report.getReport_location());
  135. bugDetail.setLogLocation(report.getLog_location());
  136. bugDetail.setDeviceModel(report.getDevice_model());
  137. bugDetail.setDeviceBrand(report.getDevice_brand());
  138. bugDetail.setDeviceOs(report.getDevice_os());
  139. //worker属性
  140. bugDetail.setWorkerId(report.getWorker_id());
  141. //众测任务属性
  142. bugDetail.setCaseAppName(crowdCase.getName());
  143. bugDetail.setCasePaperType(crowdCase.getPaper_type());
  144. bugDetail.setCaseTestType(crowdCase.getTest_type());
  145. bugDetail.setCaseDescription(crowdCase.getDescription());
  146. bugDetail.setCaseRequireDoc("");
  147. bugDetail.setCaseTakeId(report.getCase_take_id());
  148. //cp序列号
  149. bugDetail.setCpSerialNum(cpSerialNum);
  150. bugDetailList.add(bugDetail);
  151. }
  152. }
  153. }
  154. }
  155. }
  156. bugDetailToFile(bugDetailList, caseId);
  157. return bugDetailList;
  158. }
  159. public List<BugDetail> saveBugDetailFromOss(String jsonFilePath, String originalCaseId,String cpSerialNum) {
  160. try {
  161. //从oss下载json文件
  162. URL url = new URL(jsonFilePath);
  163. URLConnection urlConnection = url.openConnection();
  164. HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
  165. httpURLConnection.setConnectTimeout(1000 * 5);
  166. httpURLConnection.setRequestProperty("Charset", "UTF-8");
  167. httpURLConnection.connect();
  168. BufferedInputStream bufferedInputStream = new BufferedInputStream(httpURLConnection.getInputStream());
  169. ByteArrayOutputStream buf = new ByteArrayOutputStream();
  170. int result = bufferedInputStream.read();
  171. while (result != -1) {
  172. buf.write((byte) result);
  173. result = bufferedInputStream.read();
  174. }
  175. String json = buf.toString();
  176. //转为bugDetail
  177. List<BugDetail> bugDetailList = JSON.parseArray(json, BugDetail.class);
  178. for (BugDetail bugDetail : bugDetailList) {
  179. bugDetail.setOriginalCaseId(originalCaseId);
  180. //修改图片文件路径为oss路径
  181. String imageUrl=bugDetail.getImgUrl();
  182. String[] imageUrlArray=imageUrl.split(",");
  183. StringBuilder stringBuilder=new StringBuilder();
  184. for(String imageUrlStr:imageUrlArray){
  185. String[] filePath=imageUrlStr.split("/");
  186. String fileName=filePath[filePath.length-1];
  187. String newImageUrl=imageUrlPrefix+originalCaseId+"/"+cpSerialNum+"/"+fileName;
  188. stringBuilder.append(newImageUrl).append(",");
  189. }
  190. bugDetail.setImgUrl(stringBuilder.toString());
  191. bugDetailDao.save(bugDetail);
  192. }
  193. return bugDetailList;
  194. } catch (IOException e) {
  195. e.printStackTrace();
  196. }
  197. return new ArrayList<>();
  198. }
  199. private void bugDetailToFile(List<BugDetail> bugDetailList, String caseId) {
  200. String[] titles = {"bug_id", "bug_category", "severity", "recurrent", "bug_create_time", "bug_page", "title",
  201. "description", "img_url",
  202. "score", "parent", "children", "root", "good_num", "good_worker_id", "bad_num", "bad_worker_id",
  203. "test_case_id", "test_case_name", "test_case_front", "test_case_behind", "test_case_description", "test_case_create_time",
  204. "report_id", "report_name", "report_create_time", "script_location", "report_location", "log_location", "device_model", "device_brand", "device_os",
  205. "worker_id",
  206. "case_app_name", "case_paper_type", "case_test_type", "case_description", "case_require_doc",
  207. "case_take_id", "originalCaseId", "cpSerialNum"};
  208. //导出文件
  209. exportCsv(titles, bugDetailList, caseId);
  210. exportJson(bugDetailList, caseId);
  211. //导出图片zip包
  212. String sourceFile = "/data/image/" + caseId;
  213. try {
  214. FileOutputStream fileOutputStream = new FileOutputStream(new File("/data/imageZip/" + caseId + ".zip"));
  215. toZip(sourceFile, fileOutputStream, false);
  216. } catch (FileNotFoundException e) {
  217. e.printStackTrace();
  218. }
  219. }
  220. private void exportJson(List<BugDetail> bugDetailList, String caseId) {
  221. try {
  222. File file = new File("data/output/" + caseId + "/" + caseId + ".json");
  223. JSONArray jsonArray = new JSONArray(bugDetailList);
  224. Writer write = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
  225. write.write(jsonArray.toString());
  226. write.flush();
  227. write.close();
  228. } catch (IOException e) {
  229. e.printStackTrace();
  230. }
  231. }
  232. private <T> void exportCsv(String[] titles, List<T> list, String caseId) {
  233. try {
  234. File file = new File("data/output/" + caseId + "/" + caseId + ".csv");
  235. //构建输出流,同时指定编码
  236. OutputStreamWriter ow = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
  237. //csv文件是逗号分隔,除第一个外,每次写入一个单元格数据后需要输入逗号
  238. for (String title : titles) {
  239. ow.write(title);
  240. ow.write(",");
  241. }
  242. //写完文件头后换行
  243. ow.write("\r\n");
  244. //写内容
  245. for (Object obj : list) {
  246. //利用反射获取所有字段
  247. Field[] fields = obj.getClass().getDeclaredFields();
  248. for (Field field : fields) {
  249. //设置字段可见性
  250. field.setAccessible(true);
  251. //防止某个field没有赋值
  252. if (field.get(obj) == null) {
  253. ow.write("");
  254. } else {
  255. //解决csv文件中对于逗号和双引号的转义问题
  256. ow.write("\"" + field.get(obj).toString().replaceAll("\"", "\"\"") + "\"");
  257. }
  258. ow.write(",");
  259. }
  260. //写完一行换行
  261. ow.write("\r\n");
  262. }
  263. ow.flush();
  264. ow.close();
  265. } catch (IOException | IllegalAccessException e) {
  266. e.printStackTrace();
  267. }
  268. }
  269. private void toZip(String srcDir, OutputStream out, boolean keepDirStructure)
  270. throws RuntimeException {
  271. long start = System.currentTimeMillis();
  272. ZipOutputStream zos = null;
  273. try {
  274. zos = new ZipOutputStream(out);
  275. File sourceFile = new File(srcDir);
  276. compress(sourceFile, zos, sourceFile.getName(), keepDirStructure);
  277. long end = System.currentTimeMillis();
  278. System.out.println("压缩完成,耗时:" + (end - start) + " ms");
  279. } catch (Exception e) {
  280. throw new RuntimeException("zip error from ZipUtils", e);
  281. } finally {
  282. if (zos != null) {
  283. try {
  284. zos.close();
  285. } catch (IOException e) {
  286. e.printStackTrace();
  287. }
  288. }
  289. }
  290. }
  291. /**
  292. * 递归压缩方法
  293. *
  294. * @param sourceFile 源文件
  295. * @param zos zip输出流
  296. * @param name 压缩后的名称
  297. * @param keepDirStructure 是否保留原来的目录结构,true:保留目录结构;
  298. * false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
  299. * @throws Exception
  300. */
  301. private void compress(File sourceFile, ZipOutputStream zos, String name,
  302. boolean keepDirStructure) throws Exception {
  303. byte[] buf = new byte[BUFFER_SIZE];
  304. if (sourceFile.isFile()) {
  305. // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
  306. zos.putNextEntry(new ZipEntry(name));
  307. // copy文件到zip输出流中
  308. int len;
  309. FileInputStream in = new FileInputStream(sourceFile);
  310. while ((len = in.read(buf)) != -1) {
  311. zos.write(buf, 0, len);
  312. }
  313. // Complete the entry
  314. zos.closeEntry();
  315. in.close();
  316. } else {
  317. File[] listFiles = sourceFile.listFiles();
  318. if (listFiles == null || listFiles.length == 0) {
  319. // 需要保留原来的文件结构时,需要对空文件夹进行处理
  320. if (keepDirStructure) {
  321. // 空文件夹的处理
  322. zos.putNextEntry(new ZipEntry(name + "/"));
  323. // 没有文件,不需要文件的copy
  324. zos.closeEntry();
  325. }
  326. } else {
  327. for (File file : listFiles) {
  328. // 判断是否需要保留原来的文件结构
  329. if (keepDirStructure) {
  330. // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
  331. // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
  332. compress(file, zos, name + "/" + file.getName(), true);
  333. } else {
  334. compress(file, zos, file.getName(), false);
  335. }
  336. }
  337. }
  338. }
  339. }
  340. }