document
API test

监听取消订单

POST

Description or Example

# 知识点 ## 发送手动释放库存的消息的要点 > 我这里采取的是将发送手动释放库存的消息放到ACK外, 因为, 发送这个消息是否成功并不能作为是否能成功处理当前消息的依据, 即, 即使消息发送失败了, 可以用日志重新发送, 没有必要重新入队 # 核心代码 ```java @Component @RabbitListener(queues = "order-release-order-queue") public class OrderListener { @Autowired private OrderFeignService orderFeignService; @Autowired private WareSender wareSender; @Autowired private SendMsgUtil sendMsgUtil; @RabbitHandler public void toCancelOrder(Message message, String orderSn, Channel channel) throws IOException { try { R info = orderFeignService.updateOrderStatus(orderSn); if (info.getCode() != 0) { // 更新订单失败 throw new RuntimeException("更新订单失败"); } channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); // 更新订单成功 // 更新日志, 成功处理消息 sendMsgUtil.finish(message.getMessageProperties().getMessageId()); }catch (Exception e) { channel.basicReject(message.getMessageProperties().getDeliveryTag(), true); } //todo: 解决重新入队的问题 wareSender.sendMsgWithOrderToRelease(orderSn); } } ``` ```java @PostMapping("/unlock/all/sku/stock") public R unLockSkusStock(@RequestBody List<WareOrderTaskDetailEntity> detailEntities) { try { Boolean isSuccess = wareInfoService.unLockSkusStock(detailEntities); if (!isSuccess) return R.error("释放库存失败"); } catch (Exception e) { R.error(e.getMessage()); } return R.ok(); } ``` ```java @Override @Transactional public Boolean unLockSkusStock(List<WareOrderTaskDetailEntity> detailEntities) { // 有库存的情况下批量解锁库存 if (detailEntities != null && !detailEntities.isEmpty()) { // 先过滤掉所有已经解锁了的, 留下锁定的, 只有锁定的才可以解锁 detailEntities.stream() .filter(detail -> WareConstant.LockEnum.LOCKED.getCode() == detail.getLockStatus()) .forEach(detail -> { if (wareSkuService.releaseStock(detail)) { // 如果释放库存成功, 更新工作单状态 detail.setLockStatus(WareConstant.LockEnum.UN_LOCKED.getCode()); wareOrderTaskDetailService.updateById(detail); }else { // 释放库存失败 throw new StockException("释放库存失败"); // 这样可以批量回滚 } }); } return true; } ```