hsy
13 小时以前 a2c8749f26688749253336fe8a27e7ff79f171ce
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/statistics/SrmStatisticsServiceImpl.java
@@ -52,20 +52,55 @@
        BigDecimal totalAwardAmount = awards.stream()
                .map(a -> a.getAwardAmount() != null ? a.getAwardAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        //节约金额(预算金额-中标金额)
        BigDecimal savedAmount = totalTenderAmount.subtract(totalAwardAmount);
        // 节约金额(仅计算当年定标的项目的:预算金额 - 中标总金额)
        BigDecimal savedAmount = BigDecimal.ZERO;
        if (!awards.isEmpty()) {
            // 按项目分组汇总中标金额(处理一个项目可能有多个定标记录的情况)
            java.util.Map<Long, BigDecimal> projectAwardSumMap = awards.stream()
                    .collect(Collectors.groupingBy(
                            SrmBidAwardDO::getTenderProjectId,
                            Collectors.reducing(
                                    BigDecimal.ZERO,
                                    a -> a.getAwardAmount() != null ? a.getAwardAmount() : BigDecimal.ZERO,
                                    BigDecimal::add
                            )
                    ));
            List<Long> awardedProjectIds = new java.util.ArrayList<>(projectAwardSumMap.keySet());
            if (!awardedProjectIds.isEmpty()) {
                List<SrmTenderProjectDO> awardedProjects = tenderProjectMapper.selectBatchIds(awardedProjectIds);
                for (SrmTenderProjectDO project : awardedProjects) {
                    BigDecimal budget = project.getBudgetAmount() != null ? project.getBudgetAmount() : BigDecimal.ZERO;
                    // 处理数据异常:如果项目预算为 0 或空,直接跳过该项目的节约金额计算,避免由于缺失预算导致出现不合理的巨大负数节约金额
                    if (budget.compareTo(BigDecimal.ZERO) > 0) {
                        BigDecimal awardSum = projectAwardSumMap.getOrDefault(project.getId(), BigDecimal.ZERO);
                        savedAmount = savedAmount.add(budget.subtract(awardSum));
                    }
                }
            }
        }
        long supplierCount = bids.stream()
                .map(SrmTenderBidDO::getSupplierId)
                .distinct()
                .count();
        // 定标率 (当年创建的项目中,目前已经定标的项目数 / 当年创建的项目总数)
        BigDecimal winRate = BigDecimal.ZERO;
        if (totalTenderCount > 0) {
            long awardedProjectCount = awards.stream()
                    .map(SrmBidAwardDO::getTenderProjectId)
                    .distinct()
                    .count();
            winRate = BigDecimal.valueOf(awardedProjectCount)
            List<Long> projectIds = projects.stream().map(SrmTenderProjectDO::getId).collect(Collectors.toList());
            long awardedCount = 0;
            if (!projectIds.isEmpty()) {
                List<SrmBidAwardDO> matchedAwards = bidAwardMapper.selectList(new LambdaQueryWrapperX<SrmBidAwardDO>()
                        .in(SrmBidAwardDO::getTenderProjectId, projectIds)
                        .select(SrmBidAwardDO::getTenderProjectId));
                awardedCount = matchedAwards.stream()
                        .map(SrmBidAwardDO::getTenderProjectId)
                        .distinct()
                        .count();
            }
            winRate = BigDecimal.valueOf(awardedCount)
                    .multiply(BigDecimal.valueOf(100))
                    .divide(BigDecimal.valueOf(totalTenderCount), 1, RoundingMode.HALF_UP);
        }