修复:强化装填事务一致性

This commit is contained in:
焦龙言
2026-07-26 17:56:58 +08:00
parent 18abe861f9
commit f6e994d95f
4 changed files with 182 additions and 22 deletions
@@ -117,7 +117,7 @@ class MasterDao:
) -> Any | None:
statement = select(model).where(id_column == resource_id)
if for_update:
statement = statement.with_for_update()
statement = statement.with_for_update().execution_options(populate_existing=True)
result = await db.execute(statement)
return result.scalar_one_or_none()
@@ -187,8 +187,20 @@ class MasterDao:
return await cls._paginate(db, statement, query_object, is_page)
@classmethod
async def get_strain(cls, db: AsyncSession, strain_id: int) -> BizStrain | None:
return await cls._get(db, BizStrain, BizStrain.strain_id, strain_id)
async def get_strain(
cls,
db: AsyncSession,
strain_id: int,
*,
for_update: bool = False,
) -> BizStrain | None:
return await cls._get(
db,
BizStrain,
BizStrain.strain_id,
strain_id,
for_update=for_update,
)
@classmethod
async def find_strain_by_code(cls, db: AsyncSession, strain_code: str) -> BizStrain | None:
@@ -96,6 +96,20 @@ class FillingService:
raise ServiceException(message=admin_message)
raise PermissionException(data='', message='无权访问该托盘')
@classmethod
async def _assert_pallet_warehouse_access(
cls,
query_db: AsyncSession,
current_user: CurrentUserModel,
warehouse_id: int,
) -> None:
try:
await AccessService.assert_warehouse_access(query_db, current_user, warehouse_id)
except PermissionException:
if cls._is_admin(current_user):
raise
cls._raise_pallet_not_accessible(current_user)
@staticmethod
def _validate_empty_warehouse_pallet(
pallet: BizPallet,
@@ -232,7 +246,7 @@ class FillingService:
cls._raise_pallet_not_accessible(current_user, '托盘库存不存在')
if inventory.warehouse_id is None:
cls._raise_pallet_not_accessible(current_user, '托盘不在仓库')
await AccessService.assert_warehouse_access(
await cls._assert_pallet_warehouse_access(
query_db,
current_user,
inventory.warehouse_id,
@@ -279,8 +293,6 @@ class FillingService:
warehouse_ids=warehouse_ids,
)
if recovered is None:
if not cls._is_admin(current_user):
raise PermissionException(data='', message='无权访问该装填记录')
raise ServiceException(message='装填失败,数据冲突')
await AccessService.assert_warehouse_access(
query_db,
@@ -330,11 +342,6 @@ class FillingService:
current_user,
page_object.warehouse_id,
)
warehouse = await MasterDao.get_warehouse(query_db, page_object.warehouse_id)
if warehouse is None:
raise ServiceException(message='仓库不存在')
if warehouse.status != '0':
raise ServiceException(message='仓库已停用')
scanned_pallet = await InventoryDao.get_pallet_by_qr_token(
query_db,
@@ -351,7 +358,7 @@ class FillingService:
cls._raise_pallet_not_accessible(current_user, '托盘库存不存在')
if inventory.warehouse_id is None:
cls._raise_pallet_not_accessible(current_user, '托盘不在仓库')
await AccessService.assert_warehouse_access(
await cls._assert_pallet_warehouse_access(
query_db,
current_user,
inventory.warehouse_id,
@@ -380,6 +387,23 @@ class FillingService:
current_user,
)
warehouse = await MasterDao.get_warehouse(
query_db,
page_object.warehouse_id,
for_update=True,
)
if warehouse is None:
raise ServiceException(message='仓库不存在')
if warehouse.status != '0':
raise ServiceException(message='仓库已停用')
strain = cls._validate_active_strain(
await MasterDao.get_strain(
query_db,
page_object.strain_id,
for_update=True,
)
)
cls._validate_empty_warehouse_pallet(
pallet,
inventory,
@@ -391,7 +415,6 @@ class FillingService:
PalletFlowState(inventory.flow_state),
PalletFlowState.FILLED_IN_WAREHOUSE,
)
strain = cls._validate_active_strain(await MasterDao.get_strain(query_db, page_object.strain_id))
current_time = datetime.now()
filling = BizFillingRecord(