Compare commits

..

18 Commits

Author SHA1 Message Date
6f0bf4d57c 换下日志 2025-09-26 16:36:11 +08:00
0338f3c675 修改下日志 2025-09-26 15:38:53 +08:00
af974e7368 去掉日志 2025-09-26 15:25:35 +08:00
a2f8d90eea 续租更新时间 2025-09-26 15:15:47 +08:00
879678cb56 新增免押相关接口 2025-09-26 01:45:44 +08:00
cefafddf5a 续租要计算租电订单 2025-09-25 15:09:43 +08:00
1814c5c199 续租去掉租电订单 2025-09-25 02:06:31 +08:00
edd2d6e728 租电订单做空处理 2025-09-25 01:48:07 +08:00
c3e64ce40f 去掉空值校验 2025-09-25 00:37:55 +08:00
17dddc27a2 计算续租时间和金额 2025-09-25 00:33:26 +08:00
5136b0f940 修复bug 2025-09-23 23:43:28 +08:00
b4a37065c5 还车时间处理 2025-09-22 02:50:26 +08:00
acf125b02a 批量处理待支付定 2025-09-22 02:14:18 +08:00
1d678f2f98 处理待支付的订单 2025-09-22 01:33:10 +08:00
729ae0e19c 修复续租和逾期处理问题 2025-09-21 23:59:55 +08:00
b51e0e1cd9 解决金额计算问题 2025-09-21 13:21:34 +08:00
c08f92cf4f 续租增加租电订单金额 2025-09-21 00:34:09 +08:00
2b250068cf 设置租电订单号 2025-09-19 00:32:04 +08:00
22 changed files with 501 additions and 163 deletions

View File

@ -11,6 +11,7 @@ import lombok.Getter;
@AllArgsConstructor
@Getter
public enum PayStatusEnum {
INIT("INIT", "初始化"),
USERPAYING("USERPAYING", "用户支付中"),
SUCCESS("SUCCESS", "支付成功"),
PAYERROR("PAYERROR", "支付失败"),

View File

@ -11,6 +11,7 @@ import lombok.Getter;
@AllArgsConstructor
@Getter
public enum SubOrderTypeEnum {
NO_DEPOSIT("NO_DEPOSIT", "免押冻结订单"),
DEPOSIT("DEPOSIT", "押金订单"),
RENTCAR("RENTCAR", "租车订单"),
RENTBATTEY("RENTBATTEY", "租电订单"),

View File

@ -31,7 +31,6 @@ public interface OrderConvert {
@Mapping(source = "rentCarOrderReq.carModelId", target = "carModelId"),
@Mapping(source = "rentCarOrderReq.rentCarRuleId", target = "rentCarRuleId"),
@Mapping(source = "rentCarOrderReq.rentBatteyRuleId", target = "rentBatteyRuleId"),
@Mapping(source = "rentCarOrderReq.isAutoDeduct", target = "isAutoDeduct"),
@Mapping(source = "rentCarOrderReq.isDepositFree", target = "isDepositFree"),
@Mapping(source = "rentCarOrderReq.batteryType", target = "batteryType"),
@Mapping(source = "userInfoDTO.userId", target = "customerId"),
@ -87,6 +86,7 @@ public interface OrderConvert {
@Mapping(source = "rentBatteyRuleDTO.categoryName", target = "categoryName"),
@Mapping(source = "rentBatteyRuleDTO.title", target = "rentBatteyTitle"),
@Mapping(source = "rentBatteyRuleDTO.durationType", target = "durationType"),
@Mapping(source = "rentBatteyRuleDTO.rentPrice", target = "rentBatteyPrice"),
@Mapping(source = "rentBatteyOrder.vinBatteryNo", target = "batteyNo"),
})
OrderDetailDTO mainOrderToDetailDTO(OrderMainPO orderMainPO, CompanyStoreDTO companyStoreDTO, RentBatteyRuleDTO rentBatteyRuleDTO, CarDTO carDTO, CarModelSimpleDTO carModelSimpleDTO,OrderSubPO rentBatteyOrder);

View File

@ -119,6 +119,9 @@ public class OrderDetailDTO {
@ApiModelProperty("电池编码")
private String batteyNo;
@ApiModelProperty("租电租金")
private BigDecimal rentBatteyPrice;
@ApiModelProperty("计时方式")
private Integer durationType;
@ -176,4 +179,7 @@ public class OrderDetailDTO {
@ApiModelProperty("支付订单信息")
private List<PayOrderDTO> payOrderDTOList;
@ApiModelProperty("待支付金额")
private BigDecimal waitPayAmount;
}

View File

@ -23,6 +23,4 @@ public class ReRentCarReq {
@ApiModelProperty(value = "客户id")
private Long customerId;
@ApiModelProperty("是否开通代扣")
private Boolean isAutoDeduct = false;
}

View File

@ -5,7 +5,6 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
@ -40,17 +39,12 @@ public class RentCarOrderReq {
@ApiModelProperty(value = "租电套餐id")
@NotNull(message = "租电套餐id不能为空")
private Long rentBatteyRuleId;
@ApiModelProperty("选择的电池类型")
@NotBlank(message = "租电套餐id不能为空")
private String batteryType;
@ApiModelProperty("是否开通免押")
private Boolean isDepositFree = false;
@ApiModelProperty("是否开通代扣")
private Boolean isAutoDeduct = false;
}

View File

@ -22,6 +22,13 @@ public interface OrderService {
*/
RentCarOrderResultDTO submitRentCarOrder(RentCarOrderReq rentCarOrderReq);
/**
* 免押下单
* @param rentCarOrderReq
* @return
*/
RentCarOrderResultDTO depositFreeSubmitRentCarOrder(RentCarOrderReq rentCarOrderReq);
/**
* 续租车
* @param rentCarOrderReq
@ -42,6 +49,12 @@ public interface OrderService {
*/
void cancelOrder(PayOrderReq payOrderReq);
/**
* 取消订单
* @param orderMainPO
*/
void cancelRerentOrOverDueOrder(OrderMainPO orderMainPO);
/**
* 逾期处理
* @param rentCarOrderReq

View File

@ -103,7 +103,7 @@ public class OrderDistribServiceImpl implements OrderDistribService {
addOrderDistribPOList.add(referralDistribPO);
}
}
BigDecimal alreadyShareRate = addOrderDistribPOList.stream().map(OrderDistribPO::getDistribRate).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
BigDecimal alreadyShareRate = addOrderDistribPOList.stream().map(OrderDistribPO::getDistribRate).reduce(BigDecimal.ZERO,BigDecimal::add);
//运营商分润
String companyRate = String.valueOf(BigDecimal.ONE.subtract(alreadyShareRate).multiply(BigDecimal.valueOf(100)));
OrderDistribPO companyDistribPO = getOrderDistribPO(orderMainPO.getOrderId(),orderMainPO.getOrderNo(),DistribTypeEnum.COMPANY.getCode(),companyRate,orderMainPO.getOrderAmount(),Integer.valueOf(orderMainPO.getOperatorId().toString()),Integer.valueOf(orderMainPO.getStoreId().toString()),null);

View File

@ -18,6 +18,7 @@ import com.sczx.order.service.OrderService;
import com.sczx.order.service.PayService;
import com.sczx.order.thirdpart.dto.*;
import com.sczx.order.thirdpart.dto.req.AlipayCloseRequest;
import com.sczx.order.thirdpart.dto.req.AlipayFundFreezeRequest;
import com.sczx.order.thirdpart.dto.req.CarQueryConditionReq;
import com.sczx.order.thirdpart.integration.CarInteg;
import com.sczx.order.thirdpart.integration.PayInteg;
@ -100,9 +101,16 @@ public class OrderServiceImpl implements OrderService {
.notIn(OrderMainPO::getOrderStatus, Arrays.asList(OrderStatusEnum.AUTO_END.getCode(), OrderStatusEnum.MANUAL_END.getCode()))
.eq(OrderMainPO::getDelFlag, "0");
List<OrderMainPO> currentOrderList = orderMainRepo.list(currentOrderWrapper);
if(!currentOrderList.isEmpty()){
OrderMainPO waitPayOrder = currentOrderList.stream().filter(order -> order.getOrderStatus().equals(OrderStatusEnum.WAIT_PAY.getCode())).findFirst().orElse(null);
if(!currentOrderList.isEmpty() && waitPayOrder==null){
throw new BizException("您有未完成的订单,请先完成订单");
}
if(waitPayOrder!=null){
log.info("存在待支付的订单,取消订单");
PayOrderReq payOrderReq = new PayOrderReq();
payOrderReq.setOrderNo(waitPayOrder.getOrderNo());
cancelOrder(payOrderReq);
}
//判断是否存有空闲车辆可用
LambdaQueryWrapper<CarPO> carWrapper = new LambdaQueryWrapper<>();
@ -136,30 +144,20 @@ public class OrderServiceImpl implements OrderService {
OrderMainPO orderMainPO = OrderConvert.INSTANCE.subOrderToPo(rentCarOrderReq, userInfoDTO, rentCarRuleDTO);
orderMainPO.setOperatorId(Long.valueOf(companyStoreDTO.getOperatingCompanyId()));
orderMainPO.setOrderNo(OrderUtil.generateOrderNo());
//TODO 默认应该是待支付状态,这里先默认支付完成待取车
orderMainPO.setOrderStatus(OrderStatusEnum.WAIT_PAY.getCode());
// orderMainPO.setOrderStatus(OrderStatusEnum.WAIT_PICK.getCode());
orderMainPO.setFirstOrderTime(LocalDateTime.now());
//设置预计还车时间
LocalDateTime endRentTime = OrderUtil.getEndRentTime(orderMainPO.getFirstOrderTime(),rentCarRuleDTO.getRentalDays(), rentCarRuleDTO.getRentalType());
LocalDateTime endRentTime = OrderUtil.getEndRentTime(orderMainPO.getFirstOrderTime(),1,rentCarRuleDTO.getRentalDays(), rentCarRuleDTO.getRentalType());
orderMainPO.setEndRentTime(endRentTime);
//生成子表订单
String paymentType;
if(rentCarOrderReq.getIsAutoDeduct()){
if(StringUtils.equalsIgnoreCase(userInfoDTO.getMiniProgramType(), MiniProgramTypeEnum.WECHAT.getType())){
paymentType = PaymentTypeEnum.WX_DQ.getCode();
}else {
paymentType = PaymentTypeEnum.ZFB_DQ.getCode();
}
} else {
if(StringUtils.equalsIgnoreCase(userInfoDTO.getMiniProgramType(), MiniProgramTypeEnum.WECHAT.getType())){
paymentType = PaymentTypeEnum.WX_PAY.getCode();
}else {
paymentType = PaymentTypeEnum.ZFB_PAY.getCode();
}
if(StringUtils.equalsIgnoreCase(userInfoDTO.getMiniProgramType(), MiniProgramTypeEnum.WECHAT.getType())){
paymentType = PaymentTypeEnum.WX_PAY.getCode();
}else {
paymentType = PaymentTypeEnum.ZFB_PAY.getCode();
}
List<OrderSubPO> orderSubPOList = new ArrayList<>();
@ -185,13 +183,14 @@ public class OrderServiceImpl implements OrderService {
orderSubPOList.add(depositOrder);
}
//生成租车订单
BigDecimal rentCarOrderAmount = getRentCarAmount(rentCarRuleDTO.getRentalType(), rentCarRuleDTO.getRentalPrice(), rentCarRuleDTO.getRentalDays());
BigDecimal rentCarOrderAmount = OrderUtil.getRentCarAmount(rentCarRuleDTO.getRentalType(), rentCarRuleDTO.getRentalPrice(), rentCarRuleDTO.getRentalDays());
OrderSubPO rentOrder = new OrderSubPO();
rentOrder.setSuborderNo(OrderUtil.generateSubOrderNo(OrderUtil.ZC_PREFIX));
rentOrder.setSuborderType(SubOrderTypeEnum.RENTCAR.getCode());
rentOrder.setAmount(rentCarOrderAmount);
rentOrder.setCreatedAt(LocalDateTime.now());
rentOrder.setPaymentMethod(paymentType);
rentOrder.setReturnTime(endRentTime);
orderSubPOList.add(rentOrder);
BigDecimal orderAmount = orderSubPOList.stream().map(OrderSubPO::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
@ -238,6 +237,11 @@ public class OrderServiceImpl implements OrderService {
}
}
@Override
public RentCarOrderResultDTO depositFreeSubmitRentCarOrder(RentCarOrderReq rentCarOrderReq) {
//TODO - 免押冻结
return null;
}
@Transactional(rollbackFor = Exception.class)
@ -255,26 +259,33 @@ public class OrderServiceImpl implements OrderService {
if(orderMainPO == null){
throw new BizException("订单不存在");
}
if(OrderStatusEnum.RERENT_WAIT_PAY.getCode().equals(orderMainPO.getOrderStatus())){
//已经是待支付状态的,先取消,然后再拉起支付
cancelRerentOrOverDueOrder(orderMainPO);
orderMainPO = orderMainRepo.getOne(currentOrderWrapper);
}
if(!OrderStatusEnum.RENT_ING.getCode().equals(orderMainPO.getOrderStatus()) && !OrderStatusEnum.RENT_OVERDUE.getCode().equals(orderMainPO.getOrderStatus())){
throw new BizException("订单非租赁或逾期状态,不能续租");
}
//生成子表订单
String paymentType;
if(rentCarOrderReq.getIsAutoDeduct()){
if(StringUtils.equalsIgnoreCase(userInfoDTO.getMiniProgramType(), MiniProgramTypeEnum.WECHAT.getType())){
paymentType = PaymentTypeEnum.WX_DQ.getCode();
}else {
paymentType = PaymentTypeEnum.ZFB_DQ.getCode();
}
} else {
if(StringUtils.equalsIgnoreCase(userInfoDTO.getMiniProgramType(), MiniProgramTypeEnum.WECHAT.getType())){
paymentType = PaymentTypeEnum.WX_PAY.getCode();
}else {
paymentType = PaymentTypeEnum.ZFB_PAY.getCode();
}
if(StringUtils.equalsIgnoreCase(userInfoDTO.getMiniProgramType(), MiniProgramTypeEnum.WECHAT.getType())){
paymentType = PaymentTypeEnum.WX_PAY.getCode();
}else {
paymentType = PaymentTypeEnum.ZFB_PAY.getCode();
}
//计算续租周期
int rerentInterval = OrderUtil.calculateRerentRoundsToCoverOverdue(orderMainPO.getOverdueDays(), orderMainPO.getRentalDays());
//获取续租车金额
BigDecimal rentCarOrderAmount = OrderUtil.getReRentCarAmount(rerentInterval, orderMainPO.getRentalPrice());
// 获取租电金额
BigDecimal rentBatteyOrderAmount = BigDecimal.ZERO ;
RentBatteyRuleDTO rentBatteyRuleDTO = null;
if(orderMainPO.getRentBatteyRuleId()!=null) {
rentBatteyRuleDTO = carInteg.getRentBatteyRuleByBatteyRuleId(orderMainPO.getRentBatteyRuleId());
rentBatteyOrderAmount = Optional.ofNullable(rentBatteyRuleDTO).map(RentBatteyRuleDTO::getRentPrice).orElse(BigDecimal.ZERO);
rentCarOrderAmount = rentCarOrderAmount.add(rentBatteyOrderAmount);
}
BigDecimal rentCarOrderAmount = getReRentCarAmount(orderMainPO.getEndRentTime(), orderMainPO.getRentalType(), orderMainPO.getRentalPrice(), orderMainPO.getRentalDays());
String paymentId = OrderUtil.generateSubOrderNo(OrderUtil.ZF_PREFIX);
// 起支付返回预支付信息
RentCarRuleDTO rentCarRuleDTO = carInteg.getRentCarRuleByCarRuleId(orderMainPO.getRentCarRuleId());
@ -284,7 +295,7 @@ public class OrderServiceImpl implements OrderService {
LocalDateTime nowTime = LocalDateTime.now();
LocalDateTime oldEndRentTime = orderMainPO.getEndRentTime().isAfter(nowTime) ? orderMainPO.getEndRentTime() : nowTime;
//刷新预计还车时间
LocalDateTime newEndRentTime = OrderUtil.getEndRentTime(oldEndRentTime, orderMainPO.getRentalDays(), orderMainPO.getRentalType());
LocalDateTime newEndRentTime = OrderUtil.getEndRentTime(oldEndRentTime, rerentInterval,orderMainPO.getRentalDays(), orderMainPO.getRentalType());
//生成租车子订单
OrderSubPO rentOrder = new OrderSubPO();
@ -297,9 +308,22 @@ public class OrderServiceImpl implements OrderService {
rentOrder.setPaymentMethod(paymentType);
rentOrder.setPayStatus(PayStatusEnum.USERPAYING.getCode());
rentOrder.setReturnTime(newEndRentTime);
orderSubRepo.save(rentOrder);
//生成租电子订单
if(rentBatteyOrderAmount.compareTo(BigDecimal.ZERO)>0){
//生成租电子订单
OrderSubPO rentBatraayOrder = new OrderSubPO();
rentBatraayOrder.setOrderId(orderMainPO.getOrderId());
rentBatraayOrder.setSuborderNo(OrderUtil.generateSubOrderNo(OrderUtil.ZC_PREFIX));
rentBatraayOrder.setPaymentId(paymentId);
rentBatraayOrder.setSuborderType(SubOrderTypeEnum.RENTBATTEY.getCode());
rentBatraayOrder.setAmount(rentBatteyOrderAmount);
rentBatraayOrder.setCreatedAt(LocalDateTime.now());
rentBatraayOrder.setPaymentMethod(paymentType);
rentBatraayOrder.setPayStatus(PayStatusEnum.USERPAYING.getCode());
orderSubRepo.save(rentBatraayOrder);
}
@ -374,23 +398,37 @@ public class OrderServiceImpl implements OrderService {
LambdaQueryWrapper<OrderSubPO> orderSubQueryWrapper = new LambdaQueryWrapper<>();
orderSubQueryWrapper.eq(OrderSubPO::getOrderId, orderMainPO.getOrderId());
orderSubQueryWrapper.eq(OrderSubPO::getPayStatus, PayStatusEnum.USERPAYING.getCode());
orderSubQueryWrapper.orderByDesc(OrderSubPO::getCreatedAt).last(" limit 1");
OrderSubPO orderSubPO = orderSubRepo.getOne(orderSubQueryWrapper);
orderSubQueryWrapper.in(OrderSubPO::getPayStatus, Arrays.asList(PayStatusEnum.USERPAYING.getCode(), PayStatusEnum.INIT.getCode()));
orderSubQueryWrapper.orderByDesc(OrderSubPO::getCreatedAt);
List<OrderSubPO> orderSubPOList = orderSubRepo.list(orderSubQueryWrapper);
boolean closePayOrder = false;
//获取门店信息
CompanyStoreDTO companyStoreDTO = storeInteg.getStoreById(Integer.valueOf(orderMainPO.getStoreId().toString()));
OrderSubPO rentOrder = orderSubPOList.stream().filter(orderSubPO -> StringUtils.equalsIgnoreCase(orderSubPO.getSuborderType(), SubOrderTypeEnum.RENTCAR.getCode())).findFirst().orElse( new OrderSubPO());
//关闭支付单
if(StringUtils.equalsIgnoreCase(orderSubPO.getPaymentMethod(), PaymentTypeEnum.WX_PAY.getCode())){
log.info("开始关闭支付单");
closePayOrder = payInteg.closeOrder(Long.valueOf(companyStoreDTO.getOperatingCompanyId()), orderSubPO.getPaymentId());
} else if(StringUtils.equalsIgnoreCase(orderSubPO.getPaymentMethod(), PaymentTypeEnum.ZFB_PAY.getCode())){
log.info("开始关闭支付宝支付单");
AlipayCloseRequest alipayCloseRequest = new AlipayCloseRequest();
alipayCloseRequest.setCompanyId(Long.valueOf(companyStoreDTO.getOperatingCompanyId()));
alipayCloseRequest.setOutTradeNo(orderSubPO.getPaymentId());
closePayOrder = payInteg.alipayCloseOrder(alipayCloseRequest);
if(StringUtils.equalsIgnoreCase(rentOrder.getPaymentMethod(), PaymentTypeEnum.WX_PAY.getCode())){
log.info("开始关闭微信租车支付单");
closePayOrder = payInteg.closeOrder(Long.valueOf(companyStoreDTO.getOperatingCompanyId()), rentOrder.getPaymentId());
} else if(StringUtils.equalsIgnoreCase(rentOrder.getPaymentMethod(), PaymentTypeEnum.ZFB_PAY.getCode())){
if(orderMainPO.getIsDepositFree()){
OrderSubPO noDepositOrder = orderSubPOList.stream().filter(orderSubPO -> StringUtils.equalsIgnoreCase(orderSubPO.getSuborderType(), SubOrderTypeEnum.NO_DEPOSIT.getCode())).findFirst().orElse(null);
if(Objects.nonNull(noDepositOrder)){
log.info("开始取消支付宝押金冻结支付单");
AlipayFundFreezeRequest fundFreezeRequest = new AlipayFundFreezeRequest();
fundFreezeRequest.setCompanyId(companyStoreDTO.getOperatingCompanyId().toString());
fundFreezeRequest.setOutOrderNo(noDepositOrder.getPaymentId());
closePayOrder = payInteg.cancelFundFreeze(fundFreezeRequest);
}
}
if(StringUtils.equalsIgnoreCase(rentOrder.getPayStatus(), PayStatusEnum.USERPAYING.getCode())){
log.info("开始关闭支付宝租车支付单");
AlipayCloseRequest alipayCloseRequest = new AlipayCloseRequest();
alipayCloseRequest.setCompanyId(Long.valueOf(companyStoreDTO.getOperatingCompanyId()));
alipayCloseRequest.setOutTradeNo(rentOrder.getPaymentId());
closePayOrder = payInteg.alipayCloseOrder(alipayCloseRequest);
}
}
if(closePayOrder){
@ -409,6 +447,51 @@ public class OrderServiceImpl implements OrderService {
}
}
@Override
public void cancelRerentOrOverDueOrder(OrderMainPO orderMainPO) {
if(Objects.nonNull(orderMainPO)){
if(!OrderStatusEnum.RERENT_WAIT_PAY.getCode().equalsIgnoreCase(orderMainPO.getOrderStatus())){
throw new BizException("订单非续租或逾期待支付状态,不能取消");
}
LambdaQueryWrapper<OrderSubPO> orderSubQueryWrapper = new LambdaQueryWrapper<>();
orderSubQueryWrapper.eq(OrderSubPO::getOrderId, orderMainPO.getOrderId());
orderSubQueryWrapper.eq(OrderSubPO::getPayStatus, PayStatusEnum.USERPAYING.getCode());
orderSubQueryWrapper.orderByDesc(OrderSubPO::getCreatedAt).last(" limit 1");
OrderSubPO orderSubPO = orderSubRepo.getOne(orderSubQueryWrapper);
boolean closePayOrder = false;
//关闭支付单
if (StringUtils.equalsIgnoreCase(orderSubPO.getPaymentMethod(), PaymentTypeEnum.WX_PAY.getCode())) {
log.info("开始关闭支付单");
closePayOrder = payInteg.closeOrder(orderMainPO.getOperatorId(), orderSubPO.getPaymentId());
} else if (StringUtils.equalsIgnoreCase(orderSubPO.getPaymentMethod(), PaymentTypeEnum.ZFB_PAY.getCode())) {
log.info("开始关闭支付宝支付单");
AlipayCloseRequest alipayCloseRequest = new AlipayCloseRequest();
alipayCloseRequest.setCompanyId(orderMainPO.getOperatorId());
alipayCloseRequest.setOutTradeNo(orderSubPO.getPaymentId());
closePayOrder = payInteg.alipayCloseOrder(alipayCloseRequest);
}
if (closePayOrder) {
LambdaUpdateWrapper<OrderSubPO> updateSubWrapper = new LambdaUpdateWrapper<>();
updateSubWrapper.set(OrderSubPO::getDelFlag, "2").eq(OrderSubPO::getOrderId, orderMainPO.getOrderId())
.eq(OrderSubPO::getPayStatus, PayStatusEnum.USERPAYING.getCode());
orderSubRepo.update(updateSubWrapper);
log.info("开始恢复续租订单状态");
//更新订单状态及信息
LambdaUpdateWrapper<OrderMainPO> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(OrderMainPO::getOrderStatus, OrderStatusEnum.RENT_ING.getCode());
if(orderMainPO.getOverdueDays()>0){
updateWrapper.set(OrderMainPO::getOrderStatus, OrderStatusEnum.RENT_OVERDUE.getCode());
}
updateWrapper.eq(OrderMainPO::getOrderId, orderMainPO.getOrderId());
orderMainRepo.update(updateWrapper);
} else {
throw new BizException("支付单关闭失败");
}
}
}
@Transactional(rollbackFor = Exception.class)
@Override
@ -424,23 +507,20 @@ public class OrderServiceImpl implements OrderService {
if(orderMainPO == null){
throw new BizException("订单不存在");
}
if(OrderStatusEnum.RERENT_WAIT_PAY.getCode().equals(orderMainPO.getOrderStatus())){
//已经是待支付状态的,先取消,然后再拉起支付
cancelRerentOrOverDueOrder(orderMainPO);
orderMainPO = orderMainRepo.getOne(currentOrderWrapper);
}
if(!OrderStatusEnum.RENT_OVERDUE.getCode().equals(orderMainPO.getOrderStatus())){
throw new BizException("订单非逾期状态,不能逾期处理");
}
//生成子表订单
String paymentType;
if(rentCarOrderReq.getIsAutoDeduct()){
if(StringUtils.equalsIgnoreCase(userInfoDTO.getMiniProgramType(), MiniProgramTypeEnum.WECHAT.getType())){
paymentType = PaymentTypeEnum.WX_DQ.getCode();
}else {
paymentType = PaymentTypeEnum.ZFB_DQ.getCode();
}
} else {
if(StringUtils.equalsIgnoreCase(userInfoDTO.getMiniProgramType(), MiniProgramTypeEnum.WECHAT.getType())){
paymentType = PaymentTypeEnum.WX_PAY.getCode();
}else {
paymentType = PaymentTypeEnum.ZFB_PAY.getCode();
}
if(StringUtils.equalsIgnoreCase(userInfoDTO.getMiniProgramType(), MiniProgramTypeEnum.WECHAT.getType())){
paymentType = PaymentTypeEnum.WX_PAY.getCode();
}else {
paymentType = PaymentTypeEnum.ZFB_PAY.getCode();
}
Integer overDueDaysOrHours = OrderUtil.getOrderOverdueDays(orderMainPO.getEndRentTime());
if(StringUtils.equalsIgnoreCase(RentCarTypeEnum.HOUR_RENTAL.getCode(), orderMainPO.getRentalType())){
@ -545,6 +625,9 @@ public class OrderServiceImpl implements OrderService {
LambdaQueryWrapper<OrderMainPO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OrderMainPO::getOrderNo, orderNo);
OrderMainPO orderMainPO = orderMainRepo.getOne(queryWrapper);
if(orderMainPO==null){
return null;
}
//获取租电子订单
LambdaQueryWrapper<OrderSubPO> querySubWrapper = new LambdaQueryWrapper<>();
@ -589,10 +672,9 @@ public class OrderServiceImpl implements OrderService {
if(!CollectionUtils.isEmpty(orderSubPOList2)){
orderDetailDTO.setLastPayOrderNo(orderSubPOList2.get(0).getPaymentId());
orderDetailDTO.setPayOrderDTOList(OrderSubConvert.INSTANCE.posToPayOrderDtos(orderSubPOList2));
orderDetailDTO.setRentBatteyOrderNo(orderSubPOList2.stream().filter(orderSubPO -> StringUtils.equalsIgnoreCase(orderSubPO.getSuborderType(), SubOrderTypeEnum.RENTBATTEY.getCode())).findFirst().map(OrderSubPO::getSuborderNo).orElse( null));
}
//计算续租金额
BigDecimal reRentCarAmount = getReRentCarAmount(orderMainPO.getEndRentTime(), orderMainPO.getRentalType(), orderMainPO.getRentalPrice(), orderMainPO.getRentalDays());
orderDetailDTO.setRerentAmount(reRentCarAmount);
if(OrderStatusEnum.RENT_ING.getCode().equalsIgnoreCase(orderMainPO.getOrderStatus())){
//如果是租车中,需要判断是否逾期了
@ -623,13 +705,22 @@ public class OrderServiceImpl implements OrderService {
updateWrapper.set(OrderMainPO::getOverdueDays, overdueDays);
updateWrapper.eq(OrderMainPO::getOrderId, orderMainPO.getOrderId());
orderMainRepo.update(updateWrapper);
//计算续租周期
int rerentInterval = OrderUtil.calculateRerentRoundsToCoverOverdue(overdueDays, orderMainPO.getRentalDays());
//获取续租车金额
BigDecimal reRentCarAmount = OrderUtil.getReRentCarAmount(rerentInterval, orderMainPO.getRentalPrice());
orderDetailDTO.setRerentAmount(reRentCarAmount);
}else {
//没逾期则计算到期天数
orderDetailDTO.setExpectedDays(OrderUtil.getOrderExpectedDays(orderMainPO.getEndRentTime()));
//计算续租金额
BigDecimal reRentCarAmount = OrderUtil.getReRentCarAmount(1, orderMainPO.getRentalPrice());
orderDetailDTO.setRerentAmount(reRentCarAmount);
}
}
}
} else if(OrderStatusEnum.RENT_OVERDUE.getCode().equalsIgnoreCase(orderMainPO.getOrderStatus())){
log.info("订单已逾期的,计算逾期金额");
if(orderMainPO.getEndRentTime()!=null){
@ -638,28 +729,37 @@ public class OrderServiceImpl implements OrderService {
overdueDaysOrHours = OrderUtil.getOrderOverdueHours(orderMainPO.getEndRentTime());
}
orderDetailDTO.setOverdueAmount(OrderUtil.getOrderOverdueAmount(overdueDaysOrHours, orderMainPO.getOverdueFee()));
//计算续租周期
int rerentInterval = OrderUtil.calculateRerentRoundsToCoverOverdue(overdueDaysOrHours, orderMainPO.getRentalDays());
//获取续租车金额
BigDecimal reRentCarAmount = OrderUtil.getReRentCarAmount(rerentInterval, orderMainPO.getRentalPrice());
orderDetailDTO.setRerentAmount(reRentCarAmount);
}
} else if(OrderStatusEnum.WAIT_PAY.getCode().equalsIgnoreCase(orderMainPO.getOrderStatus())
||OrderStatusEnum.RERENT_WAIT_PAY.getCode().equalsIgnoreCase(orderMainPO.getOrderStatus())){
//去查看订单是否支付成功
LambdaQueryWrapper<OrderSubPO> querySubOrderWrapper = new LambdaQueryWrapper<>();
querySubOrderWrapper.eq(OrderSubPO::getOrderId, orderMainPO.getOrderId())
.in(OrderSubPO::getSuborderType, Arrays.asList(SubOrderTypeEnum.OVERDUE.getCode(), SubOrderTypeEnum.RENTCAR.getCode()))
.in(OrderSubPO::getSuborderType, Arrays.asList(SubOrderTypeEnum.OVERDUE.getCode(), SubOrderTypeEnum.RENTCAR.getCode(), SubOrderTypeEnum.RENTBATTEY.getCode()))
.ne(OrderSubPO::getPayStatus, PayStatusEnum.SUCCESS).orderByDesc(OrderSubPO::getCreatedAt).last(" limit 1");
OrderSubPO orderSubPO = orderSubRepo.getOne(querySubOrderWrapper);
if(orderSubPO!=null){
List<OrderSubPO> orderSubList = orderSubRepo.list(querySubOrderWrapper);
if(OrderStatusEnum.WAIT_PAY.getCode().equalsIgnoreCase(orderMainPO.getOrderStatus())){
orderDetailDTO.setWaitPayAmount(orderMainPO.getOrderAmount());
}else {
orderDetailDTO.setWaitPayAmount(orderSubList.stream().map(OrderSubPO::getAmount).reduce(BigDecimal.ZERO,BigDecimal::add));
}
if(!CollectionUtils.isEmpty(orderSubList)){
//如果是微信支付,则去微信查询支付状态,如果支付成功,则修改订单状态为支付成功
if(PaymentTypeEnum.WX_PAY.getCode().equals(orderSubPO.getPaymentMethod())){
Map<String, String> result = payInteg.orderQuery((long)companyStoreDTO.getOperatingCompanyId(), orderSubPO.getPaymentId());
if(PaymentTypeEnum.WX_PAY.getCode().equals(orderSubList.get(0).getPaymentMethod())){
Map<String, String> result = payInteg.orderQuery((long)companyStoreDTO.getOperatingCompanyId(), orderSubList.get(0).getPaymentId());
if(StringUtils.equalsIgnoreCase(result.get("trade_state"), "SUCCESS")){
String orderState = paySuccessOrder(orderMainPO, orderSubPO);
String orderState = paySuccessOrder(orderMainPO, orderSubList);
orderDetailDTO.setOrderStatus(orderState);
}
}else if(PaymentTypeEnum.ZFB_PAY.getCode().equals(orderSubPO.getPaymentMethod())){
AlipayQueryResponse alipayQueryResponse = payInteg.alipayOrderQuery(orderSubPO.getPaymentId());
}else if(PaymentTypeEnum.ZFB_PAY.getCode().equals(orderSubList.get(0).getPaymentMethod())){
AlipayQueryResponse alipayQueryResponse = payInteg.alipayOrderQuery(orderSubList.get(0).getPaymentId());
if(StringUtils.equalsIgnoreCase(alipayQueryResponse.getCode(), "SUCCESS") && StringUtils.equalsIgnoreCase(alipayQueryResponse.getTradeStatus(), "TRADE_SUCCESS")){
String orderState = paySuccessOrder(orderMainPO, orderSubPO);
String orderState = paySuccessOrder(orderMainPO, orderSubList);
orderDetailDTO.setOrderStatus(orderState);
}
}
@ -685,6 +785,16 @@ public class OrderServiceImpl implements OrderService {
if(orderMainPO==null){
return null;
}
//如果是待支付状态的订单,则取消订单
if(orderMainPO.getOrderStatus().equals(OrderStatusEnum.WAIT_PAY.getCode())){
PayOrderReq payOrderReq = new PayOrderReq();
payOrderReq.setOrderNo(orderMainPO.getOrderNo());
cancelOrder(payOrderReq);
return null;
}
if(orderMainPO.getOrderStatus().equals(OrderStatusEnum.RERENT_WAIT_PAY.getCode())){
cancelRerentOrOverDueOrder(orderMainPO);
}
return getOrderDetailByOrderNo(orderMainPO.getOrderNo());
}
@ -786,13 +896,13 @@ public class OrderServiceImpl implements OrderService {
LocalDateTime currentTime = LocalDateTime.now();
//设置预计还车时间
LocalDateTime endRentTime = OrderUtil.getEndRentTime(currentTime,orderMainPO.getRentalDays(), orderMainPO.getRentalType());
LocalDateTime endRentTime = OrderUtil.getEndRentTime(currentTime,1,orderMainPO.getRentalDays(), orderMainPO.getRentalType());
LambdaUpdateWrapper<OrderMainPO> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(OrderMainPO::getOrderStatus, OrderStatusEnum.RENT_ING.getCode());
updateWrapper.set(OrderMainPO::getStartRentTime, currentTime);
updateWrapper.set(OrderMainPO::getPickCarTime, currentTime);
updateWrapper.set(endRentTime!=null ,OrderMainPO::getEndRentTime, endRentTime);
updateWrapper.set(OrderMainPO::getEndRentTime, endRentTime);
updateWrapper.set(OrderMainPO::getVehicleId, carDTO.getId());
updateWrapper.eq(OrderMainPO::getOrderNo, bindCarToOrderReq.getOrderNo());
orderMainRepo.update(updateWrapper);
@ -824,9 +934,10 @@ public class OrderServiceImpl implements OrderService {
.orderByDesc(OrderSubPO::getCreatedAt)
.last(" limit 1");
OrderSubPO renBatteryOrderSubPO = orderSubRepo.getOne(querySubBatteryWrapper);
Long batterySubOrderId = renBatteryOrderSubPO.getSuborderId();
syncInteg.sendSubOrderId(batterySubOrderId);
if(renBatteryOrderSubPO!=null){
Long batterySubOrderId = renBatteryOrderSubPO.getSuborderId();
syncInteg.sendSubOrderId(batterySubOrderId);
}
return getOrderInfoByOrderNo(bindCarToOrderReq.getOrderNo());
} catch (Exception e){
log.warn("绑定车辆失败",e);
@ -1041,13 +1152,14 @@ public class OrderServiceImpl implements OrderService {
@Override
public IPage<OrderSimpleDTO> pageCustOrder(Integer pageNo, Integer pageSize, OrderQueryReq orderQueryReq) {
orderQueryReq.setCustomerId(Long.valueOf(jwtUtil.getUserInfoFromToken().getUserId().toString()));
batchProcessWaitPayOrder(orderQueryReq.getCustomerId(),orderQueryReq.getStoreId());
List<String> orderStatusList = orderQueryReq.getOrderStatusList().stream().map(OrderStatusEnum::getCode).collect(Collectors.toList());
return orderMainRepo.pageQueryOrder(pageNo, pageSize, orderQueryReq.getCustomerId(), orderQueryReq.getStoreId(), orderStatusList, orderQueryReq.getQueryBrandName());
}
@Override
public IPage<OrderSimpleDTO> pageStoreOrder(Integer pageNo, Integer pageSize, OrderQueryReq orderQueryReq) {
batchProcessWaitPayOrder(orderQueryReq.getCustomerId(),orderQueryReq.getStoreId());
List<String> orderStatusList = orderQueryReq.getOrderStatusList().stream().map(OrderStatusEnum::getCode).collect(Collectors.toList());
return orderMainRepo.pageQueryOrder(pageNo, pageSize, orderQueryReq.getCustomerId(), orderQueryReq.getStoreId(), orderStatusList, orderQueryReq.getQueryBrandName());
}
@ -1065,28 +1177,61 @@ public class OrderServiceImpl implements OrderService {
return orderMainRepo.pageQueryRentBatteyOrder(pageNo, pageSize, orderQueryReq.getCustomerId(), orderQueryReq.getStoreId(), orderStatusList, orderQueryReq.getQueryBrandName());
}
/**
* 批量处理待支付订单
* @param customerId
*/
private void batchProcessWaitPayOrder(Long customerId,Long storeId){
log.info("开始批量处理待支付订单");
LambdaQueryWrapper<OrderMainPO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(customerId!=null,OrderMainPO::getCustomerId, customerId)
.eq(storeId!=null,OrderMainPO::getStoreId, storeId)
.eq(OrderMainPO::getDelFlag, "0")
.in(OrderMainPO::getOrderStatus, Arrays.asList(OrderStatusEnum.WAIT_PAY.getCode(), OrderStatusEnum.RERENT_WAIT_PAY.getCode()))
.orderByDesc(OrderMainPO::getOrderId);
List<OrderMainPO> waitPayOrderList = orderMainRepo.list(queryWrapper);
if (!CollectionUtils.isEmpty(waitPayOrderList)){
waitPayOrderList.forEach(orderMainPO -> {
if(OrderStatusEnum.WAIT_PAY.getCode().equalsIgnoreCase(orderMainPO.getOrderStatus())){
PayOrderReq payOrderReq = new PayOrderReq();
payOrderReq.setOrderNo(orderMainPO.getOrderNo());
cancelOrder(payOrderReq);
}else if(OrderStatusEnum.RERENT_WAIT_PAY.getCode().equalsIgnoreCase(orderMainPO.getOrderStatus())){
//处理续租待支付订单
cancelRerentOrOverDueOrder(orderMainPO);
}
});
}
}
/**
* 支付成功更新订单状态
* @param orderMainPO
* @param orderSubPO
* @param orderSubList
* @return
*/
private String paySuccessOrder(OrderMainPO orderMainPO, OrderSubPO orderSubPO){
private String paySuccessOrder(OrderMainPO orderMainPO, List<OrderSubPO> orderSubList){
String orderStatus = null;
LambdaUpdateWrapper<OrderSubPO> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(OrderSubPO::getPayStatus, PayStatusEnum.SUCCESS.getCode());
updateWrapper.eq(OrderSubPO::getPaymentId, orderSubPO.getPaymentId());
updateWrapper.eq(OrderSubPO::getPaymentId, orderSubList.get(0).getPaymentId());
orderSubRepo.update(updateWrapper);
//租车订单
OrderSubPO rentSubPO = orderSubList.stream().filter(orderSubPO -> SubOrderTypeEnum.RENTCAR.getCode().equalsIgnoreCase(orderSubPO.getSuborderType())).findFirst().orElse( null);
LambdaUpdateWrapper<OrderMainPO> updateWrapper2 = new LambdaUpdateWrapper<>();
updateWrapper2.eq(OrderMainPO::getOrderId, orderMainPO.getOrderId());
if(OrderStatusEnum.WAIT_PAY.getCode().equalsIgnoreCase(orderMainPO.getOrderStatus())){
updateWrapper2.set(OrderMainPO::getOrderStatus, OrderStatusEnum.WAIT_PICK.getCode());
orderStatus = OrderStatusEnum.WAIT_PICK.getCode();
} else if(OrderStatusEnum.RERENT_WAIT_PAY.getCode().equalsIgnoreCase(orderMainPO.getOrderStatus())){
updateWrapper2.set(OrderMainPO::getOrderAmount, orderMainPO.getOrderAmount().add(orderSubPO.getAmount()));
updateWrapper2.set(OrderMainPO::getEndRentTime, orderSubPO.getReturnTime());
BigDecimal rentCarOrderAmount = orderSubList.stream().map(OrderSubPO::getAmount).reduce(BigDecimal.ZERO,BigDecimal::add);
updateWrapper2.set(OrderMainPO::getOrderAmount, orderMainPO.getOrderAmount().add(rentCarOrderAmount));
if(rentSubPO!=null){
updateWrapper2.set(rentSubPO.getReturnTime()!=null,OrderMainPO::getEndRentTime, rentSubPO.getReturnTime());
}
updateWrapper2.set(OrderMainPO::getOrderStatus, OrderStatusEnum.RENT_ING.getCode());
if(orderMainPO.getOverdueDays()>0){
updateWrapper2.set(OrderMainPO::getOverdueDays, 0);
@ -1094,7 +1239,7 @@ public class OrderServiceImpl implements OrderService {
orderStatus = OrderStatusEnum.RENT_ING.getCode();
}
//如果是续租订单,增加续租次数
if(SubOrderTypeEnum.RENTCAR.getCode().equalsIgnoreCase(orderSubPO.getSuborderType())){
if(rentSubPO!=null){
updateWrapper2.set(OrderMainPO::getRenewalTimes, orderMainPO.getRenewalTimes()+1);
}
orderMainRepo.update(updateWrapper2);
@ -1102,50 +1247,5 @@ public class OrderServiceImpl implements OrderService {
}
/**
* 获取租车订单金额
* @param rentalType
* @param rentalPrice
* @param rentalDays
* @return
*/
private static BigDecimal getRentCarAmount(String rentalType, BigDecimal rentalPrice, Integer rentalDays) {
BigDecimal rentCarOrderAmount = new BigDecimal(0);
if(RentCarTypeEnum.HOUR_RENTAL.getCode().equalsIgnoreCase(rentalType)||RentCarTypeEnum.DAILY_RENTAL.getCode().equalsIgnoreCase(rentalType)){
rentCarOrderAmount = rentCarOrderAmount.add(rentalPrice);
} else if(RentCarTypeEnum.DAYS_RENTAL.getCode().equalsIgnoreCase(rentalType)){
rentCarOrderAmount = rentalPrice.multiply(new BigDecimal(rentalDays));
} else {
rentCarOrderAmount = rentalPrice.multiply(new BigDecimal(30));
}
return rentCarOrderAmount;
}
/**
* 获取续租订单金额
* @param endRentTime
* @param rentalType
* @param rentalPrice
* @param ruleRentalDays
* @return
*/
private static BigDecimal getReRentCarAmount(LocalDateTime endRentTime,String rentalType, BigDecimal rentalPrice, Integer ruleRentalDays) {
//计算续租金额
BigDecimal rentCarOrderAmount = new BigDecimal(0);
if(RentCarTypeEnum.HOUR_RENTAL.getCode().equalsIgnoreCase(rentalType)){
Integer overdueHours = OrderUtil.getOrderOverdueHours(endRentTime);
rentCarOrderAmount = rentCarOrderAmount.add(rentalPrice.multiply(new BigDecimal(overdueHours+1)));
} else if(RentCarTypeEnum.DAILY_RENTAL.getCode().equalsIgnoreCase(rentalType)){
Integer rentalDays = OrderUtil.getOrderOverdueDays(endRentTime);
rentCarOrderAmount = rentCarOrderAmount.add(rentalPrice.multiply(new BigDecimal(rentalDays+1)));
} else if(RentCarTypeEnum.DAYS_RENTAL.getCode().equalsIgnoreCase(rentalType)){
Integer rentalDays = OrderUtil.getOrderOverdueDays(endRentTime);
rentCarOrderAmount = rentCarOrderAmount.add(rentalPrice.multiply(new BigDecimal(rentalDays+ruleRentalDays)));
} else {
Integer rentalDays = OrderUtil.getOrderOverdueDays(endRentTime);
rentCarOrderAmount = rentCarOrderAmount.add(rentalPrice.multiply(new BigDecimal(rentalDays+30)));
}
return rentCarOrderAmount;
}
}

View File

@ -36,7 +36,7 @@ public class NoPayOrderProcessTask {
private PayInteg payInteg;
/**
* 每30分钟检查一次逾期订单
* 每6分钟检查一次逾期订单
* 使用ShedLock确保在分布式环境下只有一个实例执行
* 分布式锁机制ShedLock使用Redis作为锁存储确保同一时间只有一个服务实例执行定时任务
* 任务名称:@SchedulerLock 注解中的 name 属性标识任务名称,相同名称的任务在分布式环境下互斥执行
@ -45,7 +45,7 @@ public class NoPayOrderProcessTask {
* lockAtLeastFor锁最少持有时间防止任务执行过快导致频繁执行
*/
@Transactional(rollbackFor = Exception.class)
@Scheduled(cron = "0 */15 * * * ?")
@Scheduled(cron = "0 */6 * * * ?")
@SchedulerLock(name = "checkNoPayOrders", lockAtMostFor = "9m", lockAtLeastFor = "1m")
public void checkNoPayOrders() {
log.info("开始执行未支付订单检查任务");
@ -66,7 +66,7 @@ public class NoPayOrderProcessTask {
LambdaQueryWrapper<OrderMainPO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(OrderMainPO::getDelFlag, "0").in(OrderMainPO::getOrderStatus,
Arrays.asList(OrderStatusEnum.WAIT_PAY.getCode(), OrderStatusEnum.RERENT_WAIT_PAY.getCode()))
.lt(OrderMainPO::getUpdateTime, LocalDateTime.now().minusHours(1));
.lt(OrderMainPO::getUpdateTime, LocalDateTime.now().minusMinutes(5));
List<OrderMainPO> orders = orderMainRepo.list(queryWrapper);
@ -122,8 +122,8 @@ public class NoPayOrderProcessTask {
if (closePayOrder) {
LambdaUpdateWrapper<OrderSubPO> updateSubWrapper = new LambdaUpdateWrapper<>();
updateSubWrapper.set(OrderSubPO::getDelFlag, "2");
updateSubWrapper.eq(OrderSubPO::getOrderId, orderMainPO.getOrderId());
updateSubWrapper.set(OrderSubPO::getDelFlag, "2").eq(OrderSubPO::getOrderId, orderMainPO.getOrderId())
.eq(OrderSubPO::getPayStatus, PayStatusEnum.USERPAYING.getCode());
orderSubRepo.update(updateSubWrapper);
if (StringUtils.equalsIgnoreCase(orderMainPO.getOrderStatus(), OrderStatusEnum.WAIT_PAY.getCode())) {

View File

@ -81,7 +81,7 @@ public class OrderOverdueTask {
.set(OrderMainPO::getOverdueDays, overdueDaysOrHours)
.eq(OrderMainPO::getOrderId, order.getOrderId())
// 确保状态未被其他节点修改
.eq(OrderMainPO::getOrderStatus, OrderStatusEnum.RENT_ING.getCode());
.in(OrderMainPO::getOrderStatus, Arrays.asList(OrderStatusEnum.RENT_ING.getCode(), OrderStatusEnum.RENT_OVERDUE.getCode()));
boolean updated = orderMainRepo.update(updateWrapper);

View File

@ -0,0 +1,14 @@
package com.sczx.order.thirdpart.dto;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@ApiModel("支付宝资金冻结响应参数")
@Data
public class AlipayFundFreezeResponse {
private boolean success;
private String message;
private String outTradeNo; // 商户订单号
private String orderStr; // 支付串(用于前端调起支付)
private String code; // 状态码
}

View File

@ -0,0 +1,14 @@
package com.sczx.order.thirdpart.dto;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@ApiModel("支付宝资金冻结响应参数")
@Data
public class AlipayQueryFreezeResponse {
private boolean success;
private String message;
private String outTradeNo; // 商户订单号
private String authNo; // 支付串(用于前端调起支付)
private String code; // 状态码
}

View File

@ -62,4 +62,7 @@ public class UnifiedPaymentInfoDTO {
@ApiModelProperty(value = "支付宝交易号")
private String tradeNo; // 支付宝交易号
@ApiModelProperty(value = "支付宝芝麻信用免押支付串(用于前端调起支付)")
private String orderStr;
}

View File

@ -0,0 +1,19 @@
package com.sczx.order.thirdpart.dto.req;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("支付宝资金冻结请求参数")
@Data
public class AlipayFinishFreezeRequest {
private String companyId;
@ApiModelProperty(value = "支付宝资金授权订单号")
private String authNo;
@ApiModelProperty(value = "解冻请求流水号")
private String outRequestNo;
@ApiModelProperty(value = "解冻金额")
private String amount;
}

View File

@ -0,0 +1,13 @@
package com.sczx.order.thirdpart.dto.req;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@ApiModel("支付宝资金冻结请求参数")
@Data
public class AlipayFundFreezeRequest {
private String companyId;
private String outOrderNo;
private String title;
private String amount;
}

View File

@ -0,0 +1,12 @@
package com.sczx.order.thirdpart.dto.req;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@ApiModel("支付宝资金冻结请求参数")
@Data
public class AlipayQueryFreezeRequest {
private String companyId;
private String outOrderNo;
private String operationType;
}

View File

@ -1,9 +1,6 @@
package com.sczx.order.thirdpart.facade;
import com.sczx.order.thirdpart.dto.AlipayCreateResponse;
import com.sczx.order.thirdpart.dto.AlipayQueryResponse;
import com.sczx.order.thirdpart.dto.AlipayResponse;
import com.sczx.order.thirdpart.dto.PaymentResponse;
import com.sczx.order.thirdpart.dto.*;
import com.sczx.order.thirdpart.dto.req.*;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
@ -86,4 +83,32 @@ public interface PayFacade {
*/
@PostMapping("/api/alipay/refundQuery")
AlipayResponse alipayRefundQuery(@RequestBody AlipayRefundRequest request);
/**
* 冻结接口
*/
@PostMapping("/api/authAlipay/fundFreeze")
AlipayFundFreezeResponse fundFreeze(@RequestBody AlipayFundFreezeRequest request);
/**
* 取消冻结
*/
@PostMapping("/api/authAlipay/cancelFundFreeze")
AlipayFundFreezeResponse cancelFundFreeze(@RequestBody AlipayFundFreezeRequest request);
/**
* 查询冻结
* @param alipayQueryFreezeRequest
* @return
*/
@PostMapping("/api/authAlipay/queryFundFreeze")
AlipayQueryFreezeResponse queryFundFreeze(@RequestBody AlipayQueryFreezeRequest alipayQueryFreezeRequest);
/**
* 完结冻结
* @param alipayFinishFreezeRequest
* @return
*/
@PostMapping("/api/authAlipay/finishFreeze")
AlipayResponse finishFreeze(@RequestBody AlipayFinishFreezeRequest alipayFinishFreezeRequest);
}

View File

@ -220,4 +220,69 @@ public class PayInteg {
throw new InnerException("支付宝查询退款失败");
}
}
/**
* 免押冻结
*/
public AlipayFundFreezeResponse fundFreeze(AlipayFundFreezeRequest request) {
try {
AlipayFundFreezeResponse result = payFacade.fundFreeze( request);
if(StringUtils.isNotBlank(result.getCode()) && "SUCCESS".equals(result.getCode())){
return result;
} else {
throw new InnerException("免押冻结失败");
}
} catch (Exception e){
log.error("免押冻结失败",e);
throw new InnerException("免押冻结失败");
}
}
/**
* 取消冻结
*/
public boolean cancelFundFreeze(AlipayFundFreezeRequest request) {
try {
AlipayFundFreezeResponse result = payFacade.cancelFundFreeze( request);
if(StringUtils.isNotBlank(result.getCode()) && "SUCCESS".equals(result.getCode())){
return true;
} else {
throw new InnerException("取消免押冻结失败");
}
} catch (Exception e){
log.error("取消免押冻结失败",e);
throw new InnerException("取消免押冻结失败");
}
}
public AlipayQueryFreezeResponse queryFundFreeze(AlipayQueryFreezeRequest alipayQueryFreezeRequest) {
try {
AlipayQueryFreezeResponse result = payFacade.queryFundFreeze( alipayQueryFreezeRequest);
if(StringUtils.isNotBlank(result.getCode()) && "SUCCESS".equals(result.getCode())){
return result;
} else {
throw new InnerException("查询免押冻结失败");
}
} catch (Exception e){
log.error("查询免押押冻结失败",e);
throw new InnerException("查询免押冻结失败");
}
}
public AlipayResponse finishFreeze(AlipayFinishFreezeRequest alipayFinishFreezeRequest) {
try {
AlipayResponse result = payFacade.finishFreeze(alipayFinishFreezeRequest);
if(StringUtils.isNotBlank(result.getCode()) && "SUCCESS".equals(result.getCode())){
return result;
} else {
throw new InnerException("完成免押冻结失败");
}
} catch (Exception e){
log.error("完成免押押冻结失败",e);
throw new InnerException("完成免押冻结失败");
}
}
}

View File

@ -1,6 +1,7 @@
package com.sczx.order.utils;
import com.sczx.order.common.enums.RentCarTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import java.math.BigDecimal;
@ -9,6 +10,7 @@ import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.UUID;
@Slf4j
public class OrderUtil {
public static final String ORDER_PREFIX = "OC";
@ -114,19 +116,64 @@ public class OrderUtil {
* @param rentalType 租期类型
* @return 预计还车时间
*/
public static LocalDateTime getEndRentTime(LocalDateTime origTime,Integer rentalDays, String rentalType) {
public static LocalDateTime getEndRentTime(LocalDateTime origTime,Integer rerentInterval,Integer rentalDays, String rentalType) {
LocalDateTime endRentTime = null;
//设置预计还车时间
if(StringUtils.equalsIgnoreCase(RentCarTypeEnum.HOUR_RENTAL.getCode(), rentalType)){
endRentTime = origTime.plusHours(1);
endRentTime = origTime.plusHours(rerentInterval);
}else if(StringUtils.equalsIgnoreCase(RentCarTypeEnum.DAILY_RENTAL.getCode(), rentalType)){
endRentTime = origTime.plusDays(1);
endRentTime = origTime.plusDays(rerentInterval);
} else if(StringUtils.equalsIgnoreCase(RentCarTypeEnum.DAYS_RENTAL.getCode(), rentalType)){
endRentTime = origTime.plusDays(rentalDays);
endRentTime = origTime.plusDays((long) rerentInterval * rentalDays);
} else if(StringUtils.equalsIgnoreCase(RentCarTypeEnum.RENT_INSTEAD_SELL.getCode(), rentalType)){
//以租代售默认期限为30天
endRentTime = origTime.plusDays(30);
endRentTime = origTime.plusDays(rerentInterval*30);
}
log.info("query endRentTime : {}", endRentTime);
return endRentTime;
}
/**
* 获取租车订单金额
* @param rentalType
* @param rentalPrice
* @param rentalDays
* @return
*/
public static BigDecimal getRentCarAmount(String rentalType, BigDecimal rentalPrice, Integer rentalDays) {
// BigDecimal rentCarOrderAmount = new BigDecimal(0);
// if(RentCarTypeEnum.HOUR_RENTAL.getCode().equalsIgnoreCase(rentalType)||RentCarTypeEnum.DAILY_RENTAL.getCode().equalsIgnoreCase(rentalType)){
// rentCarOrderAmount = rentCarOrderAmount.add(rentalPrice);
// } else if(RentCarTypeEnum.DAYS_RENTAL.getCode().equalsIgnoreCase(rentalType)){
// rentCarOrderAmount = rentalPrice.multiply(new BigDecimal(rentalDays));
// } else {
// rentCarOrderAmount = rentalPrice.multiply(new BigDecimal(30));
// }
return rentalPrice;
}
/**
* 获取续租订单金额
* @param rerentInterval 续租周期
* @param rentalPrice
* @return
*/
public static BigDecimal getReRentCarAmount(int rerentInterval,BigDecimal rentalPrice) {
//计算续租金额
return rentalPrice.multiply(new BigDecimal(rerentInterval));
}
/**
* 计算续租轮数以覆盖逾期天数
* @param overdueDays 逾期天数
* @param rentalDays 每轮续租天数
* @return 需要的续租轮数
*/
public static int calculateRerentRoundsToCoverOverdue(Integer overdueDays, Integer rentalDays) {
overdueDays = overdueDays == null|| overdueDays == 0 ? 1 : overdueDays;
rentalDays = rentalDays == null|| rentalDays == 0 ? 1 : overdueDays;
// 使用向上取整计算需要的续租轮数
return (int) Math.ceil((double) overdueDays / rentalDays);
}
}

View File

@ -22,16 +22,16 @@
<pattern>${PATTERN}</pattern>
</layout>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>DENY</onMatch>
<onMismatch>NEUTRAL</onMismatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>NEUTRAL</onMismatch>
</filter>
<!-- <filter class="ch.qos.logback.classic.filter.LevelFilter">-->
<!-- <level>WARN</level>-->
<!-- <onMatch>DENY</onMatch>-->
<!-- <onMismatch>NEUTRAL</onMismatch>-->
<!-- </filter>-->
<!-- <filter class="ch.qos.logback.classic.filter.LevelFilter">-->
<!-- <level>ERROR</level>-->
<!-- <onMatch>DENY</onMatch>-->
<!-- <onMismatch>NEUTRAL</onMismatch>-->
<!-- </filter>-->
</appender>
<appender name="WARN_FILE_APPENDER" class="ch.qos.logback.core.FileAppender">
@ -45,6 +45,18 @@
</encoder>
</appender>
<!-- 针对 MyBatis SQL 日志 -->
<logger name="org.apache.ibatis" level="DEBUG" additivity="false">
<appender-ref ref="INFO_FILE_APPENDER"/>
<appender-ref ref="STDOUT"/>
</logger>
<!-- 针对 JDBC SQL 日志 -->
<logger name="java.sql" level="DEBUG" additivity="false">
<appender-ref ref="INFO_FILE_APPENDER"/>
<appender-ref ref="STDOUT"/>
</logger>
<root level="info">
<appender-ref ref="INFO_FILE_APPENDER"/>
<appender-ref ref="WARN_FILE_APPENDER"/>

View File

@ -82,6 +82,7 @@
<where>
zos.del_flag = '0'
and zos.suborder_type = 'RENTBATTEY'
and zom.del_flag = '0'
<if test="customerId != null">
and zom.customer_id = #{customerId}