Showing
15 changed files
with
1237 additions
and
11 deletions
@@ -97,6 +97,38 @@ | @@ -97,6 +97,38 @@ | ||
97 | <artifactId>easyexcel</artifactId> | 97 | <artifactId>easyexcel</artifactId> |
98 | <version>3.1.0</version> | 98 | <version>3.1.0</version> |
99 | </dependency> | 99 | </dependency> |
100 | + <dependency> | ||
101 | + <groupId>org.apache.poi</groupId> | ||
102 | + <artifactId>poi-ooxml</artifactId> | ||
103 | + <version>4.1.2</version> | ||
104 | + </dependency> | ||
105 | + <dependency> | ||
106 | + <groupId>org.apache.poi</groupId> | ||
107 | + <artifactId>poi-scratchpad</artifactId> | ||
108 | + <version>4.1.2</version> | ||
109 | + </dependency> | ||
110 | + <dependency> | ||
111 | + <groupId>org.apache.poi</groupId> | ||
112 | + <artifactId>poi-excelant</artifactId> | ||
113 | + <version>4.1.2</version> | ||
114 | + </dependency> | ||
115 | + <dependency> | ||
116 | + <groupId>org.apache.poi</groupId> | ||
117 | + <artifactId>poi-ooxml-schemas</artifactId> | ||
118 | + <version>4.1.2</version> | ||
119 | + </dependency> | ||
120 | + <dependency> | ||
121 | + <groupId>org.jfree</groupId> | ||
122 | + <artifactId>jfreechart</artifactId> | ||
123 | + <version>1.5.3</version> | ||
124 | + </dependency> | ||
125 | + <dependency> | ||
126 | + <groupId>com.deepoove</groupId> | ||
127 | + <artifactId>poi-tl</artifactId> | ||
128 | + <version>1.10.0</version> | ||
129 | + </dependency> | ||
130 | + | ||
131 | + | ||
100 | </dependencies> | 132 | </dependencies> |
101 | <build> | 133 | <build> |
102 | <plugins> | 134 | <plugins> |
@@ -3,20 +3,35 @@ package com.ash.controller; | @@ -3,20 +3,35 @@ package com.ash.controller; | ||
3 | import com.ash.base.*; | 3 | import com.ash.base.*; |
4 | import com.ash.entity.Case; | 4 | import com.ash.entity.Case; |
5 | import com.ash.entity.CaseAnalysis; | 5 | import com.ash.entity.CaseAnalysis; |
6 | +import com.ash.entity.WarningInstance; | ||
7 | +import com.ash.entity.WarningInstanceAnalysis; | ||
8 | +import com.ash.enums.JFChartTypeEnum; | ||
6 | import com.ash.service.CaseAnalysisService; | 9 | import com.ash.service.CaseAnalysisService; |
7 | import com.ash.service.CaseService; | 10 | import com.ash.service.CaseService; |
11 | +import com.ash.service.WarningInstanceAnalysisService; | ||
8 | import com.ash.service.WarningInstanceService; | 12 | import com.ash.service.WarningInstanceService; |
9 | -import com.ash.util.DateUtils; | 13 | +import com.ash.util.*; |
14 | +import com.deepoove.poi.XWPFTemplate; | ||
15 | +import com.deepoove.poi.config.Configure; | ||
16 | +import com.deepoove.poi.data.PictureType; | ||
17 | +import com.deepoove.poi.data.Pictures; | ||
18 | +import com.deepoove.poi.data.Tables; | ||
19 | +import com.deepoove.poi.data.style.BorderStyle; | ||
10 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
11 | import org.apache.commons.collections.CollectionUtils; | 21 | import org.apache.commons.collections.CollectionUtils; |
22 | +import org.apache.commons.collections4.MapUtils; | ||
12 | import org.apache.commons.lang3.StringUtils; | 23 | import org.apache.commons.lang3.StringUtils; |
24 | +import org.springframework.core.io.ClassPathResource; | ||
13 | import org.springframework.web.bind.annotation.*; | 25 | import org.springframework.web.bind.annotation.*; |
14 | 26 | ||
15 | import javax.annotation.Resource; | 27 | import javax.annotation.Resource; |
16 | -import java.util.ArrayList; | ||
17 | -import java.util.HashMap; | ||
18 | -import java.util.List; | ||
19 | -import java.util.Map; | 28 | +import javax.servlet.http.HttpServletResponse; |
29 | +import java.io.*; | ||
30 | +import java.nio.charset.StandardCharsets; | ||
31 | +import java.text.ParseException; | ||
32 | +import java.text.SimpleDateFormat; | ||
33 | +import java.util.*; | ||
34 | +import java.util.concurrent.atomic.AtomicReference; | ||
20 | import java.util.stream.Collectors; | 35 | import java.util.stream.Collectors; |
21 | import java.util.stream.Stream; | 36 | import java.util.stream.Stream; |
22 | 37 | ||
@@ -29,6 +44,9 @@ public class StatisticsController extends BaseController { | @@ -29,6 +44,9 @@ public class StatisticsController extends BaseController { | ||
29 | private WarningInstanceService warningInstanceService; | 44 | private WarningInstanceService warningInstanceService; |
30 | 45 | ||
31 | @Resource | 46 | @Resource |
47 | + private WarningInstanceAnalysisService warningInstanceAnalysisService; | ||
48 | + | ||
49 | + @Resource | ||
32 | private CaseAnalysisService caseAnalysisService; | 50 | private CaseAnalysisService caseAnalysisService; |
33 | 51 | ||
34 | @Resource | 52 | @Resource |
@@ -168,6 +186,11 @@ public class StatisticsController extends BaseController { | @@ -168,6 +186,11 @@ public class StatisticsController extends BaseController { | ||
168 | 186 | ||
169 | } | 187 | } |
170 | 188 | ||
189 | + dataList.sort((d1, d2) -> { | ||
190 | + double value = ObjectValueOption.getObjDouble(d2.getValue()) - ObjectValueOption.getObjDouble(d1.getValue()); | ||
191 | + return (int) value; | ||
192 | + }); | ||
193 | + | ||
171 | 194 | ||
172 | return JsonResult.ok(OptionStatus.OPT_SUCCESS.getName(), dataList); | 195 | return JsonResult.ok(OptionStatus.OPT_SUCCESS.getName(), dataList); |
173 | } catch (Exception ex) { | 196 | } catch (Exception ex) { |
@@ -224,6 +247,11 @@ public class StatisticsController extends BaseController { | @@ -224,6 +247,11 @@ public class StatisticsController extends BaseController { | ||
224 | 247 | ||
225 | } | 248 | } |
226 | 249 | ||
250 | + dataList.sort((d1, d2) -> { | ||
251 | + double value = ObjectValueOption.getObjDouble(d2.getValue()) - ObjectValueOption.getObjDouble(d1.getValue()); | ||
252 | + return (int) value; | ||
253 | + }); | ||
254 | + | ||
227 | 255 | ||
228 | return JsonResult.ok(OptionStatus.OPT_SUCCESS.getName(), dataList); | 256 | return JsonResult.ok(OptionStatus.OPT_SUCCESS.getName(), dataList); |
229 | } catch (Exception ex) { | 257 | } catch (Exception ex) { |
@@ -351,4 +379,356 @@ public class StatisticsController extends BaseController { | @@ -351,4 +379,356 @@ public class StatisticsController extends BaseController { | ||
351 | } | 379 | } |
352 | 380 | ||
353 | 381 | ||
382 | + @GetMapping("/downloadReport") | ||
383 | + public void downloadReport(@RequestParam(value = "startTime", required = true) String startTime, | ||
384 | + @RequestParam(value = "endTime", required = true) String endTime, | ||
385 | + HttpServletResponse response) throws ParseException, IOException { | ||
386 | + Map<String, Object> dataMap = new HashMap<>(); | ||
387 | + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); | ||
388 | + StatisticsParams statisticsParams = new StatisticsParams(); | ||
389 | + statisticsParams.setStartTime(DateUtils.weeHours(sdf.parse(startTime), 0)); | ||
390 | + statisticsParams.setEndTime(DateUtils.weeHours(sdf.parse(endTime), 1)); | ||
391 | + JsonResult totalWiInfo = totalWiInfo(statisticsParams); | ||
392 | + dataMap.put("totalInfo", totalWiInfo.getData()); | ||
393 | + | ||
394 | + JsonResult totalCaseInfo = totalCaseInfo(statisticsParams); | ||
395 | + dataMap.put("totalCaseInfo", totalCaseInfo.getData()); | ||
396 | + | ||
397 | + //警情各地市分布饼图 | ||
398 | + List<PieChartVo> wiAreaData = warningInstanceService.statisticsCountByArea(statisticsParams); | ||
399 | + dataMap.put("wiAreaData", wiAreaData); | ||
400 | + | ||
401 | + //警情各地市环比变化柱状图 | ||
402 | + JsonResult wissAreaData = wiStatisticsSequentialByArea(statisticsParams); | ||
403 | + dataMap.put("wissAreaData", wissAreaData.getData()); | ||
404 | + | ||
405 | + //警情子类分布 | ||
406 | + List<PieChartVo> wiSubTypeData = warningInstanceService.statisticsCountBySubType(statisticsParams); | ||
407 | + dataMap.put("wiSubTypeData", wiSubTypeData); | ||
408 | + | ||
409 | + //警情趋势 | ||
410 | + List<BarChartVo> wisDateData = warningInstanceService.statisticsByDate(statisticsParams); | ||
411 | + List<PieChartVo> pdWisDateData = wisDateData.stream() | ||
412 | + .map(e -> new PieChartVo(e.getName(), e.getValue())).collect(Collectors.toList()); | ||
413 | + dataMap.put("wisDateData", pdWisDateData); | ||
414 | + | ||
415 | + //案件各地市分布 | ||
416 | + List<PieChartVo> caseAreaData = caseService.statisticsCountByArea(statisticsParams); | ||
417 | + dataMap.put("caseAreaData", caseAreaData); | ||
418 | + | ||
419 | + //电诈案件环比情况 | ||
420 | + JsonResult caseSsAreaData = caseStatisticsSequentialByArea(statisticsParams); | ||
421 | + dataMap.put("caseSsAreaData", caseSsAreaData.getData()); | ||
422 | + | ||
423 | + //案件诈骗类型分布 | ||
424 | + JsonResult csfData = caseStatisticsByFraudType(statisticsParams); | ||
425 | + dataMap.put("csfData", csfData.getData()); | ||
426 | + | ||
427 | + //案件引流方式分布图 | ||
428 | + List<PieChartVo> ccrmData = caseService.statisticsCountByRainageMethod(statisticsParams); | ||
429 | + dataMap.put("ccrmData", ccrmData); | ||
430 | + | ||
431 | + //案件支付方式分布图 | ||
432 | + List<PieChartVo> ccpmData = caseService.statisticsCountByPayMethod(statisticsParams); | ||
433 | + dataMap.put("ccpmData", ccpmData); | ||
434 | + | ||
435 | + //案件受害人职业分布图 | ||
436 | + List<PieChartVo> ccCareerData = caseService.statisticsCountByCareer(statisticsParams); | ||
437 | + dataMap.put("ccCareerData", ccCareerData); | ||
438 | + | ||
439 | + //案损分布 | ||
440 | + List<PieChartVo> ccLossData = caseService.statisticsByLoss(statisticsParams); | ||
441 | + dataMap.put("ccLossData", ccLossData); | ||
442 | + | ||
443 | + //发案趋势 | ||
444 | + List<PieChartVo> ccDateData = caseService.statisticsByDate(statisticsParams); | ||
445 | + dataMap.put("ccDateData", ccDateData); | ||
446 | + | ||
447 | + //案件受害人性别占比 | ||
448 | + List<PieChartVo> sexData = caseService.statisticsCountBySex(statisticsParams); | ||
449 | + dataMap.put("sexData", sexData); | ||
450 | + | ||
451 | + //案件受害人年龄占比 | ||
452 | + List<PieChartVo> ageData = caseService.statisticsByAge(statisticsParams); | ||
453 | + dataMap.put("ageData", ageData); | ||
454 | + | ||
455 | + //50w以上案件 | ||
456 | + JsonResult majorCaseData = majorCasePage(statisticsParams); | ||
457 | + dataMap.put("majorCaseData", majorCaseData.getData()); | ||
458 | + | ||
459 | + //50w以上警情 | ||
460 | + List<WarningInstance> majorWiData = warningInstanceService.majorWiPage(statisticsParams); | ||
461 | + if (CollectionUtils.isNotEmpty(majorWiData)) { | ||
462 | + List<String> wiIds = majorWiData | ||
463 | + .stream().map(WarningInstance::getId).collect(Collectors.toList()); | ||
464 | + Map<String, WarningInstanceAnalysis> analysisMap = warningInstanceAnalysisService.listByWiId(wiIds); | ||
465 | + majorWiData.forEach(e -> e.setAnalysis(analysisMap.get(e.getId()))); | ||
466 | + } | ||
467 | + dataMap.put("majorWiData", majorWiData); | ||
468 | + | ||
469 | + // 生成最终文件路径 | ||
470 | + String fileName = UUIDGenerator.uuid() + ".docx"; | ||
471 | + String filePath = JFChartUtils.OUTPUT_DIR + fileName; | ||
472 | + | ||
473 | + String dataRange = "【" + (startTime.equals(endTime) ? startTime : startTime + "~" + endTime) + "】"; | ||
474 | + | ||
475 | + buildWord(dataMap, dataRange, filePath); | ||
476 | + try { | ||
477 | + response.setContentType("application/octet-stream"); | ||
478 | + response.setCharacterEncoding("utf-8"); | ||
479 | + String downloadName = "统计报表"; | ||
480 | + downloadName = new String(downloadName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1); | ||
481 | + response.setHeader("Content-Disposition", "attachment;filename=" + downloadName + ".docx"); | ||
482 | + | ||
483 | + InputStream inputStream = new FileInputStream(filePath); | ||
484 | + OutputStream outputStream = response.getOutputStream(); | ||
485 | + byte[] buffer = new byte[4096]; | ||
486 | + int bytesRead = -1; | ||
487 | + while ((bytesRead = inputStream.read(buffer)) != -1) { | ||
488 | + outputStream.write(buffer, 0, bytesRead); | ||
489 | + } | ||
490 | + inputStream.close(); | ||
491 | + outputStream.close(); | ||
492 | + } catch (Exception e) { | ||
493 | + e.printStackTrace(); | ||
494 | + } | ||
495 | + | ||
496 | + } | ||
497 | + | ||
498 | + @SuppressWarnings("unchecked") | ||
499 | + public void buildWord(Map<String, Object> data, String dataRange, String filePath) throws IOException { | ||
500 | + | ||
501 | + ClassPathResource resource = new ClassPathResource("/template/statisticsReport.docx"); | ||
502 | + File file = new File(resource.getFile().toPath().toString()); | ||
503 | + | ||
504 | + Map<String, Object> dataMap = new HashMap<>(); | ||
505 | + | ||
506 | + Map<String, Object> totalInfo = (Map<String, Object>) data.get("totalInfo"); | ||
507 | + // 警情总体情况 | ||
508 | + dataMap.put("date", dataRange); | ||
509 | + dataMap.put("wiValue", totalInfo.get("value")); | ||
510 | + | ||
511 | + String sequential = (String) totalInfo.get("sequential"); | ||
512 | + if ("--".equals(sequential)) { | ||
513 | + dataMap.put("ns", true); | ||
514 | + } else { | ||
515 | + dataMap.put("hs", true); | ||
516 | + dataMap.put("sequential", sequential.replaceAll("-", "")); | ||
517 | + dataMap.put("sequentialType", sequential.contains("-") ? "下降" : "上升"); | ||
518 | + } | ||
519 | + | ||
520 | + //案件总体情况 | ||
521 | + Map<String, Object> totalCaseInfo = (Map<String, Object>) data.get("totalCaseInfo"); | ||
522 | + dataMap.put("caseValue", totalCaseInfo.get("value")); | ||
523 | + String caseSequential = (String) totalCaseInfo.get("sequential"); | ||
524 | + if ("--".equals(caseSequential)) { | ||
525 | + dataMap.put("cns", true); | ||
526 | + } else { | ||
527 | + dataMap.put("chs", true); | ||
528 | + dataMap.put("caseSequential", caseSequential.replaceAll("-", "")); | ||
529 | + dataMap.put("caseSequentialType", caseSequential.contains("-") ? "下降" : "上升"); | ||
530 | + } | ||
531 | + | ||
532 | + //警情各地市分布饼图 | ||
533 | + List<PieChartVo> wiAreaDataList = (List<PieChartVo>) data.get("wiAreaData"); | ||
534 | + String dailyPicFile = JFChartUtils.createChart(wiAreaDataList, JFChartTypeEnum.PIE, dataRange + "警情分布图", "市", "数量"); | ||
535 | + dataMap.put("sWIAreaPic", Pictures.ofStream(new FileInputStream(dailyPicFile), PictureType.JPEG).size(600, 200).create()); | ||
536 | + | ||
537 | + //警情各地市环比变化柱状图 | ||
538 | + List<PieChartVo> wissAreaData = (List<PieChartVo>) data.get("wissAreaData"); | ||
539 | + String sWISeqAreaPic = JFChartUtils.createChart(wissAreaData, JFChartTypeEnum.BAR, dataRange + "警情环比情况", "市", "环比"); | ||
540 | + dataMap.put("sWISeqAreaPic", Pictures.ofStream(new FileInputStream(sWISeqAreaPic), PictureType.JPEG).size(600, 200).create()); | ||
541 | + | ||
542 | + //警情子类分布 | ||
543 | + List<PieChartVo> wiSubTypeData = (List<PieChartVo>) data.get("wiSubTypeData"); | ||
544 | + String wiSubTypeDataPic = JFChartUtils.createChart(wiSubTypeData, JFChartTypeEnum.PIE, dataRange + "警情类别分布", "警情类别", "数量"); | ||
545 | + dataMap.put("wiSubTypeDataPic", Pictures.ofStream(new FileInputStream(wiSubTypeDataPic), PictureType.JPEG).size(600, 200).create()); | ||
546 | + | ||
547 | + | ||
548 | + //警情分析 | ||
549 | + List<PieChartVo> wisDateData = (List<PieChartVo>) data.get("wisDateData"); | ||
550 | + String wisDateDataPic = JFChartUtils.createChart(wisDateData, JFChartTypeEnum.LINE, dataRange + "警情趋势", "市", "数量"); | ||
551 | + dataMap.put("wisDateDataPic", Pictures.ofStream(new FileInputStream(wisDateDataPic), PictureType.JPEG).size(600, 200).create()); | ||
552 | + | ||
553 | + //案件各地市分布 | ||
554 | + List<PieChartVo> caseAreaData = (List<PieChartVo>) data.get("caseAreaData"); | ||
555 | + String caseAreaDataPic = JFChartUtils.createChart(caseAreaData, JFChartTypeEnum.PIE, dataRange + "案件分布图", "市", "数量"); | ||
556 | + dataMap.put("caseAreaDataPic", Pictures.ofStream(new FileInputStream(caseAreaDataPic), PictureType.JPEG).size(600, 200).create()); | ||
557 | + | ||
558 | + //电诈案件环比情况 | ||
559 | + List<PieChartVo> caseSsAreaData = (List<PieChartVo>) data.get("caseSsAreaData"); | ||
560 | + String caseSsAreaDataPic = JFChartUtils.createChart(caseSsAreaData, JFChartTypeEnum.BAR, dataRange + "电诈案件环比情况", "市", "环比"); | ||
561 | + dataMap.put("caseSsAreaDataPic", Pictures.ofStream(new FileInputStream(caseSsAreaDataPic), PictureType.JPEG).size(600, 200).create()); | ||
562 | + | ||
563 | + //案件诈骗类型分布 | ||
564 | + List<PieChartVo> csfData = (List<PieChartVo>) data.get("csfData"); | ||
565 | + String sCsfDataPic = JFChartUtils.createChart(csfData, JFChartTypeEnum.PIE, dataRange + "诈骗类型分布", "诈骗类型", "数量"); | ||
566 | + dataMap.put("sCsfDataaPic", Pictures.ofStream(new FileInputStream(sCsfDataPic), PictureType.JPEG).size(600, 200).create()); | ||
567 | + | ||
568 | + //案件引流方式分布图 | ||
569 | + List<PieChartVo> ccrmData = (List<PieChartVo>) data.get("ccrmData"); | ||
570 | + String ccrmDataPic = JFChartUtils.createChart(ccrmData, JFChartTypeEnum.PIE, dataRange + "引流方式分布图", "引流方式", "数量"); | ||
571 | + dataMap.put("ccrmDataPic", Pictures.ofStream(new FileInputStream(ccrmDataPic), PictureType.JPEG).size(600, 200).create()); | ||
572 | + | ||
573 | + //案件支付方式分布图 | ||
574 | + List<PieChartVo> ccpmData = (List<PieChartVo>) data.get("ccpmData"); | ||
575 | + String ccpmDataPic = JFChartUtils.createChart(ccpmData, JFChartTypeEnum.PIE, dataRange + "支付方式分布图", "支付方式", "数量"); | ||
576 | + dataMap.put("ccpmDataPic", Pictures.ofStream(new FileInputStream(ccpmDataPic), PictureType.JPEG).size(600, 200).create()); | ||
577 | + | ||
578 | + //案件受害人职业分布图 | ||
579 | + List<PieChartVo> ccCareerData = (List<PieChartVo>) data.get("ccCareerData"); | ||
580 | + String ccCareerDataPic = JFChartUtils.createChart(ccCareerData, JFChartTypeEnum.BAR, dataRange + "受害人职业分布图", "受害人职业", "数量"); | ||
581 | + dataMap.put("ccCareerDataPic", Pictures.ofStream(new FileInputStream(ccCareerDataPic), PictureType.JPEG).size(600, 200).create()); | ||
582 | + | ||
583 | + //案损分布 | ||
584 | + List<PieChartVo> ccLossData = (List<PieChartVo>) data.get("ccLossData"); | ||
585 | + String ccLossDataPic = JFChartUtils.createChart(ccLossData, JFChartTypeEnum.BAR, dataRange + "案损分布", "案损", "数量"); | ||
586 | + dataMap.put("ccLossDataPic", Pictures.ofStream(new FileInputStream(ccLossDataPic), PictureType.JPEG).size(600, 200).create()); | ||
587 | + | ||
588 | + int clIndex = 1; | ||
589 | + for (PieChartVo clData : ccLossData) { | ||
590 | + String key = "clr" + clIndex++; | ||
591 | + dataMap.put(key, clData.getValue()); | ||
592 | + } | ||
593 | + | ||
594 | + //发案趋势 | ||
595 | + List<PieChartVo> ccDateData = (List<PieChartVo>) data.get("ccDateData"); | ||
596 | + String ccDateDataPic = JFChartUtils.createChart(ccDateData, JFChartTypeEnum.LINE, dataRange + "发案趋势", "日期", "数量"); | ||
597 | + dataMap.put("ccDateDataPic", Pictures.ofStream(new FileInputStream(ccDateDataPic), PictureType.JPEG).size(600, 200).create()); | ||
598 | + | ||
599 | + | ||
600 | + //案件受害人性别占比 | ||
601 | + List<PieChartVo> sexData = (List<PieChartVo>) data.get("sexData"); | ||
602 | + if (CollectionUtils.isNotEmpty(sexData)) { | ||
603 | + AtomicReference<Integer> st = new AtomicReference<>(0); | ||
604 | + sexData.forEach(e -> st.updateAndGet(v -> v + (Integer) e.getValue())); | ||
605 | + for (PieChartVo cd : sexData) { | ||
606 | + if ("男".equals(cd.getName())) { | ||
607 | + dataMap.put("cMValue", cd.getValue()); | ||
608 | + dataMap.put("cMValuePer", String.format("%.1f", (Integer) cd.getValue() * 100.0 / st.get()) + "%"); | ||
609 | + } else if ("女".equals(cd.getName())) { | ||
610 | + dataMap.put("cFValue", cd.getValue()); | ||
611 | + dataMap.put("cFValuePer", String.format("%.1f", (Integer) cd.getValue() * 100.0 / st.get()) + "%"); | ||
612 | + | ||
613 | + } | ||
614 | + } | ||
615 | + } | ||
616 | + | ||
617 | + //案件受害人年龄占比 | ||
618 | + List<PieChartVo> ageData = (List<PieChartVo>) data.get("ageData"); | ||
619 | + if (CollectionUtils.isNotEmpty(ageData)) { | ||
620 | + AtomicReference<Integer> at = new AtomicReference<>(0); | ||
621 | + ageData.forEach(e -> at.updateAndGet(v -> v + (Integer) e.getValue())); | ||
622 | + for (PieChartVo cd : ageData) { | ||
623 | + dataMap.put(cd.getName(), cd.getValue()); | ||
624 | + dataMap.put(cd.getName() + "Per", String.format("%.1f", (Integer) cd.getValue() * 100.0 / at.get()) + "%"); | ||
625 | + } | ||
626 | + } | ||
627 | + | ||
628 | + //案损列表 | ||
629 | + List<Case> majorCaseData = (List<Case>) data.get("majorCaseData"); | ||
630 | + List<CaseLossVo> nllDataList = new ArrayList<>(); | ||
631 | + CaseLossVo header = new CaseLossVo(); | ||
632 | + header.setCode("案件编号"); | ||
633 | + header.setArea("地区"); | ||
634 | + header.setCounty("县区"); | ||
635 | + header.setTotalAmount("案损"); | ||
636 | + header.setFraudType("诈骗类型"); | ||
637 | + header.setRainageMethod("引流方式"); | ||
638 | + header.setPayMethod("资金支持途径"); | ||
639 | + header.setSex("受害人性别"); | ||
640 | + header.setCareer("受害人职业"); | ||
641 | + nllDataList.add(header); | ||
642 | + | ||
643 | + String caseLossAreas = ""; | ||
644 | + Map<String, String> caseLossAreaMap = new HashMap<>(); | ||
645 | + if (CollectionUtils.isNotEmpty(majorCaseData)) { | ||
646 | + for (Case cd : majorCaseData) { | ||
647 | + CaseLossVo clv = new CaseLossVo(); | ||
648 | + clv.setCode(cd.getCode()); | ||
649 | + clv.setArea(cd.getAnalysis().getArea()); | ||
650 | + clv.setCounty(cd.getAnalysis().getCounty()); | ||
651 | + clv.setTotalAmount(String.valueOf(cd.getAnalysis().getTotalAmount())); | ||
652 | + clv.setFraudType(cd.getAnalysis().getFraudType()); | ||
653 | + clv.setRainageMethod(cd.getAnalysis().getRainageMethod()); | ||
654 | + clv.setPayMethod(cd.getAnalysis().getPayMethod()); | ||
655 | + clv.setSex(cd.getAnalysis().getSex()); | ||
656 | + clv.setCareer(cd.getAnalysis().getCareer()); | ||
657 | + nllDataList.add(clv); | ||
658 | + caseLossAreaMap.put(cd.getAnalysis().getArea(), ""); | ||
659 | + } | ||
660 | + } | ||
661 | + | ||
662 | + | ||
663 | + String[][] majorCaseDataArray = nllDataList.stream() | ||
664 | + .map(e -> new String[]{e.getArea(), e.getCounty(), e.getCode() | ||
665 | + , e.getTotalAmount(), e.getFraudType(), e.getRainageMethod() | ||
666 | + , e.getPayMethod(), e.getSex(), e.getCareer() | ||
667 | + }).toArray(String[][]::new); | ||
668 | + dataMap.put("tableMcd", Tables.of(majorCaseDataArray).border(BorderStyle.DEFAULT).create()); | ||
669 | + | ||
670 | + //警情损失列表 | ||
671 | + List<WarningInstance> majorWiData = (List<WarningInstance>) data.get("majorWiData"); | ||
672 | + List<WiLossVo> mwiDataList = new ArrayList<>(); | ||
673 | + WiLossVo wiHeader = new WiLossVo(); | ||
674 | + wiHeader.setCode("案件编号"); | ||
675 | + wiHeader.setArea("地区"); | ||
676 | + wiHeader.setCounty("县区"); | ||
677 | + wiHeader.setAlarmSubType("案件类别"); | ||
678 | + wiHeader.setAmount("案损"); | ||
679 | + wiHeader.setRainageMethod("引流方式"); | ||
680 | + wiHeader.setPayMethod("支付渠道"); | ||
681 | + wiHeader.setSex("受害人性别"); | ||
682 | + wiHeader.setCareer("受害人职业"); | ||
683 | + mwiDataList.add(wiHeader); | ||
684 | + | ||
685 | + Integer wi50wValue = 0; | ||
686 | + Integer wi100wValue = 0; | ||
687 | + if (CollectionUtils.isNotEmpty(majorWiData)) { | ||
688 | + for (WarningInstance cd : majorWiData) { | ||
689 | + WiLossVo clv = new WiLossVo(); | ||
690 | + clv.setCode(cd.getCode()); | ||
691 | + clv.setArea(cd.getAnalysis().getArea()); | ||
692 | + clv.setCounty(cd.getAnalysis().getCounty()); | ||
693 | + clv.setAlarmSubType(cd.getAlarmSubType()); | ||
694 | + clv.setAmount(String.valueOf(cd.getAnalysis().getAmount())); | ||
695 | + clv.setRainageMethod(cd.getAnalysis().getRainageMethod()); | ||
696 | + clv.setPayMethod(cd.getAnalysis().getPayMethod()); | ||
697 | + clv.setSex(cd.getAnalysis().getSex()); | ||
698 | + clv.setCareer(cd.getAnalysis().getCareer()); | ||
699 | + mwiDataList.add(clv); | ||
700 | + caseLossAreaMap.put(cd.getAnalysis().getArea(), ""); | ||
701 | + if (cd.getAnalysis().getAmount() < 1000000) { | ||
702 | + wi50wValue++; | ||
703 | + } else { | ||
704 | + wi100wValue++; | ||
705 | + } | ||
706 | + } | ||
707 | + } | ||
708 | + | ||
709 | + dataMap.put("wi50wValue", wi50wValue); | ||
710 | + dataMap.put("wi100wValue", wi100wValue); | ||
711 | + | ||
712 | + String[][] majorWiDataArray = mwiDataList.stream() | ||
713 | + .map(e -> new String[]{e.getCode(), e.getArea(), e.getCounty() | ||
714 | + , e.getAlarmSubType(), e.getAmount(), e.getRainageMethod() | ||
715 | + , e.getPayMethod(), e.getSex(), e.getCareer() | ||
716 | + }).toArray(String[][]::new); | ||
717 | + dataMap.put("tableMwd", Tables.of(majorWiDataArray).border(BorderStyle.DEFAULT).create()); | ||
718 | + | ||
719 | + if (MapUtils.isNotEmpty(caseLossAreaMap)) { | ||
720 | + caseLossAreas = String.join(",", caseLossAreaMap.keySet()); | ||
721 | + } | ||
722 | + | ||
723 | + caseLossAreas = StringUtils.isNotBlank(caseLossAreas) ? caseLossAreas : "--"; | ||
724 | + dataMap.put("caseLossAreas", caseLossAreas); | ||
725 | + | ||
726 | + | ||
727 | + try (XWPFTemplate template = XWPFTemplate.compile(file, Configure.newBuilder().buildGramer("${", "}").build()) | ||
728 | + .render(dataMap)) { | ||
729 | + template.writeToFile(filePath); | ||
730 | + } | ||
731 | + | ||
732 | + } | ||
733 | + | ||
354 | } | 734 | } |
@@ -30,6 +30,12 @@ public class WarningInstanceAnalysis extends BaseModel { | @@ -30,6 +30,12 @@ public class WarningInstanceAnalysis extends BaseModel { | ||
30 | private String area; | 30 | private String area; |
31 | 31 | ||
32 | /** | 32 | /** |
33 | + * 县区 | ||
34 | + */ | ||
35 | + @TableField(value = "county") | ||
36 | + private String county; | ||
37 | + | ||
38 | + /** | ||
33 | * 案损金额 | 39 | * 案损金额 |
34 | */ | 40 | */ |
35 | @TableField(value = "amount") | 41 | @TableField(value = "amount") |
1 | +package com.ash.enums; | ||
2 | + | ||
3 | +public enum CaseVictimAgeRangeEnum { | ||
4 | + CVAR1("小于30岁"), | ||
5 | + CVAR2("31-40岁"), | ||
6 | + CVAR3("41-50岁"), | ||
7 | + CVAR4("大于50岁"), | ||
8 | + ; | ||
9 | + | ||
10 | + private final String text; | ||
11 | + | ||
12 | + private CaseVictimAgeRangeEnum(String text) { | ||
13 | + this.text = text; | ||
14 | + } | ||
15 | + | ||
16 | + public String getText() { | ||
17 | + return text; | ||
18 | + } | ||
19 | +} |
1 | +package com.ash.enums; | ||
2 | + | ||
3 | +public enum JFChartTypeEnum { | ||
4 | + LINE("折线图"), | ||
5 | + PIE("饼状图"), | ||
6 | + BAR("柱形图"), | ||
7 | + ; | ||
8 | + | ||
9 | + | ||
10 | + private final String text; | ||
11 | + | ||
12 | + private JFChartTypeEnum(String text) { | ||
13 | + this.text = text; | ||
14 | + } | ||
15 | + | ||
16 | + public String getText() { | ||
17 | + return text; | ||
18 | + } | ||
19 | +} |
1 | +package com.ash.enums; | ||
2 | + | ||
3 | +public enum LossRangeEnum { | ||
4 | + R1("小于10万"), | ||
5 | + R2("10万-20万"), | ||
6 | + R3("20万-50万"), | ||
7 | + R4("50万-100万"), | ||
8 | + R5("大于100万"), | ||
9 | + ; | ||
10 | + | ||
11 | + | ||
12 | + private final String text; | ||
13 | + | ||
14 | + private LossRangeEnum(String text) { | ||
15 | + this.text = text; | ||
16 | + } | ||
17 | + | ||
18 | + public String getText() { | ||
19 | + return text; | ||
20 | + } | ||
21 | +} |
@@ -10,7 +10,9 @@ import com.ash.entity.Case; | @@ -10,7 +10,9 @@ import com.ash.entity.Case; | ||
10 | import com.ash.entity.CaseAnalysis; | 10 | import com.ash.entity.CaseAnalysis; |
11 | import com.ash.entity.dao.CaseMapper; | 11 | import com.ash.entity.dao.CaseMapper; |
12 | import com.ash.enums.AnalysisStatusEnum; | 12 | import com.ash.enums.AnalysisStatusEnum; |
13 | +import com.ash.enums.CaseVictimAgeRangeEnum; | ||
13 | import com.ash.enums.ConformStatusEnum; | 14 | import com.ash.enums.ConformStatusEnum; |
15 | +import com.ash.enums.LossRangeEnum; | ||
14 | import com.ash.excelData.CaseExcelData; | 16 | import com.ash.excelData.CaseExcelData; |
15 | import com.ash.listener.CaseExcelListener; | 17 | import com.ash.listener.CaseExcelListener; |
16 | import com.ash.util.*; | 18 | import com.ash.util.*; |
@@ -49,6 +51,22 @@ public class CaseService { | @@ -49,6 +51,22 @@ public class CaseService { | ||
49 | @Resource | 51 | @Resource |
50 | private CaseAnalysisService caseAnalysisService; | 52 | private CaseAnalysisService caseAnalysisService; |
51 | 53 | ||
54 | + private static List<String> lossRangeList = new ArrayList<>(); | ||
55 | + private static List<String> cvaRangeList = new ArrayList<>(); | ||
56 | + | ||
57 | + static { | ||
58 | + lossRangeList.add(LossRangeEnum.R1.getText()); | ||
59 | + lossRangeList.add(LossRangeEnum.R2.getText()); | ||
60 | + lossRangeList.add(LossRangeEnum.R3.getText()); | ||
61 | + lossRangeList.add(LossRangeEnum.R4.getText()); | ||
62 | + lossRangeList.add(LossRangeEnum.R5.getText()); | ||
63 | + | ||
64 | + cvaRangeList.add(CaseVictimAgeRangeEnum.CVAR1.name()); | ||
65 | + cvaRangeList.add(CaseVictimAgeRangeEnum.CVAR2.name()); | ||
66 | + cvaRangeList.add(CaseVictimAgeRangeEnum.CVAR3.name()); | ||
67 | + cvaRangeList.add(CaseVictimAgeRangeEnum.CVAR4.name()); | ||
68 | + } | ||
69 | + | ||
52 | public Boolean save(Case data) { | 70 | public Boolean save(Case data) { |
53 | String uuid = UUIDGenerator.uuid(); | 71 | String uuid = UUIDGenerator.uuid(); |
54 | data.setId(uuid); | 72 | data.setId(uuid); |
@@ -145,7 +163,7 @@ public class CaseService { | @@ -145,7 +163,7 @@ public class CaseService { | ||
145 | 163 | ||
146 | public List<Case> getCaseLoss(StatisticsParams params) { | 164 | public List<Case> getCaseLoss(StatisticsParams params) { |
147 | MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<Case>(); | 165 | MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<Case>(); |
148 | - mpjQueryWrapper.select("t.id,ca.total_amount as totalAmount") | 166 | + mpjQueryWrapper.select("t.id,ca.total_amount as totalAmount,ca.age") |
149 | .leftJoin("t_ash_case_analysis ca on t.id=ca.case_id"); | 167 | .leftJoin("t_ash_case_analysis ca on t.id=ca.case_id"); |
150 | 168 | ||
151 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | 169 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
@@ -161,6 +179,64 @@ public class CaseService { | @@ -161,6 +179,64 @@ public class CaseService { | ||
161 | return caseMapper.selectJoinList(Case.class, mpjQueryWrapper); | 179 | return caseMapper.selectJoinList(Case.class, mpjQueryWrapper); |
162 | } | 180 | } |
163 | 181 | ||
182 | + public List<PieChartVo> statisticsByLoss(StatisticsParams params) { | ||
183 | + LinkedHashMap<String, Integer> dataMap = new LinkedHashMap<>(); | ||
184 | + lossRangeList.forEach(e -> dataMap.put(e, 0)); | ||
185 | + List<Case> caseLoss = getCaseLoss(params); | ||
186 | + for (Case loss : caseLoss) { | ||
187 | + Double totalAmount = loss.getTotalAmount(); | ||
188 | + if (totalAmount == null) { | ||
189 | + continue; | ||
190 | + } | ||
191 | + LossRangeEnum lossRange = LossRangeEnum.R1; | ||
192 | + if (totalAmount < 100000) { | ||
193 | + lossRange = LossRangeEnum.R1; | ||
194 | + } else if (totalAmount >= 100000 && totalAmount < 200000) { | ||
195 | + lossRange = LossRangeEnum.R2; | ||
196 | + } else if (totalAmount >= 200000 && totalAmount < 500000) { | ||
197 | + lossRange = LossRangeEnum.R3; | ||
198 | + } else if (totalAmount >= 500000 && totalAmount < 1000000) { | ||
199 | + lossRange = LossRangeEnum.R4; | ||
200 | + } else if (totalAmount >= 1000000) { | ||
201 | + lossRange = LossRangeEnum.R4; | ||
202 | + } | ||
203 | + Integer cv = dataMap.get(lossRange.getText()); | ||
204 | + cv++; | ||
205 | + dataMap.put(lossRange.getText(), cv); | ||
206 | + } | ||
207 | + | ||
208 | + return dataMap.keySet().stream() | ||
209 | + .map(e -> new PieChartVo(e, dataMap.get(e))).collect(Collectors.toList()); | ||
210 | + } | ||
211 | + | ||
212 | + public List<PieChartVo> statisticsByAge(StatisticsParams params) { | ||
213 | + LinkedHashMap<String, Integer> dataMap = new LinkedHashMap<>(); | ||
214 | + cvaRangeList.forEach(e -> dataMap.put(e, 0)); | ||
215 | + List<Case> caseLoss = getCaseLoss(params); | ||
216 | + for (Case loss : caseLoss) { | ||
217 | + Integer age = loss.getAge(); | ||
218 | + if (age == null) { | ||
219 | + continue; | ||
220 | + } | ||
221 | + CaseVictimAgeRangeEnum cvaRange = CaseVictimAgeRangeEnum.CVAR1; | ||
222 | + if (age <= 30) { | ||
223 | + cvaRange = CaseVictimAgeRangeEnum.CVAR1; | ||
224 | + } else if (age <= 40) { | ||
225 | + cvaRange = CaseVictimAgeRangeEnum.CVAR2; | ||
226 | + } else if (age <= 50) { | ||
227 | + cvaRange = CaseVictimAgeRangeEnum.CVAR3; | ||
228 | + } else { | ||
229 | + cvaRange = CaseVictimAgeRangeEnum.CVAR4; | ||
230 | + } | ||
231 | + Integer cv = dataMap.get(cvaRange.name()); | ||
232 | + cv++; | ||
233 | + dataMap.put(cvaRange.name(), cv); | ||
234 | + } | ||
235 | + | ||
236 | + return dataMap.keySet().stream() | ||
237 | + .map(e -> new PieChartVo(e, dataMap.get(e))).collect(Collectors.toList()); | ||
238 | + } | ||
239 | + | ||
164 | public int getCaseTopLoss(StatisticsParams params) { | 240 | public int getCaseTopLoss(StatisticsParams params) { |
165 | MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<Case>(); | 241 | MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<Case>(); |
166 | mpjQueryWrapper.select("t.id,ca.total_amount as totalAmount") | 242 | mpjQueryWrapper.select("t.id,ca.total_amount as totalAmount") |
@@ -185,9 +261,35 @@ public class CaseService { | @@ -185,9 +261,35 @@ public class CaseService { | ||
185 | } | 261 | } |
186 | } | 262 | } |
187 | 263 | ||
264 | + public List<PieChartVo> statisticsByDate(StatisticsParams params) { | ||
265 | + MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<>(); | ||
266 | + mpjQueryWrapper.select("DATE_FORMAT(t.alarm_date, '%Y-%m-%d') as alarmDate,count(0) as field_count"); | ||
267 | + | ||
268 | + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
269 | + if (params.getStartTime() != null) { | ||
270 | + mpjQueryWrapper.ge("t.alarm_date", sdf.format(DateUtils.weeHours(params.getStartTime(), 0))); | ||
271 | + | ||
272 | + } | ||
273 | + | ||
274 | + if (params.getEndTime() != null) { | ||
275 | + mpjQueryWrapper.le("t.alarm_date", sdf.format(DateUtils.weeHours(params.getEndTime(), 1))); | ||
276 | + } | ||
277 | + | ||
278 | + mpjQueryWrapper.groupBy("DATE_FORMAT(t.alarm_date, '%Y-%m-%d')"); | ||
279 | + mpjQueryWrapper.orderByAsc("DATE_FORMAT(t.alarm_date, '%Y-%m-%d')"); | ||
280 | + List<Map<String, Object>> dataList = caseMapper.selectJoinMaps(mpjQueryWrapper); | ||
281 | + List<PieChartVo> resultList = new ArrayList<>(); | ||
282 | + resultList = dataList.stream().map(e -> { | ||
283 | + Integer fieldCount = ObjectValueOption.getObjInt(e.get("field_count")); | ||
284 | + return new PieChartVo(ObjectValueOption.getObjString(e.get("alarmDate")), fieldCount); | ||
285 | + } | ||
286 | + ).filter(e -> StringUtils.isNotBlank(e.getName())).collect(Collectors.toList()); | ||
287 | + return resultList; | ||
288 | + } | ||
289 | + | ||
188 | 290 | ||
189 | public List<BarChartVo> statisticsByArea(StatisticsParams params) { | 291 | public List<BarChartVo> statisticsByArea(StatisticsParams params) { |
190 | - MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<Case>(); | 292 | + MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<>(); |
191 | mpjQueryWrapper.select("ca.area,count(t.id) as field_count") | 293 | mpjQueryWrapper.select("ca.area,count(t.id) as field_count") |
192 | .leftJoin("t_ash_case_analysis ca on t.id=ca.case_id"); | 294 | .leftJoin("t_ash_case_analysis ca on t.id=ca.case_id"); |
193 | 295 | ||
@@ -214,8 +316,7 @@ public class CaseService { | @@ -214,8 +316,7 @@ public class CaseService { | ||
214 | total.updateAndGet(v -> v + fieldCount); | 316 | total.updateAndGet(v -> v + fieldCount); |
215 | return new BarChartVo(ObjectValueOption.getObjString(e.get("area")), fieldCount.toString()); | 317 | return new BarChartVo(ObjectValueOption.getObjString(e.get("area")), fieldCount.toString()); |
216 | } | 318 | } |
217 | - ).collect(Collectors.toList()); | ||
218 | - resultList = resultList.stream().filter(e -> StringUtils.isNotBlank(e.getName())).collect(Collectors.toList()); | 319 | + ).filter(e -> StringUtils.isNotBlank(e.getName())).collect(Collectors.toList()); |
219 | if (resultList.size() > 7) { | 320 | if (resultList.size() > 7) { |
220 | resultList = resultList.subList(0, 7); | 321 | resultList = resultList.subList(0, 7); |
221 | } | 322 | } |
@@ -229,6 +330,161 @@ public class CaseService { | @@ -229,6 +330,161 @@ public class CaseService { | ||
229 | return resultList; | 330 | return resultList; |
230 | } | 331 | } |
231 | 332 | ||
333 | + public List<PieChartVo> statisticsCountByArea(StatisticsParams params) { | ||
334 | + MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<>(); | ||
335 | + mpjQueryWrapper.select("ca.area,count(t.id) as field_count") | ||
336 | + .leftJoin("t_ash_case_analysis ca on t.id=ca.case_id"); | ||
337 | + | ||
338 | + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
339 | + if (params.getStartTime() != null) { | ||
340 | + mpjQueryWrapper.ge("t.alarm_date", sdf.format(DateUtils.weeHours(params.getStartTime(), 0))); | ||
341 | + | ||
342 | + } | ||
343 | + | ||
344 | + if (params.getEndTime() != null) { | ||
345 | + mpjQueryWrapper.le("t.alarm_date", sdf.format(DateUtils.weeHours(params.getEndTime(), 1))); | ||
346 | + } | ||
347 | + | ||
348 | + mpjQueryWrapper.groupBy("ca.area"); | ||
349 | + mpjQueryWrapper.orderByDesc("field_count"); | ||
350 | + | ||
351 | + List<Map<String, Object>> dataList = caseMapper.selectJoinMaps(mpjQueryWrapper); | ||
352 | + List<PieChartVo> resultList = new ArrayList<>(); | ||
353 | + if (!CollectionUtils.isEmpty(dataList)) { | ||
354 | + resultList = dataList.stream().map(e -> { | ||
355 | + Integer fieldCount = ObjectValueOption.getObjInt(e.get("field_count")); | ||
356 | + return new PieChartVo(ObjectValueOption.getObjString(e.get("area")), fieldCount); | ||
357 | + } | ||
358 | + ).filter(e -> StringUtils.isNotBlank(e.getName())).collect(Collectors.toList()); | ||
359 | + | ||
360 | + } | ||
361 | + return resultList; | ||
362 | + } | ||
363 | + | ||
364 | + public List<PieChartVo> statisticsCountByRainageMethod(StatisticsParams params) { | ||
365 | + MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<>(); | ||
366 | + mpjQueryWrapper.select("ca.rainage_method,count(t.id) as field_count") | ||
367 | + .leftJoin("t_ash_case_analysis ca on t.id=ca.case_id"); | ||
368 | + | ||
369 | + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
370 | + if (params.getStartTime() != null) { | ||
371 | + mpjQueryWrapper.ge("t.alarm_date", sdf.format(DateUtils.weeHours(params.getStartTime(), 0))); | ||
372 | + | ||
373 | + } | ||
374 | + | ||
375 | + if (params.getEndTime() != null) { | ||
376 | + mpjQueryWrapper.le("t.alarm_date", sdf.format(DateUtils.weeHours(params.getEndTime(), 1))); | ||
377 | + } | ||
378 | + | ||
379 | + mpjQueryWrapper.groupBy("ca.rainage_method"); | ||
380 | + mpjQueryWrapper.orderByDesc("field_count"); | ||
381 | + | ||
382 | + List<Map<String, Object>> dataList = caseMapper.selectJoinMaps(mpjQueryWrapper); | ||
383 | + List<PieChartVo> resultList = new ArrayList<>(); | ||
384 | + if (!CollectionUtils.isEmpty(dataList)) { | ||
385 | + resultList = dataList.stream().map(e -> { | ||
386 | + Integer fieldCount = ObjectValueOption.getObjInt(e.get("field_count")); | ||
387 | + return new PieChartVo(ObjectValueOption.getObjString(e.get("rainage_method")), fieldCount); | ||
388 | + } | ||
389 | + ).filter(e -> StringUtils.isNotBlank(e.getName())).collect(Collectors.toList()); | ||
390 | + | ||
391 | + } | ||
392 | + return resultList; | ||
393 | + } | ||
394 | + | ||
395 | + public List<PieChartVo> statisticsCountByPayMethod(StatisticsParams params) { | ||
396 | + MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<>(); | ||
397 | + mpjQueryWrapper.select("ca.pay_method,count(t.id) as field_count") | ||
398 | + .leftJoin("t_ash_case_analysis ca on t.id=ca.case_id"); | ||
399 | + | ||
400 | + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
401 | + if (params.getStartTime() != null) { | ||
402 | + mpjQueryWrapper.ge("t.alarm_date", sdf.format(DateUtils.weeHours(params.getStartTime(), 0))); | ||
403 | + | ||
404 | + } | ||
405 | + | ||
406 | + if (params.getEndTime() != null) { | ||
407 | + mpjQueryWrapper.le("t.alarm_date", sdf.format(DateUtils.weeHours(params.getEndTime(), 1))); | ||
408 | + } | ||
409 | + | ||
410 | + mpjQueryWrapper.groupBy("ca.pay_method"); | ||
411 | + mpjQueryWrapper.orderByDesc("field_count"); | ||
412 | + | ||
413 | + List<Map<String, Object>> dataList = caseMapper.selectJoinMaps(mpjQueryWrapper); | ||
414 | + List<PieChartVo> resultList = new ArrayList<>(); | ||
415 | + if (!CollectionUtils.isEmpty(dataList)) { | ||
416 | + resultList = dataList.stream().map(e -> { | ||
417 | + Integer fieldCount = ObjectValueOption.getObjInt(e.get("field_count")); | ||
418 | + return new PieChartVo(ObjectValueOption.getObjString(e.get("pay_method")), fieldCount); | ||
419 | + } | ||
420 | + ).filter(e -> StringUtils.isNotBlank(e.getName())).collect(Collectors.toList()); | ||
421 | + | ||
422 | + } | ||
423 | + return resultList; | ||
424 | + } | ||
425 | + | ||
426 | + public List<PieChartVo> statisticsCountByCareer(StatisticsParams params) { | ||
427 | + MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<>(); | ||
428 | + mpjQueryWrapper.select("ca.career,count(t.id) as field_count") | ||
429 | + .leftJoin("t_ash_case_analysis ca on t.id=ca.case_id"); | ||
430 | + | ||
431 | + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
432 | + if (params.getStartTime() != null) { | ||
433 | + mpjQueryWrapper.ge("t.alarm_date", sdf.format(DateUtils.weeHours(params.getStartTime(), 0))); | ||
434 | + | ||
435 | + } | ||
436 | + | ||
437 | + if (params.getEndTime() != null) { | ||
438 | + mpjQueryWrapper.le("t.alarm_date", sdf.format(DateUtils.weeHours(params.getEndTime(), 1))); | ||
439 | + } | ||
440 | + | ||
441 | + mpjQueryWrapper.groupBy("ca.career"); | ||
442 | + mpjQueryWrapper.orderByDesc("field_count"); | ||
443 | + | ||
444 | + List<Map<String, Object>> dataList = caseMapper.selectJoinMaps(mpjQueryWrapper); | ||
445 | + List<PieChartVo> resultList = new ArrayList<>(); | ||
446 | + if (!CollectionUtils.isEmpty(dataList)) { | ||
447 | + resultList = dataList.stream().map(e -> { | ||
448 | + Integer fieldCount = ObjectValueOption.getObjInt(e.get("field_count")); | ||
449 | + return new PieChartVo(ObjectValueOption.getObjString(e.get("career")), fieldCount); | ||
450 | + } | ||
451 | + ).filter(e -> StringUtils.isNotBlank(e.getName())).collect(Collectors.toList()); | ||
452 | + | ||
453 | + } | ||
454 | + return resultList; | ||
455 | + } | ||
456 | + | ||
457 | + public List<PieChartVo> statisticsCountBySex(StatisticsParams params) { | ||
458 | + MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<>(); | ||
459 | + mpjQueryWrapper.select("ca.sex,count(t.id) as field_count") | ||
460 | + .leftJoin("t_ash_case_analysis ca on t.id=ca.case_id"); | ||
461 | + | ||
462 | + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
463 | + if (params.getStartTime() != null) { | ||
464 | + mpjQueryWrapper.ge("t.alarm_date", sdf.format(DateUtils.weeHours(params.getStartTime(), 0))); | ||
465 | + | ||
466 | + } | ||
467 | + | ||
468 | + if (params.getEndTime() != null) { | ||
469 | + mpjQueryWrapper.le("t.alarm_date", sdf.format(DateUtils.weeHours(params.getEndTime(), 1))); | ||
470 | + } | ||
471 | + | ||
472 | + mpjQueryWrapper.groupBy("ca.sex"); | ||
473 | + mpjQueryWrapper.orderByDesc("field_count"); | ||
474 | + | ||
475 | + List<Map<String, Object>> dataList = caseMapper.selectJoinMaps(mpjQueryWrapper); | ||
476 | + List<PieChartVo> resultList = new ArrayList<>(); | ||
477 | + if (!CollectionUtils.isEmpty(dataList)) { | ||
478 | + resultList = dataList.stream().map(e -> { | ||
479 | + Integer fieldCount = ObjectValueOption.getObjInt(e.get("field_count")); | ||
480 | + return new PieChartVo(ObjectValueOption.getObjString(e.get("sex")), fieldCount); | ||
481 | + } | ||
482 | + ).filter(e -> StringUtils.isNotBlank(e.getName())).collect(Collectors.toList()); | ||
483 | + | ||
484 | + } | ||
485 | + return resultList; | ||
486 | + } | ||
487 | + | ||
232 | public List<PieChartVo> statisticsByFraudType(StatisticsParams params) { | 488 | public List<PieChartVo> statisticsByFraudType(StatisticsParams params) { |
233 | MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<Case>(); | 489 | MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<Case>(); |
234 | mpjQueryWrapper.select("ca.fraud_type as fraudType,count(t.id) as field_count") | 490 | mpjQueryWrapper.select("ca.fraud_type as fraudType,count(t.id) as field_count") |
@@ -294,7 +550,7 @@ public class CaseService { | @@ -294,7 +550,7 @@ public class CaseService { | ||
294 | } | 550 | } |
295 | 551 | ||
296 | public List<BarChartVo> statisticsSequentialByArea(StatisticsParams params) { | 552 | public List<BarChartVo> statisticsSequentialByArea(StatisticsParams params) { |
297 | - MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<Case>(); | 553 | + MPJQueryWrapper<Case> mpjQueryWrapper = new MPJQueryWrapper<>(); |
298 | mpjQueryWrapper.select("ca.area,count(t.id) as field_count") | 554 | mpjQueryWrapper.select("ca.area,count(t.id) as field_count") |
299 | .leftJoin("t_ash_case_analysis ca on t.id=ca.case_id"); | 555 | .leftJoin("t_ash_case_analysis ca on t.id=ca.case_id"); |
300 | 556 |
@@ -145,7 +145,7 @@ public class WarningInstanceService { | @@ -145,7 +145,7 @@ public class WarningInstanceService { | ||
145 | } | 145 | } |
146 | 146 | ||
147 | public List<BarChartVo> statisticsByArea(StatisticsParams params) { | 147 | public List<BarChartVo> statisticsByArea(StatisticsParams params) { |
148 | - MPJQueryWrapper<WarningInstance> mpjQueryWrapper = new MPJQueryWrapper<WarningInstance>(); | 148 | + MPJQueryWrapper<WarningInstance> mpjQueryWrapper = new MPJQueryWrapper<>(); |
149 | mpjQueryWrapper.select("wia.area,count(t.id) as field_count") | 149 | mpjQueryWrapper.select("wia.area,count(t.id) as field_count") |
150 | .leftJoin("t_ash_warning_instance_analysis wia on t.id=wia.wi_id"); | 150 | .leftJoin("t_ash_warning_instance_analysis wia on t.id=wia.wi_id"); |
151 | 151 | ||
@@ -186,6 +186,88 @@ public class WarningInstanceService { | @@ -186,6 +186,88 @@ public class WarningInstanceService { | ||
186 | return resultList; | 186 | return resultList; |
187 | } | 187 | } |
188 | 188 | ||
189 | + public List<PieChartVo> statisticsCountByArea(StatisticsParams params) { | ||
190 | + MPJQueryWrapper<WarningInstance> mpjQueryWrapper = new MPJQueryWrapper<>(); | ||
191 | + mpjQueryWrapper.select("wia.area,count(t.id) as field_count") | ||
192 | + .leftJoin("t_ash_warning_instance_analysis wia on t.id=wia.wi_id"); | ||
193 | + | ||
194 | + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
195 | + if (params.getStartTime() != null) { | ||
196 | + mpjQueryWrapper.ge("t.alarm_date", sdf.format(DateUtils.weeHours(params.getStartTime(), 0))); | ||
197 | + | ||
198 | + } | ||
199 | + | ||
200 | + if (params.getEndTime() != null) { | ||
201 | + mpjQueryWrapper.le("t.alarm_date", sdf.format(DateUtils.weeHours(params.getEndTime(), 1))); | ||
202 | + } | ||
203 | + | ||
204 | + mpjQueryWrapper.groupBy("wia.area"); | ||
205 | + mpjQueryWrapper.orderByDesc("field_count"); | ||
206 | + | ||
207 | + List<Map<String, Object>> dataList = warningInstanceMapper.selectJoinMaps(mpjQueryWrapper); | ||
208 | + List<PieChartVo> resultList = new ArrayList<>(); | ||
209 | + if (!CollectionUtils.isEmpty(dataList)) { | ||
210 | + resultList = dataList.stream().map(e -> { | ||
211 | + Integer fieldCount = ObjectValueOption.getObjInt(e.get("field_count")); | ||
212 | + return new PieChartVo(ObjectValueOption.getObjString(e.get("area")), fieldCount); | ||
213 | + } | ||
214 | + ).filter(e -> StringUtils.isNotBlank(e.getName())).collect(Collectors.toList()); | ||
215 | + } | ||
216 | + return resultList; | ||
217 | + } | ||
218 | + | ||
219 | + public List<PieChartVo> statisticsCountBySubType(StatisticsParams params) { | ||
220 | + MPJQueryWrapper<WarningInstance> mpjQueryWrapper = new MPJQueryWrapper<>(); | ||
221 | + mpjQueryWrapper.select("t.sub_type,count(t.id) as field_count"); | ||
222 | + | ||
223 | + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
224 | + if (params.getStartTime() != null) { | ||
225 | + mpjQueryWrapper.ge("t.alarm_date", sdf.format(DateUtils.weeHours(params.getStartTime(), 0))); | ||
226 | + | ||
227 | + } | ||
228 | + | ||
229 | + if (params.getEndTime() != null) { | ||
230 | + mpjQueryWrapper.le("t.alarm_date", sdf.format(DateUtils.weeHours(params.getEndTime(), 1))); | ||
231 | + } | ||
232 | + | ||
233 | + mpjQueryWrapper.groupBy("t.sub_type"); | ||
234 | + mpjQueryWrapper.orderByDesc("field_count"); | ||
235 | + | ||
236 | + List<Map<String, Object>> dataList = warningInstanceMapper.selectJoinMaps(mpjQueryWrapper); | ||
237 | + List<PieChartVo> resultList = new ArrayList<>(); | ||
238 | + if (!CollectionUtils.isEmpty(dataList)) { | ||
239 | + resultList = dataList.stream().map(e -> { | ||
240 | + Integer fieldCount = ObjectValueOption.getObjInt(e.get("field_count")); | ||
241 | + return new PieChartVo(ObjectValueOption.getObjString(e.get("sub_type")), fieldCount); | ||
242 | + } | ||
243 | + ).filter(e -> StringUtils.isNotBlank(e.getName())).collect(Collectors.toList()); | ||
244 | + } | ||
245 | + return resultList; | ||
246 | + } | ||
247 | + | ||
248 | + public List<WarningInstance> majorWiPage(StatisticsParams params) { | ||
249 | + MPJQueryWrapper<WarningInstance> mpjQueryWrapper = new MPJQueryWrapper<>(); | ||
250 | + mpjQueryWrapper.select("t.*") | ||
251 | + .leftJoin("t_ash_warning_instance_analysis wia on t.id=wia.wi_id"); | ||
252 | + | ||
253 | + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | ||
254 | + if (params.getStartTime() != null) { | ||
255 | + mpjQueryWrapper.ge("t.alarm_date", sdf.format(DateUtils.weeHours(params.getStartTime(), 0))); | ||
256 | + | ||
257 | + } | ||
258 | + | ||
259 | + if (params.getEndTime() != null) { | ||
260 | + mpjQueryWrapper.le("t.alarm_date", sdf.format(DateUtils.weeHours(params.getEndTime(), 1))); | ||
261 | + } | ||
262 | + | ||
263 | + mpjQueryWrapper.ge("wia.amount", 500000); | ||
264 | + mpjQueryWrapper.orderByDesc("amount"); | ||
265 | + | ||
266 | + return warningInstanceMapper.selectJoinList(WarningInstance.class, mpjQueryWrapper); | ||
267 | + | ||
268 | + | ||
269 | + } | ||
270 | + | ||
189 | public List<BarChartVo> statisticsByDate(StatisticsParams params) { | 271 | public List<BarChartVo> statisticsByDate(StatisticsParams params) { |
190 | MPJQueryWrapper<WarningInstance> mpjQueryWrapper = new MPJQueryWrapper<WarningInstance>(); | 272 | MPJQueryWrapper<WarningInstance> mpjQueryWrapper = new MPJQueryWrapper<WarningInstance>(); |
191 | mpjQueryWrapper.select("DATE_FORMAT(t.alarm_date, '%Y-%m-%d') as alarmDate,count(0) as field_count"); | 273 | mpjQueryWrapper.select("DATE_FORMAT(t.alarm_date, '%Y-%m-%d') as alarmDate,count(0) as field_count"); |
@@ -322,6 +404,7 @@ public class WarningInstanceService { | @@ -322,6 +404,7 @@ public class WarningInstanceService { | ||
322 | WarningInstanceAnalysis wa = new WarningInstanceAnalysis(); | 404 | WarningInstanceAnalysis wa = new WarningInstanceAnalysis(); |
323 | wa.setWiId(cd.getId()); | 405 | wa.setWiId(cd.getId()); |
324 | wa.setArea(cd.getMunicipalPolice().replaceAll("公安局", "")); | 406 | wa.setArea(cd.getMunicipalPolice().replaceAll("公安局", "")); |
407 | + wa.setCounty(analysisResult.getString("area")); | ||
325 | wa.setAmount(analysisResult.getDouble("value")); | 408 | wa.setAmount(analysisResult.getDouble("value")); |
326 | wa.setSex(analysisResult.getString("gender")); | 409 | wa.setSex(analysisResult.getString("gender")); |
327 | wa.setCareer(analysisResult.getString("occupation")); | 410 | wa.setCareer(analysisResult.getString("occupation")); |
src/main/java/com/ash/util/CaseLossVo.java
0 → 100644
1 | +package com.ash.util; | ||
2 | + | ||
3 | +import lombok.Data; | ||
4 | + | ||
5 | +/** | ||
6 | + * 报表导出案损列表vo | ||
7 | + */ | ||
8 | +@Data | ||
9 | +public class CaseLossVo { | ||
10 | + /** | ||
11 | + * 案件编号 | ||
12 | + */ | ||
13 | + private String code; | ||
14 | + | ||
15 | + /** | ||
16 | + * 地区 | ||
17 | + */ | ||
18 | + private String area; | ||
19 | + | ||
20 | + /** | ||
21 | + * 县区 | ||
22 | + */ | ||
23 | + private String county; | ||
24 | + | ||
25 | + /** | ||
26 | + * 案损 | ||
27 | + */ | ||
28 | + private String totalAmount; | ||
29 | + | ||
30 | + /** | ||
31 | + * 诈骗类型 | ||
32 | + */ | ||
33 | + private String fraudType; | ||
34 | + | ||
35 | + /** | ||
36 | + * 引流方式 | ||
37 | + */ | ||
38 | + private String rainageMethod; | ||
39 | + | ||
40 | + /** | ||
41 | + * 支付方式 | ||
42 | + */ | ||
43 | + private String payMethod; | ||
44 | + | ||
45 | + /** | ||
46 | + * 受害人性别 | ||
47 | + */ | ||
48 | + private String sex; | ||
49 | + | ||
50 | + /** | ||
51 | + * 受害人职业 | ||
52 | + */ | ||
53 | + private String career; | ||
54 | + | ||
55 | +} |
src/main/java/com/ash/util/JFCTest.java
0 → 100644
1 | +package com.ash.util; | ||
2 | + | ||
3 | +import com.ash.base.PieChartVo; | ||
4 | +import com.ash.enums.JFChartTypeEnum; | ||
5 | +import com.deepoove.poi.XWPFTemplate; | ||
6 | +import com.deepoove.poi.config.Configure; | ||
7 | +import com.deepoove.poi.data.PictureType; | ||
8 | +import com.deepoove.poi.data.Pictures; | ||
9 | +import com.deepoove.poi.data.Tables; | ||
10 | +import com.deepoove.poi.data.style.BorderStyle; | ||
11 | +import lombok.extern.slf4j.Slf4j; | ||
12 | +import org.jfree.chart.ChartFactory; | ||
13 | +import org.jfree.chart.ChartUtils; | ||
14 | +import org.jfree.chart.JFreeChart; | ||
15 | +import org.jfree.chart.StandardChartTheme; | ||
16 | +import org.jfree.chart.plot.CategoryPlot; | ||
17 | +import org.jfree.data.category.DefaultCategoryDataset; | ||
18 | +import org.springframework.util.ResourceUtils; | ||
19 | + | ||
20 | +import java.awt.*; | ||
21 | +import java.io.File; | ||
22 | +import java.io.FileInputStream; | ||
23 | +import java.io.IOException; | ||
24 | +import java.time.LocalDate; | ||
25 | +import java.util.ArrayList; | ||
26 | +import java.util.HashMap; | ||
27 | +import java.util.Map; | ||
28 | +import java.util.List; | ||
29 | + | ||
30 | +@Slf4j | ||
31 | +public class JFCTest { | ||
32 | + private static final String TEMPLATE_PATH = "D:/data/jfreetest/report.docx"; | ||
33 | + private static final String OUTPUT_DIR = "D:/data/jfreetest/analysis/"; | ||
34 | + private static final String PIC_DIR = OUTPUT_DIR + "pic/"; | ||
35 | + | ||
36 | + public static void main(String[] args) { | ||
37 | + List<PieChartVo> dataList = new ArrayList<>(); | ||
38 | + PieChartVo d1 = new PieChartVo("类型1", 1.2); | ||
39 | + PieChartVo d2 = new PieChartVo("类型2", 4.2); | ||
40 | + PieChartVo d3 = new PieChartVo("类型3", -3.2); | ||
41 | + PieChartVo d4 = new PieChartVo("类型4", 10.2); | ||
42 | + PieChartVo d5 = new PieChartVo("类型5", 10.2); | ||
43 | + PieChartVo d6 = new PieChartVo("类型6", -10.2); | ||
44 | + PieChartVo d7 = new PieChartVo("类型7", 20.2); | ||
45 | + | ||
46 | + dataList.add(d1); | ||
47 | + dataList.add(d2); | ||
48 | + dataList.add(d3); | ||
49 | + dataList.add(d4); | ||
50 | + dataList.add(d5); | ||
51 | + dataList.add(d6); | ||
52 | + dataList.add(d7); | ||
53 | + getWord(dataList); | ||
54 | + } | ||
55 | + | ||
56 | + | ||
57 | + public static void getWord(List<PieChartVo> dataList) { | ||
58 | + try { | ||
59 | + // 获取模板文件 | ||
60 | + File file = ResourceUtils.getFile(TEMPLATE_PATH); | ||
61 | + | ||
62 | + // 构建模板替换的数据 | ||
63 | + Map<String, Object> dataMap = buildTemplateData(dataList); | ||
64 | + //表格 | ||
65 | + dataMap.put("table0", Tables.of(new String[][] { | ||
66 | + new String[] { "00", "01" }, | ||
67 | + new String[] { "10", "11" } | ||
68 | + }).border(BorderStyle.DEFAULT).create()); | ||
69 | + | ||
70 | + | ||
71 | + // 生成最终文件路径 | ||
72 | + String fileName = UUIDGenerator.uuid() + ".docx"; | ||
73 | + String filePath = OUTPUT_DIR + fileName; | ||
74 | + | ||
75 | + // 使用 POI-TL 渲染模板并保存 | ||
76 | + try (XWPFTemplate template = XWPFTemplate.compile(file, Configure.newBuilder().buildGramer("${", "}").build()) | ||
77 | + .render(dataMap)) { | ||
78 | + template.writeToFile(filePath); | ||
79 | + } | ||
80 | + //上传文件返回附件id | ||
81 | + } catch (Exception e) { | ||
82 | + e.printStackTrace(); | ||
83 | + } | ||
84 | + } | ||
85 | + | ||
86 | + private static Map<String, Object> buildTemplateData(List<PieChartVo> dataList) throws IOException { | ||
87 | + Map<String, Object> dataMap = new HashMap<>(); | ||
88 | + | ||
89 | + // 设置日期和在线总数 | ||
90 | + dataMap.put("date", LocalDate.now()); | ||
91 | + // 查询设备数据 | ||
92 | + dataMap.put("onlineTotal", 100); | ||
93 | + // 生成每日在线图表 | ||
94 | + String dailyPicFile = JFChartUtils.createChart(dataList, JFChartTypeEnum.BAR, "监测站总在线数", "小时", "数量"); | ||
95 | + //图片插入就用Pictures类构建PictureBuilder,可查看Pictures其他方法,比如插入base64等 | ||
96 | + dataMap.put("dailyOnlinePic", Pictures.ofStream(new FileInputStream(dailyPicFile), PictureType.JPEG).size(600, 200).create()); | ||
97 | + return dataMap; | ||
98 | + } | ||
99 | + | ||
100 | + | ||
101 | +} |
src/main/java/com/ash/util/JFChartUtils.java
0 → 100644
1 | +package com.ash.util; | ||
2 | + | ||
3 | +import com.ash.base.PieChartVo; | ||
4 | +import com.ash.enums.JFChartTypeEnum; | ||
5 | +import lombok.extern.slf4j.Slf4j; | ||
6 | +import org.jfree.chart.*; | ||
7 | +import org.jfree.chart.axis.AxisLocation; | ||
8 | +import org.jfree.chart.axis.CategoryAxis; | ||
9 | +import org.jfree.chart.axis.NumberAxis; | ||
10 | +import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; | ||
11 | +import org.jfree.chart.labels.StandardPieSectionLabelGenerator; | ||
12 | +import org.jfree.chart.plot.CategoryPlot; | ||
13 | +import org.jfree.chart.plot.PiePlot; | ||
14 | +import org.jfree.chart.renderer.category.BarRenderer; | ||
15 | +import org.jfree.chart.renderer.category.CategoryItemRenderer; | ||
16 | +import org.jfree.chart.renderer.category.StandardBarPainter; | ||
17 | +import org.jfree.data.category.DefaultCategoryDataset; | ||
18 | +import org.jfree.data.general.DefaultPieDataset; | ||
19 | +import org.springframework.stereotype.Component; | ||
20 | + | ||
21 | +import java.awt.*; | ||
22 | +import java.io.File; | ||
23 | +import java.io.IOException; | ||
24 | +import java.text.DecimalFormat; | ||
25 | +import java.util.ArrayList; | ||
26 | +import java.util.List; | ||
27 | + | ||
28 | +@Slf4j | ||
29 | +@Component | ||
30 | +public class JFChartUtils { | ||
31 | + | ||
32 | + public static final String OUTPUT_DIR = "D:/data/jfreetest/analysis/"; | ||
33 | + private static final String PIC_DIR = OUTPUT_DIR + "pic/"; | ||
34 | + | ||
35 | + public static List<Color> colorList = new ArrayList<>(); | ||
36 | + | ||
37 | + static { | ||
38 | + Color c1 = new Color(65, 105, 225); | ||
39 | + Color c2 = new Color(0, 191, 255); | ||
40 | + Color c3 = new Color(135, 206, 250); | ||
41 | + Color c4 = new Color(192, 192, 192); | ||
42 | + Color c5 = new Color(144, 238, 144); | ||
43 | + Color c6 = new Color(147, 112, 219); | ||
44 | + colorList.add(c1); | ||
45 | + colorList.add(c2); | ||
46 | + colorList.add(c3); | ||
47 | + colorList.add(c4); | ||
48 | + colorList.add(c5); | ||
49 | + colorList.add(c6); | ||
50 | + } | ||
51 | + | ||
52 | + // 设置折现图表样式 | ||
53 | + private static void setLineChartStyle(JFreeChart chart) { | ||
54 | + CategoryPlot plot = chart.getCategoryPlot(); | ||
55 | + chart.setBackgroundPaint(Color.WHITE); | ||
56 | + plot.setBackgroundPaint(Color.WHITE); | ||
57 | + plot.setDomainGridlinePaint(Color.LIGHT_GRAY); | ||
58 | + plot.setRangeGridlinePaint(Color.LIGHT_GRAY); | ||
59 | + // 设置第一条折线的粗细 | ||
60 | + plot.getRenderer().setSeriesStroke(0, new BasicStroke(3.0f)); | ||
61 | + // 根据样式设置折线颜色 | ||
62 | + plot.getRenderer().setSeriesPaint(0, colorList.get(0)); | ||
63 | + plot.setNoDataMessage("暂无数据"); | ||
64 | + | ||
65 | + } | ||
66 | + | ||
67 | + // 设置柱形图表样式 | ||
68 | + private static void setBarChartStyle(JFreeChart chart) { | ||
69 | + | ||
70 | + CategoryPlot categoryplot = (CategoryPlot) chart.getPlot(); //获取图表对象 | ||
71 | + categoryplot.setBackgroundPaint(ChartColor.WHITE); //设置图表的背景颜色 | ||
72 | + categoryplot.setOutlinePaint(ChartColor.BLACK); //图表边框颜色 | ||
73 | + categoryplot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_LEFT); //设置xy轴的位置 | ||
74 | + categoryplot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT); | ||
75 | + categoryplot.setNoDataMessage("暂无数据"); | ||
76 | + | ||
77 | + BarRenderer customBarRenderer = (BarRenderer) categoryplot.getRenderer(); | ||
78 | + //取消柱子上的渐变色 | ||
79 | + customBarRenderer.setBarPainter(new StandardBarPainter()); | ||
80 | + //设置阴影,false代表没有阴影 | ||
81 | + customBarRenderer.setShadowVisible(false); | ||
82 | + //设置柱子宽度,如果宽度设置的太小,会导致文字不在柱子的中间。 | ||
83 | + customBarRenderer.setMaximumBarWidth(30); | ||
84 | + customBarRenderer.setMinimumBarLength(0.8); | ||
85 | + customBarRenderer.setItemMargin(-1.2); //设置柱子间距 | ||
86 | + customBarRenderer.setSeriesPaint(0, colorList.get(0)); | ||
87 | + customBarRenderer.setDrawBarOutline(false); | ||
88 | + customBarRenderer.setIncludeBaseInRange(true); | ||
89 | + | ||
90 | + CategoryItemRenderer renderer = categoryplot.getRenderer(); | ||
91 | + renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator()); | ||
92 | + renderer.setDefaultItemLabelsVisible(true); | ||
93 | + | ||
94 | + | ||
95 | + //数据轴设置 | ||
96 | + NumberAxis numberaxis = (NumberAxis) categoryplot.getRangeAxis(); | ||
97 | + numberaxis.setUpperMargin(0.1);//设置最高的一个柱与图片顶端的距离(最高柱的10%) | ||
98 | + numberaxis.setLowerMargin(0.1); | ||
99 | + numberaxis.setTickLabelFont(new Font("宋体", Font.BOLD, 12)); | ||
100 | + numberaxis.setLabelFont(new Font("宋体", Font.BOLD, 12)); | ||
101 | + | ||
102 | + //项目轴设置 | ||
103 | + CategoryAxis domainAxis = categoryplot.getDomainAxis(); | ||
104 | + domainAxis.setTickLabelFont(new Font("宋体", Font.BOLD, 15)); | ||
105 | + | ||
106 | + } | ||
107 | + | ||
108 | + // 设置饼图表样式 | ||
109 | + private static void setPieChartStyle(JFreeChart chart, DefaultPieDataset pieData) { | ||
110 | + | ||
111 | + PiePlot plot = (PiePlot) chart.getPlot(); | ||
112 | + chart.setBackgroundPaint(Color.WHITE); | ||
113 | + plot.setBackgroundPaint(Color.WHITE); | ||
114 | + // 设置标签字体 | ||
115 | + plot.setLabelFont(new Font("宋体", Font.PLAIN, 14)); | ||
116 | + // 设置无数据信息字体(如果需要) | ||
117 | + plot.setNoDataMessageFont(new Font("宋体", Font.PLAIN, 18)); | ||
118 | + plot.setNoDataMessage("暂无数据"); | ||
119 | + plot.setLabelGenerator(new StandardPieSectionLabelGenerator( | ||
120 | + "{2}", | ||
121 | + new DecimalFormat("#,##0"), // 数值格式(带千分位) | ||
122 | + new DecimalFormat("0.0%") // 百分比格式 | ||
123 | + )); | ||
124 | + for (int i = 0; i < pieData.getItemCount() && i < colorList.size(); i++) { | ||
125 | + plot.setSectionPaint(pieData.getKey(i).toString(), colorList.get(i)); | ||
126 | + } | ||
127 | + | ||
128 | + } | ||
129 | + | ||
130 | + | ||
131 | + private static DefaultCategoryDataset buildDailyDataset(List<PieChartVo> dataList) { | ||
132 | + DefaultCategoryDataset dataset = new DefaultCategoryDataset(); | ||
133 | + dataList.forEach(t -> dataset.addValue(ObjectValueOption.getObjDouble(t.getValue()), "", t.getName())); | ||
134 | + return dataset; | ||
135 | + } | ||
136 | + | ||
137 | + | ||
138 | + private static DefaultPieDataset buildPieDataset(List<PieChartVo> dataList) { | ||
139 | + DefaultPieDataset dataset = new DefaultPieDataset(); | ||
140 | + dataList.forEach(t -> dataset.setValue(t.getName(), ObjectValueOption.getObjDouble(t.getValue()))); | ||
141 | + return dataset; | ||
142 | + } | ||
143 | + | ||
144 | + | ||
145 | + // 生成图表并保存为图片 | ||
146 | + public static String createChart(List<PieChartVo> dataList, JFChartTypeEnum type, String title, String xAxisLabel, String yAxisLabel) throws IOException { | ||
147 | + // 设置全局字体(支持中文) | ||
148 | + StandardChartTheme chartTheme = new StandardChartTheme("CN"); | ||
149 | + chartTheme.setExtraLargeFont(new Font("宋体", Font.PLAIN, 14)); // 标题字体 | ||
150 | + chartTheme.setLargeFont(new Font("宋体", Font.PLAIN, 14)); // 图例字体 | ||
151 | + chartTheme.setRegularFont(new Font("宋体", Font.PLAIN, 12)); // 轴标签字体 | ||
152 | + ChartFactory.setChartTheme(chartTheme); | ||
153 | + JFreeChart chart = null; | ||
154 | + switch (type) { | ||
155 | + case LINE: | ||
156 | + DefaultCategoryDataset dataset = buildDailyDataset(dataList); | ||
157 | + chart = ChartFactory.createLineChart(title, xAxisLabel, yAxisLabel, dataset); | ||
158 | + setLineChartStyle(chart); | ||
159 | + break; | ||
160 | + case PIE: | ||
161 | + DefaultPieDataset pieData = buildPieDataset(dataList); | ||
162 | + chart = ChartFactory.createPieChart(title, pieData, true, true, false); | ||
163 | + setPieChartStyle(chart, pieData); | ||
164 | + break; | ||
165 | + case BAR: | ||
166 | + DefaultCategoryDataset batData = buildDailyDataset(dataList); | ||
167 | + chart = ChartFactory.createBarChart(title, xAxisLabel, yAxisLabel, batData); | ||
168 | + setBarChartStyle(chart); | ||
169 | + break; | ||
170 | + } | ||
171 | + | ||
172 | + | ||
173 | + // 保存图表为图片 | ||
174 | + String picFile = PIC_DIR + UUIDGenerator.uuid() + ".png"; | ||
175 | + File file = new File(picFile); | ||
176 | + if (!file.getParentFile().exists()) { | ||
177 | + if (!file.getParentFile().mkdirs()) { | ||
178 | + log.error("目录创建失败!" + file.getParentFile().getAbsolutePath()); | ||
179 | + } | ||
180 | + } | ||
181 | + //int numberOfCategories = dataset.getColumnCount(); | ||
182 | + //int width = Math.max(800, numberOfCategories * 50); // 每个类别宽度为50,最小宽度为800 | ||
183 | + ChartUtils.saveChartAsPNG(file, chart, 1200, 400); | ||
184 | + return picFile; | ||
185 | + } | ||
186 | + | ||
187 | + | ||
188 | +} |
@@ -17,4 +17,12 @@ public class ObjectValueOption { | @@ -17,4 +17,12 @@ public class ObjectValueOption { | ||
17 | return Integer.parseInt(ojb.toString()); | 17 | return Integer.parseInt(ojb.toString()); |
18 | 18 | ||
19 | } | 19 | } |
20 | + | ||
21 | + public static Double getObjDouble(Object ojb) { | ||
22 | + if (ojb == null) { | ||
23 | + return 0D; | ||
24 | + } | ||
25 | + return Double.parseDouble(ojb.toString()); | ||
26 | + | ||
27 | + } | ||
20 | } | 28 | } |
src/main/java/com/ash/util/WiLossVo.java
0 → 100644
1 | +package com.ash.util; | ||
2 | + | ||
3 | +import lombok.Data; | ||
4 | + | ||
5 | +/** | ||
6 | + * 报表导出警情损列表vo | ||
7 | + */ | ||
8 | +@Data | ||
9 | +public class WiLossVo { | ||
10 | + /** | ||
11 | + * 案件编号 | ||
12 | + */ | ||
13 | + private String code; | ||
14 | + | ||
15 | + /** | ||
16 | + * 地区 | ||
17 | + */ | ||
18 | + private String area; | ||
19 | + | ||
20 | + /** | ||
21 | + * 县区 | ||
22 | + */ | ||
23 | + private String county; | ||
24 | + | ||
25 | + /** | ||
26 | + * 接警警情子类 | ||
27 | + */ | ||
28 | + private String alarmSubType; | ||
29 | + | ||
30 | + /** | ||
31 | + * 案损 | ||
32 | + */ | ||
33 | + private String amount; | ||
34 | + | ||
35 | + /** | ||
36 | + * 引流方式 | ||
37 | + */ | ||
38 | + private String rainageMethod; | ||
39 | + | ||
40 | + /** | ||
41 | + * 支付方式 | ||
42 | + */ | ||
43 | + private String payMethod; | ||
44 | + | ||
45 | + /** | ||
46 | + * 受害人性别 | ||
47 | + */ | ||
48 | + private String sex; | ||
49 | + | ||
50 | + /** | ||
51 | + * 受害人职业 | ||
52 | + */ | ||
53 | + private String career; | ||
54 | + | ||
55 | +} |
No preview for this file type