@@ -11,10 +11,12 @@ import pers.amos.mall.common.enums.OrderTypeEnum;
import pers.amos.mall.common.log.LogUtil ;
import pers.amos.mall.common.response.Result ;
import pers.amos.mall.route.dal.dataobject.FixedScheduleDO ;
import pers.amos.mall.route.dal.dataobject.InventoryDO ;
import pers.amos.mall.route.dal.dataobject.InventoryLogDO ;
import pers.amos.mall.route.dal.dataobject.RollingScheduleDO ;
import pers.amos.mall.route.dal.repository.FixedScheduleRepository ;
import pers.amos.mall.route.dal.repository.InventoryLogRepository ;
import pers.amos.mall.route.dal.repository.InventoryRepository ;
import pers.amos.mall.route.dal.repository.RollingScheduleRepository ;
import java.time.LocalDateTime ;
@@ -31,6 +33,9 @@ public class RouteServiceImpl implements RouteService {
@Autowired
private RollingScheduleRepository rollingScheduleRepository ;
@Autowired
private InventoryRepository inventoryRepository ;
@Autowired
private InventoryLogRepository inventoryLogRepository ;
@@ -73,6 +78,7 @@ public class RouteServiceImpl implements RouteService {
// ==================== 固定班次库存操作 ====================
private Result < Boolean > checkFixedScheduleInventory ( InventoryCheckDTO dto ) {
// 1. 查询固定班次
FixedScheduleDO schedule = fixedScheduleRepository . getOne (
Wrappers . lambdaQuery ( FixedScheduleDO . class )
. eq ( FixedScheduleDO : : getScheduleCode , dto . getScheduleCode ( ) )
@@ -82,7 +88,15 @@ public class RouteServiceImpl implements RouteService {
return Result . fail ( " SCHEDULE_NOT_FOUND " , " 班次不存在 " ) ;
}
if ( schedule . getAvailableSeats ( ) < dto . getQuantity ( ) ) {
// 2. 通过库存编码查询库存
InventoryDO inventory = inventoryRepository . findByInventoryCode ( schedule . getInventoryCode ( ) ) ;
if ( inventory = = null ) {
return Result . fail ( " INVENTORY_NOT_FOUND " , " 库存不存在 " ) ;
}
// 3. 检查剩余库存
if ( inventory . getRemainingStock ( ) < dto . getQuantity ( ) ) {
return Result . fail ( " INSUFFICIENT_INVENTORY " , " 库存不足 " ) ;
}
@@ -90,6 +104,7 @@ public class RouteServiceImpl implements RouteService {
}
private Result < Boolean > lockFixedScheduleInventory ( InventoryOperationDTO dto ) {
// 1. 查询固定班次
FixedScheduleDO schedule = fixedScheduleRepository . getOne (
Wrappers . lambdaQuery ( FixedScheduleDO . class )
. eq ( FixedScheduleDO : : getScheduleCode , dto . getScheduleCode ( ) )
@@ -99,33 +114,47 @@ public class RouteServiceImpl implements RouteService {
return Result . fail ( " SCHEDULE_NOT_FOUND " , " 班次不存在 " ) ;
}
Integer beforeQty = schedule . getAvailableSeats ( ) ;
// 2. 查询库存
InventoryDO inventory = inventoryRepository . findByInventoryCode ( schedule . getInventoryCode ( ) ) ;
// 扣减可用库存
boolean success = fixedScheduleRepository . update (
Wrappers . lambdaUpdate ( FixedScheduleDO . class )
. eq ( FixedScheduleDO : : getScheduleCode , dto . getScheduleCode ( ) )
. setSql ( " available_seats = available_seats - " + dto . getQuantity ( ) )
. ge ( FixedScheduleDO : : getAvailableSeats , dto . getQuantity ( ) )
) ;
if ( inventory = = null ) {
return Result . fail ( " INVENTORY_NOT_FOUND " , " 库存不存在 " ) ;
}
Integer beforeQty = inventory . getRemainingStock ( ) ;
// 3. 扣减剩余库存(使用乐观锁)
inventory . setRemainingStock ( inventory . getRemainingStock ( ) - dto . getQuantity ( ) ) ;
inventory . setUpdateTime ( LocalDateTime . now ( ) ) ;
boolean success = inventoryRepository . updateWithVersion ( inventory ) ;
if ( ! success ) {
return Result . fail ( " INVENTORY_LOCK_FAILED " , " 库存锁定失败,可能库存不足或并发冲突 " ) ;
}
// 记录库存日志
saveInventoryLog ( OrderTypeEnum . FIXED . getCode ( ) , dto . getScheduleCode ( ) , null , InventoryOperationTypeEnum . LOCK . getCode ( ) ,
dto . getQuantity ( ) , beforeQty , beforeQty - dto . getQuantity ( ) ,
dto . getOrderNo ( ) , " 锁定库存 " ) ;
// 4. 记录库存日志
saveInventoryLog (
OrderTypeEnum . FIXED . getCode ( ) ,
dto . getScheduleCode ( ) ,
null ,
schedule . getInventoryCode ( ) ,
InventoryOperationTypeEnum . LOCK . getCode ( ) ,
dto . getQuantity ( ) ,
beforeQty ,
beforeQty - dto . getQuantity ( ) ,
dto . getOrderNo ( ) ,
" 锁定库存 "
) ;
LogUtil . info ( " 固定班次库存锁定成功, scheduleCode={}, quantity={}, orderNo={} " ,
dto . getScheduleCode ( ) , dto . getQuantity ( ) , dto . getOrderNo ( ) ) ;
LogUtil . info ( " 固定班次库存锁定成功, scheduleCode={}, inventoryCode={}, quantity={}, orderNo={} " ,
dto . getScheduleCode ( ) , schedule . getInventoryCode ( ) , dto . getQuantity ( ) , dto . getOrderNo ( ) ) ;
return Result . success ( true ) ;
}
private Result < Boolean > deductFixedScheduleInventory ( InventoryOperationDTO dto ) {
// 固定班次在锁定时已经扣减了available_seats, 这里只需要增加sold_seats
// 1. 查询 固定班次
FixedScheduleDO schedule = fixedScheduleRepository . getOne (
Wrappers . lambdaQuery ( FixedScheduleDO . class )
. eq ( FixedScheduleDO : : getScheduleCode , dto . getScheduleCode ( ) )
@@ -135,26 +164,43 @@ public class RouteServiceImpl implements RouteService {
return Result . fail ( " SCHEDULE_NOT_FOUND " , " 班次不存在 " ) ;
}
Integer beforeSold = schedule . getSoldSeats ( ) ;
// 2. 查询库存
InventoryDO inventory = inventoryRepository . findByInventoryCode ( schedule . getInventoryCode ( ) ) ;
fixedScheduleRepository . update (
Wrappers . lambdaUpdate ( FixedScheduleDO . class )
. eq ( FixedScheduleDO : : getScheduleCode , dto . getScheduleCode ( ) )
. setSql ( " sold_seats = sold_seats + " + dto . getQuantity ( ) )
if ( inventory = = null ) {
return Result . fail ( " INVENTORY_NOT_FOUND " , " 库存不存在 " ) ;
}
Integer beforeSold = inventory . getSoldStock ( ) ;
// 3. 增加已售库存
inventory . setSoldStock ( inventory . getSoldStock ( ) + dto . getQuantity ( ) ) ;
inventory . setUpdateTime ( LocalDateTime . now ( ) ) ;
inventoryRepository . save ( inventory ) ;
// 4. 记录库存日志
saveInventoryLog (
OrderTypeEnum . FIXED . getCode ( ) ,
dto . getScheduleCode ( ) ,
null ,
schedule . getInventoryCode ( ) ,
InventoryOperationTypeEnum . DEDUCT . getCode ( ) ,
dto . getQuantity ( ) ,
beforeSold ,
beforeSold + dto . getQuantity ( ) ,
dto . getOrderNo ( ) ,
" 扣减库存(支付成功) "
) ;
// 记录库存日志
saveInventoryLog ( OrderTypeEnum . FIXED . getCode ( ) , dto . getScheduleCode ( ) , null , InventoryOperationTypeEnum . DEDUCT . getCode ( ) ,
dto . getQuantity ( ) , beforeSold , beforeSold + dto . getQuantity ( ) ,
dto . getOrderNo ( ) , " 扣减库存(支付成功) " ) ;
LogUtil . info ( " 固定班次库存扣减成功, scheduleCode={}, quantity={}, orderNo={} " ,
dto . getScheduleCode ( ) , dto . getQuantity ( ) , dto . getOrderNo ( ) ) ;
LogUtil . info ( " 固定班次库存扣减成功, scheduleCode={}, inventoryCode={}, quantity={}, orderNo={} " ,
dto . getScheduleCode ( ) , schedule . getInventoryCode ( ) , dto . getQuantity ( ) , dto . getOrderNo ( ) ) ;
return Result . success ( true ) ;
}
private Result < Boolean > releaseFixedScheduleInventory ( InventoryOperationDTO dto ) {
// 1. 查询固定班次
FixedScheduleDO schedule = fixedScheduleRepository . getOne (
Wrappers . lambdaQuery ( FixedScheduleDO . class )
. eq ( FixedScheduleDO : : getScheduleCode , dto . getScheduleCode ( ) )
@@ -164,22 +210,37 @@ public class RouteServiceImpl implements RouteService {
return Result . fail ( " SCHEDULE_NOT_FOUND " , " 班次不存在 " ) ;
}
Integer beforeQty = schedule . getAvailableSeats ( ) ;
// 2. 查询库存
InventoryDO inventory = inventoryRepository . findByInventoryCode ( schedule . getInventoryCode ( ) ) ;
// 释放库存
fixedScheduleRepository . update (
Wrappers . lambdaUpdate ( FixedScheduleDO . class )
. eq ( FixedScheduleDO : : getScheduleCode , dto . getScheduleCode ( ) )
. setSql ( " available_seats = available_seats + " + dto . getQuantity ( ) )
if ( inventory = = null ) {
return Result . fail ( " INVENTORY_NOT_FOUND " , " 库存不存在 " ) ;
}
Integer beforeQty = inventory . getRemainingStock ( ) ;
// 3. 释放库存(增加剩余库存)
inventory . setRemainingStock ( inventory . getRemainingStock ( ) + dto . getQuantity ( ) ) ;
inventory . setUpdateTime ( LocalDateTime . now ( ) ) ;
inventoryRepository . save ( inventory ) ;
// 4. 记录库存日志
saveInventoryLog (
OrderTypeEnum . FIXED . getCode ( ) ,
dto . getScheduleCode ( ) ,
null ,
schedule . getInventoryCode ( ) ,
InventoryOperationTypeEnum . RELEASE . getCode ( ) ,
dto . getQuantity ( ) ,
beforeQty ,
beforeQty + dto . getQuantity ( ) ,
dto . getOrderNo ( ) ,
" 释放库存(订单取消/超时) "
) ;
// 记录库存日志
saveInventoryLog ( OrderTypeEnum . FIXED . getCode ( ) , dto . getScheduleCode ( ) , null , InventoryOperationTypeEnum . RELEASE . getCode ( ) ,
dto . getQuantity ( ) , beforeQty , beforeQty + dto . getQuantity ( ) ,
dto . getOrderNo ( ) , " 释放库存(订单取消/超时) " ) ;
LogUtil . info ( " 固定班次库存释放成功, scheduleCode={}, quantity={}, orderNo={} " ,
dto . getScheduleCode ( ) , dto . getQuantity ( ) , dto . getOrderNo ( ) ) ;
LogUtil . info ( " 固定班次库存释放成功, scheduleCode={}, inventoryCode={}, quantity={}, orderNo={} " ,
dto . getScheduleCode ( ) , schedule . getInventoryCode ( ) , dto . getQuantity ( ) , dto . getOrderNo ( ) ) ;
return Result . success ( true ) ;
}
@@ -187,6 +248,7 @@ public class RouteServiceImpl implements RouteService {
// ==================== 滚动班次库存操作 ====================
private Result < Boolean > checkRollingScheduleInventory ( InventoryCheckDTO dto ) {
// 1. 查询滚动班次
RollingScheduleDO schedule = rollingScheduleRepository . getOne (
Wrappers . lambdaQuery ( RollingScheduleDO . class )
. eq ( RollingScheduleDO : : getRollingScheduleCode , dto . getRollingScheduleCode ( ) )
@@ -196,7 +258,15 @@ public class RouteServiceImpl implements RouteService {
return Result . fail ( " SCHEDULE_NOT_FOUND " , " 滚动班次不存在 " ) ;
}
if ( schedule . getAvailableSeats ( ) < dto . getQuantity ( ) ) {
// 2. 通过库存编码查询库存
InventoryDO inventory = inventoryRepository . findByInventoryCode ( schedule . getInventoryCode ( ) ) ;
if ( inventory = = null ) {
return Result . fail ( " INVENTORY_NOT_FOUND " , " 库存不存在 " ) ;
}
// 3. 检查剩余库存
if ( inventory . getRemainingStock ( ) < dto . getQuantity ( ) ) {
return Result . fail ( " INSUFFICIENT_INVENTORY " , " 库存不足 " ) ;
}
@@ -204,6 +274,7 @@ public class RouteServiceImpl implements RouteService {
}
private Result < Boolean > lockRollingScheduleInventory ( InventoryOperationDTO dto ) {
// 1. 查询滚动班次
RollingScheduleDO schedule = rollingScheduleRepository . getOne (
Wrappers . lambdaQuery ( RollingScheduleDO . class )
. eq ( RollingScheduleDO : : getRollingScheduleCode , dto . getRollingScheduleCode ( ) )
@@ -213,32 +284,47 @@ public class RouteServiceImpl implements RouteService {
return Result . fail ( " SCHEDULE_NOT_FOUND " , " 滚动班次不存在 " ) ;
}
Integer beforeQty = schedule . getAvailableSeats ( ) ;
// 2. 查询库存
InventoryDO inventory = inventoryRepository . findByInventoryCode ( schedule . getInventoryCode ( ) ) ;
// 乐观锁扣减共享库存池
boolean success = rollingScheduleRepository . update (
Wrappers . lambdaUpdate ( RollingScheduleDO . class )
. eq ( RollingScheduleDO : : getRollingScheduleCode , dto . getRollingScheduleCode ( ) )
. setSql ( " available_seats = available_seats - " + dto . getQuantity ( ) )
. ge ( RollingScheduleDO : : getAvailableSeats , dto . getQuantity ( ) )
) ;
if ( inventory = = null ) {
return Result . fail ( " INVENTORY_NOT_FOUND " , " 库存不存在 " ) ;
}
Integer beforeQty = inventory . getRemainingStock ( ) ;
// 3. 扣减剩余库存(使用乐观锁)
inventory . setRemainingStock ( inventory . getRemainingStock ( ) - dto . getQuantity ( ) ) ;
inventory . setUpdateTime ( LocalDateTime . now ( ) ) ;
boolean success = inventoryRepository . updateWithVersion ( inventory ) ;
if ( ! success ) {
return Result . fail ( " INVENTORY_LOCK_FAILED " , " 库存锁定失败,可能库存不足或并发冲突 " ) ;
}
// 记录库存日志
saveInventoryLog ( OrderTypeEnum . ROLLING . getCode ( ) , null , dto . getRollingScheduleCode ( ) , InventoryOperationTypeEnum . LOCK . getCode ( ) ,
dto . getQuantity ( ) , beforeQty , beforeQty - dto . getQuantity ( ) ,
dto . getOrderNo ( ) , " 锁定共享库存池 " ) ;
// 4. 记录库存日志
saveInventoryLog (
OrderTypeEnum . ROLLING . getCode ( ) ,
null ,
dto . getRollingScheduleCode ( ) ,
schedule . getInventoryCode ( ) ,
InventoryOperationTypeEnum . LOCK . getCode ( ) ,
dto . getQuantity ( ) ,
beforeQty ,
beforeQty - dto . getQuantity ( ) ,
dto . getOrderNo ( ) ,
" 锁定共享库存池 "
) ;
LogUtil . info ( " 滚动班次库存锁定成功, rollingScheduleCode={}, quantity={}, orderNo={} " ,
dto . getRollingScheduleCode ( ) , dto . getQuantity ( ) , dto . getOrderNo ( ) ) ;
LogUtil . info ( " 滚动班次库存锁定成功, rollingScheduleCode={}, inventoryCode={}, quantity={}, orderNo={} " ,
dto . getRollingScheduleCode ( ) , schedule . getInventoryCode ( ) , dto . getQuantity ( ) , dto . getOrderNo ( ) ) ;
return Result . success ( true ) ;
}
private Result < Boolean > deductRollingScheduleInventory ( InventoryOperationDTO dto ) {
// 1. 查询滚动班次
RollingScheduleDO schedule = rollingScheduleRepository . getOne (
Wrappers . lambdaQuery ( RollingScheduleDO . class )
. eq ( RollingScheduleDO : : getRollingScheduleCode , dto . getRollingScheduleCode ( ) )
@@ -248,26 +334,43 @@ public class RouteServiceImpl implements RouteService {
return Result . fail ( " SCHEDULE_NOT_FOUND " , " 滚动班次不存在 " ) ;
}
Integer beforeSold = schedule . getSoldSeats ( ) ;
// 2. 查询库存
InventoryDO inventory = inventoryRepository . findByInventoryCode ( schedule . getInventoryCode ( ) ) ;
rollingScheduleRepository . update (
Wrappers . lambdaUpdate ( RollingScheduleDO . class )
. eq ( RollingScheduleDO : : getRollingScheduleCode , dto . getRollingScheduleCode ( ) )
. setSql ( " sold_seats = sold_seats + " + dto . getQuantity ( ) )
if ( inventory = = null ) {
return Result . fail ( " INVENTORY_NOT_FOUND " , " 库存不存在 " ) ;
}
Integer beforeSold = inventory . getSoldStock ( ) ;
// 3. 增加已售库存
inventory . setSoldStock ( inventory . getSoldStock ( ) + dto . getQuantity ( ) ) ;
inventory . setUpdateTime ( LocalDateTime . now ( ) ) ;
inventoryRepository . save ( inventory ) ;
// 4. 记录库存日志
saveInventoryLog (
OrderTypeEnum . ROLLING . getCode ( ) ,
null ,
dto . getRollingScheduleCode ( ) ,
schedule . getInventoryCode ( ) ,
InventoryOperationTypeEnum . DEDUCT . getCode ( ) ,
dto . getQuantity ( ) ,
beforeSold ,
beforeSold + dto . getQuantity ( ) ,
dto . getOrderNo ( ) ,
" 扣减库存(支付成功) "
) ;
// 记录库存日志
saveInventoryLog ( OrderTypeEnum . ROLLING . getCode ( ) , null , dto . getRollingScheduleCode ( ) , InventoryOperationTypeEnum . DEDUCT . getCode ( ) ,
dto . getQuantity ( ) , beforeSold , beforeSold + dto . getQuantity ( ) ,
dto . getOrderNo ( ) , " 扣减库存(支付成功) " ) ;
LogUtil . info ( " 滚动班次库存扣减成功, rollingScheduleCode={}, quantity={}, orderNo={} " ,
dto . getRollingScheduleCode ( ) , dto . getQuantity ( ) , dto . getOrderNo ( ) ) ;
LogUtil . info ( " 滚动班次库存扣减成功, rollingScheduleCode={}, inventoryCode={}, quantity={}, orderNo={} " ,
dto . getRollingScheduleCode ( ) , schedule . getInventoryCode ( ) , dto . getQuantity ( ) , dto . getOrderNo ( ) ) ;
return Result . success ( true ) ;
}
private Result < Boolean > releaseRollingScheduleInventory ( InventoryOperationDTO dto ) {
// 1. 查询滚动班次
RollingScheduleDO schedule = rollingScheduleRepository . getOne (
Wrappers . lambdaQuery ( RollingScheduleDO . class )
. eq ( RollingScheduleDO : : getRollingScheduleCode , dto . getRollingScheduleCode ( ) )
@@ -277,22 +380,37 @@ public class RouteServiceImpl implements RouteService {
return Result . fail ( " SCHEDULE_NOT_FOUND " , " 滚动班次不存在 " ) ;
}
Integer beforeQty = schedule . getAvailableSeats ( ) ;
// 2. 查询库存
InventoryDO inventory = inventoryRepository . findByInventoryCode ( schedule . getInventoryCode ( ) ) ;
// 释放库存
rollingScheduleRepository . update (
Wrappers . lambdaUpdate ( RollingScheduleDO . class )
. eq ( RollingScheduleDO : : getRollingScheduleCode , dto . getRollingScheduleCode ( ) )
. setSql ( " available_seats = available_seats + " + dto . getQuantity ( ) )
if ( inventory = = null ) {
return Result . fail ( " INVENTORY_NOT_FOUND " , " 库存不存在 " ) ;
}
Integer beforeQty = inventory . getRemainingStock ( ) ;
// 3. 释放库存(增加剩余库存)
inventory . setRemainingStock ( inventory . getRemainingStock ( ) + dto . getQuantity ( ) ) ;
inventory . setUpdateTime ( LocalDateTime . now ( ) ) ;
inventoryRepository . save ( inventory ) ;
// 4. 记录库存日志
saveInventoryLog (
OrderTypeEnum . ROLLING . getCode ( ) ,
null ,
dto . getRollingScheduleCode ( ) ,
schedule . getInventoryCode ( ) ,
InventoryOperationTypeEnum . RELEASE . getCode ( ) ,
dto . getQuantity ( ) ,
beforeQty ,
beforeQty + dto . getQuantity ( ) ,
dto . getOrderNo ( ) ,
" 释放库存(订单取消/超时) "
) ;
// 记录库存日志
saveInventoryLog ( OrderTypeEnum . ROLLING . getCode ( ) , null , dto . getRollingScheduleCode ( ) , InventoryOperationTypeEnum . RELEASE . getCode ( ) ,
dto . getQuantity ( ) , beforeQty , beforeQty + dto . getQuantity ( ) ,
dto . getOrderNo ( ) , " 释放库存(订单取消/超时) " ) ;
LogUtil . info ( " 滚动班次库存释放成功, rollingScheduleCode={}, quantity={}, orderNo={} " ,
dto . getRollingScheduleCode ( ) , dto . getQuantity ( ) , dto . getOrderNo ( ) ) ;
LogUtil . info ( " 滚动班次库存释放成功, rollingScheduleCode={}, inventoryCode={}, quantity={}, orderNo={} " ,
dto . getRollingScheduleCode ( ) , schedule . getInventoryCode ( ) , dto . getQuantity ( ) , dto . getOrderNo ( ) ) ;
return Result . success ( true ) ;
}
@@ -300,13 +418,15 @@ public class RouteServiceImpl implements RouteService {
// ==================== 库存日志记录 ====================
private void saveInventoryLog ( String inventoryType , String scheduleCode ,
String rollingScheduleCode , String operationTyp e,
Integer quantity , Integer beforeQty , Integer afterQ ty,
String rollingScheduleCode , String inventoryCod e,
String operationType , Integer quanti ty,
Integer beforeQty , Integer afterQty ,
String orderNo , String remark ) {
InventoryLogDO inventoryLogDO = new InventoryLogDO ( ) ;
inventoryLogDO . setInventoryType ( inventoryType ) ;
inventoryLogDO . setScheduleCode ( scheduleCode ) ;
inventoryLogDO . setRollingScheduleCode ( rollingScheduleCode ) ;
inventoryLogDO . setInventoryCode ( inventoryCode ) ;
inventoryLogDO . setOperationType ( operationType ) ;
inventoryLogDO . setQuantity ( quantity ) ;
inventoryLogDO . setBeforeQty ( beforeQty ) ;