修复回调问题,通道问题
This commit is contained in:
1 parent
75c942c5c8
commit
6ba8b4fa00
5 files changed
+104
-65
No files matched your search
+2
-2
@@ -406,14 +406,14 @@ public class ChannelServiceImpl implements ChannelService {
|
||||
throw exception0(1_008_015_001, "出货失败!原因: " + body.getMsg());
|
||||
}
|
||||
} else {
|
||||
deviceLog.setDeviceStatus(501);
|
||||
deviceLog.setDeviceStatus(99);
|
||||
deviceLog.setContent("操作失败!原因: 请求出货响应为空");
|
||||
productDeviceLogService.createDeviceLog(deviceLog);
|
||||
throw exception(CHANNEL_ERROR);
|
||||
}
|
||||
/*} catch (Exception e) {
|
||||
System.err.println("请求异常: " + e.getMessage());
|
||||
deviceLog.setDeviceStatus(500);
|
||||
deviceLog.setDeviceStatus(99);
|
||||
deviceLog.setContent("请求异常: " + e.getMessage());
|
||||
productDeviceLogService.createDeviceLog(deviceLog);
|
||||
throw exception0(1_008_016_001, "请求异常: " + e.getMessage());
|
||||
|
||||
+64
-41
@@ -30,7 +30,7 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
|
||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.yudao.module.product.enums.sku.ProductSkuPurchaseBizTypeEnum;
|
||||
import cn.iocoder.yudao.module.product.enums.spu.PurchaseLimitTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.api.giftvoucher.GiftVoucherApi;
|
||||
import cn.iocoder.yudao.module.promotion.api.giftvoucher.dto.GiftVoucherRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.social.SocialClientApi;
|
||||
@@ -78,12 +78,9 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
@@ -152,47 +149,73 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||
|
||||
// =================== Order ===================
|
||||
|
||||
public List<TradeOrderItemDO> findUserSuccessOrderItem(Long payUserId, List<Long> skuIdList, ProductSkuPurchaseBizTypeEnum status) {
|
||||
List<Integer> statusList = new ArrayList<>();
|
||||
statusList.add(TradeOrderStatusEnum.UNPAID.getStatus());
|
||||
statusList.add(TradeOrderStatusEnum.UNDELIVERED.getStatus());
|
||||
statusList.add(TradeOrderStatusEnum.DELIVERED.getStatus());
|
||||
statusList.add(TradeOrderStatusEnum.COMPLETED.getStatus());
|
||||
// 查询用户订单
|
||||
LambdaQueryWrapperX<TradeOrderDO> orderQuery = new LambdaQueryWrapperX<TradeOrderDO>().eq(TradeOrderDO::getUserId, payUserId).in(TradeOrderDO::getStatus, statusList);
|
||||
// 限购一天一次
|
||||
if (ObjectUtil.equals(status, ProductSkuPurchaseBizTypeEnum.ONCE_A_DAY)) {
|
||||
orderQuery.between(TradeOrderDO::getCreateTime, LocalDate.now(), LocalDate.now().plusDays(1));
|
||||
}
|
||||
List<TradeOrderDO> orderList = tradeOrderMapper.selectList(orderQuery);
|
||||
if (ObjectUtil.isEmpty(orderList)) return null;
|
||||
List<Long> orderIds = orderList.stream().map(TradeOrderDO::getId).collect(Collectors.toList());
|
||||
// 查询订单项
|
||||
List<TradeOrderItemDO> orderItemList = tradeOrderItemMapper.selectList(new LambdaQueryWrapperX<TradeOrderItemDO>()
|
||||
.eq(TradeOrderItemDO::getUserId, payUserId)
|
||||
.in(TradeOrderItemDO::getOrderId, orderIds)
|
||||
);
|
||||
if (ObjectUtil.isEmpty(orderItemList)) return null;
|
||||
orderItemList = orderItemList.stream().filter(v -> skuIdList.contains(v.getSkuId())).collect(Collectors.toList());
|
||||
return orderItemList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断sku是否限购
|
||||
* 结算阶段限购预校验(按 SPU 限购规则)
|
||||
*/
|
||||
@Override
|
||||
public void isSkuPurchaseLimit(Long payUserId, List<Long> skuIdList) {
|
||||
List<ProductSkuRespDTO> skuList = productSkuApi.getSkuList(skuIdList);
|
||||
// 检查每天限购一次
|
||||
ProductSkuPurchaseBizTypeEnum onceADayStatus = ProductSkuPurchaseBizTypeEnum.ONCE_A_DAY;
|
||||
List<ProductSkuRespDTO> onceADay = skuList.stream().filter((v) -> ObjectUtil.equals(v.getPurchaseBizType(), onceADayStatus.getStatus())).collect(Collectors.toList());
|
||||
if (ObjectUtil.isNotEmpty(onceADay)) {
|
||||
List<Long> targetIdList = onceADay.stream().map(ProductSkuRespDTO::getId).collect(Collectors.toList());
|
||||
List<TradeOrderItemDO> targetSkuList = findUserSuccessOrderItem(payUserId, targetIdList, onceADayStatus);
|
||||
if (ObjectUtil.isNotEmpty(targetSkuList)) {
|
||||
String spuName = targetSkuList.stream().map(TradeOrderItemDO::getSpuName).collect(Collectors.joining());
|
||||
throw exception(ORDER_RECEIVE_FAIL_STATUS_PURCHASE, "【" + spuName + "】", onceADayStatus.getName());
|
||||
if (CollUtil.isEmpty(skuList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 本次请求每个 SPU 的购买数量(按 skuList 聚合;结算页通常每条 sku 一项)
|
||||
Map<Long, Integer> currentPurchaseBySpu = new HashMap<>();
|
||||
for (ProductSkuRespDTO sku : skuList) {
|
||||
if (sku == null || sku.getSpuId() == null) {
|
||||
continue;
|
||||
}
|
||||
currentPurchaseBySpu.merge(sku.getSpuId(), 1, Integer::sum);
|
||||
}
|
||||
if (currentPurchaseBySpu.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(new ArrayList<>(currentPurchaseBySpu.keySet()));
|
||||
if (CollUtil.isEmpty(spuList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ProductSpuRespDTO spu : spuList) {
|
||||
if (spu == null || spu.getId() == null) {
|
||||
continue;
|
||||
}
|
||||
Integer limitType = spu.getPurchaseLimitType();
|
||||
Integer limitCount = spu.getPurchaseLimitCount();
|
||||
if (limitType == null || Objects.equals(limitType, PurchaseLimitTypeEnum.NONE.getType())
|
||||
|| limitCount == null || limitCount <= 0) {
|
||||
continue; // 不限购
|
||||
}
|
||||
|
||||
PurchaseLimitTypeEnum limitTypeEnum = PurchaseLimitTypeEnum.valueOf(limitType);
|
||||
if (limitTypeEnum == null) {
|
||||
continue;
|
||||
}
|
||||
LocalDateTime startTime = getStartTimeByLimitType(limitTypeEnum);
|
||||
if (startTime == null) {
|
||||
startTime = LocalDateTime.of(2000, 1, 1, 0, 0);
|
||||
}
|
||||
|
||||
int historyPurchaseCount = tradeOrderItemMapper.selectPurchaseCountByUserAndSpu(payUserId, spu.getId(), startTime);
|
||||
int currentPurchaseCount = currentPurchaseBySpu.getOrDefault(spu.getId(), 0);
|
||||
if (historyPurchaseCount + currentPurchaseCount > limitCount) {
|
||||
throw exception(ORDER_CREATE_PURCHASE_LIMIT_EXCEED, spu.getName(), limitTypeEnum.getName(), limitCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private LocalDateTime getStartTimeByLimitType(PurchaseLimitTypeEnum limitType) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
switch (limitType) {
|
||||
case DAILY:
|
||||
return now.toLocalDate().atStartOfDay();
|
||||
case WEEKLY:
|
||||
return now.with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY))
|
||||
.toLocalDate().atStartOfDay();
|
||||
case LIFETIME:
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ public enum DispenseResultStatusEnum {
|
||||
CHANNEL_ERROR(6, "通道号错误"),
|
||||
CHANNEL_TYPE_ERROR(7, "通道类型错误"),
|
||||
/** 系统/业务异常(如网络异常、参数错误等) */
|
||||
EXCEPTION(500, "出货异常"),
|
||||
EXCEPTION(99, "出货异常"),
|
||||
;
|
||||
|
||||
private final int value;
|
||||
|
||||
+32
-16
@@ -107,7 +107,7 @@ public class TradeDeviceOrderHandler implements TradeOrderHandler {
|
||||
} catch (Throwable ex) {
|
||||
// 兜底保护:这里不再向上抛异常,仅记录日志,避免影响支付回调流程
|
||||
log.error("订单--{}:[设备出货处理异常]:原因: {}", order.getNo(), ex.getMessage(), ex);
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setDeviceStatus(99);
|
||||
deviceLogSaveReqVO.setContent("[出货异常]原因:" + ex.getMessage());
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
}
|
||||
@@ -137,7 +137,7 @@ public class TradeDeviceOrderHandler implements TradeOrderHandler {
|
||||
List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(spuIds);
|
||||
if (CollUtil.isEmpty(spuList)) {
|
||||
log.error("订单:{}, 提货柜订单spu列表为空", order.getNo());
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setDeviceStatus(99);
|
||||
deviceLogSaveReqVO.setContent("[出货异常]原因:提货柜订单spu列表为空");
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
return;
|
||||
@@ -148,6 +148,8 @@ public class TradeDeviceOrderHandler implements TradeOrderHandler {
|
||||
log.error("订单:{}, 中包含非提货柜商品,跳过设备出货处理", order.getNo());
|
||||
return;
|
||||
}
|
||||
Map<Long, String> spuNameMap = spuList.stream()
|
||||
.collect(Collectors.toMap(ProductSpuRespDTO::getId, ProductSpuRespDTO::getName, (a, b) -> a));
|
||||
|
||||
String deviceId = findUniqueDeviceId(order, spuList, deviceLogSaveReqVO);
|
||||
if (deviceId == null) {
|
||||
@@ -160,13 +162,13 @@ public class TradeDeviceOrderHandler implements TradeOrderHandler {
|
||||
if (CollUtil.isEmpty(skuListBySpu)) {
|
||||
log.warn("订单:{} 商品下无货道(SKU),跳过设备出货处理", order.getNo());
|
||||
deviceLogSaveReqVO.setDeviceId(deviceId);
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setDeviceStatus(99);
|
||||
deviceLogSaveReqVO.setContent("[出货异常]原因:商品下无货道(SKU)");
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
return;
|
||||
}
|
||||
|
||||
String cabinetType = findUniqueCabinetType(order, skuListBySpu, deviceId, deviceLogSaveReqVO);
|
||||
String cabinetType = findUniqueCabinetType(order, skuListBySpu, spuNameMap, deviceId, deviceLogSaveReqVO);
|
||||
if (cabinetType == null) {
|
||||
// 已在方法内部记录日志
|
||||
return;
|
||||
@@ -176,7 +178,7 @@ public class TradeDeviceOrderHandler implements TradeOrderHandler {
|
||||
DispenseRequestBo request = buildDispenseRequest(order, orderItems, deviceId, cabinetType);
|
||||
if (request == null) {
|
||||
deviceLogSaveReqVO.setDeviceId(deviceId);
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setDeviceStatus(99);
|
||||
deviceLogSaveReqVO.setContent("[出货异常]原因:存在商品无可用货道(有库存且通道类型匹配)");
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
return;
|
||||
@@ -213,7 +215,7 @@ public class TradeDeviceOrderHandler implements TradeOrderHandler {
|
||||
.count() == 1;
|
||||
if (!isSingleDevice) {
|
||||
log.error("订单:{}, 明细中包含多个设备的商品", order.getNo());
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setDeviceStatus(99);
|
||||
deviceLogSaveReqVO.setContent("[出货异常]原因:订单明细中包含多台贩卖机商品");
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
return null;
|
||||
@@ -223,7 +225,7 @@ public class TradeDeviceOrderHandler implements TradeOrderHandler {
|
||||
if (deviceId == null) {
|
||||
// 设备编号为空,无法出货
|
||||
log.error("订单:{}, 商品的设备编号为空", order.getNo());
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setDeviceStatus(99);
|
||||
deviceLogSaveReqVO.setContent("[出货异常]原因:商品的设备编号为空");
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
return null;
|
||||
@@ -236,6 +238,7 @@ public class TradeDeviceOrderHandler implements TradeOrderHandler {
|
||||
*/
|
||||
private String findUniqueCabinetType(TradeOrderDO order,
|
||||
List<ProductSkuRespDTO> skuList,
|
||||
Map<Long, String> spuNameMap,
|
||||
String deviceId,
|
||||
DeviceLogSaveReqVO deviceLogSaveReqVO) {
|
||||
boolean isSingleCabinetType = skuList.stream()
|
||||
@@ -243,15 +246,28 @@ public class TradeDeviceOrderHandler implements TradeOrderHandler {
|
||||
.distinct()
|
||||
.count() == 1;
|
||||
if (!isSingleCabinetType) {
|
||||
log.error("订单:{}, 明细中包含多个通道类型", order.getNo());
|
||||
deviceLogSaveReqVO.setDeviceId(deviceId);
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setContent("[出货异常]原因:订单明细中包含多个通道类型");
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
return null;
|
||||
// 临时放开校验:不再因“多个通道类型”中断出货流程,仅记录告警日志便于排查
|
||||
log.warn("订单:{}, 明细中包含多个通道类型,已跳过该校验并继续出货", order.getNo());
|
||||
Map<String, List<ProductSkuRespDTO>> skuByCabinetType = skuList.stream()
|
||||
.collect(Collectors.groupingBy(sku -> StrUtil.blankToDefault(sku.getCabinetType(), "<null>")));
|
||||
skuByCabinetType.forEach((type, skus) -> {
|
||||
String details = skus.stream()
|
||||
.map(sku -> String.format("spuId=%s,spuName=%s,skuId=%s,cabinetType=%s,cabinetChannel=%s",
|
||||
sku.getSpuId(),
|
||||
spuNameMap.getOrDefault(sku.getSpuId(), "<unknown>"),
|
||||
sku.getId(),
|
||||
sku.getCabinetType(),
|
||||
sku.getCabinetChannel()))
|
||||
.collect(Collectors.joining(" | "));
|
||||
log.warn("订单:{}, 通道类型分组[{}] -> {}", order.getNo(), type, details);
|
||||
});
|
||||
}
|
||||
|
||||
return skuList.get(0).getCabinetType();
|
||||
return skuList.stream()
|
||||
.map(ProductSkuRespDTO::getCabinetType)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.findFirst()
|
||||
.orElse(skuList.get(0).getCabinetType());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,7 +350,7 @@ public class TradeDeviceOrderHandler implements TradeOrderHandler {
|
||||
if (body == null) {
|
||||
log.error("订单--{}:[出货失败]:响应体为空", order.getNo());
|
||||
deviceLogSaveReqVO.setDeviceId(request.getDeviceId());
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setDeviceStatus(99);
|
||||
deviceLogSaveReqVO.setContent("[出货失败]原因:响应为空");
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
return;
|
||||
@@ -357,7 +373,7 @@ public class TradeDeviceOrderHandler implements TradeOrderHandler {
|
||||
// HTTP 请求异常
|
||||
log.error("订单--{}:[出货异常]:原因: {}", order.getNo(), e.getMessage(), e);
|
||||
deviceLogSaveReqVO.setDeviceId(request.getDeviceId());
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setDeviceStatus(99);
|
||||
deviceLogSaveReqVO.setContent("[出货异常]原因:" + e.getMessage());
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
}
|
||||
|
||||
+5
-5
@@ -117,7 +117,7 @@ public class TradeGiftVoucherOrderHandler implements TradeOrderHandler {
|
||||
if (deviceId == null){
|
||||
//imei为空
|
||||
log.error("订单:{},商品的设备编号为空",order.getNo());
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setDeviceStatus(99);
|
||||
deviceLogSaveReqVO.setContent("[出货异常]原因:商品的设备编号为空");
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
return;
|
||||
@@ -203,7 +203,7 @@ public class TradeGiftVoucherOrderHandler implements TradeOrderHandler {
|
||||
System.err.println("请求异常: " + e.getMessage());
|
||||
log.error("订单--{}:[出货异常]:原因: {}",order.getNo(), e.getMessage());
|
||||
deviceLogSaveReqVO.setDeviceId(deviceId);
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setDeviceStatus(99);
|
||||
deviceLogSaveReqVO.setContent("[出货异常]原因:"+e.getMessage());
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
}
|
||||
@@ -211,14 +211,14 @@ public class TradeGiftVoucherOrderHandler implements TradeOrderHandler {
|
||||
System.out.println("订单明细中包含多个通道类型");
|
||||
log.error("订单:{},明细中包含多个通道类型",order.getNo());
|
||||
deviceLogSaveReqVO.setDeviceId(deviceId);
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setDeviceStatus(99);
|
||||
deviceLogSaveReqVO.setContent("[出货异常]原因:订单明细中包含多个通道类型");
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
}
|
||||
} else {
|
||||
System.out.println("订单明细中包含多个商品创建人");
|
||||
log.error("订单:{},明细中包含多个商品创建人",order.getNo());
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setDeviceStatus(99);
|
||||
deviceLogSaveReqVO.setContent("[出货异常]原因:订单明细中包含多台贩卖机商品");
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
}
|
||||
@@ -226,7 +226,7 @@ public class TradeGiftVoucherOrderHandler implements TradeOrderHandler {
|
||||
}else {
|
||||
System.out.println("提货柜订单spu列表为空");
|
||||
log.error("订单:{},提货柜订单spu列表为空",order.getNo());
|
||||
deviceLogSaveReqVO.setDeviceStatus(500);
|
||||
deviceLogSaveReqVO.setDeviceStatus(99);
|
||||
deviceLogSaveReqVO.setContent("[出货异常]原因:提货柜订单spu列表为空");
|
||||
deviceLogService.createDeviceLog(deviceLogSaveReqVO);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user