fix(cloud): 优化预约单过期处理和微信支付回调逻辑
- 添加费标准详情字段并实现相关查询逻辑 - 优化预约单过期处理逻辑,增加缓冲期和精确的时间判断 - 完善微信支付回调处理,增加参数校验和幂等性检查 - 添加支付成功通知功能
This commit is contained in:
parent
a0fef83bf3
commit
90b805d0f4
@ -1,6 +1,7 @@
|
||||
package com.evotech.hd.common.core.entity.cloud;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.evotech.hd.common.core.entity.BaseEntity;
|
||||
@ -96,6 +97,9 @@ public class OrderSwapBattery extends BaseEntity implements Serializable {
|
||||
|
||||
@Schema(description = "费用标准")
|
||||
private String feeStandardJson;
|
||||
@Schema(description = "费用标准详情")
|
||||
@TableField(exist = false)
|
||||
private BatteryStationHdFeeStandard feeStandardDetail;
|
||||
|
||||
@Schema(description = "上次租赁电池时车辆里程")
|
||||
private BigDecimal lastRentBatCarOdo;
|
||||
|
||||
@ -53,6 +53,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
|
||||
@ -87,6 +89,8 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
|
||||
private BatteryStationDao batteryStationDao;
|
||||
@Resource
|
||||
private GZHTemplateMessageService gzhTemplateMessageService;
|
||||
@Resource
|
||||
private BatteryStationHdFeeStandardDao batteryStationHdFeeStandardDao;
|
||||
|
||||
|
||||
@Override
|
||||
@ -247,8 +251,17 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
|
||||
if (page.getRecords().isEmpty()) {
|
||||
return new Result<List<OrderSwapBattery>>().error(CodeMsg.DATABASE_RESULT_NULL);
|
||||
}
|
||||
return new Result<List<OrderSwapBattery>>().success(page);
|
||||
}
|
||||
page.getRecords().forEach(osb -> {
|
||||
if (StringUtils.hasText(osb.getFeeStandardJson())){
|
||||
String feeStandardJson = osb.getFeeStandardJson();
|
||||
BatteryStationHdFeeStandard bean = JSONUtil.toBean(feeStandardJson, BatteryStationHdFeeStandard.class);
|
||||
osb.setFeeStandardDetail(bean);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return new Result<List<OrderSwapBattery>>().success(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<OrderSwapBattery>> listByCompany(PageListSwapOrderRequest plsor) {
|
||||
|
||||
@ -86,28 +86,59 @@ public class TradeServiceImpl implements TradeService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<String> wechatPayNotifyHandle(TradeDetail tradeDetail) {
|
||||
// 1. 添加交易
|
||||
boolean b = tradeDetailDao.exists(new QueryWrapper<TradeDetail>()
|
||||
.eq("out_trade_no", tradeDetail.getOutTradeNo())
|
||||
.eq("transaction_id", tradeDetail.getTransactionId())
|
||||
.eq("pay_result", tradeDetail.getPayResult()));
|
||||
if (b) {
|
||||
log.info("\r\n===>>>已处理过此回调:" + tradeDetail);
|
||||
return new Result<String>().error("重复消息!");
|
||||
try {
|
||||
// 1. 参数校验
|
||||
if (tradeDetail == null || !StringUtils.hasText(tradeDetail.getOutTradeNo())) {
|
||||
log.error("微信支付回调参数异常: {}", JSONUtil.toJsonStr(tradeDetail));
|
||||
return new Result<String>().error("参数异常");
|
||||
}
|
||||
|
||||
// 2. 幂等性检查
|
||||
boolean isProcessed = tradeDetailDao.exists(new QueryWrapper<TradeDetail>()
|
||||
.eq("out_trade_no", tradeDetail.getOutTradeNo())
|
||||
.eq("transaction_id", tradeDetail.getTransactionId())
|
||||
.eq("pay_result", tradeDetail.getPayResult()));
|
||||
|
||||
if (isProcessed) {
|
||||
log.info("重复的微信支付回调, outTradeNo: {}", tradeDetail.getOutTradeNo());
|
||||
return new Result<String>().error("重复消息");
|
||||
}
|
||||
|
||||
// 3. 记录交易
|
||||
log.info("开始处理微信支付回调, outTradeNo: {}, 交易信息: {}",
|
||||
tradeDetail.getOutTradeNo(),
|
||||
JSONUtil.toJsonStr(tradeDetail));
|
||||
|
||||
add(tradeDetail);
|
||||
|
||||
// 4. 业务处理
|
||||
payNotifyHandleService.payNotifyBussinessHandle(tradeDetail);
|
||||
|
||||
// 5. 发送支付成功通知
|
||||
if (StringUtils.hasText(tradeDetail.getOrderNo())) {
|
||||
OrderSwapBattery order = orderSwapBatteryDao.selectOne(
|
||||
new LambdaQueryWrapper<OrderSwapBattery>()
|
||||
.eq(OrderSwapBattery::getOrderNo, tradeDetail.getOrderNo())
|
||||
);
|
||||
|
||||
if (order != null) {
|
||||
gzhTemplateMessageService.orderMessageSend2(order.getPkId(), 3);
|
||||
log.info("支付成功通知已发送, orderNo: {}", tradeDetail.getOrderNo());
|
||||
} else {
|
||||
log.warn("未找到对应的订单, orderNo: {}", tradeDetail.getOrderNo());
|
||||
}
|
||||
}
|
||||
|
||||
return new Result<String>().success("OK");
|
||||
} catch (Exception e) {
|
||||
log.error("处理微信支付回调异常, outTradeNo: {}, 异常信息: {}",
|
||||
tradeDetail.getOutTradeNo(),
|
||||
e.getMessage(),
|
||||
e);
|
||||
throw new RuntimeException("处理支付回调失败", e);
|
||||
}
|
||||
|
||||
// 添加交易
|
||||
log.info("请求时间{} 是否存在交易{} 添加交易>>>>>{}" ,new Date() ,b, JSONUtil.toJsonStr(tradeDetail));
|
||||
add(tradeDetail);
|
||||
// 2. 业务类型处理
|
||||
payNotifyHandleService.payNotifyBussinessHandle(tradeDetail);
|
||||
|
||||
return new Result<String>().success("OK");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package com.evotech.hd.cloud.task;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryPreDao;
|
||||
import com.evotech.hd.cloud.service.OrderSwapBatteryService;
|
||||
@ -16,6 +17,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
@ -32,37 +34,62 @@ public class OrderSwapBatteryTask {
|
||||
@Resource
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
@Scheduled(cron = "0 0 * * * ?") // 每小时执行一次
|
||||
// @Scheduled(cron = "0 0 * * * ?") // 每小时执行一次
|
||||
@Scheduled(cron = "0 */2 * * * ?")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void orderSwapBatteryExpired() {
|
||||
log.info("\r\n===>>> 开始查找预约单更新预约状态..");
|
||||
|
||||
// 查询条件,排除已过期和无效状态
|
||||
QueryWrapper<OrderSwapBatteryPre> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper
|
||||
.ne("status", 4)//无效
|
||||
.ne("status", 3) //过期
|
||||
.ne("status", 2); //过期
|
||||
|
||||
// 查询条件,只查询未处理的预约单
|
||||
LambdaQueryWrapper<OrderSwapBatteryPre> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq( OrderSwapBatteryPre::getStatus,1)
|
||||
.le( OrderSwapBatteryPre::getReservationTime, new Date())
|
||||
.select(OrderSwapBatteryPre::getPkId,
|
||||
OrderSwapBatteryPre::getSourceId,
|
||||
OrderSwapBatteryPre::getReservationTime,
|
||||
OrderSwapBatteryPre::getSwapDuration,
|
||||
OrderSwapBatteryPre::getStatus)
|
||||
.orderByDesc(OrderSwapBatteryPre::getReservationTime)
|
||||
.last("limit 1000");
|
||||
List<OrderSwapBatteryPre> orderSwapBatteryPreList = orderSwapBatteryPreDao.selectList(queryWrapper);
|
||||
|
||||
// 获取当前时间
|
||||
Date currentTime = new Date();
|
||||
int expiredCount = 0; // 记录过期的预约单数量
|
||||
int expiredCount = 0;
|
||||
|
||||
for (OrderSwapBatteryPre order : orderSwapBatteryPreList) {
|
||||
// 检查预约时间是否已过期
|
||||
if (order.getReservationTime() != null && order.getReservationTime().before(currentTime)) {
|
||||
// 更新状态为过期
|
||||
order.setStatus(4); // 设置为过期状态
|
||||
try {
|
||||
orderSwapBatteryPreDao.updateById(order);
|
||||
//发送公众号过期提醒
|
||||
//templateMessageService.orderMessageSend(order, 4);
|
||||
expiredCount++;
|
||||
log.info("预约单已过期,订单ID: {}", order.getSourceId()); // 记录过期的订单ID
|
||||
} catch (Exception e) {
|
||||
log.error("更新预约单状态失败,预约人:{},订单ID: {}, 错误信息: {}", order.getUname(), order.getPkId(), e.getMessage());
|
||||
try {
|
||||
// 1. 解析预约时间段
|
||||
String[] timeRange = order.getSwapDuration().split("-");
|
||||
if (timeRange.length != 2) {
|
||||
log.error("预约时间段格式错误,订单ID: {}", order.getPkId());
|
||||
continue;
|
||||
}
|
||||
|
||||
// 2. 计算预约结束时间
|
||||
Date reservationDate = order.getReservationTime();
|
||||
String endTimeStr = timeRange[1].trim();
|
||||
Date endTime = DateUtil.parse(DateUtil.format(reservationDate, "yyyy-MM-dd") + " " + endTimeStr,
|
||||
"yyyy-MM-dd HH:mm");
|
||||
|
||||
// 3. 添加30分钟缓冲期
|
||||
Date expireTime = DateUtil.offsetMinute(endTime, 30);
|
||||
|
||||
// 4. 判断是否过期
|
||||
if (currentTime.after(expireTime)) {
|
||||
order.setStatus(4); // 设置为过期状态
|
||||
orderSwapBatteryPreDao.updateById(order);
|
||||
|
||||
// 发送公众号过期提醒
|
||||
// templateMessageService.preOrderMessageSend(order);
|
||||
|
||||
expiredCount++;
|
||||
log.info("预约单已过期,订单ID: {}, 预约时间: {}, 过期时间: {}",
|
||||
order.getSourceId(),
|
||||
DateUtil.format(order.getReservationTime(), "yyyy-MM-dd HH:mm:ss"),
|
||||
DateUtil.format(expireTime, "yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("处理预约单过期失败,预约人:{},订单ID: {}, 错误信息: {}",
|
||||
order.getUname(), order.getPkId(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -124,4 +124,4 @@ hbyt:
|
||||
order_to_pay_template_id: IE0_RGuN5ufU4GFrCgM9JeUfvlWfbneEuUMDsn0RBQs
|
||||
order_end_template_id: C5-AGh67aFXChQONqSwxaRrJgFrn_Z25VTlTk0jHSUY
|
||||
wallet_recharge_template_id: 8JXsn_VkI0S0YZSbT2EKmV_zOxyudo4IsBLeU7V-SFk
|
||||
|
||||
order_to_pay_template_id2: K6cdaBOkxGJpah0vsz5rq5UBID04mk-eEWp2XM0KyA0
|
||||
Loading…
Reference in New Issue
Block a user