带延期记录的支付有效结束时间错误修复

This commit is contained in:
gaoqr
2026-06-16 10:21:01 +08:00
parent c73d64e182
commit 53a36b8046
@@ -232,40 +232,33 @@ public class PayProductProcessorNew {
} }
/** /**
* 计算结束时间 * 计算订购后的结束时间
* *
* @param duration * 规则:
* @param durationUnit * 1、已过期:从今天开始计算
* @return * 2、未过期:从当前结束时间开始叠加
* 3、扣减已经消耗的延期天数(未来延期不扣)
* 4、叠加优惠活动赠送时长
*/ */
private LocalDate calculateEndTime(Integer duration, Integer durationUnit) { private LocalDate calculateEndTime(Integer duration, Integer durationUnit) {
LocalDate today = LocalDate.now(); LocalDate today = LocalDate.now();
// 1、 计算延期后的实际有效期
LocalDate maxDelayEnd = endTime;
if (CollUtil.isNotEmpty(delayRespVOList)) {
// 找到延期记录中最大的 delayTime 作为最终有效期
maxDelayEnd = delayRespVOList.stream()
.map(ProductDelayRespVO::getDelayTime)
.max(LocalDate::compareTo)
.orElse(endTime);
}
// 2、 计算有效期叠加的起点 // 1、计算续费起点
LocalDate purchaseStart; LocalDate purchaseStart;
if (today.isAfter(maxDelayEnd)) { if (today.isAfter(endTime)) {
// 已过期从今天开始累加 // 已过期从今天开始
purchaseStart = today; purchaseStart = today;
} else { } else {
// 未过期 → 从 maxDelayEnd 的下一天开始累加 // 未过期,从当前结束时间开始
purchaseStart = maxDelayEnd; purchaseStart = endTime;
} }
// 3、加正常时间 // 2、增加购买时长
if (ObjectUtil.isNotNull(duration) && durationUnit != null) { if (ObjectUtil.isNotNull(duration) && durationUnit != null) {
endTime = addTime(purchaseStart, duration, durationUnit); endTime = addTime(purchaseStart, duration, durationUnit);
} }
// 4、扣延期天数 // 3、扣除已经消耗的延期天数
long delayDays = 0L; long delayDays = 0L;
if (CollUtil.isNotEmpty(delayRespVOList)) { if (CollUtil.isNotEmpty(delayRespVOList)) {
delayDays = calculateDelayDays(startTime, delayRespVOList); delayDays = calculateDelayDays(startTime, delayRespVOList);
@@ -275,11 +268,12 @@ public class PayProductProcessorNew {
endTime = endTime.minusDays(delayDays); endTime = endTime.minusDays(delayDays);
} }
// 5、累加优惠活动赠送时间 // 4、累加活动赠送时间
if (CollUtil.isNotEmpty(availableProductPromotionList)) { if (CollUtil.isNotEmpty(availableProductPromotionList)) {
calculateGiftDuration(duration, durationUnit); calculateGiftDuration(duration, durationUnit);
} }
// 校验扣减完毕后是不是还是过期了,那么就是订购时间无法覆盖延期扣减
if (endTime.isBefore(today)) { if (endTime.isBefore(today)) {
throw new ServiceException(PRODUCT_PURCHASE_ENDTIME_BEFORE_DELAYTIME_ERROR, LocalDateTimeUtil.format(endTime, DatePattern.NORM_DATE_PATTERN)); throw new ServiceException(PRODUCT_PURCHASE_ENDTIME_BEFORE_DELAYTIME_ERROR, LocalDateTimeUtil.format(endTime, DatePattern.NORM_DATE_PATTERN));
} }
@@ -332,16 +326,25 @@ public class PayProductProcessorNew {
List<DateIntervalDTO> intervals = new ArrayList<>(); List<DateIntervalDTO> intervals = new ArrayList<>();
for (ProductDelayRespVO record : delayRecords) { for (ProductDelayRespVO record : delayRecords) {
// 延期开始日期(原结束日期的下一天)
LocalDate delayStart = record.getEndTime().plusDays(1); LocalDate delayStart = record.getEndTime().plusDays(1);
// 延期结束日期
LocalDate delayEnd = record.getDelayTime(); LocalDate delayEnd = record.getDelayTime();
// 异常数据
if (delayEnd.isBefore(delayStart)) { if (delayEnd.isBefore(delayStart)) {
record.setRemark("无扣减"); record.setRemark("无扣减");
continue; // 异常数据,忽略 continue;
}
// 延期尚未开始
if (startTime.isBefore(delayStart)) {
record.setRemark("无扣减");
continue;
} }
LocalDate intervalEnd; LocalDate intervalEnd;
if (!delayEnd.isAfter(startTime)) { if (startTime.isAfter(delayEnd)) {
// 情况1:延期结束在计算结束之前 → 整段都扣 // 情况1:延期结束在计算结束之前 → 整段都扣
intervalEnd = delayEnd; intervalEnd = delayEnd;
} else { } else {