diff --git a/src/main/java/com/sczx/order/dto/RejectOrderReq.java b/src/main/java/com/sczx/order/dto/RejectOrderReq.java index 9748391..6453d35 100644 --- a/src/main/java/com/sczx/order/dto/RejectOrderReq.java +++ b/src/main/java/com/sczx/order/dto/RejectOrderReq.java @@ -2,10 +2,11 @@ package com.sczx.order.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; - +@AllArgsConstructor @Builder @ApiModel(value = "驳回订单请求") @Data diff --git a/src/main/java/com/sczx/order/service/impl/OrderServiceImpl.java b/src/main/java/com/sczx/order/service/impl/OrderServiceImpl.java index cd61e36..aab859c 100644 --- a/src/main/java/com/sczx/order/service/impl/OrderServiceImpl.java +++ b/src/main/java/com/sczx/order/service/impl/OrderServiceImpl.java @@ -100,10 +100,21 @@ public class OrderServiceImpl implements OrderService { .notIn(OrderMainPO::getOrderStatus, Arrays.asList(OrderStatusEnum.AUTO_END.getCode(), OrderStatusEnum.MANUAL_END.getCode())) .eq(OrderMainPO::getDelFlag, "0"); List currentOrderList = orderMainRepo.list(currentOrderWrapper); - if(currentOrderList.size()>0){ + if(!currentOrderList.isEmpty()){ throw new BizException("您有未完成的订单,请先完成订单"); } + //判断是否存有空闲车辆可用 + LambdaQueryWrapper carWrapper = new LambdaQueryWrapper<>(); + carWrapper.eq(CarPO::getModelId, rentCarOrderReq.getCarModelId()) + .eq(CarPO::getDelFlag, "0") + .eq(CarPO::getBrsStatus, "0") + .eq(CarPO::getStoreId, rentCarOrderReq.getStoreId()); + List carPOList = carRepo.list(carWrapper); + if(CollectionUtils.isEmpty(carPOList)){ + throw new BizException("门店没有该车型的车辆可租"); + } + //获取门店信息 CompanyStoreDTO companyStoreDTO = storeInteg.getStoreById(Integer.valueOf(rentCarOrderReq.getStoreId().toString())); @@ -191,23 +202,6 @@ public class OrderServiceImpl implements OrderService { UnifiedPaymentInfoDTO unifiedPaymentInfoDTO = payService.prepayOrder(paymentType,rentCarRuleDTO.getRuleName(),Long.valueOf(companyStoreDTO.getOperatingCompanyId()),paymentId,userInfoDTO ,orderMainPO.getOrderAmount()); -// UnifiedPaymentInfoDTO unifiedPaymentInfoDTO = new UnifiedPaymentInfoDTO(); -// -// //发起支付 -// if(StringUtils.equalsIgnoreCase(userInfoDTO.getMiniProgramType(), MiniProgramTypeEnum.WECHAT.getType())){ -// PaymentRequest paymentRequest = new PaymentRequest(); -// paymentRequest.setCompanyId(Long.valueOf(companyStoreDTO.getOperatingCompanyId())); -// paymentRequest.setOutTradeNo(paymentId); -// paymentRequest.setOpenId(userInfoDTO.getWechatOpenid()); -// paymentRequest.setAttach(companyStoreDTO.getOperatingCompanyId().toString()); -// paymentRequest.setSpbillCreateIp("127.0.0.1"); -// paymentRequest.setBody(rentCarRuleDTO.getRuleName()); -//// paymentRequest.setTotalFee(orderMainPO.getOrderAmount().multiply(new BigDecimal(100)).intValue()); -// paymentRequest.setTotalFee(10); -// unifiedPaymentInfoDTO = payInteg.unifiedOrder(paymentRequest); -// // TODO 其他支付类型 -// } - for(OrderSubPO orderSubPO : orderSubPOList){ orderSubPO.setPaymentId(paymentId); orderSubPO.setPayStatus(PayStatusEnum.USERPAYING.getCode()); @@ -311,9 +305,6 @@ public class OrderServiceImpl implements OrderService { //更新订单状态及信息 LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); -// updateWrapper.set(OrderMainPO::getRenewalTimes, orderMainPO.getRenewalTimes()+1); -// updateWrapper.set(OrderMainPO::getEndRentTime, newEndRentTime); -// updateWrapper.set(OrderMainPO::getOrderAmount, orderMainPO.getOrderAmount().add(rentCarOrderAmount)); updateWrapper.set(OrderMainPO::getOrderStatus, OrderStatusEnum.RERENT_WAIT_PAY.getCode()); updateWrapper.eq(OrderMainPO::getOrderNo, rentCarOrderReq.getOrderNo()); orderMainRepo.update(updateWrapper); @@ -357,24 +348,17 @@ public class OrderServiceImpl implements OrderService { SimpleUserInfoDTO userInfoDTO = jwtUtil.getUserInfoFromToken(); OrderSubPO orderSubPO = orderSubPOList.get(0); + if(StringUtils.equalsIgnoreCase(orderSubPO.getPaymentMethod(), PaymentTypeEnum.WX_PAY.getCode()) && !StringUtils.equalsIgnoreCase(userInfoDTO.getMiniProgramType(), MiniProgramTypeEnum.WECHAT.getType())){ + throw new InnerException("请使用微信小程序支付"); + } + + if(StringUtils.equalsIgnoreCase(orderSubPO.getPaymentMethod(), PaymentTypeEnum.ZFB_PAY.getCode()) && !StringUtils.equalsIgnoreCase(userInfoDTO.getMiniProgramType(), MiniProgramTypeEnum.ALIPAY.getType())){ + throw new InnerException("请使用支付宝小程序支付"); + } + RentCarRuleDTO rentCarRuleDTO = carInteg.getRentCarRuleByCarRuleId(orderMainPO.getRentCarRuleId()); BigDecimal orderAmount = orderSubPOList.stream().map(OrderSubPO::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add); - // 起支付返回预支付信息 - // //发起支付 -// if(StringUtils.equalsIgnoreCase(orderSubPO.getPaymentMethod(), PaymentTypeEnum.WX_PAY.getCode())){ -// PaymentRequest paymentRequest = new PaymentRequest(); -// paymentRequest.setCompanyId(Long.valueOf(companyStoreDTO.getOperatingCompanyId())); -// paymentRequest.setOutTradeNo(orderSubPO.getPaymentId()); -// paymentRequest.setOpenId(userInfoDTO.getWechatOpenid()); -// paymentRequest.setAttach(companyStoreDTO.getOperatingCompanyId().toString()); -// paymentRequest.setSpbillCreateIp("127.0.0.1"); -// paymentRequest.setBody(rentCarRuleDTO.getRuleName()); -//// BigDecimal orderAmount = orderSubPOList.stream().map(OrderSubPO::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add); -//// paymentRequest.setTotalFee(orderAmount.multiply(new BigDecimal(100)).intValue()); -// paymentRequest.setTotalFee(10); -// unifiedPaymentInfoDTO = payInteg.unifiedOrder(paymentRequest); -// // TODO 其他支付类型 -// } + return payService.prepayOrder(orderSubPO.getPaymentMethod(),rentCarRuleDTO.getRuleName(),orderMainPO.getOperatorId(),orderSubPO.getPaymentId(),userInfoDTO ,orderAmount); } @@ -492,13 +476,6 @@ public class OrderServiceImpl implements OrderService { LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); //将订单状态改为续租待或逾期待支付状态 updateWrapper.set(OrderMainPO::getOrderStatus, OrderStatusEnum.RERENT_WAIT_PAY.getCode()); -// updateWrapper.set(OrderMainPO::getOrderAmount, orderMainPO.getOrderAmount().add(overDueAmount)); -// updateWrapper.set(OrderMainPO::getEndRentTime, orderMainPO.getEndRentTime().plusHours(overDueDaysOrHours)); -// if(StringUtils.equalsIgnoreCase(RentCarTypeEnum.HOUR_RENTAL.getCode(), orderMainPO.getRentalType())){ -// updateWrapper.set(OrderMainPO::getEndRentTime, orderMainPO.getEndRentTime().plusHours(overDueDaysOrHours)); -// }else { -// updateWrapper.set(OrderMainPO::getEndRentTime, orderMainPO.getEndRentTime().plusDays(overDueDaysOrHours)); -// } updateWrapper.eq(OrderMainPO::getOrderNo, rentCarOrderReq.getOrderNo()); orderMainRepo.update(updateWrapper); @@ -607,7 +584,7 @@ public class OrderServiceImpl implements OrderService { } LambdaQueryWrapper querySubWrapper2 = new LambdaQueryWrapper<>(); querySubWrapper2.eq(OrderSubPO::getOrderId, orderMainPO.getOrderId()) - .eq(OrderSubPO::getPayStatus, PayStatusEnum.SUCCESS.getCode()).orderByDesc(OrderSubPO::getUpdateTime); + .in(OrderSubPO::getPayStatus, Arrays.asList(PayStatusEnum.SUCCESS.getCode(), PayStatusEnum.REFUNDING.getCode(), PayStatusEnum.REFUND_SUCCESS.getCode())).orderByDesc(OrderSubPO::getUpdateTime); List orderSubPOList2 = orderSubRepo.list(querySubWrapper2); if(!CollectionUtils.isEmpty(orderSubPOList2)){ orderDetailDTO.setLastPayOrderNo(orderSubPOList2.get(0).getPaymentId()); @@ -1106,6 +1083,10 @@ public class OrderServiceImpl implements OrderService { } orderStatus = OrderStatusEnum.RENT_ING.getCode(); } + //如果是续租订单,增加续租次数 + if(SubOrderTypeEnum.RENTCAR.getCode().equalsIgnoreCase(orderSubPO.getSuborderType())){ + updateWrapper2.set(OrderMainPO::getRenewalTimes, orderMainPO.getRenewalTimes()+1); + } orderMainRepo.update(updateWrapper2); return orderStatus; } diff --git a/src/main/java/com/sczx/order/task/NoPickCarProcessTask.java b/src/main/java/com/sczx/order/task/NoPickCarProcessTask.java new file mode 100644 index 0000000..58cf540 --- /dev/null +++ b/src/main/java/com/sczx/order/task/NoPickCarProcessTask.java @@ -0,0 +1,98 @@ +package com.sczx.order.task; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.sczx.order.common.enums.OrderStatusEnum; +import com.sczx.order.dto.RejectOrderReq; +import com.sczx.order.po.OrderMainPO; +import com.sczx.order.repository.OrderMainRepo; +import com.sczx.order.service.OrderService; +import lombok.extern.slf4j.Slf4j; +import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; + +/** + * 当前未提车订单处理任务 + */ +@Slf4j +@Component +public class NoPickCarProcessTask { + @Autowired + private OrderMainRepo orderMainRepo; + + private OrderService orderService; + + /** + * 每30分钟检查一次逾期订单 + * 使用ShedLock确保在分布式环境下只有一个实例执行 + * 分布式锁机制:ShedLock使用Redis作为锁存储,确保同一时间只有一个服务实例执行定时任务 + * 任务名称:@SchedulerLock 注解中的 name 属性标识任务名称,相同名称的任务在分布式环境下互斥执行 + * 锁时长配置: + * lockAtMostFor:锁最多持有时间,防止节点宕机导致锁无法释放 + * lockAtLeastFor:锁最少持有时间,防止任务执行过快导致频繁执行 + */ + @Transactional(rollbackFor = Exception.class) + @Scheduled(cron = "0 5 0 * * ?")//0点过5分执行 + @SchedulerLock(name = "checkNoPickCarOrders", lockAtMostFor = "9m", lockAtLeastFor = "1m") + public void checkNoPickCarOrders() { + log.info("开始执行当天未提车订单检查任务"); + try { + processNoPickCarOrders(); + log.info("当天未提车订单检查任务执行完成"); + } catch (Exception e) { + log.error("当天未提车订单检查任务失败", e); + } + } + + /** + * 处理当天未提车订单 + */ + private void processNoPickCarOrders() { + try { + // 查询所有进行中的订单且当前时间已超过预计还车时间 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(OrderMainPO::getDelFlag, "0").in(OrderMainPO::getOrderStatus, + Collections.singletonList(OrderStatusEnum.WAIT_PICK.getCode())) + .lt(OrderMainPO::getUpdateTime, LocalDateTime.now()); + + List orders = orderMainRepo.list(queryWrapper); + + if (orders.isEmpty()) { + log.info("无当天未提车订单"); + return; + } + + log.info("发现{}个当天未提车订单,开始处理", orders.size()); + + int successCount = 0; + for (OrderMainPO order : orders) { + try { + processWayPay(order); + } catch (Exception e) { + log.error("更新订单{}状态失败", order.getOrderNo(), e); + } + } + + log.info("当天未提车订单处理完成,成功处理{}个订单", successCount); + } catch (Exception e) { + log.error("处理当天未提车订单失败", e); + throw e; + } + } + + /** + * 处理当天未提车订单 + * + * @param orderMainPO + */ + private void processWayPay(OrderMainPO orderMainPO) { + RejectOrderReq rejectOrderReq = new RejectOrderReq(orderMainPO.getOrderNo(), "当天未提车取消"); + orderService.rejectRentOrder(rejectOrderReq); + } +}