diff --git a/src/main/java/com/biutag/supervision/pojo/dto/report/BusinessLineOverviewSection.java b/src/main/java/com/biutag/supervision/pojo/dto/report/BusinessLineOverviewSection.java new file mode 100644 index 0000000..d9731a4 --- /dev/null +++ b/src/main/java/com/biutag/supervision/pojo/dto/report/BusinessLineOverviewSection.java @@ -0,0 +1,25 @@ +package com.biutag.supervision.pojo.dto.report; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +@Schema(description = "各业务条线情况-总览") +public class BusinessLineOverviewSection { + + @Schema(description = "统计开始时间", example = "2026年3月1日") + private String periodStart; + + @Schema(description = "统计结束时间", example = "2026年3月31日") + private String periodEnd; + + @Schema(description = "各业务条线情况-总览总数") + private Integer businessLineTotal; + + @Schema(description = "各业务条线情况-总览文本(已拼接)") + private String businessLineOverviewText; +} \ No newline at end of file diff --git a/src/main/java/com/biutag/supervision/pojo/dto/report/BusinessLineStatItem.java b/src/main/java/com/biutag/supervision/pojo/dto/report/BusinessLineStatItem.java new file mode 100644 index 0000000..2864eba --- /dev/null +++ b/src/main/java/com/biutag/supervision/pojo/dto/report/BusinessLineStatItem.java @@ -0,0 +1,35 @@ +package com.biutag.supervision.pojo.dto.report; + +import com.biutag.supervision.pojo.enums.report.TrendEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; + +@Getter +@Setter +@Schema(description = "条线统计项") +public class BusinessLineStatItem { + + @Schema(description = "条线/项目名称") + private String lineName; + + @Schema(description = "下发条数") + private Integer issuedCount; + + @Schema(description = "占比(%)") + private BigDecimal issuedRate; + + @Schema(description = "环比增幅(%)") + private BigDecimal momRate; + + @Schema(description = "环比趋势") + private TrendEnum trendMom; + + @Schema(description = "同比增幅(%)") + private BigDecimal yoyRate; + + @Schema(description = "同比趋势") + private TrendEnum trendYoy; +} \ No newline at end of file diff --git a/src/main/java/com/biutag/supervision/pojo/dto/report/ReportViewModel.java b/src/main/java/com/biutag/supervision/pojo/dto/report/ReportViewModel.java index b0ebde6..62e8491 100644 --- a/src/main/java/com/biutag/supervision/pojo/dto/report/ReportViewModel.java +++ b/src/main/java/com/biutag/supervision/pojo/dto/report/ReportViewModel.java @@ -25,4 +25,9 @@ public class ReportViewModel { @Schema(description = "总体部分") private OverviewSection overviewSection; + @Schema(description = "各业务条线情况-总览部分") + private BusinessLineOverviewSection businessLineOverviewSection; + + + } diff --git a/src/main/java/com/biutag/supervision/pojo/param/NegativeQueryParam.java b/src/main/java/com/biutag/supervision/pojo/param/NegativeQueryParam.java index 2ead5e6..a2a4f7f 100644 --- a/src/main/java/com/biutag/supervision/pojo/param/NegativeQueryParam.java +++ b/src/main/java/com/biutag/supervision/pojo/param/NegativeQueryParam.java @@ -1,5 +1,6 @@ package com.biutag.supervision.pojo.param; +import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; @@ -116,4 +117,23 @@ public class NegativeQueryParam extends BasePage { private String issuingDepartName; + public NegativeQueryParam newQueryParam() { + NegativeQueryParam target = new NegativeQueryParam(); + BeanUtil.copyProperties(this, target); + + target.setHappenTime(this.happenTime == null ? new ArrayList<>() : new ArrayList<>(this.happenTime)); + target.setDiscoveryTime(this.discoveryTime == null ? new ArrayList<>() : new ArrayList<>(this.discoveryTime)); + target.setCrtTime(this.crtTime == null ? new ArrayList<>() : new ArrayList<>(this.crtTime)); + target.setProcessingStatus(this.processingStatus == null ? new ArrayList<>() : new ArrayList<>(this.processingStatus)); + target.setCheckStatus(this.checkStatus == null ? null : new ArrayList<>(this.checkStatus)); + target.setCheckStatusCode(this.checkStatusCode == null ? null : new ArrayList<>(this.checkStatusCode)); + target.setHandleResultCode(this.handleResultCode == null ? new ArrayList<>() : new ArrayList<>(this.handleResultCode)); + target.setMailTime(this.mailTime == null ? new ArrayList<>() : new ArrayList<>(this.mailTime)); + target.setThreeLevelCode(this.threeLevelCode == null ? null : new ArrayList<>(this.threeLevelCode)); + target.setProblemSourcesCode(this.problemSourcesCode == null ? null : new ArrayList<>(this.problemSourcesCode)); + target.setInvolveDepartIds(this.involveDepartIds == null ? null : Set.copyOf(this.involveDepartIds)); + + return target; + } + } diff --git a/src/main/java/com/biutag/supervision/service/SupDictProblemSourceService.java b/src/main/java/com/biutag/supervision/service/SupDictProblemSourceService.java index bf2da8e..f09eb44 100644 --- a/src/main/java/com/biutag/supervision/service/SupDictProblemSourceService.java +++ b/src/main/java/com/biutag/supervision/service/SupDictProblemSourceService.java @@ -47,4 +47,22 @@ public class SupDictProblemSourceService extends ServiceImpl buildIdMap() { + List tree = buildTree(); + Map map = new HashMap<>(); + flatten(tree, map); + return map; + } + + private void flatten(List nodes, Map map) { + for (DictProblemSourceTree node : nodes) { + map.put(node.getId(), node); + if (node.getChildren() != null && !node.getChildren().isEmpty()) { + flatten(node.getChildren(), map); + } + } + } + } diff --git a/src/main/java/com/biutag/supervision/service/report/ReportDataServiceImpl.java b/src/main/java/com/biutag/supervision/service/report/ReportDataServiceImpl.java index dc3e11b..33c90a0 100644 --- a/src/main/java/com/biutag/supervision/service/report/ReportDataServiceImpl.java +++ b/src/main/java/com/biutag/supervision/service/report/ReportDataServiceImpl.java @@ -2,15 +2,19 @@ package com.biutag.supervision.service.report; import cn.hutool.core.util.StrUtil; import com.biutag.supervision.constants.enums.CheckStatusEnum; +import com.biutag.supervision.pojo.domain.NegativeVo; +import com.biutag.supervision.pojo.dto.report.BusinessLineOverviewSection; import com.biutag.supervision.pojo.dto.report.OverviewSection; import com.biutag.supervision.pojo.dto.report.ReportViewModel; import com.biutag.supervision.pojo.entity.NegativeBlame; import com.biutag.supervision.pojo.param.NegativeQueryParam; import com.biutag.supervision.pojo.param.negativeBlame.NegativeBlameQueryParam; +import com.biutag.supervision.pojo.vo.DictProblemSourceTree; import com.biutag.supervision.pojo.vo.NegativeQueryVo; import com.biutag.supervision.repository.negative.NegativeResourceService; import com.biutag.supervision.repository.negativeBlame.NegativeBlameResourceService; import com.biutag.supervision.service.NegativeQueryService; +import com.biutag.supervision.service.SupDictProblemSourceService; import com.biutag.supervision.util.DateCompareRangeUtil; import com.biutag.supervision.util.ReportTrendUtil; import com.biutag.supervision.util.TimeUtil; @@ -21,6 +25,7 @@ import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import java.util.stream.Stream; @Service @@ -35,6 +40,9 @@ public class ReportDataServiceImpl implements ReportDataService { @Resource private NegativeQueryService negativeQueryService; + @Resource + private SupDictProblemSourceService supDictProblemSourceService; + @Override public ReportViewModel buildViewModel(NegativeQueryParam request) { String periodStart = TimeUtil.formatDate(request.getCrtTime().get(0)); @@ -43,10 +51,53 @@ public class ReportDataServiceImpl implements ReportDataService { vm.setPeriodStart(periodStart); vm.setPeriodEnd(periodEnd); vm.setOverviewSection(buildOverviewSection(request, periodStart, periodEnd)); -// + vm.setBusinessLineOverviewSection(buildbusinessLineOverviewSection(request, periodStart, periodEnd)); return vm; } + /** + * 业务条线的总览 + * @param request + * @param periodStart + * @param periodEnd + * @return + */ + private BusinessLineOverviewSection buildbusinessLineOverviewSection(NegativeQueryParam request, String periodStart, String periodEnd) { + // 总体数据 + NegativeQueryParam ztNegativeQueryParam = request.newQueryParam(); + List ztNegativeList = negativeQueryService.page(ztNegativeQueryParam).getRecords(); + Map idMap = supDictProblemSourceService.buildIdMap(); + // 计数 + Map aggByParentLabel = ztNegativeList.stream() + .map(NegativeQueryVo::getProblemSourcesCode) // 收集二级id + .map(childId -> parentLabel2Level(childId, idMap)) // 解析未一级label + .collect(Collectors.groupingBy(s -> s, Collectors.counting())); + // 排序 + List> sorted = aggByParentLabel.entrySet().stream() + .sorted((a, b) -> Long.compare(b.getValue(), a.getValue())) + .toList(); + // 3)拼接总览文本(全部列出) + StringBuilder businessLineOverviewText = new StringBuilder(); + for (int i = 0; i < sorted.size(); i++) { + String label = sorted.get(i).getKey(); + int cnt = Math.toIntExact(sorted.get(i).getValue()); + businessLineOverviewText.append(i + 1) + .append("、") + .append(label) + .append(",") + .append(cnt) + .append("条,占比") + .append(ReportTrendUtil.percent(cnt, ztNegativeList.size())) + .append("%;"); + } + BusinessLineOverviewSection businessLineOverviewSection = new BusinessLineOverviewSection(); + businessLineOverviewSection.setPeriodStart(periodStart); + businessLineOverviewSection.setPeriodEnd(periodEnd); + businessLineOverviewSection.setBusinessLineTotal(ztNegativeList.size()); + businessLineOverviewSection.setBusinessLineOverviewText(businessLineOverviewText.toString()); + return businessLineOverviewSection; + } + /** * 总体情况计算 * @@ -59,13 +110,16 @@ public class ReportDataServiceImpl implements ReportDataService { DateCompareRangeUtil.CompareDateRange compareDateRange = DateCompareRangeUtil.buildCompareDateRange(request.getCrtTime().get(0), request.getCrtTime().get(1)); // 总体数据 - List ztNegativeList = negativeQueryService.page(request).getRecords(); + NegativeQueryParam ztnegativeQueryParam = request.newQueryParam(); + List ztNegativeList = negativeQueryService.page(ztnegativeQueryParam).getRecords(); // 环比数据 - request.setCrtTime(compareDateRange.mom()); - List hbNegativList = negativeQueryService.page(request).getRecords(); + NegativeQueryParam hbNegativeQueryParam = request.newQueryParam(); + hbNegativeQueryParam.setCrtTime(compareDateRange.mom()); + List hbNegativList = negativeQueryService.page(hbNegativeQueryParam).getRecords(); // 同比数据 - request.setCrtTime(compareDateRange.yoy()); - List tbNegativList = negativeQueryService.page(request).getRecords(); + NegativeQueryParam tbNegativeQueryParam = request.newQueryParam(); + tbNegativeQueryParam.setCrtTime(compareDateRange.yoy()); + List tbNegativList = negativeQueryService.page(tbNegativeQueryParam).getRecords(); // 市局下发数据 List sjxfNegativeList = ztNegativeList.stream().filter(one -> Objects.equals(0, one.getCrtDepartLevel())).toList(); // 分县市局下发数据 @@ -73,11 +127,11 @@ public class ReportDataServiceImpl implements ReportDataService { // 办结数据 List bjNegativeList = ztNegativeList.stream().filter(one -> !Objects.isNull(one.getCompleteDate())).toList(); // 办结中属实数据 - List bjssNegativeList = bjNegativeList.stream().filter(one -> CheckStatusEnum.TRUE_LIST.contains(one.getCheckStatus())).toList(); + List bjssNegativeList = bjNegativeList.stream().filter(one -> CheckStatusEnum.TRUE_SET.contains(one.getCheckStatus())).toList(); // 办结中基本属实数据 - List bjjbssNegativeList = bjNegativeList.stream().filter(one -> CheckStatusEnum.PART_TRUE_LIST.contains(one.getCheckStatus())).toList(); + List bjjbssNegativeList = bjNegativeList.stream().filter(one -> CheckStatusEnum.PART_TRUE_SET.contains(one.getCheckStatus())).toList(); // 办结中不属实数据 - List bjbssNegativeList = bjNegativeList.stream().filter(one -> CheckStatusEnum.FALSE_LIST.contains(one.getCheckStatus())).toList(); + List bjbssNegativeList = bjNegativeList.stream().filter(one -> CheckStatusEnum.FALSE_SET.contains(one.getCheckStatus())).toList(); // 属实 基本属实中的问责数据 List ssNegativeIds = Stream.concat(bjssNegativeList.stream(), bjjbssNegativeList.stream()) .map(NegativeQueryVo::getId).filter(StrUtil::isNotBlank).distinct().toList(); @@ -167,12 +221,12 @@ public class ReportDataServiceImpl implements ReportDataService { // 属实 int verified = (int) closed.stream() - .filter(n -> CheckStatusEnum.TRUE_LIST.contains(n.getCheckStatus())) + .filter(n -> CheckStatusEnum.TRUE_SET.contains(n.getCheckStatus())) .count(); // 基本属实 int partVerified = (int) closed.stream() - .filter(n -> CheckStatusEnum.PART_TRUE_LIST.contains(n.getCheckStatus())) + .filter(n -> CheckStatusEnum.PART_TRUE_SET.contains(n.getCheckStatus())) .count(); // 查实率 = (属实 + 基本属实) / 办结 @@ -180,4 +234,18 @@ public class ReportDataServiceImpl implements ReportDataService { } + private String parentLabel2Level(String childId, Map idMap) { + if (StrUtil.isBlank(childId)) { + return "未归类"; + } + DictProblemSourceTree child = idMap.get(childId); + if (child == null) { + return "未归类"; + } + DictProblemSourceTree parent = idMap.get(child.getParentId()); + // 若 child 没父,说明 child 自己就是一级(兜底) + return parent != null ? StrUtil.blankToDefault(parent.getLabel(), "未归类") + : StrUtil.blankToDefault(child.getLabel(), "未归类"); + } + } \ No newline at end of file diff --git a/src/main/resources/static/templates/督审一体化平台研判分析报告.docx b/src/main/resources/static/templates/督审一体化平台研判分析报告.docx index d13e753..5eae08f 100644 Binary files a/src/main/resources/static/templates/督审一体化平台研判分析报告.docx and b/src/main/resources/static/templates/督审一体化平台研判分析报告.docx differ