功能:隔离五类测试业务链路

This commit is contained in:
焦龙言
2026-09-23 08:27:14 +08:00
parent 43fe17cc70
commit f5df2150d8
18 changed files with 1206 additions and 831 deletions
@@ -16,6 +16,7 @@ from module_business.dao.master_dao import MasterDao
from module_business.dao.operation_dao import OperationDao
from module_business.domain.enums import PalletEventType, PalletFlowState
from module_business.domain.pallet_state_machine import PalletStateMachine
from module_business.domain.test_batch_scope import TestBatchScope
from module_business.entity.do.master_do import BizPallet, BizStrain
from module_business.entity.do.operation_do import BizFillingRecord, BizPalletEvent, BizPalletInventory
from module_business.entity.vo.master_vo import StrainPageQueryModel
@@ -27,6 +28,7 @@ from module_business.entity.vo.operation_vo import (
PalletScanResponseModel,
)
from module_business.service.access_service import AccessService
from module_business.service.test_batch_access_service import TestBatchAccessService
class FillingService:
@@ -180,6 +182,7 @@ class FillingService:
query_db: AsyncSession,
query_object: FillingPageQueryModel,
current_user: CurrentUserModel,
test_scope: TestBatchScope,
is_page: bool = True,
) -> PageModel | list[FillingModel]:
warehouse_ids = await cls._warehouse_scope(query_db, current_user)
@@ -192,8 +195,9 @@ class FillingService:
result = await OperationDao.get_filling_list(
query_db,
query_object,
is_page,
warehouse_ids=warehouse_ids,
scope=test_scope,
is_page=is_page,
)
rows = result.rows if isinstance(result, PageModel) else result
models = [FillingModel.model_validate(record) for record in rows]
@@ -207,11 +211,13 @@ class FillingService:
query_db: AsyncSession,
filling_id: int,
current_user: CurrentUserModel,
test_scope: TestBatchScope,
) -> FillingModel:
warehouse_ids = await cls._warehouse_scope(query_db, current_user)
filling = await OperationDao.get_filling_by_id(
query_db,
filling_id,
test_scope,
warehouse_ids=warehouse_ids,
)
if filling is None:
@@ -223,11 +229,13 @@ class FillingService:
cls,
query_db: AsyncSession,
current_user: CurrentUserModel,
test_scope: TestBatchScope,
) -> list[BusinessOptionModel]:
cls._current_identity(current_user)
strains = await MasterDao.list_strain(
query_db,
StrainPageQueryModel(status='0'),
test_scope,
False,
)
options = [
@@ -247,11 +255,12 @@ class FillingService:
query_db: AsyncSession,
qr_token: str,
current_user: CurrentUserModel,
test_scope: TestBatchScope,
) -> PalletScanResponseModel:
pallet = await InventoryDao.get_pallet_by_qr_token(query_db, qr_token)
pallet = await InventoryDao.get_pallet_by_qr_token(query_db, qr_token, test_scope)
if pallet is None:
cls._raise_pallet_not_accessible(current_user)
inventory = await MasterDao.get_pallet_inventory(query_db, pallet.pallet_id)
inventory = await MasterDao.get_pallet_inventory(query_db, pallet.pallet_id, test_scope)
if inventory is None:
cls._raise_pallet_not_accessible(current_user, '托盘库存不存在')
if inventory.warehouse_id is None:
@@ -292,6 +301,7 @@ class FillingService:
page_object: FillingCreateModel,
request_hash: str,
current_user: CurrentUserModel,
test_scope: TestBatchScope,
) -> CrudResponseModel:
try:
warehouse_ids = await cls._warehouse_scope(query_db, current_user)
@@ -300,6 +310,7 @@ class FillingService:
recovered = await OperationDao.get_filling_by_idempotency_key(
query_db,
page_object.idempotency_key,
test_scope,
warehouse_ids=[page_object.warehouse_id],
)
if recovered is None:
@@ -321,9 +332,11 @@ class FillingService:
query_db: AsyncSession,
page_object: FillingCreateModel,
current_user: CurrentUserModel,
test_scope: TestBatchScope,
) -> CrudResponseModel:
recovery_transaction_ended = False
try:
await TestBatchAccessService.lock_active_batch(query_db, test_scope)
request_hash = cls._build_request_hash(page_object)
user_id, user_name = cls._current_identity(current_user)
warehouse_ids = await cls._warehouse_scope(query_db, current_user)
@@ -333,6 +346,7 @@ class FillingService:
existing = await OperationDao.get_filling_by_idempotency_key(
query_db,
page_object.idempotency_key,
test_scope,
warehouse_ids=[page_object.warehouse_id],
)
if existing is not None:
@@ -356,6 +370,7 @@ class FillingService:
scanned_pallet = await InventoryDao.get_pallet_by_qr_token(
query_db,
page_object.qr_token,
test_scope,
)
if scanned_pallet is None:
cls._raise_pallet_not_accessible(current_user)
@@ -363,6 +378,7 @@ class FillingService:
inventory = await InventoryDao.get_inventory_for_update(
query_db,
scanned_pallet.pallet_id,
test_scope,
)
if inventory is None:
cls._raise_pallet_not_accessible(current_user, '托盘库存不存在')
@@ -376,6 +392,7 @@ class FillingService:
locked_pallets = await InventoryDao.get_pallets_by_ids(
query_db,
[scanned_pallet.pallet_id],
test_scope,
)
if len(locked_pallets) != 1 or locked_pallets[0].pallet_id != scanned_pallet.pallet_id:
cls._raise_pallet_not_accessible(current_user)
@@ -385,6 +402,7 @@ class FillingService:
concurrent = await OperationDao.get_active_filling_for_update(
query_db,
inventory.active_filling_id,
test_scope,
)
if concurrent is not None and concurrent.idempotency_key == page_object.idempotency_key:
# 结束首次非锁定读取建立的 RR 快照,再按最新数据范围恢复并发成功结果。
@@ -395,11 +413,13 @@ class FillingService:
page_object,
request_hash,
current_user,
test_scope,
)
warehouse = await MasterDao.get_warehouse(
query_db,
inventory.warehouse_id,
test_scope,
for_update=True,
)
if warehouse is None:
@@ -416,6 +436,7 @@ class FillingService:
await MasterDao.get_strain(
query_db,
page_object.strain_id,
test_scope,
for_update=True,
)
)
@@ -452,6 +473,7 @@ class FillingService:
create_time=current_time,
update_by=user_name,
update_time=current_time,
test_batch_id=test_scope.batch_id,
)
filling = await OperationDao.add_filling_record(query_db, filling)
filling_id = filling.filling_id
@@ -485,6 +507,7 @@ class FillingService:
occurred_at=current_time,
idempotency_key=page_object.idempotency_key,
request_hash=request_hash,
test_batch_id=test_scope.batch_id,
)
await InventoryDao.add_event(query_db, inventory, event)
await query_db.commit()
@@ -496,6 +519,7 @@ class FillingService:
page_object,
request_hash,
current_user,
test_scope,
)
except Exception:
if not recovery_transaction_ended: