Commit 1ec5b03e by Jony.L

Merge remote-tracking branch 'origin/new-pay' into new-pay

parents e0ea5f18 c1e137db
...@@ -11,6 +11,10 @@ public interface ErrorCodeConstants { ...@@ -11,6 +11,10 @@ public interface ErrorCodeConstants {
ErrorCode RESOURCE_CATEGORY_NOT_EXISTS = new ErrorCode(1_030_001_000, "算力资源分类表(仅用于算力服务器分类)不存在"); ErrorCode RESOURCE_CATEGORY_NOT_EXISTS = new ErrorCode(1_030_001_000, "算力资源分类表(仅用于算力服务器分类)不存在");
ErrorCode RESOURCE_SKU_NOT_EXISTS = new ErrorCode(1_030_002_000, "算力资源SKU表(价格和租赁信息)不存在"); ErrorCode RESOURCE_SKU_NOT_EXISTS = new ErrorCode(1_030_002_000, "算力资源SKU表(价格和租赁信息)不存在");
ErrorCode RESOURCE_SPU_NOT_EXISTS = new ErrorCode(1_030_003_000, "算力资源SPU表(基础配置信息)不存在"); ErrorCode RESOURCE_SPU_NOT_EXISTS = new ErrorCode(1_030_003_000, "算力资源SPU表(基础配置信息)不存在");
/**
* 算力资源SPU库存不足
*/
ErrorCode RESOURCE_SPU_STOCK_NOT_ENOUGH = new ErrorCode(1_030_003_001, "算力资源SPU库存不足,订单创建失败");
ErrorCode RESOURCE_ORDER_NOT_EXISTS = new ErrorCode(1_030_004_000, "算力资源订单不存在"); ErrorCode RESOURCE_ORDER_NOT_EXISTS = new ErrorCode(1_030_004_000, "算力资源订单不存在");
ErrorCode RESOURCE_ORDER_SKU_NOT_EXISTS = new ErrorCode(1_030_004_001, "算力资源SKU不存在"); ErrorCode RESOURCE_ORDER_SKU_NOT_EXISTS = new ErrorCode(1_030_004_001, "算力资源SKU不存在");
ErrorCode RESOURCE_ORDER_SPU_NOT_EXISTS = new ErrorCode(1_030_004_002, "算力资源SPU不存在"); ErrorCode RESOURCE_ORDER_SPU_NOT_EXISTS = new ErrorCode(1_030_004_002, "算力资源SPU不存在");
......
...@@ -11,8 +11,8 @@ import lombok.Getter; ...@@ -11,8 +11,8 @@ import lombok.Getter;
*/ */
@Getter @Getter
public enum ResourceSkuStatus { public enum ResourceSkuStatus {
ONLINE(0, "上架"), OFFLINE(0, "下架"),
OFFLINE(1, "下架"); ONLINE(1, "上架");
private final Integer value; private final Integer value;
private final String label; private final String label;
......
...@@ -28,4 +28,15 @@ public interface ResourceSkuMapper extends BaseMapperX<ResourceSkuDO> { ...@@ -28,4 +28,15 @@ public interface ResourceSkuMapper extends BaseMapperX<ResourceSkuDO> {
.orderByDesc(ResourceSkuDO::getId)); .orderByDesc(ResourceSkuDO::getId));
} }
/**
* 将指定 SPU 下的所有 SKU 批量下架
*
* @param spuId 关联的 SPU ID
* @param status 目标状态(通常为下架 0)
* @return 受影响行数
*/
@org.apache.ibatis.annotations.Update("UPDATE compute_resource_sku SET status = #{status} WHERE spu_id = #{spuId}")
int updateStatusBySpuId(@org.apache.ibatis.annotations.Param("spuId") Long spuId,
@org.apache.ibatis.annotations.Param("status") Integer status);
} }
\ No newline at end of file
...@@ -44,4 +44,13 @@ public interface ResourceSpuMapper extends BaseMapperX<ResourceSpuDO> { ...@@ -44,4 +44,13 @@ public interface ResourceSpuMapper extends BaseMapperX<ResourceSpuDO> {
.orderByDesc(ResourceSpuDO::getId)); .orderByDesc(ResourceSpuDO::getId));
} }
/**
* 原子递减库存:仅当库存大于0时将库存-1
*
* @param id SPU 主键ID
* @return 受影响行数(1 表示成功递减,0 表示库存不足或不存在)
*/
@org.apache.ibatis.annotations.Update("UPDATE compute_resource_spu SET stock = stock - 1 WHERE id = #{id} AND stock > 0")
int decrementStock(@org.apache.ibatis.annotations.Param("id") Long id);
} }
\ No newline at end of file
...@@ -19,6 +19,8 @@ import com.luhu.computility.module.compute.dal.mysql.resourceorder.ResourceOrder ...@@ -19,6 +19,8 @@ import com.luhu.computility.module.compute.dal.mysql.resourceorder.ResourceOrder
import com.luhu.computility.module.compute.dal.redis.no.ResourceOrderNoRedisDAO; import com.luhu.computility.module.compute.dal.redis.no.ResourceOrderNoRedisDAO;
import com.luhu.computility.module.compute.enums.ResourceOrderInvoiceStatus; import com.luhu.computility.module.compute.enums.ResourceOrderInvoiceStatus;
import com.luhu.computility.module.compute.enums.ResourceOrderStatus; import com.luhu.computility.module.compute.enums.ResourceOrderStatus;
import com.luhu.computility.module.compute.enums.ResourceSkuStatus;
import com.luhu.computility.module.compute.enums.ResourceSpuStatus;
import com.luhu.computility.module.compute.service.resourcecategory.ResourceCategoryService; import com.luhu.computility.module.compute.service.resourcecategory.ResourceCategoryService;
import com.luhu.computility.module.compute.service.resourcesku.ResourceSkuService; import com.luhu.computility.module.compute.service.resourcesku.ResourceSkuService;
import com.luhu.computility.module.compute.service.resourcespu.ResourceSpuService; import com.luhu.computility.module.compute.service.resourcespu.ResourceSpuService;
...@@ -36,6 +38,8 @@ import com.luhu.computility.module.pay.enums.WpgjOrderStatusEnum; ...@@ -36,6 +38,8 @@ import com.luhu.computility.module.pay.enums.WpgjOrderStatusEnum;
import com.luhu.computility.module.pay.enums.order.PayOrderStatusEnum; import com.luhu.computility.module.pay.enums.order.PayOrderStatusEnum;
import com.luhu.computility.module.pay.framework.pay.core.client.impl.wpgj.WpgjPayProperties; import com.luhu.computility.module.pay.framework.pay.core.client.impl.wpgj.WpgjPayProperties;
import com.luhu.computility.module.pay.service.order.PayOrderService; import com.luhu.computility.module.pay.service.order.PayOrderService;
import com.luhu.computility.module.compute.dal.mysql.resourcespu.ResourceSpuMapper;
import com.luhu.computility.module.compute.dal.mysql.resourcesku.ResourceSkuMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -98,6 +102,12 @@ public class ResourceOrderServiceImpl implements ResourceOrderService { ...@@ -98,6 +102,12 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
@Resource @Resource
private WpgjPayProperties wpgjPayProperties; private WpgjPayProperties wpgjPayProperties;
@Resource
private ResourceSpuMapper resourceSpuMapper;
@Resource
private ResourceSkuMapper resourceSkuMapper;
@Override @Override
public Long createResourceOrder(ResourceOrderSaveReqVO createReqVO) { public Long createResourceOrder(ResourceOrderSaveReqVO createReqVO) {
// 插入 // 插入
...@@ -187,6 +197,11 @@ public class ResourceOrderServiceImpl implements ResourceOrderService { ...@@ -187,6 +197,11 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
throw exception(RESOURCE_ORDER_SPU_NOT_EXISTS); throw exception(RESOURCE_ORDER_SPU_NOT_EXISTS);
} }
// 校验SPU库存是否充足(<= 0 视为无库存)
if (spu.getStock() == null || spu.getStock() <= 0) {
throw exception(RESOURCE_SPU_STOCK_NOT_ENOUGH);
}
// 构建订单数据 // 构建订单数据
ResourceOrderDO order = new ResourceOrderDO(); ResourceOrderDO order = new ResourceOrderDO();
order.setUserId(userId); order.setUserId(userId);
...@@ -259,6 +274,13 @@ public class ResourceOrderServiceImpl implements ResourceOrderService { ...@@ -259,6 +274,13 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
updateOrder.setPayTime(LocalDateTime.now()); updateOrder.setPayTime(LocalDateTime.now());
resourceOrderMapper.updateById(updateOrder); resourceOrderMapper.updateById(updateOrder);
// 4. 扣减库存并在库存为0时下架对应的 SPU 和其全部 SKU
try {
handleStockAndStatusAfterPaid(order);
} catch (Exception ex) {
log.error("[updateOrderPaid] 扣减库存或下架处理失败, orderId={}", orderId, ex);
}
} }
@Override @Override
...@@ -553,6 +575,8 @@ public class ResourceOrderServiceImpl implements ResourceOrderService { ...@@ -553,6 +575,8 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
orderId, wpgjOrderAmt, resourceOrderAmt); orderId, wpgjOrderAmt, resourceOrderAmt);
return; return;
} }
log.error("[updateOrderPaidByWpgj] WPGJ金额: {}, 订单金额: {}",
orderId, wpgjOrderAmt, resourceOrderAmt);
// 4. 更新算力资源订单状态为已支付 // 4. 更新算力资源订单状态为已支付
ResourceOrderDO updateResourceOrder = new ResourceOrderDO(); ResourceOrderDO updateResourceOrder = new ResourceOrderDO();
...@@ -569,6 +593,13 @@ public class ResourceOrderServiceImpl implements ResourceOrderService { ...@@ -569,6 +593,13 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
resourceOrderMapper.updateById(updateResourceOrder); resourceOrderMapper.updateById(updateResourceOrder);
payOrderWpgjMapper.updateById(updatePayOrder); payOrderWpgjMapper.updateById(updatePayOrder);
// 5. 扣减库存并在库存为0时下架对应的 SPU 和其全部 SKU
try {
handleStockAndStatusAfterPaid(order);
} catch (Exception ex) {
log.error("[updateOrderPaidByWpgj] 扣减库存或下架处理失败, orderId={}", orderId, ex);
}
log.info("[updateOrderPaidByWpgj] WPGJ支付成功回调处理完成,订单ID: {}, WPGJ订单号: {}", log.info("[updateOrderPaidByWpgj] WPGJ支付成功回调处理完成,订单ID: {}, WPGJ订单号: {}",
orderId, notifyDTO.getOrderId()); orderId, notifyDTO.getOrderId());
...@@ -580,6 +611,53 @@ public class ResourceOrderServiceImpl implements ResourceOrderService { ...@@ -580,6 +611,53 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
} }
} }
/**
* 支付完成后扣减 SPU 库存,若库存为 0 则下架对应 SPU 及其所有 SKU
*/
private void handleStockAndStatusAfterPaid(ResourceOrderDO order) {
// 仅当订单包含 SKU 时才处理
if (order.getSkuId() == null) {
return;
}
ResourceSkuDO sku = resourceSkuService.getResourceSku(order.getSkuId());
if (sku == null) {
log.warn("[handleStockAndStatusAfterPaid] SKU 不存在, skuId={}", order.getSkuId());
return;
}
Long spuId = sku.getSpuId();
if (spuId == null) {
log.warn("[handleStockAndStatusAfterPaid] SKU 未绑定 SPU, skuId={}", sku.getId());
return;
}
// 原子扣减库存
int affected = resourceSpuMapper.decrementStock(spuId);
if (affected == 0) {
// 并发下可能库存已为0,记录日志即可
log.warn("[handleStockAndStatusAfterPaid] 库存递减失败,可能库存不足或已变更,spuId={}", spuId);
}
// 重新查询库存,若为 0 则下架 SPU 与其所有 SKU
ResourceSpuDO spuAfter = resourceSpuService.getResourceSpu(spuId);
if (spuAfter == null) {
log.warn("[handleStockAndStatusAfterPaid] SPU 不存在, spuId={}", spuId);
return;
}
Integer stock = spuAfter.getStock();
if (stock == null || stock <= 0) {
// 下架 SPU
ResourceSpuDO updateSpu = new ResourceSpuDO();
updateSpu.setId(spuId);
updateSpu.setStatus(ResourceSpuStatus.OFFLINE.getValue());
resourceSpuMapper.updateById(updateSpu);
// 下架该 SPU 下所有 SKU
resourceSkuMapper.updateStatusBySpuId(spuId, ResourceSkuStatus.OFFLINE.getValue());
log.info("[handleStockAndStatusAfterPaid] 库存为0,已下架 SPU 及其所有 SKU,spuId={}", spuId);
}
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateOrderFailedByWpgj(Long orderId, WpgjPayNotifyDTO notifyDTO) { public void updateOrderFailedByWpgj(Long orderId, WpgjPayNotifyDTO notifyDTO) {
......
...@@ -112,6 +112,10 @@ ...@@ -112,6 +112,10 @@
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId> <artifactId>flatten-maven-plugin</artifactId>
</plugin> </plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins> </plugins>
</pluginManagement> </pluginManagement>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment