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);
}
```