diff --git a/src/main/java/com/biutag/supervision/pojo/dto/report/OverviewSection.java b/src/main/java/com/biutag/supervision/pojo/dto/report/OverviewSection.java index e08c281..f9cec7c 100644 --- a/src/main/java/com/biutag/supervision/pojo/dto/report/OverviewSection.java +++ b/src/main/java/com/biutag/supervision/pojo/dto/report/OverviewSection.java @@ -70,6 +70,12 @@ public class OverviewSection { @Schema(description = "查实率同比变化率", example = "5.1") private BigDecimal verifiedYoyRate; + @Schema(description = "查实和基本查实数和", example = "420") + private Integer verifiedAndBasicallyVerifiedCount; + + @Schema(description = "问责问题数", example = "5") + private Integer accountabilityProblemTotal; + @Schema(description = "问责总人次", example = "58") private Integer accountabilityTotal; diff --git a/src/main/java/com/biutag/supervision/pojo/dto/report/accountability/ReportAccountabilityStatsRequestDTO.java b/src/main/java/com/biutag/supervision/pojo/dto/report/accountability/ReportAccountabilityStatsRequestDTO.java index 654ad04..7aa7bb8 100644 --- a/src/main/java/com/biutag/supervision/pojo/dto/report/accountability/ReportAccountabilityStatsRequestDTO.java +++ b/src/main/java/com/biutag/supervision/pojo/dto/report/accountability/ReportAccountabilityStatsRequestDTO.java @@ -1,5 +1,6 @@ package com.biutag.supervision.pojo.dto.report.accountability; +import com.biutag.supervision.pojo.vo.NegativeQueryVo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; @@ -18,7 +19,13 @@ import java.util.List; @Schema(description = "报表问责统计请求DTO") public class ReportAccountabilityStatsRequestDTO { - @Schema(description = "问题ID列表") + @Deprecated + @Schema(description = "属实、部分问题ID列表") private List negativeIds = new ArrayList<>(); + + @Schema(description = "原始问题列表") + private List negativeQueryVoList; + + } \ No newline at end of file diff --git a/src/main/java/com/biutag/supervision/pojo/dto/report/accountability/ReportAccountabilityStatsResponseDTO.java b/src/main/java/com/biutag/supervision/pojo/dto/report/accountability/ReportAccountabilityStatsResponseDTO.java index f28a91a..b6acb1b 100644 --- a/src/main/java/com/biutag/supervision/pojo/dto/report/accountability/ReportAccountabilityStatsResponseDTO.java +++ b/src/main/java/com/biutag/supervision/pojo/dto/report/accountability/ReportAccountabilityStatsResponseDTO.java @@ -1,13 +1,16 @@ package com.biutag.supervision.pojo.dto.report.accountability; +import com.biutag.supervision.pojo.dto.report.businessLine.BusinessLinePersonRankItem; import com.biutag.supervision.pojo.entity.NegativeBlame; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * @ClassName ReportAccountabilityStatsResponseDTO @@ -20,13 +23,19 @@ import java.util.List; @Schema(description = "报表问责统计结果DTO") public class ReportAccountabilityStatsResponseDTO { - @Schema(description = "问责总数 = 个人问责 + 领导问责 + 单位问责", example = "12") + @Schema(description = "问责问题条数") + private int accountabilityNegativeCount; + + @Schema(description = "问责率 问责问题条数/办结的条数") + private BigDecimal accountabilityNegativeRate; + + @Schema(description = "问责总人次数 = 个人问责 + 领导问责 + 单位问责", example = "12") private int total; - @Schema(description = "个人问责数 = 个人问责 + 领导问责", example = "8") + @Schema(description = "个人问责人次数 = 个人问责 + 领导问责", example = "8") private int personal; - @Schema(description = "单位问责数", example = "4") + @Schema(description = "单位问责人次数", example = "4") private int unit; @Schema(description = "个人问责列表") @@ -38,4 +47,13 @@ public class ReportAccountabilityStatsResponseDTO { @Schema(description = "单位问责列表") private List unitBlames = new ArrayList<>(); + @Schema(description = "问责人员TOP3") + private List topPersons; + + @Schema(description = "个人问责类型次数map") + private Map personalTypeCountMap; + + @Schema(description = "单位问责类型次数map") + private Map unitTypeCountMap; + } \ No newline at end of file diff --git a/src/main/java/com/biutag/supervision/pojo/dto/report/businessLine/BusinessLinePersonRankItem.java b/src/main/java/com/biutag/supervision/pojo/dto/report/businessLine/BusinessLinePersonRankItem.java index 81c5aa0..3089920 100644 --- a/src/main/java/com/biutag/supervision/pojo/dto/report/businessLine/BusinessLinePersonRankItem.java +++ b/src/main/java/com/biutag/supervision/pojo/dto/report/businessLine/BusinessLinePersonRankItem.java @@ -1,14 +1,16 @@ package com.biutag.supervision.pojo.dto.report.businessLine; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Getter; -import lombok.Setter; +import lombok.*; import java.math.BigDecimal; @Getter @Setter @Schema(description = "业务条线重点人员排行项") +@Builder +@AllArgsConstructor +@NoArgsConstructor public class BusinessLinePersonRankItem { @Schema(description = "人员姓名") diff --git a/src/main/java/com/biutag/supervision/pojo/dto/report/businessLine/BusinessLineRankItem.java b/src/main/java/com/biutag/supervision/pojo/dto/report/businessLine/BusinessLineRankItem.java index 4a2458c..83a968c 100644 --- a/src/main/java/com/biutag/supervision/pojo/dto/report/businessLine/BusinessLineRankItem.java +++ b/src/main/java/com/biutag/supervision/pojo/dto/report/businessLine/BusinessLineRankItem.java @@ -1,7 +1,9 @@ package com.biutag.supervision.pojo.dto.report.businessLine; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import java.math.BigDecimal; @@ -9,6 +11,8 @@ import java.math.BigDecimal; @Getter @Setter @Schema(description = "业务条线排行项") +@AllArgsConstructor +@NoArgsConstructor public class BusinessLineRankItem { @Schema(description = "名称,如 执法程序问题 / 某某派出所") diff --git a/src/main/java/com/biutag/supervision/pojo/dto/report/closed/ClosedStatsCalcResponseDTO.java b/src/main/java/com/biutag/supervision/pojo/dto/report/closed/ClosedStatsCalcResponseDTO.java index e953186..cb84b42 100644 --- a/src/main/java/com/biutag/supervision/pojo/dto/report/closed/ClosedStatsCalcResponseDTO.java +++ b/src/main/java/com/biutag/supervision/pojo/dto/report/closed/ClosedStatsCalcResponseDTO.java @@ -1,5 +1,6 @@ package com.biutag.supervision.pojo.dto.report.closed; +import com.biutag.supervision.pojo.dto.report.businessLine.BusinessLineRankItem; import com.biutag.supervision.pojo.vo.NegativeQueryVo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; @@ -41,4 +42,7 @@ public class ClosedStatsCalcResponseDTO { @Schema(description = "不属实问题列表") private List unverifiedList = new ArrayList<>(); + @Schema(description = "问题单位排名") + private List topUnits; + } \ No newline at end of file diff --git a/src/main/java/com/biutag/supervision/service/report/impl/ReportAccountabilitySectionServiceImpl.java b/src/main/java/com/biutag/supervision/service/report/impl/ReportAccountabilitySectionServiceImpl.java index 2f012eb..a3b4ea1 100644 --- a/src/main/java/com/biutag/supervision/service/report/impl/ReportAccountabilitySectionServiceImpl.java +++ b/src/main/java/com/biutag/supervision/service/report/impl/ReportAccountabilitySectionServiceImpl.java @@ -1,5 +1,6 @@ package com.biutag.supervision.service.report.impl; +import cn.hutool.core.util.StrUtil; import com.biutag.supervision.pojo.dto.report.accountability.*; import com.biutag.supervision.pojo.entity.NegativeBlame; import com.biutag.supervision.pojo.param.NegativeQueryParam; @@ -12,11 +13,13 @@ import com.deepoove.poi.data.PictureRenderData; import com.deepoove.poi.data.PictureType; import com.deepoove.poi.data.Pictures; import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.*; @Service +@Slf4j public class ReportAccountabilitySectionServiceImpl implements ReportAccountabilitySectionService { @Resource @@ -27,76 +30,54 @@ public class ReportAccountabilitySectionServiceImpl implements ReportAccountabil @Override public AccountabilityOverviewSection buildAccountabilityOverviewSection(ReportAccountabilitySectionRequestDTO requestDTO) { + log.info("问责情况总览开始计算======================================================================================="); if (requestDTO == null || requestDTO.getNegativeQueryParam() == null) { return new AccountabilityOverviewSection(); } - NegativeQueryParam request = requestDTO.getNegativeQueryParam(); String periodStart = requestDTO.getPeriodStart(); String periodEnd = requestDTO.getPeriodEnd(); - NegativeQueryParam currentQueryParam = request.newQueryParam(); + NegativeQueryParam currentQueryParam = requestDTO.getNegativeQueryParam().newQueryParam(); List currentList = negativeQueryService.page(currentQueryParam).getRecords(); - - List negativeIds = currentList.stream() - .map(NegativeQueryVo::getId) - .filter(Objects::nonNull) - .toList(); - ReportAccountabilityStatsRequestDTO statsRequestDTO = new ReportAccountabilityStatsRequestDTO(); - statsRequestDTO.setNegativeIds(negativeIds); - ReportAccountabilityStatsResponseDTO statsResponseDTO = - reportAccountabilityStatsService.calculateAccountabilityStats(statsRequestDTO); - + statsRequestDTO.setNegativeQueryVoList(currentList); + ReportAccountabilityStatsResponseDTO statsResponseDTO = reportAccountabilityStatsService.calculateAccountabilityStats(statsRequestDTO); AccountabilityOverviewSection section = new AccountabilityOverviewSection(); section.setPeriodStart(periodStart); section.setPeriodEnd(periodEnd); section.setProblemTypeCount(currentList.size()); section.setPersonalAccountabilityCount(statsResponseDTO.getPersonal()); section.setDepartmentAccountabilityCount(statsResponseDTO.getUnit()); - + log.info("问责情况总览开始计算结束======================================================================================="); return section; } @Override public AccountabilityUnitSection buildAccountabilityUnitDetailSection(ReportAccountabilitySectionRequestDTO requestDTO) { + log.info("对单位追责问责情况开始计算======================================================================================="); if (requestDTO == null || requestDTO.getNegativeQueryParam() == null) { return new AccountabilityUnitSection(); } - NegativeQueryParam request = requestDTO.getNegativeQueryParam(); - - NegativeQueryParam currentQueryParam = request.newQueryParam(); + NegativeQueryParam currentQueryParam = requestDTO.getNegativeQueryParam().newQueryParam(); List currentList = negativeQueryService.page(currentQueryParam).getRecords(); - - List negativeIds = currentList.stream() - .map(NegativeQueryVo::getId) - .filter(Objects::nonNull) - .toList(); - ReportAccountabilityStatsRequestDTO statsRequestDTO = new ReportAccountabilityStatsRequestDTO(); - statsRequestDTO.setNegativeIds(negativeIds); - ReportAccountabilityStatsResponseDTO statsResponseDTO = - reportAccountabilityStatsService.calculateAccountabilityStats(statsRequestDTO); - - Map> unitMap = statsResponseDTO.getUnitBlames().stream() - .collect(java.util.stream.Collectors.groupingBy(NegativeBlame::getHandleResultName)); - + statsRequestDTO.setNegativeQueryVoList(currentList); + ReportAccountabilityStatsResponseDTO statsResponseDTO = reportAccountabilityStatsService.calculateAccountabilityStats(statsRequestDTO); AccountabilityUnitSection section = new AccountabilityUnitSection(); section.setTotalCount(statsResponseDTO.getUnit()); - - List typeItems = unitMap.entrySet().stream() + List typeItems = statsResponseDTO.getUnitTypeCountMap().entrySet().stream() .map(entry -> { AccountabilityTypeItem item = new AccountabilityTypeItem(); item.setTypeName(entry.getKey()); - item.setCount(entry.getValue().size()); + item.setCount(entry.getValue()); return item; }) .sorted(Comparator.comparing(AccountabilityTypeItem::getCount).reversed()) .toList(); section.setTypeItems(typeItems); - Map pieData = new LinkedHashMap<>(); for (AccountabilityTypeItem typeItem : typeItems) { pieData.put(typeItem.getTypeName(), typeItem.getCount()); @@ -107,53 +88,28 @@ public class ReportAccountabilitySectionServiceImpl implements ReportAccountabil .size(500, 300) .create(); section.setDepartPieChart(picture); + log.info("对单位追责问责情况计算结束======================================================================================="); return section; } @Override public AccountabilityPersonalSection buildAccountabilityPersonalOverviewSection(ReportAccountabilitySectionRequestDTO requestDTO) { + log.info("对个人追责问责情况计算开始======================================================================================="); if (requestDTO == null || requestDTO.getNegativeQueryParam() == null) { return new AccountabilityPersonalSection(); } - - NegativeQueryParam request = requestDTO.getNegativeQueryParam(); - - NegativeQueryParam currentQueryParam = request.newQueryParam(); + NegativeQueryParam currentQueryParam = requestDTO.getNegativeQueryParam().newQueryParam(); List currentList = negativeQueryService.page(currentQueryParam).getRecords(); - - List negativeIds = currentList.stream() - .map(NegativeQueryVo::getId) - .filter(Objects::nonNull) - .toList(); - ReportAccountabilityStatsRequestDTO statsRequestDTO = new ReportAccountabilityStatsRequestDTO(); - statsRequestDTO.setNegativeIds(negativeIds); - ReportAccountabilityStatsResponseDTO statsResponseDTO = - reportAccountabilityStatsService.calculateAccountabilityStats(statsRequestDTO); - - Map> leadMap = statsResponseDTO.getLeadBlames().stream() - .collect(java.util.stream.Collectors.groupingBy(NegativeBlame::getLeadHandleResultName)); - - Map> personMap = statsResponseDTO.getPersonalBlames().stream() - .collect(java.util.stream.Collectors.groupingBy(NegativeBlame::getHandleResultName)); - - Map> mergedMap = new HashMap<>(personMap); - leadMap.forEach((key, value) -> - mergedMap.merge(key, value, (list1, list2) -> { - List list = new ArrayList<>(list1); - list.addAll(list2); - return list; - }) - ); - + statsRequestDTO.setNegativeQueryVoList(currentList); + ReportAccountabilityStatsResponseDTO statsResponseDTO = reportAccountabilityStatsService.calculateAccountabilityStats(statsRequestDTO); AccountabilityPersonalSection section = new AccountabilityPersonalSection(); section.setTotalCount(statsResponseDTO.getPersonal()); - - List typeItems = mergedMap.entrySet().stream() + List typeItems = statsResponseDTO.getPersonalTypeCountMap().entrySet().stream() .map(entry -> { AccountabilityTypeItem item = new AccountabilityTypeItem(); item.setTypeName(entry.getKey()); - item.setCount(entry.getValue().size()); + item.setCount(entry.getValue()); return item; }) .sorted(Comparator.comparing(AccountabilityTypeItem::getCount).reversed()) @@ -170,6 +126,7 @@ public class ReportAccountabilitySectionServiceImpl implements ReportAccountabil .size(500, 300) .create(); section.setPersonPieChart(picture); + log.info("对个人追责问责情况计算结束======================================================================================="); return section; } } \ No newline at end of file diff --git a/src/main/java/com/biutag/supervision/service/report/impl/ReportAccountabilityStatsServiceImpl.java b/src/main/java/com/biutag/supervision/service/report/impl/ReportAccountabilityStatsServiceImpl.java index 3ed55d6..9331e0e 100644 --- a/src/main/java/com/biutag/supervision/service/report/impl/ReportAccountabilityStatsServiceImpl.java +++ b/src/main/java/com/biutag/supervision/service/report/impl/ReportAccountabilityStatsServiceImpl.java @@ -2,48 +2,84 @@ package com.biutag.supervision.service.report.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; +import com.biutag.supervision.constants.enums.ProcessingStatusEnum; import com.biutag.supervision.pojo.dto.report.accountability.ReportAccountabilityStatsRequestDTO; import com.biutag.supervision.pojo.dto.report.accountability.ReportAccountabilityStatsResponseDTO; +import com.biutag.supervision.pojo.dto.report.businessLine.BusinessLinePersonRankItem; import com.biutag.supervision.pojo.entity.NegativeBlame; +import com.biutag.supervision.pojo.entity.SupDictData; +import com.biutag.supervision.pojo.entity.SupPolice; +import com.biutag.supervision.pojo.model.PoliceModel; +import com.biutag.supervision.pojo.param.PoliceQueryParam; +import com.biutag.supervision.pojo.param.SupPoliceQueryParam; import com.biutag.supervision.pojo.param.negativeBlame.NegativeBlameQueryParam; +import com.biutag.supervision.pojo.vo.NegativeQueryVo; import com.biutag.supervision.repository.negativeBlame.NegativeBlameResourceService; +import com.biutag.supervision.repository.supPolice.SupPoliceResourceService; +import com.biutag.supervision.service.SupDictDataService; +import com.biutag.supervision.service.SupPoliceService; import com.biutag.supervision.service.report.ReportAccountabilityStatsService; +import com.biutag.supervision.util.ReportTrendUtil; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; @Service @Schema(description = "报表问责统计服务") +@Slf4j public class ReportAccountabilityStatsServiceImpl implements ReportAccountabilityStatsService { @Resource private NegativeBlameResourceService negativeBlameResourceService; + @Resource + private SupPoliceService supPoliceService; + + @Resource + private SupDictDataService supDictDataService; + @Override public ReportAccountabilityStatsResponseDTO calculateAccountabilityStats(ReportAccountabilityStatsRequestDTO requestDTO) { ReportAccountabilityStatsResponseDTO responseDTO = new ReportAccountabilityStatsResponseDTO(); - if (requestDTO == null || CollUtil.isEmpty(requestDTO.getNegativeIds())) { + if (requestDTO == null || CollUtil.isEmpty(requestDTO.getNegativeQueryVoList())) { + return responseDTO; + } + // 1. 办结数据 + List closedNegativeList = requestDTO.getNegativeQueryVoList().stream() + .filter(one -> ProcessingStatusEnum.completed.name().equals(one.getProcessingStatus())) + .toList(); + log.info("办结数据数量: {}", closedNegativeList.size()); + if (CollUtil.isEmpty(closedNegativeList)) { return responseDTO; } + // 2. 提取办结问题ID,作为问责查询范围 + List closedNegativeIds = closedNegativeList.stream() + .map(NegativeQueryVo::getId) + .filter(StrUtil::isNotBlank) + .distinct() + .toList(); + log.info("去重后的办结问题ID数量: {}", closedNegativeIds.size()); NegativeBlameQueryParam queryParam = new NegativeBlameQueryParam(); - queryParam.setNegativeIds(requestDTO.getNegativeIds()); - + queryParam.setNegativeIds(closedNegativeIds); List negativeBlames = negativeBlameResourceService.query(queryParam); + log.info("查询到的问责记录总数: {}", negativeBlames.size()); - // 个人问责 + + // 3. 个人问责 List personalBlames = negativeBlames.stream() .filter(one -> "personal".equals(one.getType())) .filter(one -> StrUtil.isNotBlank(one.getHandleResultName())) .filter(one -> !"不予追责".equals(one.getHandleResultName())) .toList(); - - // 个人问责中的领导问责 + log.info("个人问责记录数量: {}", personalBlames.size()); + // 4. 领导问责(从个人问责记录中拆分,按 negativeId + 领导姓名 + 领导处理结果 去重) Set seenLead = new HashSet<>(); List leadBlames = personalBlames.stream() .filter(one -> StrUtil.isNotBlank(one.getLeadHandleResultName())) @@ -52,25 +88,170 @@ public class ReportAccountabilityStatsServiceImpl implements ReportAccountabilit one.getNegativeId() + "_" + one.getLeadHandleResultName() + "_" + one.getLeadName() )) .toList(); - - // 单位问责 + log.info("领导问责记录数量: {} (去重后)", leadBlames.size()); + // 5. 单位问责 List unitBlames = negativeBlames.stream() .filter(one -> "department".equals(one.getType())) .filter(one -> StrUtil.isNotBlank(one.getHandleResultName())) .filter(one -> !"不予追责".equals(one.getHandleResultName())) .toList(); + log.info("单位问责记录数量: {}", unitBlames.size()); + // 6. 统计人次数 + int personalCount = personalBlames.stream() + .mapToInt(one -> countHandleResult(one.getHandleResultName())) + .sum(); + log.info("涉及个人人次数:" + personalCount); + int leadCount = leadBlames.stream() + .mapToInt(one -> countHandleResult(one.getLeadHandleResultName())) + .sum(); + log.info("领导人次数:" + leadCount); + int unitCount = unitBlames.stream() + .mapToInt(one -> countHandleResult(one.getHandleResultName())) + .sum(); + log.info("单位问责次数" + unitCount); + int finalPersonalCount = personalCount + leadCount; + int totalCount = finalPersonalCount + unitCount; + + // 7. 统计问责问题条数:三类问责记录中的 negativeId 去重 + Set accountabilityNegativeIds = new HashSet<>(); + + personalBlames.stream() + .map(NegativeBlame::getNegativeId) + .filter(StrUtil::isNotBlank) + .forEach(accountabilityNegativeIds::add); + + leadBlames.stream() + .map(NegativeBlame::getNegativeId) + .filter(StrUtil::isNotBlank) + .forEach(accountabilityNegativeIds::add); + + unitBlames.stream() + .map(NegativeBlame::getNegativeId) + .filter(StrUtil::isNotBlank) + .forEach(accountabilityNegativeIds::add); + int accountabilityNegativeCount = accountabilityNegativeIds.size(); + // 8. 问责率 = 问责问题条数 / 办结条数 + BigDecimal accountabilityNegativeRate = ReportTrendUtil.percent(accountabilityNegativeCount, closedNegativeList.size()); - int personalCount = personalBlames.size() + leadBlames.size(); - int unitCount = unitBlames.size(); + // 9. 计算个人问责类型次数map(包含个人和领导,并拆分"、") + Map personalTypeCountMap = new HashMap<>(); - responseDTO.setPersonal(personalCount); + // 处理个人问责记录 + personalBlames.forEach(blame -> + addHandleResultsToMap(personalTypeCountMap, blame.getHandleResultName()) + ); + + // 处理领导问责记录 + leadBlames.forEach(blame -> + addHandleResultsToMap(personalTypeCountMap, blame.getLeadHandleResultName()) + ); + // 10. 计算单位问责类型次数map(拆分"、") + Map unitTypeCountMap = new HashMap<>(); + unitBlames.forEach(blame -> + addHandleResultsToMap(unitTypeCountMap, blame.getHandleResultName()) + ); + + // 11. 计算问责人员TOP3 + List topPersons = calculateTopPersons(personalBlames); + + // 问责率 + responseDTO.setAccountabilityNegativeRate(accountabilityNegativeRate); + // 问责问题条数 + responseDTO.setAccountabilityNegativeCount(accountabilityNegativeCount); + responseDTO.setPersonal(finalPersonalCount); responseDTO.setUnit(unitCount); - responseDTO.setTotal(personalCount + unitCount); + responseDTO.setTotal(totalCount); responseDTO.setPersonalBlames(personalBlames); responseDTO.setLeadBlames(leadBlames); responseDTO.setUnitBlames(unitBlames); - + responseDTO.setTopPersons(topPersons); return responseDTO; } + + private boolean hasValidHandleResult(String handleResultName) { + return countHandleResult(handleResultName) > 0; + } + + + /** + * 将处理结果拆分后添加到统计Map中 + */ + private void addHandleResultsToMap(Map map, String handleResultName) { + if (StrUtil.isBlank(handleResultName)) { + return; + } + + StrUtil.splitTrim(handleResultName, "、").stream() + .filter(StrUtil::isNotBlank) + .filter(item -> !"不予追责".equals(item)) + .map(String::trim) + .forEach(result -> + map.put(result, map.getOrDefault(result, 0) + 1) + ); + } + + + + private int countHandleResult(String handleResultName) { + if (StrUtil.isBlank(handleResultName)) { + return 0; + } + + return StrUtil.splitTrim(handleResultName, "、").stream() + .filter(StrUtil::isNotBlank) + .filter(item -> !"不予追责".equals(item)) + .map(String::trim) + .toList() + .size(); + } + + /** + * 计算问责人员TOP3 + */ + private List calculateTopPersons(List personalBlames) { + if (CollUtil.isEmpty(personalBlames)) { + return Collections.emptyList(); + } + List supDictData = supDictDataService.listByDictType("personType"); + Map dictValueLabelMap = supDictData.stream() + .collect(Collectors.toMap( + SupDictData::getDictValue, + SupDictData::getDictLabel, + (v1, v2) -> v1, + LinkedHashMap::new + )); + return personalBlames.stream() + .collect(Collectors.groupingBy( + blame -> String.join("|", + Objects.toString(blame.getNegativeId(), ""), + Objects.toString(blame.getBlameEmpNo(), "") + ) + )) + .entrySet().stream() + .sorted((entry1, entry2) -> Integer.compare(entry2.getValue().size(), entry1.getValue().size())) + .map(entry -> { + List value = entry.getValue(); + NegativeBlame blame = value.get(0); + + PoliceQueryParam policeQueryParam = new PoliceQueryParam(); + policeQueryParam.setEmpNo(blame.getBlameEmpNo()); + List records = supPoliceService.page(policeQueryParam).getRecords(); + String unitName = "未知"; + String identityName = "未知"; + if (CollUtil.isNotEmpty(records)){ + unitName = records.get(0).getParentDepartShortName() + records.get(0).getDepartShortName(); + identityName = dictValueLabelMap.get(records.get(0).getPersonType()); + } + + return BusinessLinePersonRankItem.builder() + .personName(blame.getBlameName()) + .unitName(unitName) + .identityName(identityName) + .count(value.size()) + .build(); + }) + .toList(); + } + } \ No newline at end of file diff --git a/src/main/java/com/biutag/supervision/service/report/impl/ReportBusinessLineSectionServiceImpl.java b/src/main/java/com/biutag/supervision/service/report/impl/ReportBusinessLineSectionServiceImpl.java index a6c8b69..679d311 100644 --- a/src/main/java/com/biutag/supervision/service/report/impl/ReportBusinessLineSectionServiceImpl.java +++ b/src/main/java/com/biutag/supervision/service/report/impl/ReportBusinessLineSectionServiceImpl.java @@ -1,8 +1,8 @@ package com.biutag.supervision.service.report.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; -import com.biutag.supervision.constants.enums.CheckStatusEnum; import com.biutag.supervision.constants.enums.ProcessingStatusEnum; import com.biutag.supervision.pojo.dto.report.accountability.ReportAccountabilityStatsRequestDTO; import com.biutag.supervision.pojo.dto.report.accountability.ReportAccountabilityStatsResponseDTO; @@ -11,9 +11,12 @@ import com.biutag.supervision.pojo.dto.report.base.ReportBaseQueryResponseDTO; import com.biutag.supervision.pojo.dto.report.businessLine.*; import com.biutag.supervision.pojo.dto.report.closed.ClosedStatsCalcRequestDTO; import com.biutag.supervision.pojo.dto.report.closed.ClosedStatsCalcResponseDTO; +import com.biutag.supervision.pojo.entity.NegativeBlame; +import com.biutag.supervision.pojo.entity.NegativeProblemRelation; import com.biutag.supervision.pojo.param.NegativeQueryParam; import com.biutag.supervision.pojo.vo.DictProblemSourceTree; import com.biutag.supervision.pojo.vo.NegativeQueryVo; +import com.biutag.supervision.service.NegativeProblemRelationService; import com.biutag.supervision.service.NegativeQueryService; import com.biutag.supervision.service.SupDictProblemSourceService; import com.biutag.supervision.service.report.ReportAccountabilityStatsService; @@ -27,6 +30,7 @@ import com.deepoove.poi.data.PictureType; import com.deepoove.poi.data.Pictures; import jakarta.annotation.Resource; import lombok.Data; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.math.BigDecimal; @@ -34,6 +38,7 @@ import java.util.*; import java.util.stream.Collectors; @Service +@Slf4j public class ReportBusinessLineSectionServiceImpl implements ReportBusinessLineSectionService { @Resource @@ -50,10 +55,12 @@ public class ReportBusinessLineSectionServiceImpl implements ReportBusinessLineS @Resource private ReportAccountabilityStatsService reportAccountabilityStatsService; + @Resource + private NegativeProblemRelationService negativeProblemRelationService; @Override public BusinessLineOverviewSection buildBusinessLineOverviewSection(ReportBusinessLineSectionRequestDTO requestDTO) { - + log.info("条线总览开始计算======================================================================================="); if (requestDTO == null || requestDTO.getNegativeQueryParam() == null) { return new BusinessLineOverviewSection(); } @@ -106,55 +113,58 @@ public class ReportBusinessLineSectionServiceImpl implements ReportBusinessLineS .size(500, 300) .create(); section.setProblemPieChart(picture); + log.info("条线总览计算结束======================================================================================="); return section; } @Override public List buildBusinessLineDetailSections(ReportBusinessLineSectionRequestDTO requestDTO) { + log.info("条线明细开始计算======================================================================================="); if (requestDTO == null || requestDTO.getNegativeQueryParam() == null) { return new ArrayList<>(); } NegativeQueryParam request = requestDTO.getNegativeQueryParam(); - + // 查询本期、环比、同比三期基础数据 ReportBaseQueryRequestDTO baseRequestDTO = new ReportBaseQueryRequestDTO(); baseRequestDTO.setNegativeQueryParam(request); ReportBaseQueryResponseDTO baseQueryResponseDTO = reportBaseQueryService.queryBaseData(baseRequestDTO); - List currentList = baseQueryResponseDTO.getCurrentList(); List momList = baseQueryResponseDTO.getMomList(); List yoyList = baseQueryResponseDTO.getYoyList(); + // 构建问题来源字典ID映射,用于解析业务条线 Map idMap = supDictProblemSourceService.buildIdMap(); - + // 本期按业务条线分组 Map> currentGroup = currentList.stream() .collect(Collectors.groupingBy( vo -> parentLabel2Level(vo.getProblemSourcesCode(), idMap), LinkedHashMap::new, Collectors.toList() )); - + // 环比分组 Map> momGroup = momList.stream() .collect(Collectors.groupingBy( vo -> parentLabel2Level(vo.getProblemSourcesCode(), idMap), LinkedHashMap::new, Collectors.toList() )); - + // 同比分组 Map> yoyGroup = yoyList.stream() .collect(Collectors.groupingBy( vo -> parentLabel2Level(vo.getProblemSourcesCode(), idMap), LinkedHashMap::new, Collectors.toList() )); - List>> sortedEntries = currentGroup.entrySet().stream() .sorted((a, b) -> Integer.compare(b.getValue().size(), a.getValue().size())) .toList(); + /** + * 遍历每个业务条线进行统计 + */ List result = new ArrayList<>(); int index = 1; - for (Map.Entry> entry : sortedEntries) { String fatherBusinessLineName = entry.getKey(); List lineList = entry.getValue(); @@ -164,85 +174,59 @@ public class ReportBusinessLineSectionServiceImpl implements ReportBusinessLineS BusinessLineDetailSection section = new BusinessLineDetailSection(); section.setOrderNo(toChineseOrderNo(index++)); section.setBusinessFatherLineName(fatherBusinessLineName); - section.setBusinessLineName(fatherBusinessLineName); + section.setBusinessLineName(lineList.get(0).getProblemSources()); int totalIssued = lineList.size(); section.setTotalIssued(totalIssued); - List closedList = lineList.stream() - .filter(one -> ProcessingStatusEnum.completed.name().equals(one.getProcessingStatus())) - .toList(); - section.setClosedCount(closedList.size()); - + // 办结 / 查实统计 ClosedStatsCalcRequestDTO closedStatsCalcRequestDTO = new ClosedStatsCalcRequestDTO(); closedStatsCalcRequestDTO.setNegativeQueryVoList(lineList); ClosedStatsCalcResponseDTO closedStats = reportClosedStatsService.calculateClosedStats(closedStatsCalcRequestDTO); - - int verifiedTotal = Optional.ofNullable(closedStats.getClosedCount()).orElse(0); + int verifiedTotal = closedStats.getVerifiedCount() + closedStats.getBasicallyVerifiedCount(); + section.setClosedCount(closedStats.getClosedCount()); section.setVerifiedTotal(verifiedTotal); - section.setVerifiedRate(Optional.ofNullable(closedStats.getVerifiedRate()).orElse(BigDecimal.ZERO)); - - List verifiedNegativeIds = closedList.stream() - .filter(one -> CheckStatusEnum.TRUE_SET.contains(one.getCheckStatusCode()) - || CheckStatusEnum.PART_TRUE_SET.contains(one.getCheckStatusCode())) - .map(NegativeQueryVo::getId) - .filter(StrUtil::isNotBlank) - .distinct() - .toList(); - + section.setVerifiedRate(closedStats.getVerifiedRate()); + // 问责统计 ReportAccountabilityStatsRequestDTO statsRequestDTO = new ReportAccountabilityStatsRequestDTO(); - statsRequestDTO.setNegativeIds(verifiedNegativeIds); + statsRequestDTO.setNegativeQueryVoList(lineList); ReportAccountabilityStatsResponseDTO accountabilityStats = reportAccountabilityStatsService.calculateAccountabilityStats(statsRequestDTO); section.setAccountabilityTotal(accountabilityStats.getTotal()); - section.setAccountabilityRate(ReportTrendUtil.calcRate(accountabilityStats.getTotal(), verifiedTotal)); + section.setAccountabilityRate(accountabilityStats.getAccountabilityNegativeRate()); section.setPersonalAccountabilityCount(accountabilityStats.getPersonal()); section.setDepartmentAccountabilityCount(accountabilityStats.getUnit()); + //问题类型 TOP3 +// Set collect = lineList.stream().map(NegativeQueryVo::getId).collect(Collectors.toSet()); +// List negativeProblemRelations = negativeProblemRelationService.list(collect); +// // 1. 分组统计,value为所有数据的List +// Map> groupedMap = negativeProblemRelations.stream() +// .collect(Collectors.groupingBy( +// relation -> relation.getOneLevelContent() + +// relation.getTwoLevelContent() + +// relation.getThreeLevelContent() +// )); +// // 2. 按List大小(数量)降序排序 +// List>> sortedList = groupedMap.entrySet().stream() +// .sorted((entry1, entry2) -> Integer.compare(entry2.getValue().size(), entry1.getValue().size())) +// .collect(Collectors.toList()); +// section.setTopProblemTypes(topProblemTypes); + + // 重点单位 TOP3 + section.setTopUnits(closedStats.getTopUnits().stream().limit(3).toList()); + // 重点人员 TOP3 + section.setTopPersons(accountabilityStats.getTopPersons().stream().limit(3).toList()); - List topProblemTypes = lineList.stream() - .collect(Collectors.groupingBy( - vo -> leafProblemLabel(vo.getProblemSourcesCode(), idMap), - Collectors.counting() - )) - .entrySet().stream() - .sorted((a, b) -> Long.compare(b.getValue(), a.getValue())) - .limit(3) - .map(e -> buildRankItem( - e.getKey(), - e.getValue().intValue(), - safePercentString(e.getValue().intValue(), totalIssued) - )) - .toList(); - section.setTopProblemTypes(topProblemTypes); - - List topUnits = lineList.stream() - .filter(one -> StrUtil.isNotBlank(one.getInvolveDepartName())) - .collect(Collectors.groupingBy(NegativeQueryVo::getInvolveDepartName, Collectors.counting())) - .entrySet().stream() - .sorted((a, b) -> Long.compare(b.getValue(), a.getValue())) - .limit(3) - .map(e -> buildRankItem( - e.getKey(), - e.getValue().intValue(), - safePercentString(e.getValue().intValue(), totalIssued) - )) - .toList(); - section.setTopUnits(topUnits); - - List topPersons = buildTopPersons(lineList, totalIssued); - section.setTopPersons(topPersons); int currentCount = totalIssued; int momCount = momGroup.getOrDefault(fatherBusinessLineName, Collections.emptyList()).size(); int yoyCount = yoyGroup.getOrDefault(fatherBusinessLineName, Collections.emptyList()).size(); - section.setMomRate(ReportTrendUtil.calcRate(currentCount, momCount)); section.setMomTrend(ReportTrendUtil.calcTrend(currentCount, momCount)); section.setYoyRate(ReportTrendUtil.calcRate(currentCount, yoyCount)); section.setYoyTrend(ReportTrendUtil.calcTrend(currentCount, yoyCount)); - result.add(section); } - + log.info("条线明细计算结束======================================================================================="); return result; } diff --git a/src/main/java/com/biutag/supervision/service/report/impl/ReportClosedStatsServiceImpl.java b/src/main/java/com/biutag/supervision/service/report/impl/ReportClosedStatsServiceImpl.java index ffd78c3..3990754 100644 --- a/src/main/java/com/biutag/supervision/service/report/impl/ReportClosedStatsServiceImpl.java +++ b/src/main/java/com/biutag/supervision/service/report/impl/ReportClosedStatsServiceImpl.java @@ -1,7 +1,9 @@ package com.biutag.supervision.service.report.impl; +import cn.hutool.core.util.StrUtil; import com.biutag.supervision.constants.enums.CheckStatusEnum; import com.biutag.supervision.constants.enums.ProcessingStatusEnum; +import com.biutag.supervision.pojo.dto.report.businessLine.BusinessLineRankItem; import com.biutag.supervision.pojo.dto.report.closed.ClosedStatsCalcRequestDTO; import com.biutag.supervision.pojo.dto.report.closed.ClosedStatsCalcResponseDTO; import com.biutag.supervision.pojo.vo.NegativeQueryVo; @@ -12,6 +14,7 @@ import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; @Service public class ReportClosedStatsServiceImpl implements ReportClosedStatsService { @@ -45,6 +48,19 @@ public class ReportClosedStatsServiceImpl implements ReportClosedStatsService { closedList.size() ); + + // 4. 计算重点单位 TOP3(已办结且部门名称不为空) + List topUnits = closedList.stream() + .filter(one -> StrUtil.isNotBlank(one.getInvolveDepartName())) + .collect(Collectors.groupingBy(NegativeQueryVo::getInvolveDepartName, Collectors.counting())) + .entrySet().stream() + .sorted((a, b) -> Long.compare(b.getValue(), a.getValue())) + .map(e -> new BusinessLineRankItem( + e.getKey(), + e.getValue().intValue(), + ReportTrendUtil.percent(e.getValue().intValue(), closedList.size()) + )) + .toList(); ClosedStatsCalcResponseDTO responseDTO = new ClosedStatsCalcResponseDTO(); responseDTO.setClosedCount(closedList.size()); @@ -57,7 +73,7 @@ public class ReportClosedStatsServiceImpl implements ReportClosedStatsService { responseDTO.setVerifiedList(verifiedList); responseDTO.setBasicallyVerifiedList(basicallyVerifiedList); responseDTO.setUnverifiedList(unverifiedList); - + responseDTO.setTopUnits(topUnits); return responseDTO; } } \ No newline at end of file diff --git a/src/main/java/com/biutag/supervision/service/report/impl/ReportOverviewSectionServiceImpl.java b/src/main/java/com/biutag/supervision/service/report/impl/ReportOverviewSectionServiceImpl.java index e6fe0f2..b286146 100644 --- a/src/main/java/com/biutag/supervision/service/report/impl/ReportOverviewSectionServiceImpl.java +++ b/src/main/java/com/biutag/supervision/service/report/impl/ReportOverviewSectionServiceImpl.java @@ -1,28 +1,28 @@ package com.biutag.supervision.service.report.impl; -import cn.hutool.core.util.StrUtil; -import com.biutag.supervision.constants.enums.CheckStatusEnum; -import com.biutag.supervision.constants.enums.ProcessingStatusEnum; import com.biutag.supervision.pojo.dto.report.OverviewSection; import com.biutag.supervision.pojo.dto.report.accountability.ReportAccountabilityStatsRequestDTO; import com.biutag.supervision.pojo.dto.report.accountability.ReportAccountabilityStatsResponseDTO; import com.biutag.supervision.pojo.dto.report.base.ReportBaseQueryRequestDTO; import com.biutag.supervision.pojo.dto.report.base.ReportBaseQueryResponseDTO; +import com.biutag.supervision.pojo.dto.report.closed.ClosedStatsCalcRequestDTO; +import com.biutag.supervision.pojo.dto.report.closed.ClosedStatsCalcResponseDTO; import com.biutag.supervision.pojo.dto.report.overview.ReportOverviewSectionRequestDTO; import com.biutag.supervision.pojo.param.NegativeQueryParam; import com.biutag.supervision.pojo.vo.NegativeQueryVo; import com.biutag.supervision.service.report.ReportAccountabilityStatsService; import com.biutag.supervision.service.report.ReportBaseQueryService; +import com.biutag.supervision.service.report.ReportClosedStatsService; import com.biutag.supervision.service.report.ReportOverviewSectionService; import com.biutag.supervision.util.ReportTrendUtil; import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.stream.Stream; /** * @ClassName ReportOverviewSectionServiceImpl @@ -31,6 +31,7 @@ import java.util.stream.Stream; * @Date 2026/3/9 */ @Service +@Slf4j public class ReportOverviewSectionServiceImpl implements ReportOverviewSectionService { /** @@ -47,6 +48,13 @@ public class ReportOverviewSectionServiceImpl implements ReportOverviewSectionSe @Resource private ReportAccountabilityStatsService reportAccountabilityStatsService; + + /** + * 办结/查实统计服务 + */ + @Resource + private ReportClosedStatsService reportClosedStatsService; + /** * 构建总体概览数据 * @@ -58,7 +66,7 @@ public class ReportOverviewSectionServiceImpl implements ReportOverviewSectionSe if (requestDTO == null || requestDTO.getNegativeQueryParam() == null) { return new OverviewSection(); } - + log.info("总览数据开始计算======================================================================================="); NegativeQueryParam request = requestDTO.getNegativeQueryParam(); String periodStart = requestDTO.getPeriodStart(); String periodEnd = requestDTO.getPeriodEnd(); @@ -68,201 +76,124 @@ public class ReportOverviewSectionServiceImpl implements ReportOverviewSectionSe baseRequestDTO.setNegativeQueryParam(request); ReportBaseQueryResponseDTO baseQueryResponseDTO = reportBaseQueryService.queryBaseData(baseRequestDTO); - List ztNegativeList = baseQueryResponseDTO.getCurrentList(); - List hbNegativeList = baseQueryResponseDTO.getMomList(); - List tbNegativeList = baseQueryResponseDTO.getYoyList(); - // 市局下发数据 - List sjxfNegativeList = ztNegativeList.stream() + List currentList = baseQueryResponseDTO.getCurrentList(); + List momList = baseQueryResponseDTO.getMomList(); + List yoyList = baseQueryResponseDTO.getYoyList(); + + // 2. 基础分组数据 + List cityIssuedList = currentList.stream() .filter(one -> Objects.equals(0, one.getCrtDepartLevel())) .toList(); - // 分县市局下发数据 - List fxsjxfNegativeList = ztNegativeList.stream() + List countyIssuedList = currentList.stream() .filter(one -> Objects.equals(2, one.getCrtDepartLevel())) .toList(); - // 本期办结数据 - List bjNegativeList = ztNegativeList.stream() - .filter(one -> ProcessingStatusEnum.completed.name().equals(one.getProcessingStatus())) - .toList(); - - // 本期办结中属实数据 - List bjssNegativeList = bjNegativeList.stream() - .filter(one -> CheckStatusEnum.TRUE_SET.contains(one.getCheckStatusCode())) - .toList(); + // 3. 办结/查实统计 + ClosedStatsCalcResponseDTO currentClosedStats = calculateClosedStats(currentList); + ClosedStatsCalcResponseDTO momClosedStats = calculateClosedStats(momList); + ClosedStatsCalcResponseDTO yoyClosedStats = calculateClosedStats(yoyList); - // 本期办结中基本属实数据 - List bjjbssNegativeList = bjNegativeList.stream() - .filter(one -> CheckStatusEnum.PART_TRUE_SET.contains(one.getCheckStatusCode())) - .toList(); + // 4. 问责统计 + ReportAccountabilityStatsResponseDTO currentAccountabilityStats = calculateAccountabilityStats(currentList); + ReportAccountabilityStatsResponseDTO momAccountabilityStats = calculateAccountabilityStats(momList); + ReportAccountabilityStatsResponseDTO yoyAccountabilityStats = calculateAccountabilityStats(yoyList); - // 本期办结中不属实数据 - List bjbssNegativeList = bjNegativeList.stream() - .filter(one -> CheckStatusEnum.FALSE_SET.contains(one.getCheckStatusCode())) - .toList(); + // 5. 环比/同比基础值 + int currentTotal = currentList.size(); + int momTotal = momList.size(); + int yoyTotal = yoyList.size(); - // 本期属实 + 基本属实问题ID,用于计算问责数据 - List ssNegativeIds = Stream.concat(bjssNegativeList.stream(), bjjbssNegativeList.stream()) - .map(NegativeQueryVo::getId) - .filter(StrUtil::isNotBlank) - .distinct() - .toList(); - - ReportAccountabilityStatsRequestDTO currentRequestDTO = new ReportAccountabilityStatsRequestDTO(); - currentRequestDTO.setNegativeIds(ssNegativeIds); - ReportAccountabilityStatsResponseDTO currentAccountabilityStats = - reportAccountabilityStatsService.calculateAccountabilityStats(currentRequestDTO); - - // ==================== 环比问责数据 ==================== - - // 环比办结数据 - List hbBjNegativeList = hbNegativeList.stream() - .filter(one -> ProcessingStatusEnum.completed.name().equals(one.getProcessingStatus())) - .toList(); - - // 环比办结中属实数据 - List hbBjssNegativeList = hbBjNegativeList.stream() - .filter(one -> CheckStatusEnum.TRUE_SET.contains(one.getCheckStatusCode())) - .toList(); - - // 环比办结中基本属实数据 - List hbBjjbssNegativeList = hbBjNegativeList.stream() - .filter(one -> CheckStatusEnum.PART_TRUE_SET.contains(one.getCheckStatusCode())) - .toList(); - - // 环比属实 + 基本属实问题ID - List hbNegativeIds = Stream.concat(hbBjssNegativeList.stream(), hbBjjbssNegativeList.stream()) - .map(NegativeQueryVo::getId) - .filter(StrUtil::isNotBlank) - .distinct() - .toList(); + BigDecimal currentVerifiedRate = defaultZero(currentClosedStats.getVerifiedRate()); + BigDecimal momVerifiedRate = defaultZero(momClosedStats.getVerifiedRate()); + BigDecimal yoyVerifiedRate = defaultZero(yoyClosedStats.getVerifiedRate()); - ReportAccountabilityStatsRequestDTO momRequestDTO = new ReportAccountabilityStatsRequestDTO(); - momRequestDTO.setNegativeIds(hbNegativeIds); - ReportAccountabilityStatsResponseDTO momAccountabilityStats = - reportAccountabilityStatsService.calculateAccountabilityStats(momRequestDTO); - - // ==================== 同比问责数据 ==================== - - // 同比办结数据 - List tbBjNegativeList = tbNegativeList.stream() - .filter(one -> ProcessingStatusEnum.completed.name().equals(one.getProcessingStatus())) - .toList(); - - // 同比办结中属实数据 - List tbBjssNegativeList = tbBjNegativeList.stream() - .filter(one -> CheckStatusEnum.TRUE_SET.contains(one.getCheckStatusCode())) - .toList(); - - // 同比办结中基本属实数据 - List tbBjjbssNegativeList = tbBjNegativeList.stream() - .filter(one -> CheckStatusEnum.PART_TRUE_SET.contains(one.getCheckStatusCode())) - .toList(); - - // 同比属实 + 基本属实问题ID - List tbNegativeIds = Stream.concat(tbBjssNegativeList.stream(), tbBjjbssNegativeList.stream()) - .map(NegativeQueryVo::getId) - .filter(StrUtil::isNotBlank) - .distinct() - .toList(); - - ReportAccountabilityStatsRequestDTO yoyRequestDTO = new ReportAccountabilityStatsRequestDTO(); - yoyRequestDTO.setNegativeIds(tbNegativeIds); - ReportAccountabilityStatsResponseDTO yoyAccountabilityStats = - reportAccountabilityStatsService.calculateAccountabilityStats(yoyRequestDTO); - - // 本期、环比、同比问题总数 - int current = ztNegativeList.size(); - int mom = hbNegativeList.size(); - int yoy = tbNegativeList.size(); + int currentAccountabilityTotal = currentAccountabilityStats.getTotal(); + int momAccountabilityTotal = momAccountabilityStats.getTotal(); + int yoyAccountabilityTotal = yoyAccountabilityStats.getTotal(); + // 6. 组装结果 OverviewSection overviewSection = new OverviewSection(); - - // 统计区间 overviewSection.setPeriodStart(periodStart); overviewSection.setPeriodEnd(periodEnd); - // 总下发数及环比、同比 - overviewSection.setTotalIssued(ztNegativeList.size()); - overviewSection.setMomRate(ReportTrendUtil.calcRate(current, mom)); - overviewSection.setMomTrend(ReportTrendUtil.calcTrend(current, mom)); - overviewSection.setYoyRate(ReportTrendUtil.calcRate(current, yoy)); - overviewSection.setYoyTrend(ReportTrendUtil.calcTrend(current, yoy)); - - // 市局 / 分县市局下发情况 - overviewSection.setCityIssued(sjxfNegativeList.size()); - overviewSection.setCityRate(ReportTrendUtil.percent(sjxfNegativeList.size(), ztNegativeList.size())); - overviewSection.setCountyIssued(fxsjxfNegativeList.size()); - overviewSection.setCountyRate(ReportTrendUtil.percent(fxsjxfNegativeList.size(), ztNegativeList.size())); - - // 办结情况 - overviewSection.setClosedCount(bjNegativeList.size()); - overviewSection.setVerifiedCount(bjssNegativeList.size()); - overviewSection.setBasicallyVerifiedCount(bjjbssNegativeList.size()); - overviewSection.setUnverifiedCount(bjbssNegativeList.size()); - - // 查实率及环比、同比 - BigDecimal curVerifiedRate = calcVerifiedRate(ztNegativeList); - BigDecimal momVerifiedRate = calcVerifiedRate(hbNegativeList); - BigDecimal yoyVerifiedRate = calcVerifiedRate(tbNegativeList); - - overviewSection.setVerifiedRate(curVerifiedRate); - overviewSection.setVerifiedMomRate(ReportTrendUtil.calcRate(curVerifiedRate, momVerifiedRate)); - overviewSection.setVerifiedMomTrend(ReportTrendUtil.calcTrend(curVerifiedRate, momVerifiedRate)); - overviewSection.setVerifiedYoyRate(ReportTrendUtil.calcRate(curVerifiedRate, yoyVerifiedRate)); - overviewSection.setVerifiedYoyTrend(ReportTrendUtil.calcTrend(curVerifiedRate, yoyVerifiedRate)); - - // 问责数据及环比、同比 - int accountabilityTotal = currentAccountabilityStats.getTotal(); - overviewSection.setAccountabilityTotal(accountabilityTotal); + // 总下发 + overviewSection.setTotalIssued(currentTotal); + overviewSection.setMomRate(ReportTrendUtil.calcRate(currentTotal, momTotal)); + overviewSection.setMomTrend(ReportTrendUtil.calcTrend(currentTotal, momTotal)); + overviewSection.setYoyRate(ReportTrendUtil.calcRate(currentTotal, yoyTotal)); + overviewSection.setYoyTrend(ReportTrendUtil.calcTrend(currentTotal, yoyTotal)); + + // 市局 / 分县市局下发 + overviewSection.setCityIssued(cityIssuedList.size()); + overviewSection.setCityRate(ReportTrendUtil.percent(cityIssuedList.size(), currentTotal)); + overviewSection.setCountyIssued(countyIssuedList.size()); + overviewSection.setCountyRate(ReportTrendUtil.percent(countyIssuedList.size(), currentTotal)); + + // 办结 / 核查 + overviewSection.setClosedCount(currentClosedStats.getClosedCount()); + overviewSection.setVerifiedCount(currentClosedStats.getVerifiedCount()); + overviewSection.setBasicallyVerifiedCount(currentClosedStats.getBasicallyVerifiedCount()); + overviewSection.setUnverifiedCount(currentClosedStats.getUnverifiedCount()); + overviewSection.setVerifiedAndBasicallyVerifiedCount(currentClosedStats.getVerifiedCount() + currentClosedStats.getBasicallyVerifiedCount()); + + // 查实率 + overviewSection.setVerifiedRate(currentVerifiedRate); + overviewSection.setVerifiedMomRate(ReportTrendUtil.calcRate(currentVerifiedRate, momVerifiedRate)); + overviewSection.setVerifiedMomTrend(ReportTrendUtil.calcTrend(currentVerifiedRate, momVerifiedRate)); + overviewSection.setVerifiedYoyRate(ReportTrendUtil.calcRate(currentVerifiedRate, yoyVerifiedRate)); + overviewSection.setVerifiedYoyTrend(ReportTrendUtil.calcTrend(currentVerifiedRate, yoyVerifiedRate)); + + // 问责统计 + overviewSection.setAccountabilityProblemTotal(currentAccountabilityStats.getAccountabilityNegativeCount()); + overviewSection.setAccountabilityTotal(currentAccountabilityTotal); overviewSection.setPersonalAccountability(currentAccountabilityStats.getPersonal()); overviewSection.setUnitAccountability(currentAccountabilityStats.getUnit()); - overviewSection.setAccountabilityMomRate(ReportTrendUtil.calcRate(accountabilityTotal, momAccountabilityStats.getTotal())); - overviewSection.setAccountabilityMomTrend(ReportTrendUtil.calcTrend(accountabilityTotal, momAccountabilityStats.getTotal())); - overviewSection.setAccountabilityYoyRate(ReportTrendUtil.calcRate(accountabilityTotal, yoyAccountabilityStats.getTotal())); - overviewSection.setAccountabilityYoyTrend(ReportTrendUtil.calcTrend(accountabilityTotal, yoyAccountabilityStats.getTotal())); - - // 集中问题 - Map.Entry problemEntry = - ReportTrendUtil.topBy(NegativeQueryVo::getProblemSources, bjssNegativeList, bjjbssNegativeList); + overviewSection.setAccountabilityMomRate(ReportTrendUtil.calcRate(currentAccountabilityTotal, momAccountabilityTotal)); + overviewSection.setAccountabilityMomTrend(ReportTrendUtil.calcTrend(currentAccountabilityTotal, momAccountabilityTotal)); + overviewSection.setAccountabilityYoyRate(ReportTrendUtil.calcRate(currentAccountabilityTotal, yoyAccountabilityTotal)); + overviewSection.setAccountabilityYoyTrend(ReportTrendUtil.calcTrend(currentAccountabilityTotal, yoyAccountabilityTotal)); + + // 集中问题(基于属实 + 基本属实) + Map.Entry problemEntry = ReportTrendUtil.topBy( + NegativeQueryVo::getProblemSources, + currentClosedStats.getVerifiedList(), + currentClosedStats.getBasicallyVerifiedList() + ); overviewSection.setTopProblemProject(problemEntry != null ? problemEntry.getKey() : null); - // 重点关注单位 - Map.Entry departEntry = - ReportTrendUtil.topBy(NegativeQueryVo::getInvolveDepartName, bjssNegativeList, bjjbssNegativeList); + // 重点关注单位(基于属实 + 基本属实) + Map.Entry departEntry = ReportTrendUtil.topBy(NegativeQueryVo::getInvolveDepartName, + currentClosedStats.getVerifiedList(), + currentClosedStats.getBasicallyVerifiedList() + ); overviewSection.setTopProblemUnit(departEntry != null ? departEntry.getKey() : null); + log.info("总览数据计算结束======================================================================================="); return overviewSection; } + private ClosedStatsCalcResponseDTO calculateClosedStats(List list) { + ClosedStatsCalcRequestDTO requestDTO = new ClosedStatsCalcRequestDTO(); + requestDTO.setNegativeQueryVoList(list); + return reportClosedStatsService.calculateClosedStats(requestDTO); + } + + /** - * 计算查实率 - * 查实率 = (属实数 + 基本属实数)/ 办结数 * 100 - * - * @param list 问题数据列表 - * @return 查实率 + * 统一计算问责统计 */ - private BigDecimal calcVerifiedRate(List list) { - // 办结数据 - List closed = list.stream() - .filter(one -> ProcessingStatusEnum.completed.name().equals(one.getProcessingStatus())) - .toList(); + private ReportAccountabilityStatsResponseDTO calculateAccountabilityStats(List list) { + ReportAccountabilityStatsRequestDTO requestDTO = new ReportAccountabilityStatsRequestDTO(); + requestDTO.setNegativeQueryVoList(list); + return reportAccountabilityStatsService.calculateAccountabilityStats(requestDTO); + } + + private BigDecimal defaultZero(BigDecimal value) { + return value == null ? BigDecimal.ZERO : value; + } - int closedCount = closed.size(); - if (closedCount == 0) { - return BigDecimal.ZERO; - } - // 属实数 - int verified = (int) closed.stream() - .filter(n -> CheckStatusEnum.TRUE_SET.contains(n.getCheckStatusCode())) - .count(); - // 基本属实数 - int partVerified = (int) closed.stream() - .filter(n -> CheckStatusEnum.PART_TRUE_SET.contains(n.getCheckStatusCode())) - .count(); - return ReportTrendUtil.percent(verified + partVerified, closedCount); - } } \ No newline at end of file diff --git a/src/main/java/com/biutag/supervision/service/report/impl/ReportUnitInvestigationSectionServiceImpl.java b/src/main/java/com/biutag/supervision/service/report/impl/ReportUnitInvestigationSectionServiceImpl.java index e931af5..8481ded 100644 --- a/src/main/java/com/biutag/supervision/service/report/impl/ReportUnitInvestigationSectionServiceImpl.java +++ b/src/main/java/com/biutag/supervision/service/report/impl/ReportUnitInvestigationSectionServiceImpl.java @@ -41,6 +41,7 @@ public class ReportUnitInvestigationSectionServiceImpl implements ReportUnitInve @Override public UnitInvestigationOverviewSection buildUnitInvestigationOverviewSection(ReportUnitInvestigationSectionRequestDTO requestDTO) { + log.info("单位查处情况总览开始计算======================================================================================="); if (requestDTO == null || requestDTO.getNegativeQueryParam() == null) { return new UnitInvestigationOverviewSection(); } @@ -88,7 +89,9 @@ public class ReportUnitInvestigationSectionServiceImpl implements ReportUnitInve topUnits.sort(Comparator.comparing(UnitInvestigationItem::getVerifiedProblemCount).reversed()); topUnits = topUnits.stream().limit(3).toList(); - + for (int i = 0; i < topUnits.size(); i++) { + topUnits.get(i).setRank(i + 1); + } UnitInvestigationOverviewSection section = new UnitInvestigationOverviewSection(); section.setPeriodStart(periodStart); section.setPeriodEnd(periodEnd); @@ -112,7 +115,7 @@ public class ReportUnitInvestigationSectionServiceImpl implements ReportUnitInve .size(500, 300) .create(); section.setUnitBarChart(picture); - + log.info("单位查处情况总览计算结束======================================================================================="); return section; } } \ No newline at end of file diff --git a/src/main/java/com/biutag/supervision/util/ReportTrendUtil.java b/src/main/java/com/biutag/supervision/util/ReportTrendUtil.java index 119aed4..28633f8 100644 --- a/src/main/java/com/biutag/supervision/util/ReportTrendUtil.java +++ b/src/main/java/com/biutag/supervision/util/ReportTrendUtil.java @@ -107,6 +107,7 @@ public class ReportTrendUtil { return TrendEnum.STABLE; } + @SafeVarargs public static Map.Entry topBy(Function mapper, List... lists) { return Arrays.stream(lists) diff --git a/src/main/resources/static/templates/督审一体化平台研判分析报告.docx b/src/main/resources/static/templates/督审一体化平台研判分析报告.docx index 3fe6b2e..dcd537f 100644 Binary files a/src/main/resources/static/templates/督审一体化平台研判分析报告.docx and b/src/main/resources/static/templates/督审一体化平台研判分析报告.docx differ