实战来了,基于DDD实现库存扣减~

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

@RestController
@Tag(name = "InventoryController", description = "库存API接口")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class InventoryController {
 ...
 
    @Operation(summary = "库存预扣",description = "sq-,wq+,创建订单时调用")
    @PostMapping("/api/inventory/withholdInventory")
    public void withholdInventory(@Valid @RequestBody InventoryLockRequest lockRequest)  {
        inventoryService.withholdInventory(lockRequest);
    }

    @Operation(summary = "库存扣减",description = "wq-,oq+,付款时调用")
    @PutMapping("/api/inventory/deductionInventory")
    public void deductionInventory(@RequestParam("transactionId") Long transactionId)  {
        inventoryService.deductionInventory(transactionId);
    }

    @Operation(summary = "库存发货",description = "oq-,发货时调用")
    @PutMapping("/api/inventory/shipInventory")
    public void shipInventory(@RequestParam("transactionId") Long transactionId)  {
        inventoryService.shipInventory(transactionId);
    }

    @Operation(summary = "释放库存")
    @PutMapping("/api/inventory/releaseInventory")
    public void releaseInventory(@RequestParam("transactionId") Long transactionId)  {
        inventoryService.releaseInventory(transactionId);
    }
    ...
}

在这里插入图片描述

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class InventoryServiceImpl implements InventoryService {    
    ...
    @Override
    @Transactional
    public void withholdInventory(InventoryLockRequest inventoryLockRequest) {
        Long inventoryId = inventoryLockRequest.getInventoryId();
        //1. 获取库存
        Inventory inventory = Optional.ofNullable(inventoryRepository.find(new InventoryId(inventoryId)))
                .orElseThrow(()->new BusinessException("No inventory found with id:" + inventoryId));

        // 2. 幂等校验
        boolean exists = inventoryRepository.existsWithTransactionId(inventoryLockRequest.getTransactionId());

        if(exists ){
            log.error("Inventory record with transaction ID {} already exists, no deduction will be made.", inventoryLockRequest.getTransactionId());
            return;
        }

        //3. 库存预扣
        inventory.withholdInventory(inventoryLockRequest.getQuantity());

        //4. 生成扣减记录
        InventoryRecord inventoryRecord = InventoryRecord.builder()
                .inventoryId(inventoryId)
                .userId(inventoryLockRequest.getUserId())
                .deductionQuantity(inventoryLockRequest.getQuantity())
                .transactionId(inventoryLockRequest.getTransactionId())
                .state(InventoryRecordStateEnum.PRE_DEDUCTION.code())
                .build();

        inventory.addInventoryRecord(inventoryRecord);

        inventoryRepository.save(inventory);
    }
    ...
}

在这里插入图片描述

@Data
public class Inventory implements Aggregate<InventoryId> {
    @Serial
    private static final long serialVersionUID = 2139884371907883203L;
    private InventoryId id;
 
 ...

    /**
     * 库存预扣 sq-,wq+
     * @param quantity  数量
     */
    public void withholdInventory(int quantity){
        if (quantity <= 0) {
            throw new BusinessException("扣减库存数量必须大于零");
        }

        if (getInventoryQuantity() - quantity < 0) {
            throw new BusinessException("库存不足,无法扣减库存");
        }

        sellableQuantity -= quantity;
        withholdingQuantity += quantity;
    }
  
    /**
     * 释放库存
     * @param currentState 当前状态
     * @param quantity 数量
     */
    public void releaseInventory(int currentState, Integer quantity) {
        InventoryRecordStateEnum stateEnum = InventoryRecordStateEnum.of(currentState);
        switch (stateEnum){
            //sq+,wq-
            case PRE_DEDUCTION -> {
                sellableQuantity += quantity;
                withholdingQuantity -= quantity;
            }
            //sq+,oq-
            case DEDUCTION -> {
                sellableQuantity += quantity;
                occupyQuantity -= quantity;
            }
            //sq+
            case SHIPPED -> {
                sellableQuantity += quantity;
            }
        }
    }
 ...
}

/**
* 仓储接口定义
*/
public interface InventoryRepository extends Repository<Inventory, InventoryId> {
    boolean existsWithTransactionId(Long transactionId);

    Inventory findByTransactionId(Long transactionId);
}

在这里插入图片描述

@Repository
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class InventoryRepositoryImpl implements InventoryRepository {
    ...
    @Override
    public Inventory find(InventoryId inventoryId) {

        InventoryItemDO inventoryItemDO = inventoryItemMapper.selectById(inventoryId.getValue());
        return itemInventoryConverter.fromData(inventoryItemDO);
    }

    @Override
    public Inventory save(Inventory aggregate) {
        InventoryItemDO inventoryItemDO = itemInventoryConverter.toData(aggregate);

        if(inventoryItemDO.getId() == null){
            inventoryItemMapper.insert(inventoryItemDO);
        }else{
            inventoryItemMapper.updateById(inventoryItemDO);
        }

        InventoryRecord inventoryRecord = aggregate.getInventoryRecordList().get(0);
        InventoryRecordDO inventoryRecordDO = inventoryRecordConverter.toData(inventoryRecord);

        if(inventoryRecordDO.getId() == null){
            inventoryRecordMapper.insert(inventoryRecordDO);
        }else{
            inventoryRecordMapper.updateById(inventoryRecordDO);
        }

        return aggregate;
    }
    ...
}

在这里插入图片描述

转载:https://mp.weixin.qq.com/s?__biz=MzAwMTk4NjM1MA==&mid=2247517846&idx=1&sn=9e06785056234fc1b208912efe041f5c&chksm=9ad39cd7ada415c1f0f165880a8f8d0125dfcd271ccb0538da1333c55aada4d6a3e2f122abec&scene=132&exptype=timeline_recommend_article_extendread_samebiz#wechat_redirect

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值