document
API test

解锁库存

POST

Description or Example

# 知识点 ## 解锁库存的场景 1. 如果没有订单, 一定要解锁库存呢 2. 如果存在订单, 且订单的状态为取消, 需要解锁库存 3. <font color="red">**如果工作单的状态为已解锁或已扣除, 不能解锁库存**</font> 4. **如果没有工作单, 不需要库存** > ++**判断逻辑: 判断是否有工作单 => 没有(不) | 有 -> 继续判断工作单状态 => 已释放|已扣除(不) | 锁定 -> 判断是否有订单 => 没有(不) | 有 -> 判断订单状态 => 未支付(释放) | 其他(不)**++ ## 为什么更新工作单状态 > 因为以后的场景存在主动释放和被动释放库存, 避免这两个操作重复释放库存, 因此需要时刻更新工作单状态, 只有被锁定的库存才能释放, 这样彻底保证了幂等性问题 ## 主动解锁库存能不能批量解锁? > 答案是不能的, 即使ware_id和sku_id的查询条件可以做到, 但是不同条件下的个数不同, 根本做不出这样的SQL, 所以只能一个一个改 ## 获取工作单详情的流程 > 首先通过订单获取工作单, 然后通过工作单获取所有的工作单详情 # 核心代码 ```java @RequestMapping("/unlock/sku/stock/{taskDetailId}") public R unLockSkuStock(@PathVariable String taskDetailId) { try{ Boolean isSuccess = wareInfoService.unlockSkuStock(taskDetailId); if (isSuccess) return R.ok(); else throw new StockException("解锁库存失败"); }catch (Exception e) { return R.error("解锁失败"); } } ``` ```java @Override public Boolean unlockSkuStock(String taskDetailId) { WareOrderTaskDetailEntity detail = wareOrderTaskDetailService.getById(taskDetailId); if (WareConstant.LockEnum.LOCKED.getCode() == detail.getLockStatus()) { // 判断锁定状态是否为已锁定 if (wareSkuService.releaseStock(detail)) { // 如果释放库存成功, 更新工作单状态 detail.setLockStatus(WareConstant.LockEnum.UN_LOCKED.getCode()); return wareOrderTaskDetailService.updateById(detail); } return false; } // 其他状态即 已解锁或者已扣除, 都不需要解锁 return true; } ``` ```xml <update id="releaseStock"> UPDATE wms_ware_sku SET stock_locked = stock_locked - #{detail.skuNum} WHERE ware_id = #{detail.wareId} AND sku_id = #{detail.skuId} </update> ``` ```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; } ``` ```java /** * 通过订单号获取工作单 * @param orderSn * @return */ @GetMapping("/{orderSn}") public R getTaskByOrderSn(@PathVariable String orderSn) { return R.ok().setData(wareOrderTaskService.getTaskByOrderSn(orderSn)); } ``` ```java public WareOrderTaskEntity getTaskByOrderSn(String orderSn) { LambdaQueryWrapper<WareOrderTaskEntity> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(WareOrderTaskEntity::getOrderSn, orderSn); return this.getOne(queryWrapper); } ``` ```java @GetMapping("/allDetail/{taskId}") public R getAllTaskDetailByTaskId(@PathVariable String taskId) { return R.ok().setData(wareOrderTaskDetailService.getAllTaskDetailByTaskId(taskId)); } ``` ```java @Override public List<WareOrderTaskDetailEntity> getAllTaskDetailByTaskId(String taskId) { LambdaQueryWrapper<WareOrderTaskDetailEntity> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(WareOrderTaskDetailEntity::getTaskId, taskId); return this.list(queryWrapper); } ```