feat(ticket): 接单时同步商城订单发货状态

- 在接单方法上添加事务注解确保操作原子性
- 优化时间获取逻辑避免重复调用当前时间
- 新增updateShopOrderDeliveryStatusAfterAccept方法处理发货状态同步
- 查询关联水票订单并更新对应商城订单的配送状态为20(已发货)
- 添加幂等性检查避免重复更新并记录异常情况日志
- 引入ShopOrder和ShopOrderService依赖支持订单状态更新
This commit is contained in:
2026-02-10 11:29:00 +08:00
parent 011c9e458a
commit 4481850809

View File

@@ -1,6 +1,8 @@
package com.gxwebsoft.glt.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.common.core.exception.BusinessException;
import com.gxwebsoft.common.core.web.PageParam;
@@ -18,8 +20,10 @@ import com.gxwebsoft.glt.service.GltUserTicketLogService;
import com.gxwebsoft.glt.service.GltUserTicketService;
import com.gxwebsoft.shop.entity.ShopDealerCapital;
import com.gxwebsoft.shop.entity.ShopDealerUser;
import com.gxwebsoft.shop.entity.ShopOrder;
import com.gxwebsoft.shop.service.ShopDealerCapitalService;
import com.gxwebsoft.shop.service.ShopDealerUserService;
import com.gxwebsoft.shop.service.ShopOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.stereotype.Service;
@@ -70,6 +74,9 @@ public class GltTicketOrderServiceImpl extends ServiceImpl<GltTicketOrderMapper,
@Resource
private UserMapper userMapper;
@Resource
private ShopOrderService shopOrderService;
@Override
public PageResult<GltTicketOrder> pageRel(GltTicketOrderParam param) {
PageParam<GltTicketOrder, GltTicketOrderParam> page = new PageParam<>(param);
@@ -192,6 +199,7 @@ public class GltTicketOrderServiceImpl extends ServiceImpl<GltTicketOrderMapper,
}
@Override
@Transactional(rollbackFor = Exception.class)
public void accept(Integer id, Integer riderId, Integer tenantId) {
if (id == null) {
throw new BusinessException("订单id不能为空");
@@ -204,9 +212,10 @@ public class GltTicketOrderServiceImpl extends ServiceImpl<GltTicketOrderMapper,
}
// 原子接单:避免并发抢单
LocalDateTime now = LocalDateTime.now();
boolean ok = this.lambdaUpdate()
.set(GltTicketOrder::getRiderId, riderId)
.set(GltTicketOrder::getUpdateTime, LocalDateTime.now())
.set(GltTicketOrder::getUpdateTime, now)
.eq(GltTicketOrder::getId, id)
.eq(GltTicketOrder::getTenantId, tenantId)
.eq(GltTicketOrder::getDeleted, 0)
@@ -215,6 +224,8 @@ public class GltTicketOrderServiceImpl extends ServiceImpl<GltTicketOrderMapper,
.and(w -> w.isNull(GltTicketOrder::getRiderId).or().eq(GltTicketOrder::getRiderId, 0))
.update();
if (ok) {
// 接单成功后同步商城订单发货状态10未发货 -> 20已发货
updateShopOrderDeliveryStatusAfterAccept(id, tenantId, now);
return;
}
@@ -233,6 +244,73 @@ public class GltTicketOrderServiceImpl extends ServiceImpl<GltTicketOrderMapper,
throw new BusinessException("订单状态不允许接单");
}
private void updateShopOrderDeliveryStatusAfterAccept(Integer ticketOrderId, Integer tenantId, LocalDateTime now) {
if (ticketOrderId == null || tenantId == null) {
return;
}
// 找到关联水票的商城订单glt_user_ticket.orderId / orderNo
GltTicketOrder ticketOrder = this.lambdaQuery()
.select(GltTicketOrder::getId, GltTicketOrder::getUserTicketId)
.eq(GltTicketOrder::getId, ticketOrderId)
.eq(GltTicketOrder::getTenantId, tenantId)
.eq(GltTicketOrder::getDeleted, 0)
.last("limit 1")
.one();
if (ticketOrder == null || ticketOrder.getUserTicketId() == null) {
return;
}
GltUserTicket userTicket = gltUserTicketService.getOne(
new LambdaQueryWrapper<GltUserTicket>()
.eq(GltUserTicket::getTenantId, tenantId)
.eq(GltUserTicket::getDeleted, 0)
.eq(GltUserTicket::getId, ticketOrder.getUserTicketId())
.last("limit 1")
);
if (userTicket == null) {
return;
}
Integer shopOrderId = userTicket.getOrderId();
String shopOrderNo = userTicket.getOrderNo();
if (shopOrderId == null && !StringUtils.hasText(shopOrderNo)) {
return;
}
LambdaUpdateWrapper<ShopOrder> uw = new LambdaUpdateWrapper<ShopOrder>()
.eq(ShopOrder::getTenantId, tenantId)
.eq(ShopOrder::getDeleted, 0)
.and(w -> w.ne(ShopOrder::getDeliveryStatus, 20).or().isNull(ShopOrder::getDeliveryStatus))
.set(ShopOrder::getDeliveryStatus, 20)
.set(ShopOrder::getUpdateTime, now);
if (shopOrderId != null) {
uw.eq(ShopOrder::getOrderId, shopOrderId);
} else {
uw.eq(ShopOrder::getOrderNo, shopOrderNo);
}
boolean updated = shopOrderService.update(uw);
if (updated) {
return;
}
// 幂等:若已是 20则视为成功否则记录日志便于排查关联关系/数据缺失
LambdaQueryWrapper<ShopOrder> qw = new LambdaQueryWrapper<ShopOrder>()
.eq(ShopOrder::getTenantId, tenantId)
.eq(ShopOrder::getDeleted, 0)
.eq(ShopOrder::getDeliveryStatus, 20);
if (shopOrderId != null) {
qw.eq(ShopOrder::getOrderId, shopOrderId);
} else {
qw.eq(ShopOrder::getOrderNo, shopOrderNo);
}
if (shopOrderService.count(qw) <= 0) {
log.warn("接单成功但同步商城订单发货状态失败 - tenantId={}, ticketOrderId={}, shopOrderId={}, shopOrderNo={}",
tenantId, ticketOrderId, shopOrderId, shopOrderNo);
}
}
@Override
public void start(Integer id, Integer riderId, Integer tenantId) {
if (id == null) {