feat(ticket): 添加订单状态字段并完善水票订单关联逻辑

- 在GltTicketOrder实体中添加orderStatus字段用于存储订单状态
- 更新GltTicketOrderMapper.xml查询语句以包含orderStatus字段
- 在GltTicketOrderParam参数类中添加orderStatus查询条件支持
- 实现resolveShopOrderNo方法用于关联商城订单号的获取逻辑
- 添加测试方法testOrderData用于处理已退款订单相关的水票撤销操作
- 增加findTicketsByOrder和findTicketsByOrderGoodsFallback辅助方法
- 完善水票订单与商城订单的关联关系处理机制
This commit is contained in:
2026-03-01 21:12:14 +08:00
parent 1c1c341bb9
commit f7334021e0
5 changed files with 184 additions and 1 deletions

View File

@@ -34,6 +34,10 @@ public class GltTicketOrder implements Serializable {
@Schema(description = "订单编号") @Schema(description = "订单编号")
private String orderNo; private String orderNo;
@Schema(description = "订单状态")
@TableField(exist = false)
private Integer orderStatus;
@Schema(description = "门店ID") @Schema(description = "门店ID")
private Integer storeId; private Integer storeId;

View File

@@ -11,7 +11,7 @@
d.name as receiverName, d.phone as receiverPhone, d.name as receiverName, d.phone as receiverPhone,
d.province as receiverProvince, d.city as receiverCity, d.region as receiverRegion, d.province as receiverProvince, d.city as receiverCity, d.region as receiverRegion,
d.address as receiverAddress, d.full_address as receiverFullAddress, d.lat as receiverLat, d.lng as receiverLng, d.address as receiverAddress, d.full_address as receiverFullAddress, d.lat as receiverLat, d.lng as receiverLng,
COALESCE(o.order_no, f.order_no) as orderNo COALESCE(o.order_no, f.order_no) as orderNo, o.order_status as orderStatus
FROM glt_ticket_order a FROM glt_ticket_order a
LEFT JOIN shop_store b ON a.store_id = b.id LEFT JOIN shop_store b ON a.store_id = b.id
LEFT JOIN shop_store_warehouse w ON a.warehouse_id = w.id LEFT JOIN shop_store_warehouse w ON a.warehouse_id = w.id

View File

@@ -87,4 +87,8 @@ public class GltTicketOrderParam extends BaseParam {
@QueryField(type = QueryType.EQ) @QueryField(type = QueryType.EQ)
private Integer deleted; private Integer deleted;
@Schema(description = "订单状态")
@QueryField(type = QueryType.EQ)
private Integer orderStatus;
} }

View File

@@ -155,6 +155,8 @@ public class GltTicketOrderServiceImpl extends ServiceImpl<GltTicketOrderMapper,
gltTicketOrder.setStatus(0); gltTicketOrder.setStatus(0);
gltTicketOrder.setDeleted(0); gltTicketOrder.setDeleted(0);
gltTicketOrder.setTenantId(tenantId); gltTicketOrder.setTenantId(tenantId);
// 关联商城订单号(用于后台/对账/追踪);优先取水票上的 orderNo缺失则按 orderId/orderGoodsId 兜底反查。
gltTicketOrder.setOrderNo(resolveShopOrderNo(userTicket, tenantId));
if (gltTicketOrder.getDeliveryStatus() == null) { if (gltTicketOrder.getDeliveryStatus() == null) {
gltTicketOrder.setDeliveryStatus(DELIVERY_STATUS_WAITING); gltTicketOrder.setDeliveryStatus(DELIVERY_STATUS_WAITING);
} }
@@ -203,6 +205,43 @@ public class GltTicketOrderServiceImpl extends ServiceImpl<GltTicketOrderMapper,
return gltTicketOrder; return gltTicketOrder;
} }
private String resolveShopOrderNo(GltUserTicket userTicket, Integer tenantId) {
if (userTicket == null || tenantId == null) {
return null;
}
if (StringUtils.hasText(userTicket.getOrderNo())) {
return userTicket.getOrderNo();
}
Integer orderId = userTicket.getOrderId();
// 兜底:历史数据可能只写了 orderGoodsId未写 orderId/orderNo
if (orderId == null && userTicket.getOrderGoodsId() != null) {
ShopOrderGoods og = shopOrderGoodsService.getOne(
new LambdaQueryWrapper<ShopOrderGoods>()
.select(ShopOrderGoods::getOrderId)
.eq(ShopOrderGoods::getTenantId, tenantId)
.eq(ShopOrderGoods::getId, userTicket.getOrderGoodsId())
.last("limit 1")
);
if (og != null) {
orderId = og.getOrderId();
}
}
if (orderId == null) {
return null;
}
ShopOrder order = shopOrderService.getOne(
new LambdaQueryWrapper<ShopOrder>()
.select(ShopOrder::getOrderNo)
.eq(ShopOrder::getTenantId, tenantId)
.eq(ShopOrder::getDeleted, 0)
.eq(ShopOrder::getOrderId, orderId)
.last("limit 1")
);
return order == null ? null : order.getOrderNo();
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void accept(Integer id, Integer riderId, Integer tenantId) { public void accept(Integer id, Integer riderId, Integer tenantId) {

View File

@@ -2,9 +2,17 @@ package com.gxwebsoft;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gxwebsoft.glt.entity.GltUserTicket;
import com.gxwebsoft.glt.service.GltTicketRevokeService;
import com.gxwebsoft.glt.service.GltUserTicketService;
import com.gxwebsoft.hjm.controller.PushCallback; import com.gxwebsoft.hjm.controller.PushCallback;
import com.gxwebsoft.hjm.entity.HjmCar; import com.gxwebsoft.hjm.entity.HjmCar;
import com.gxwebsoft.hjm.service.HjmCarService; import com.gxwebsoft.hjm.service.HjmCarService;
import com.gxwebsoft.shop.entity.ShopOrder;
import com.gxwebsoft.shop.entity.ShopOrderGoods;
import com.gxwebsoft.shop.service.ShopOrderGoodsService;
import com.gxwebsoft.shop.service.ShopOrderService;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -14,6 +22,9 @@ import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.text.ParseException; import java.text.ParseException;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/** /**
* Created by WebSoft on 2020-03-23 23:37 * Created by WebSoft on 2020-03-23 23:37
@@ -25,6 +36,131 @@ public class TestMain {
@Resource @Resource
private HjmCarService hjmCarService; private HjmCarService hjmCarService;
@Resource
private ShopOrderService shopOrderService;
@Resource
private ShopOrderGoodsService shopOrderGoodsService;
@Resource
private GltUserTicketService gltUserTicketService;
@Resource
private GltTicketRevokeService gltTicketRevokeService;
/**
* 查询已退款订单ShopOrder关联的gltUserTicket仅处理租户ID=10584
*/
@Test
public void testOrderData() {
final int tenantId = 10584;
final int ORDER_STATUS_REFUND_SUCCESS = 6;
// 安全开关:默认只查询/打印;如需实际撤销,将其改为 true
final boolean doRevoke = false;
int lastOrderId = 0;
int batchSize = 200;
int scannedOrders = 0;
int ordersWithTickets = 0;
int matchedTickets = 0;
int revokedTickets = 0;
while (true) {
List<ShopOrder> orders = shopOrderService.list(new LambdaQueryWrapper<ShopOrder>()
.select(ShopOrder::getOrderId, ShopOrder::getOrderNo, ShopOrder::getRefundTime, ShopOrder::getRefundMoney,
ShopOrder::getOrderStatus, ShopOrder::getPayStatus, ShopOrder::getCreateTime)
.eq(ShopOrder::getTenantId, tenantId)
.eq(ShopOrder::getDeleted, 0)
.eq(ShopOrder::getOrderStatus, ORDER_STATUS_REFUND_SUCCESS)
.gt(ShopOrder::getOrderId, lastOrderId)
.orderByAsc(ShopOrder::getOrderId)
.last("limit " + batchSize));
if (orders == null || orders.isEmpty()) {
break;
}
for (ShopOrder o : orders) {
if (o == null || o.getOrderId() == null) {
continue;
}
scannedOrders++;
lastOrderId = Math.max(lastOrderId, o.getOrderId());
List<GltUserTicket> tickets = findTicketsByOrder(tenantId, o.getOrderId(), o.getOrderNo());
if (tickets == null || tickets.isEmpty()) {
tickets = findTicketsByOrderGoodsFallback(tenantId, o.getOrderId());
}
if (tickets == null || tickets.isEmpty()) {
continue;
}
ordersWithTickets++;
matchedTickets += tickets.size();
logger.info("已退款订单关联水票 - tenantId={}, orderId={}, orderNo={}, refundMoney={}, refundTime={}, tickets={}",
tenantId, o.getOrderId(), o.getOrderNo(), o.getRefundMoney(), o.getRefundTime(),
tickets.stream().filter(Objects::nonNull).map(GltUserTicket::getId).collect(Collectors.toList()));
if (doRevoke) {
int revoked = gltTicketRevokeService.revokeByShopOrder(
tenantId,
o.getOrderId(),
o.getOrderNo(),
"TestMain: 历史退款订单撤销水票"
);
revokedTickets += revoked;
}
}
}
logger.info("扫描完成 - tenantId={}, scannedOrders={}, ordersWithTickets={}, matchedTickets={}, doRevoke={}, revokedTickets={}",
tenantId, scannedOrders, ordersWithTickets, matchedTickets, doRevoke, revokedTickets);
}
private List<GltUserTicket> findTicketsByOrder(Integer tenantId, Integer orderId, String orderNo) {
LambdaQueryWrapper<GltUserTicket> qw = new LambdaQueryWrapper<GltUserTicket>()
.eq(GltUserTicket::getTenantId, tenantId)
.eq(GltUserTicket::getDeleted, 0);
if (orderId != null && StrUtil.isNotBlank(orderNo)) {
qw.and(w -> w.eq(GltUserTicket::getOrderId, orderId).or().eq(GltUserTicket::getOrderNo, orderNo));
} else if (orderId != null) {
qw.eq(GltUserTicket::getOrderId, orderId);
} else if (StrUtil.isNotBlank(orderNo)) {
qw.eq(GltUserTicket::getOrderNo, orderNo);
} else {
return List.of();
}
return gltUserTicketService.list(qw);
}
/**
* 兼容历史数据:部分水票仅记录了 order_goods_id未回填 order_id/order_no。
*/
private List<GltUserTicket> findTicketsByOrderGoodsFallback(Integer tenantId, Integer orderId) {
if (tenantId == null || orderId == null) {
return List.of();
}
List<ShopOrderGoods> goods = shopOrderGoodsService.list(new LambdaQueryWrapper<ShopOrderGoods>()
.select(ShopOrderGoods::getId)
.eq(ShopOrderGoods::getTenantId, tenantId)
.eq(ShopOrderGoods::getOrderId, orderId));
if (goods == null || goods.isEmpty()) {
return List.of();
}
List<Integer> orderGoodsIds = goods.stream()
.map(ShopOrderGoods::getId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (orderGoodsIds.isEmpty()) {
return List.of();
}
return gltUserTicketService.list(new LambdaQueryWrapper<GltUserTicket>()
.eq(GltUserTicket::getTenantId, tenantId)
.eq(GltUserTicket::getDeleted, 0)
.in(GltUserTicket::getOrderGoodsId, orderGoodsIds));
}
/** /**
* 生成唯一的key用于jwt工具类 * 生成唯一的key用于jwt工具类
*/ */