Browse Source

对接拼团数据1

master
wangfukang 10 hours ago
parent
commit
6dffe82f35
  1. 16
      hiver-admin/test-output/test-report.html
  2. 37
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/mq/OrderAsyncProducer.java
  3. 2
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java
  4. 36
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java
  5. 7
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallRefundRecordServiceImpl.java
  6. 24
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/DaQuReceiptRenderUtil.java

16
hiver-admin/test-output/test-report.html

@ -35,7 +35,7 @@
<a href="#"><span class="badge badge-primary">Hiver</span></a>
</li>
<li class="m-r-10">
<a href="#"><span class="badge badge-primary">九月 19, 2026 15:49:28</span></a>
<a href="#"><span class="badge badge-primary">九月 20, 2026 17:27:21</span></a>
</li>
</ul>
</div>
@ -84,7 +84,7 @@
<div class="test-detail">
<span class="meta text-white badge badge-sm"></span>
<p class="name">passTest</p>
<p class="text-sm"><span>15:49:29 下午</span> / <span>0.022 secs</span></p>
<p class="text-sm"><span>17:27:22 下午</span> / <span>0.025 secs</span></p>
</div>
<div class="test-contents d-none">
<div class="detail-head">
@ -92,9 +92,9 @@
<div class="info">
<div class='float-right'><span class='badge badge-default'>#test-id=1</span></div>
<h5 class="test-status text-pass">passTest</h5>
<span class='badge badge-success'>09.19.2026 15:49:29</span>
<span class='badge badge-danger'>09.19.2026 15:49:29</span>
<span class='badge badge-default'>0.022 secs</span>
<span class='badge badge-success'>09.20.2026 17:27:22</span>
<span class='badge badge-danger'>09.20.2026 17:27:22</span>
<span class='badge badge-default'>0.025 secs</span>
</div>
<div class="m-t-10 m-l-5"></div>
</div>
@ -104,7 +104,7 @@
<tbody>
<tr class="event-row">
<td><span class="badge log pass-bg">Pass</span></td>
<td>15:49:29</td>
<td>17:27:22</td>
<td>
Test passed
</td>
@ -128,13 +128,13 @@
<div class="col-md-3">
<div class="card"><div class="card-body">
<p class="m-b-0">Started</p>
<h3>九月 19, 2026 15:49:28</h3>
<h3>九月 20, 2026 17:27:21</h3>
</div></div>
</div>
<div class="col-md-3">
<div class="card"><div class="card-body">
<p class="m-b-0">Ended</p>
<h3>九月 19, 2026 15:49:29</h3>
<h3>九月 20, 2026 17:27:22</h3>
</div></div>
</div>
<div class="col-md-3">

37
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/mq/OrderAsyncProducer.java

@ -18,6 +18,7 @@ import java.util.Set;
@Slf4j
@Component
public class OrderAsyncProducer {
private static final long CLOUD_PRINT_INITIAL_DELAY_MILLIS = 5 * 1000L;
@Autowired
private RabbitTemplate rabbitTemplate;
@ -54,34 +55,36 @@ public class OrderAsyncProducer {
}
public void sendCloudPrint(String orderId, String printReason) {
sendCloudPrint(orderId, printReason, 0);
sendCloudPrintDelay(orderId, printReason, 0, CLOUD_PRINT_INITIAL_DELAY_MILLIS, "云打印初始延迟任务");
}
public void sendCloudPrint(String orderId, String printReason, int retryCount) {
sendCloudPrintDelay(orderId, printReason, retryCount, 0, "云打印任务");
}
private void sendCloudPrintDelay(String orderId, String printReason, int retryCount, long delayMillis, String logPrefix) {
Map<String, Object> msg = new HashMap<>();
msg.put("orderId", orderId);
msg.put("printReason", printReason);
msg.put("retryCount", retryCount);
msg.put("timestamp", System.currentTimeMillis());
rabbitTemplate.convertAndSend(OrderQueueConfig.ORDER_DIRECT_EXCHANGE, OrderQueueConfig.ASYNC_PRINT_ROUTING, JSON.toJSONString(msg));
log.info("【云打印MQ】已发出云打印任务, orderId={}, reason={}, retryCount={}", orderId, printReason, retryCount);
if (delayMillis > 0) {
rabbitTemplate.convertAndSend(OrderQueueConfig.ORDER_DIRECT_EXCHANGE,
OrderQueueConfig.ASYNC_PRINT_RETRY_DELAY_ROUTING,
JSON.toJSONString(msg),
message -> {
message.getMessageProperties().setExpiration(String.valueOf(delayMillis));
return message;
});
} else {
rabbitTemplate.convertAndSend(OrderQueueConfig.ORDER_DIRECT_EXCHANGE, OrderQueueConfig.ASYNC_PRINT_ROUTING, JSON.toJSONString(msg));
}
log.info("【云打印MQ】已发出{}, orderId={}, reason={}, retryCount={}, delayMillis={}",
logPrefix, orderId, printReason, retryCount, delayMillis);
}
public void sendCloudPrintDelayRetry(String orderId, String printReason, int retryCount, long delayMillis) {
Map<String, Object> msg = new HashMap<>();
msg.put("orderId", orderId);
msg.put("printReason", printReason);
msg.put("retryCount", retryCount);
msg.put("timestamp", System.currentTimeMillis());
rabbitTemplate.convertAndSend(OrderQueueConfig.ORDER_DIRECT_EXCHANGE,
OrderQueueConfig.ASYNC_PRINT_RETRY_DELAY_ROUTING,
JSON.toJSONString(msg),
message -> {
message.getMessageProperties().setExpiration(String.valueOf(delayMillis));
return message;
});
log.info("【云打印MQ】已发出云打印延迟重试任务, orderId={}, reason={}, retryCount={}, delayMillis={}",
orderId, printReason, retryCount, delayMillis);
sendCloudPrintDelay(orderId, printReason, retryCount, delayMillis, "云打印延迟重试任务");
}
/**

2
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallDeliveryOrderServiceImpl.java

@ -557,7 +557,7 @@ public class MallDeliveryOrderServiceImpl extends ServiceImpl<MallDeliveryOrderM
}
for (String clientId : clientIds) {
try {
jPushService.sendPushNotification(clientId, "一笔新的中转配送单,请及时接单", pushId);
jPushService.sendPushNotification(clientId, "有新的中转配送单,请及时接单", pushId);
} catch (Exception e) {
log.warn("中转配送推送失败, deliveryId={}, err={}", delivery.getId(), e.getMessage());
}

36
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallOrderServiceImpl.java

@ -1769,13 +1769,7 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
if(orders != null && !orders.isEmpty()){
orders.forEach(order -> {
// 配送信息
if(order.getOrderType() == ORDER_TYPE_FACETOFACE){
order.setDeliveryInfo(mallDeliveryOrderMapper.selectByGroupId(order.getId()));
}else{
LambdaQueryWrapper<MallDeliveryOrder> dq = new LambdaQueryWrapper<>();
dq.eq(MallDeliveryOrder::getOrderId, order.getId()).last("LIMIT 1");
order.setDeliveryInfo(mallDeliveryOrderMapper.selectOne(dq));
}
order.setDeliveryInfo(findDetailDelivery(order));
});
}
return orders;
@ -1930,13 +1924,7 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
vo.setGoodsList(mallOrderGoodsMapper.selectByOrderId(orderId));
// 配送信息
if(order.getOrderType() == ORDER_TYPE_FACETOFACE){
vo.setDeliveryInfo(mallDeliveryOrderMapper.selectByGroupId(orderId));
}else{
LambdaQueryWrapper<MallDeliveryOrder> dq = new LambdaQueryWrapper<>();
dq.eq(MallDeliveryOrder::getOrderId, orderId).last("LIMIT 1");
vo.setDeliveryInfo(mallDeliveryOrderMapper.selectOne(dq));
}
vo.setDeliveryInfo(findDetailDelivery(order));
// 拼团信息(拼团订单才查)
if (ORDER_TYPE_GROUP == order.getOrderType() || GROUP_STATUS_FACE2FACE == order.getOrderType()) {
// 通过 headOrderId 或 groupUserIds 中包含此 userId 查找拼团
@ -1998,6 +1986,24 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
return vo;
}
private MallDeliveryOrder findDetailDelivery(MallOrder order) {
if (order == null || order.getId() == null) {
return null;
}
MallDeliveryOrder delivery = null;
if (Integer.valueOf(ORDER_TYPE_FACETOFACE).equals(order.getOrderType())) {
delivery = mallDeliveryOrderMapper.selectByGroupId(order.getId());
} else {
LambdaQueryWrapper<MallDeliveryOrder> dq = new LambdaQueryWrapper<>();
dq.eq(MallDeliveryOrder::getOrderId, order.getId()).last("LIMIT 1");
delivery = mallDeliveryOrderMapper.selectOne(dq);
}
if (delivery == null && Integer.valueOf(DELIVERY_TYPE_EXPRESS).equals(order.getDeliveryType())) {
delivery = mallDeliveryOrderMapper.selectByGroupId(order.getId());
}
return delivery;
}
// ================================================================
// 私有工具方法
// ================================================================
@ -2328,7 +2334,7 @@ public class MallOrderServiceImpl extends ServiceImpl<MallOrderMapper, MallOrder
if (matched == null || !dto.getRegionId().equals(matched.getId())) {
throw new RuntimeException("收货地址不在当前区域配送范围内");
}
dto.setPutAreaId(null);
dto.setPutAreaId(address.getId());
}
private LocalDateTime calculateTransferArriveTime(String regionId, String shopId, Integer deliveryType,

7
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/MallRefundRecordServiceImpl.java

@ -932,6 +932,7 @@ public class MallRefundRecordServiceImpl extends ServiceImpl<MallRefundRecordMap
// 商家原因全额退款且配送员已取货(正常发佣金)时配送单应为已送达(3),其余场景取消(4)
int deliveryTargetStatus = Integer.valueOf(1).equals(mallRefundRecord.getRefundTypeStatus())
&& merchantRecordIncludesDeliveryFee(order, mallRefundRecord) ? 3 : 4;
Date deliveryFinishTime = deliveryTargetStatus == 3 ? new Date() : null;
//面对面拼团
if(mallRefundRecord.getOrderType() == STATUS_WAIT_PICKUP){
MallDeliveryOrder delivery = mallDeliveryOrderMapper.selectByGroupId(mallRefundRecord.getOrderId());
@ -940,6 +941,9 @@ public class MallRefundRecordServiceImpl extends ServiceImpl<MallRefundRecordMap
LambdaUpdateWrapper<MallDeliveryOrder> duw = new LambdaUpdateWrapper<>();
duw.eq(MallDeliveryOrder::getOrderId, delivery.getOrderId())
.set(MallDeliveryOrder::getStatus, deliveryTargetStatus);
if (deliveryFinishTime != null) {
duw.set(MallDeliveryOrder::getFinishTime, deliveryFinishTime);
}
mallDeliveryOrderMapper.update(null, duw);
//更新缓存
workerOrderCacheUtil.remove(delivery.getWorkerId(),delivery.getId());
@ -949,6 +953,9 @@ public class MallRefundRecordServiceImpl extends ServiceImpl<MallRefundRecordMap
LambdaUpdateWrapper<MallDeliveryOrder> duw = new LambdaUpdateWrapper<>();
duw.eq(MallDeliveryOrder::getOrderId, mallRefundRecord.getOrderId())
.set(MallDeliveryOrder::getStatus, deliveryTargetStatus);
if (deliveryFinishTime != null) {
duw.set(MallDeliveryOrder::getFinishTime, deliveryFinishTime);
}
mallDeliveryOrderMapper.update(null, duw);
//更新缓存
LambdaQueryWrapper<MallDeliveryOrder> qw = new LambdaQueryWrapper<>();

24
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/DaQuReceiptRenderUtil.java

@ -27,7 +27,10 @@ public final class DaQuReceiptRenderUtil {
centerLarge(sb, orderNo(order));
centerLarge(sb, orderTypeText(order, delivery, refundPrint, forcedOrderPrint));
if (delivery != null && Integer.valueOf(1).equals(delivery.getAppointmentDelivery())) {
left(sb, "要求送达时间:" + formatTime(delivery.getMustFinishTime()));
largeLeft(sb, "要求送达时间:" + formatTime(delivery.getMustFinishTime()));
}
if (isFaceToFaceDelivery(order)) {
largeLeft(sb, "本单编号:" + defaultString(order.getNumberCode()));
}
left(sb, defaultString(order.getShopName()));
left(sb, "下单时间:" + formatTime(order.getCreateTime()));
@ -78,7 +81,7 @@ public final class DaQuReceiptRenderUtil {
left(sb, "锦鲤免单:-" + amount(order.getFreeAmount()));
}
left(sb, "合计金额:" + amount(safe(order.getGoodsAmount()).add(safe(order.getDeliveryFee())).add(safe(order.getPackageFee()))));
left(sb, (hasRefund ? "应退金额:" : "实付金额:") + amount(order.getTotalAmount()));
left(sb, amountLabel(order, hasRefund) + amount(order.getTotalAmount()));
largeLeft(sb, "备注:" + defaultString(order.getRemark()));
br(sb);
@ -132,8 +135,7 @@ public final class DaQuReceiptRenderUtil {
private static String orderNo(MallOrderVO order) {
MallDeliveryOrder delivery = order.getDeliveryInfo();
if (Integer.valueOf(1).equals(order.getDeliveryType())
&& Integer.valueOf(3).equals(order.getOrderType())
if (isFaceToFaceDelivery(order)
&& delivery != null
&& StringUtils.isNotBlank(delivery.getNumberCode())) {
return delivery.getNumberCode();
@ -144,7 +146,7 @@ public final class DaQuReceiptRenderUtil {
private static String orderTypeText(MallOrderVO order, MallDeliveryOrder delivery, boolean refundPrint, boolean forcedOrderPrint) {
Integer status = order.getStatus();
if (delivery != null && Integer.valueOf(1).equals(delivery.getAppointmentDelivery())
&& Integer.valueOf(11).equals(status)) {
&& !refundPrint) {
return "预约单";
}
if (delivery != null && Integer.valueOf(1).equals(delivery.getTransferDelivery())
@ -194,6 +196,18 @@ public final class DaQuReceiptRenderUtil {
return StringUtils.containsIgnoreCase(printReason, "REFUND");
}
private static boolean isFaceToFaceDelivery(MallOrderVO order) {
return Integer.valueOf(1).equals(order.getDeliveryType())
&& Integer.valueOf(3).equals(order.getOrderType());
}
private static String amountLabel(MallOrderVO order, boolean hasRefund) {
if (hasRefund && !Integer.valueOf(2).equals(order.getDeliveryType())) {
return "实付金额:";
}
return "实付金额:";
}
private static boolean isOrderEventPrint(String printReason) {
return StringUtils.containsIgnoreCase(printReason, "ACCEPT_ORDER")
|| StringUtils.containsIgnoreCase(printReason, "SHOP_INSTANT_MAKE");

Loading…
Cancel
Save