This commit is contained in:
2026-01-05 11:28:28 +08:00
parent 0b02f66fb5
commit f3c42856fc
2 changed files with 85 additions and 65 deletions

View File

@@ -14,10 +14,7 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -167,44 +164,99 @@ public class ShopProdStatisticServiceImpl extends ServiceImpl<ShopProdStatisticM
* @return 合并后的数据
*/
private List<ShopProdStatistic> mergeProdStatistic(List<ShopProdStatistic> realTimeDataByDay, List<ShopProdStatistic> dateRange) {
if (realTimeDataByDay == null) {
realTimeDataByDay = new ArrayList<>();
}
if (dateRange == null) {
dateRange = new ArrayList<>();
}
// 1. 使用防御性编程,确保非空列表
List<ShopProdStatistic> realTimeData = Optional.ofNullable(realTimeDataByDay).orElseGet(ArrayList::new);
List<ShopProdStatistic> rangeData = Optional.ofNullable(dateRange).orElseGet(ArrayList::new);
return Stream.concat(realTimeDataByDay.stream(), dateRange.stream())
calculateValidData(realTimeData);
calculateValidData(rangeData);
return Stream.concat(realTimeData.stream(), rangeData.stream())
.filter(Objects::nonNull)
.collect(Collectors.toMap(
ShopProdStatistic::getProdId,
Function.identity(),
(stat1, stat2) -> {
// 创建合并后的对象
ShopProdStatistic merged = new ShopProdStatistic();
merged.setId(stat1.getId());
merged.setShopId(stat1.getShopId());
merged.setProdId(stat1.getProdId());
merged.setProductName(stat1.getProductName());
// 安全处理BigDecimal相加处理null值
merged.setSaleCount(safeAdd(stat1.getSaleCount(), stat2.getSaleCount()));
merged.setSaleAmount(safeAdd(stat1.getSaleAmount(), stat2.getSaleAmount()));
merged.setRefundCount(safeAdd(stat1.getRefundCount(), stat2.getRefundCount()));
merged.setRefundAmount(safeAdd(stat1.getRefundAmount(), stat2.getRefundAmount()));
return merged;
}
this::mergeStatistics
))
.values()
.stream()
.peek(this::recalculateValidData)
.toList();
}
/**
* 计算有效销售数据
*/
private void calculateValidData(List<ShopProdStatistic> statistics) {
if (statistics == null || statistics.isEmpty()) {
return;
}
statistics.forEach(stat -> {
if (stat != null) {
stat.setValidSaleCount(safeSubtract(stat.getSaleCount(), stat.getRefundCount()));
stat.setValidSaleAmount(safeSubtract(stat.getValidSaleAmount(), stat.getRefundAmount()));
}
});
}
/**
* 合并两个统计对象
*/
private ShopProdStatistic mergeStatistics(ShopProdStatistic stat1, ShopProdStatistic stat2) {
// 使用第一个非空对象作为基准
ShopProdStatistic baseStat = Optional.ofNullable(stat1).orElse(stat2);
ShopProdStatistic otherStat = stat1 == null ? null : stat2;
if (otherStat == null) {
return baseStat;
}
ShopProdStatistic merged = new ShopProdStatistic();
// 设置基本信息(优先使用非空值)
merged.setId(baseStat.getId());
merged.setShopId(baseStat.getShopId());
merged.setProdId(baseStat.getProdId());
merged.setProductName(
Optional.ofNullable(baseStat.getProductName())
.orElse(otherStat.getProductName())
);
// 合并数值字段
merged.setSaleCount(safeAdd(baseStat.getSaleCount(), otherStat.getSaleCount()));
merged.setSaleAmount(safeAdd(baseStat.getSaleAmount(), otherStat.getSaleAmount()));
merged.setRefundCount(safeAdd(baseStat.getRefundCount(), otherStat.getRefundCount()));
merged.setRefundAmount(safeAdd(baseStat.getRefundAmount(), otherStat.getRefundAmount()));
return merged;
}
/**
* 重新计算合并后的有效数据
*/
private void recalculateValidData(ShopProdStatistic stat) {
if (stat != null) {
stat.setValidSaleCount(safeSubtract(stat.getSaleCount(), stat.getRefundCount()));
stat.setValidSaleAmount(safeSubtract(stat.getSaleAmount(), stat.getRefundAmount()));
}
}
/**
* 安全的BigDecimal加法处理null值
*/
private BigDecimal safeAdd(BigDecimal num1, BigDecimal num2) {
BigDecimal safeNum1 = num1 != null ? num1 : BigDecimal.ZERO;
BigDecimal safeNum2 = num2 != null ? num2 : BigDecimal.ZERO;
BigDecimal safeNum1 = Optional.ofNullable(num1).orElse(BigDecimal.ZERO);
BigDecimal safeNum2 = Optional.ofNullable(num2).orElse(BigDecimal.ZERO);
return safeNum1.add(safeNum2);
}
/**
* 安全的BigDecimal减法处理null值
*/
private BigDecimal safeSubtract(BigDecimal num1, BigDecimal num2) {
BigDecimal safeNum1 = Optional.ofNullable(num1).orElse(BigDecimal.ZERO);
BigDecimal safeNum2 = Optional.ofNullable(num2).orElse(BigDecimal.ZERO);
return safeNum1.subtract(safeNum2);
}
}