fix(order): 续费时间无缝衔接,避免空窗期多送有效期

- 续费时根据父订单到期时间判断,未逾期顺延,否则从当天延续一个月
- 后台统一计算续费开始与结束时间,不信任前端传入的时间参数
- 更新订单与续费记录的起始和结束时间逻辑,防止有效期重叠或空白
- 修改查询参数,支持仅查询续费单(rentOrderId 不为空)
- 保持支付状态和订单状态更新的正常流程,确保续费处理正确
This commit is contained in:
2026-07-27 11:36:51 +08:00
parent 1555fe1898
commit 8e081af4d8
5 changed files with 35 additions and 14 deletions

View File

@@ -162,8 +162,12 @@ public class OrderPayController extends BaseController {
one.setCurrPeriods(order.getCurrPeriods() + 1);
one.setPeriods(order.getPeriods());
one.setRentOrderId(order.getOrderId());
one.setStartTime(order.getExpirationTime());
one.setExpirationTime(DateUtil.offset(order.getExpirationTime(), DateField.MONTH, 1));
// 续费无缝衔接:未逾期时从上一个到期日顺延一个月;已逾期时从今天顺延,
// 避免“旧到期日~续费当天”这段空窗期被白送(表现为下半月续费有效期多给一个月)
Date baseExpire = order.getExpirationTime();
Date renewStart = (baseExpire != null && baseExpire.after(new Date())) ? baseExpire : new Date();
one.setStartTime(renewStart);
one.setExpirationTime(DateUtil.offset(renewStart, DateField.MONTH, 1));
one.setPayStatus(PAY_STATUS_NO_PAY);
one.setBatteryDeposit(order.getBatteryDeposit());
one.setBatteryInsurance(order.getBatteryInsurance());
@@ -262,11 +266,19 @@ public class OrderPayController extends BaseController {
}
Order order = new Order();
order.setOrderId(orderPay.getRentOrderId());
order.setStartTime(orderPay.getStartTime());
order.setExpirationTime(orderPay.getExpirationTime());
orderService.updateById(order);
// 续费时间以父订单当前到期日为准无缝衔接,不信任前端传入的 startTime/expirationTime
// 避免后台操作时把有效期算多一个月
Order parentOrder = orderService.getById(orderPay.getRentOrderId());
if (parentOrder == null) {
return fail("关联订单不存在");
}
Date parentExpire = parentOrder.getExpirationTime();
Date renewStart = (parentExpire != null && parentExpire.after(new Date())) ? parentExpire : new Date();
Date renewExpire = DateUtil.offset(renewStart, DateField.MONTH, 1);
parentOrder.setStartTime(renewStart);
parentOrder.setExpirationTime(renewExpire);
orderService.updateById(parentOrder);
OrderPay olderPay = orderPayService.getOne(Wrappers.lambdaQuery(OrderPay.class).eq(OrderPay::getOrderNo, orderPay.getOrderNo()));
OrderPay newOrderPay = new OrderPay();
@@ -274,10 +286,10 @@ public class OrderPayController extends BaseController {
newOrderPay.setOrderPrice(BigDecimal.valueOf(orderPay.getOrderPriceInt()));
newOrderPay.setStartTime(orderPay.getStartTime());
newOrderPay.setStartTime(renewStart);
newOrderPay.setPayTime(new Date());
newOrderPay.setCreateTime(new Date());
newOrderPay.setExpirationTime(orderPay.getExpirationTime());
newOrderPay.setExpirationTime(renewExpire);
newOrderPay.setOrderNo(IdUtil.getSnowflakeNextIdStr());
newOrderPay.setIsAdminRenew(1);//是否管理员续费订单

View File

@@ -575,7 +575,9 @@ public class PaymentController extends BaseController {
}
Date expirationTime = parentOrder.getExpirationTime();
DateTime nextMonthTime = DateUtil.offsetMonth(expirationTime, 1);
// 逾期续费从今天衔接,避免“旧到期日~续费当天”空窗期白送一个月
Date renewBase = (expirationTime != null && expirationTime.after(new Date())) ? expirationTime : new Date();
DateTime nextMonthTime = DateUtil.offsetMonth(renewBase, 1);
parentOrder.setExpirationTime(nextMonthTime);
orderService.updateById(parentOrder);
// 保存续费订单状态
@@ -583,7 +585,7 @@ public class PaymentController extends BaseController {
d.setDeliveryStatus(DELIVERY_STATUS_ACCEPT);
d.setReceiptStatus(RECEIPT_STATUS_YES);
d.setOrderStatus(ORDER_STATUS_COMPLETED);
d.setStartTime(expirationTime);
d.setStartTime(renewBase);
d.setExpirationTime(nextMonthTime);
orderService.updateById(d);
}

View File

@@ -25,6 +25,9 @@
<if test="param.rentOrderId != null">
AND a.rent_order_id = #{param.rentOrderId}
</if>
<if test="param.rentOrderIdNotNull != null and param.rentOrderIdNotNull">
AND a.rent_order_id IS NOT NULL
</if>
<if test="param.payStatus != null">
AND a.pay_status = #{param.payStatus}
</if>

View File

@@ -116,6 +116,9 @@ public class OrderPayParam extends BaseParam {
@QueryField(type = QueryType.EQ)
private Integer rentOrderId;
@ApiModelProperty(value = "仅查询续费单rentOrderId 不为空)")
private Boolean rentOrderIdNotNull;
@ApiModelProperty(value = "电池租金")
@QueryField(type = QueryType.EQ)
private BigDecimal batteryRent;

View File

@@ -260,16 +260,17 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
// 主订单
Order parentOrder = orderService.getById(order.getRentOrderId());
parentOrder.setCurrPeriods(count + 1);
// 更新过期时间延长一个月
// 更新过期时间延长一个月(逾期时从今天衔接,避免空窗期白送)
Date expirationTime = parentOrder.getExpirationTime();
DateTime nextMonthTime = DateUtil.offsetMonth(expirationTime, 1);
Date renewBase = (expirationTime != null && expirationTime.after(new Date())) ? expirationTime : new Date();
DateTime nextMonthTime = DateUtil.offsetMonth(renewBase, 1);
parentOrder.setExpirationTime(nextMonthTime);
// 保存续费订单状态
// order.setDeliveryStatus(DELIVERY_STATUS_YES);
order.setDeliveryStatus(DELIVERY_STATUS_ACCEPT);
order.setReceiptStatus(RECEIPT_STATUS_YES);
order.setOrderStatus(ORDER_STATUS_COMPLETED);
order.setStartTime(expirationTime);
order.setStartTime(renewBase);
order.setExpirationTime(nextMonthTime);
try {