|
|
|
|
@ -16,6 +16,8 @@ import com.biutag.supervision.pojo.dto.report.businessLine.BusinessLineDetailSec
|
|
|
|
|
import com.biutag.supervision.pojo.dto.report.businessLine.BusinessLineOverviewSection; |
|
|
|
|
import com.biutag.supervision.pojo.dto.report.businessLine.BusinessLinePersonRankItem; |
|
|
|
|
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.dto.report.unitInvestigation.UnitInvestigationItem; |
|
|
|
|
import com.biutag.supervision.pojo.dto.report.unitInvestigation.UnitInvestigationOverviewSection; |
|
|
|
|
import com.biutag.supervision.pojo.entity.NegativeBlame; |
|
|
|
|
@ -66,6 +68,13 @@ public class ReportDataServiceImpl implements ReportDataService {
|
|
|
|
|
@Resource |
|
|
|
|
private SupDepartResourceService supDepartResourceService; |
|
|
|
|
|
|
|
|
|
@Resource |
|
|
|
|
private ReportClosedStatsService reportClosedStatsService; |
|
|
|
|
|
|
|
|
|
@Resource |
|
|
|
|
private ReportBaseQueryService reportBaseQueryService; |
|
|
|
|
|
|
|
|
|
// 一定要拆分为弱领域模型 不然不能维护
|
|
|
|
|
@Override |
|
|
|
|
public ReportViewModel buildViewModel(NegativeQueryParam request) { |
|
|
|
|
String periodStart = TimeUtil.formatDate(request.getCrtTime().get(0)); |
|
|
|
|
@ -73,12 +82,19 @@ public class ReportDataServiceImpl implements ReportDataService {
|
|
|
|
|
ReportViewModel vm = new ReportViewModel(); |
|
|
|
|
vm.setPeriodStart(periodStart); |
|
|
|
|
vm.setPeriodEnd(periodEnd); |
|
|
|
|
// 总体概览
|
|
|
|
|
vm.setOverviewSection(buildOverviewSection(request, periodStart, periodEnd)); |
|
|
|
|
// 各业务条线情况-总览部分
|
|
|
|
|
vm.setBusinessLineOverviewSection(buildBusinessLineOverviewSection(request, periodStart, periodEnd)); |
|
|
|
|
// 各业务条线情况-明细部分
|
|
|
|
|
vm.setBusinessLineDetailSections(buildBusinessLineDetailSections(request, periodStart, periodEnd)); |
|
|
|
|
// 单位查处情况总览
|
|
|
|
|
vm.setUnitInvestigationOverviewSection(buildUnitInvestigationOverviewSection(request, periodStart, periodEnd)); |
|
|
|
|
// 问责追责情况总览
|
|
|
|
|
vm.setAccountabilityOverviewSection(buildAccountabilityOverviewSection(request, periodStart, periodEnd)); |
|
|
|
|
// 单位问责追责情况明细
|
|
|
|
|
vm.setAccountabilityUnitDetailSection(buildAccountabilityUnitDetailSection(request, periodStart, periodEnd)); |
|
|
|
|
// 个人问责追责情况
|
|
|
|
|
vm.setAccountabilityPersonOverviewSection(buildAccountabilityPersonOverviewSection(request, periodStart, periodEnd)); |
|
|
|
|
// System.out.println(1/0);
|
|
|
|
|
return vm; |
|
|
|
|
@ -255,109 +271,155 @@ public class ReportDataServiceImpl implements ReportDataService {
|
|
|
|
|
* @param periodEnd |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private List<BusinessLineDetailSection> buildBusinessLineDetailSections(NegativeQueryParam request, String periodStart, String periodEnd) { |
|
|
|
|
List<BusinessLineDetailSection> list = new ArrayList<>(); |
|
|
|
|
|
|
|
|
|
// 第一条
|
|
|
|
|
BusinessLineDetailSection section1 = new BusinessLineDetailSection(); |
|
|
|
|
section1.setOrderNo("一"); |
|
|
|
|
section1.setBusinessLineName("执法监督"); |
|
|
|
|
section1.setBusinessFatherLineName("执法办案"); |
|
|
|
|
section1.setTotalIssued(12); |
|
|
|
|
section1.setVerifiedTotal(8); |
|
|
|
|
section1.setVerifiedRate(new BigDecimal("66.67")); |
|
|
|
|
section1.setAccountabilityTotal(5); |
|
|
|
|
section1.setAccountabilityRate(new BigDecimal("62.50")); |
|
|
|
|
section1.setPersonalAccountabilityCount(3); |
|
|
|
|
section1.setDepartmentAccountabilityCount(2); |
|
|
|
|
section1.setTopProblemTypes(Arrays.asList( |
|
|
|
|
buildRankItem("执法程序问题", 3, "37.50"), |
|
|
|
|
buildRankItem("案件管理问题", 2, "25.00"), |
|
|
|
|
buildRankItem("执法作风问题", 2, "25.00") |
|
|
|
|
)); |
|
|
|
|
section1.setTopUnits(Arrays.asList( |
|
|
|
|
buildRankItem("XX派出所", 2, "25.00"), |
|
|
|
|
buildRankItem("XX大队", 2, "25.00"), |
|
|
|
|
buildRankItem("XX中队", 1, "12.50") |
|
|
|
|
)); |
|
|
|
|
section1.setTopPersons(Arrays.asList( |
|
|
|
|
buildPersonRankItem("张三", "XX派出所", "民警", 2, "25.00"), |
|
|
|
|
buildPersonRankItem("李四", "XX大队", "辅警", 1, "12.50"), |
|
|
|
|
buildPersonRankItem("王五", "XX中队", "民警", 1, "12.50") |
|
|
|
|
)); |
|
|
|
|
section1.setMomRate(new BigDecimal("20.00")); |
|
|
|
|
section1.setMomTrend(TrendEnum.UP); |
|
|
|
|
section1.setYoyRate(new BigDecimal("10.00")); |
|
|
|
|
section1.setYoyTrend(TrendEnum.DOWN); |
|
|
|
|
list.add(section1); |
|
|
|
|
|
|
|
|
|
// 第二条
|
|
|
|
|
BusinessLineDetailSection section2 = new BusinessLineDetailSection(); |
|
|
|
|
section2.setOrderNo("二"); |
|
|
|
|
section2.setBusinessLineName("案件管理"); |
|
|
|
|
section2.setBusinessFatherLineName("执法办案"); |
|
|
|
|
section2.setTotalIssued(9); |
|
|
|
|
section2.setVerifiedTotal(6); |
|
|
|
|
section2.setVerifiedRate(new BigDecimal("66.67")); |
|
|
|
|
section2.setAccountabilityTotal(4); |
|
|
|
|
section2.setAccountabilityRate(new BigDecimal("50.00")); |
|
|
|
|
section2.setPersonalAccountabilityCount(2); |
|
|
|
|
section2.setDepartmentAccountabilityCount(2); |
|
|
|
|
section2.setTopProblemTypes(Arrays.asList( |
|
|
|
|
buildRankItem("案件审核把关不严", 2, "33.33"), |
|
|
|
|
buildRankItem("卷宗管理不规范", 2, "33.33"), |
|
|
|
|
buildRankItem("系统录入不及时", 1, "16.67") |
|
|
|
|
)); |
|
|
|
|
section2.setTopUnits(Arrays.asList( |
|
|
|
|
buildRankItem("XX法制大队", 2, "33.33"), |
|
|
|
|
buildRankItem("XX派出所", 1, "16.67"), |
|
|
|
|
buildRankItem("XX治安大队", 1, "16.67") |
|
|
|
|
)); |
|
|
|
|
section2.setTopPersons(Arrays.asList( |
|
|
|
|
buildPersonRankItem("赵六", "XX法制大队", "民警", 2, "33.33"), |
|
|
|
|
buildPersonRankItem("孙七", "XX派出所", "民警", 1, "16.67"), |
|
|
|
|
buildPersonRankItem("周八", "XX治安大队", "辅警", 1, "16.67") |
|
|
|
|
)); |
|
|
|
|
section2.setMomRate(new BigDecimal("12.50")); |
|
|
|
|
section2.setMomTrend(TrendEnum.DOWN); |
|
|
|
|
section2.setYoyRate(new BigDecimal("8.00")); |
|
|
|
|
section2.setYoyTrend(TrendEnum.UP); |
|
|
|
|
list.add(section2); |
|
|
|
|
|
|
|
|
|
// 第三条
|
|
|
|
|
BusinessLineDetailSection section3 = new BusinessLineDetailSection(); |
|
|
|
|
section3.setOrderNo("三"); |
|
|
|
|
section3.setBusinessLineName("作风建设"); |
|
|
|
|
section3.setBusinessFatherLineName("队伍管理"); |
|
|
|
|
section3.setTotalIssued(7); |
|
|
|
|
section3.setVerifiedTotal(5); |
|
|
|
|
section3.setVerifiedRate(new BigDecimal("71.43")); |
|
|
|
|
section3.setAccountabilityTotal(3); |
|
|
|
|
section3.setAccountabilityRate(new BigDecimal("60.00")); |
|
|
|
|
section3.setPersonalAccountabilityCount(2); |
|
|
|
|
section3.setDepartmentAccountabilityCount(1); |
|
|
|
|
section3.setTopProblemTypes(Arrays.asList( |
|
|
|
|
buildRankItem("纪律作风问题", 2, "40.00"), |
|
|
|
|
buildRankItem("窗口服务问题", 1, "20.00"), |
|
|
|
|
buildRankItem("值班备勤问题", 1, "20.00") |
|
|
|
|
private List<BusinessLineDetailSection> buildBusinessLineDetailSections(NegativeQueryParam request, |
|
|
|
|
String periodStart, |
|
|
|
|
String periodEnd) { |
|
|
|
|
DateCompareRangeUtil.CompareDateRange compareDateRange = DateCompareRangeUtil.buildCompareDateRange(request.getCrtTime().get(0), request.getCrtTime().get(1)); |
|
|
|
|
|
|
|
|
|
// 本期数据
|
|
|
|
|
NegativeQueryParam currentQueryParam = request.newQueryParam(); |
|
|
|
|
List<NegativeQueryVo> currentList = negativeQueryService.page(currentQueryParam).getRecords(); |
|
|
|
|
|
|
|
|
|
// 环比数据
|
|
|
|
|
NegativeQueryParam momQueryParam = request.newQueryParam(); |
|
|
|
|
momQueryParam.setCrtTime(compareDateRange.mom()); |
|
|
|
|
List<NegativeQueryVo> momList = negativeQueryService.page(momQueryParam).getRecords(); |
|
|
|
|
|
|
|
|
|
// 同比数据
|
|
|
|
|
NegativeQueryParam yoyQueryParam = request.newQueryParam(); |
|
|
|
|
yoyQueryParam.setCrtTime(compareDateRange.yoy()); |
|
|
|
|
List<NegativeQueryVo> yoyList = negativeQueryService.page(yoyQueryParam).getRecords(); |
|
|
|
|
|
|
|
|
|
Map<String, DictProblemSourceTree> idMap = supDictProblemSourceService.buildIdMap(); |
|
|
|
|
|
|
|
|
|
// 按“父级业务条线”分组
|
|
|
|
|
Map<String, List<NegativeQueryVo>> currentGroup = currentList.stream() |
|
|
|
|
.collect(Collectors.groupingBy( |
|
|
|
|
vo -> parentLabel2Level(vo.getProblemSourcesCode(), idMap), |
|
|
|
|
LinkedHashMap::new, |
|
|
|
|
Collectors.toList() |
|
|
|
|
)); |
|
|
|
|
section3.setTopUnits(Arrays.asList( |
|
|
|
|
buildRankItem("XX交警大队", 2, "40.00"), |
|
|
|
|
buildRankItem("XX派出所", 1, "20.00"), |
|
|
|
|
buildRankItem("XX巡特警大队", 1, "20.00") |
|
|
|
|
|
|
|
|
|
Map<String, List<NegativeQueryVo>> momGroup = momList.stream() |
|
|
|
|
.collect(Collectors.groupingBy( |
|
|
|
|
vo -> parentLabel2Level(vo.getProblemSourcesCode(), idMap), |
|
|
|
|
LinkedHashMap::new, |
|
|
|
|
Collectors.toList() |
|
|
|
|
)); |
|
|
|
|
section3.setTopPersons(Arrays.asList( |
|
|
|
|
buildPersonRankItem("吴九", "XX交警大队", "民警", 2, "40.00"), |
|
|
|
|
buildPersonRankItem("郑十", "XX派出所", "辅警", 1, "20.00"), |
|
|
|
|
buildPersonRankItem("钱一", "XX巡特警大队", "民警", 1, "20.00") |
|
|
|
|
|
|
|
|
|
Map<String, List<NegativeQueryVo>> yoyGroup = yoyList.stream() |
|
|
|
|
.collect(Collectors.groupingBy( |
|
|
|
|
vo -> parentLabel2Level(vo.getProblemSourcesCode(), idMap), |
|
|
|
|
LinkedHashMap::new, |
|
|
|
|
Collectors.toList() |
|
|
|
|
)); |
|
|
|
|
section3.setMomRate(new BigDecimal("0.00")); |
|
|
|
|
section3.setMomTrend(TrendEnum.STABLE); |
|
|
|
|
section3.setYoyRate(new BigDecimal("15.00")); |
|
|
|
|
section3.setYoyTrend(TrendEnum.UP); |
|
|
|
|
list.add(section3); |
|
|
|
|
|
|
|
|
|
return list; |
|
|
|
|
// 按本期数量倒序
|
|
|
|
|
List<Map.Entry<String, List<NegativeQueryVo>>> sortedEntries = currentGroup.entrySet().stream() |
|
|
|
|
.sorted((a, b) -> Integer.compare(b.getValue().size(), a.getValue().size())) |
|
|
|
|
.toList(); |
|
|
|
|
|
|
|
|
|
List<BusinessLineDetailSection> result = new ArrayList<>(); |
|
|
|
|
int index = 1; |
|
|
|
|
|
|
|
|
|
for (Map.Entry<String, List<NegativeQueryVo>> entry : sortedEntries) { |
|
|
|
|
String fatherBusinessLineName = entry.getKey(); |
|
|
|
|
List<NegativeQueryVo> lineList = entry.getValue(); |
|
|
|
|
|
|
|
|
|
if (CollUtil.isEmpty(lineList)) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
BusinessLineDetailSection section = new BusinessLineDetailSection(); |
|
|
|
|
section.setOrderNo(toChineseOrderNo(index++)); |
|
|
|
|
section.setBusinessFatherLineName(fatherBusinessLineName); |
|
|
|
|
// 这里明细项名称按父级条线展示;若你模板里想展示别的,可自行替换
|
|
|
|
|
section.setBusinessLineName(fatherBusinessLineName); |
|
|
|
|
|
|
|
|
|
// 1. 下发总数
|
|
|
|
|
int totalIssued = lineList.size(); |
|
|
|
|
section.setTotalIssued(totalIssued); |
|
|
|
|
|
|
|
|
|
// 2. 已办结数
|
|
|
|
|
List<NegativeQueryVo> closedList = lineList.stream() |
|
|
|
|
.filter(one -> ProcessingStatusEnum.completed.name().equals(one.getProcessingStatus())) |
|
|
|
|
.toList(); |
|
|
|
|
section.setClosedCount(closedList.size()); |
|
|
|
|
|
|
|
|
|
// 3. 查实总数 / 查实率
|
|
|
|
|
ClosedStatsCalcRequestDTO closedStatsCalcRequestDTO = new ClosedStatsCalcRequestDTO(); |
|
|
|
|
closedStatsCalcRequestDTO.setNegativeQueryVoList(lineList); |
|
|
|
|
ClosedStatsCalcResponseDTO closedStats = reportClosedStatsService.calcClosedStats(closedStatsCalcRequestDTO); |
|
|
|
|
|
|
|
|
|
int verifiedTotal = Optional.ofNullable(closedStats.getClosedCount()).orElse(0); |
|
|
|
|
section.setVerifiedTotal(verifiedTotal); |
|
|
|
|
section.setVerifiedRate(Optional.ofNullable(closedStats.getVerifiedRate()).orElse(BigDecimal.ZERO)); |
|
|
|
|
|
|
|
|
|
// 4. 问责统计:按本条线内“属实 + 基本属实”的问题统计
|
|
|
|
|
List<String> 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(); |
|
|
|
|
|
|
|
|
|
AccountabilityStats accountabilityStats = buildAccountabilityStats(verifiedNegativeIds); |
|
|
|
|
section.setAccountabilityTotal(accountabilityStats.getTotal()); |
|
|
|
|
section.setAccountabilityRate(ReportTrendUtil.calcRate(accountabilityStats.getTotal(), verifiedTotal)); |
|
|
|
|
section.setPersonalAccountabilityCount(accountabilityStats.getPersonal()); |
|
|
|
|
section.setDepartmentAccountabilityCount(accountabilityStats.getUnit()); |
|
|
|
|
|
|
|
|
|
// 5. 问题类型 TOP3(本条线下的二级/叶子问题类型)
|
|
|
|
|
List<BusinessLineRankItem> 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); |
|
|
|
|
|
|
|
|
|
// 6. 重点单位 TOP3
|
|
|
|
|
List<BusinessLineRankItem> 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); |
|
|
|
|
|
|
|
|
|
// 7. 重点人员 TOP3
|
|
|
|
|
List<BusinessLinePersonRankItem> topPersons = buildTopPersons(lineList, totalIssued); |
|
|
|
|
section.setTopPersons(topPersons); |
|
|
|
|
|
|
|
|
|
// 8. 环比 / 同比(按该父级条线的问题下发总数比较)
|
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private BusinessLineRankItem buildRankItem(String name, Integer count, String rate) { |
|
|
|
|
@ -694,4 +756,120 @@ public class ReportDataServiceImpl implements ReportDataService {
|
|
|
|
|
private List<NegativeBlame> unitBlames = new ArrayList<>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String leafProblemLabel(String problemSourceCode, Map<String, DictProblemSourceTree> idMap) { |
|
|
|
|
if (StrUtil.isBlank(problemSourceCode)) { |
|
|
|
|
return "未归类"; |
|
|
|
|
} |
|
|
|
|
DictProblemSourceTree node = idMap.get(problemSourceCode); |
|
|
|
|
if (node == null || StrUtil.isBlank(node.getLabel())) { |
|
|
|
|
return "未归类"; |
|
|
|
|
} |
|
|
|
|
return node.getLabel(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private String safePercentString(int numerator, int denominator) { |
|
|
|
|
return ReportTrendUtil.percent(numerator, denominator).toPlainString(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private String toChineseOrderNo(int index) { |
|
|
|
|
String[] arr = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十"}; |
|
|
|
|
if (index >= 1 && index <= arr.length) { |
|
|
|
|
return arr[index - 1]; |
|
|
|
|
} |
|
|
|
|
return String.valueOf(index); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private List<BusinessLinePersonRankItem> buildTopPersons(List<NegativeQueryVo> lineList, int totalIssued) { |
|
|
|
|
Map<String, PersonAgg> personAggMap = new LinkedHashMap<>(); |
|
|
|
|
|
|
|
|
|
for (NegativeQueryVo vo : lineList) { |
|
|
|
|
String personName = readStringByGetter(vo, |
|
|
|
|
"getInvolvePersonName", |
|
|
|
|
"getPersonName", |
|
|
|
|
"getPoliceName", |
|
|
|
|
"getHandlePersonName", |
|
|
|
|
"getName"); |
|
|
|
|
|
|
|
|
|
if (StrUtil.isBlank(personName)) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
String unitName = firstNotBlank( |
|
|
|
|
readStringByGetter(vo, "getInvolveDepartName"), |
|
|
|
|
readStringByGetter(vo, "getUnitName"), |
|
|
|
|
readStringByGetter(vo, "getDepartName"), |
|
|
|
|
"未知单位" |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
String identityName = firstNotBlank( |
|
|
|
|
readStringByGetter(vo, "getIdentityName"), |
|
|
|
|
readStringByGetter(vo, "getInvolveIdentityName"), |
|
|
|
|
readStringByGetter(vo, "getPoliceTypeName"), |
|
|
|
|
readStringByGetter(vo, "getUserTypeName"), |
|
|
|
|
"未知身份" |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
String key = personName + "||" + unitName + "||" + identityName; |
|
|
|
|
PersonAgg agg = personAggMap.computeIfAbsent(key, k -> { |
|
|
|
|
PersonAgg x = new PersonAgg(); |
|
|
|
|
x.setPersonName(personName); |
|
|
|
|
x.setUnitName(unitName); |
|
|
|
|
x.setIdentityName(identityName); |
|
|
|
|
x.setCount(0); |
|
|
|
|
return x; |
|
|
|
|
}); |
|
|
|
|
agg.setCount(agg.getCount() + 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return personAggMap.values().stream() |
|
|
|
|
.sorted(Comparator.comparing(PersonAgg::getCount).reversed()) |
|
|
|
|
.limit(3) |
|
|
|
|
.map(one -> buildPersonRankItem( |
|
|
|
|
one.getPersonName(), |
|
|
|
|
one.getUnitName(), |
|
|
|
|
one.getIdentityName(), |
|
|
|
|
one.getCount(), |
|
|
|
|
safePercentString(one.getCount(), totalIssued) |
|
|
|
|
)) |
|
|
|
|
.toList(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private String readStringByGetter(Object target, String... getterNames) { |
|
|
|
|
if (target == null || getterNames == null) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
for (String getterName : getterNames) { |
|
|
|
|
try { |
|
|
|
|
java.lang.reflect.Method method = target.getClass().getMethod(getterName); |
|
|
|
|
Object value = method.invoke(target); |
|
|
|
|
if (value instanceof String str && StrUtil.isNotBlank(str)) { |
|
|
|
|
return str; |
|
|
|
|
} |
|
|
|
|
} catch (Exception ignored) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private String firstNotBlank(String... values) { |
|
|
|
|
if (values == null) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
for (String value : values) { |
|
|
|
|
if (StrUtil.isNotBlank(value)) { |
|
|
|
|
return value; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Data |
|
|
|
|
private static class PersonAgg { |
|
|
|
|
private String personName; |
|
|
|
|
private String unitName; |
|
|
|
|
private String identityName; |
|
|
|
|
private int count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |