修复:收紧入库数据范围校验

This commit is contained in:
焦龙言
2026-07-26 16:14:27 +08:00
parent 6f22cf0282
commit 2e616ab6e0
5 changed files with 416 additions and 74 deletions
@@ -2,7 +2,7 @@ import hashlib
import json
import secrets
from datetime import datetime
from typing import Any
from typing import Any, NoReturn
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession
@@ -81,18 +81,27 @@ class InboundService:
user_id, _ = cls._current_identity(current_user)
return sorted(set(await AccessDao.list_user_warehouse_ids(query_db, user_id)))
@classmethod
def _raise_inbound_not_accessible(
cls,
current_user: CurrentUserModel,
) -> NoReturn:
if cls._is_admin(current_user):
raise ServiceException(message='入库单不存在')
raise PermissionException(data='', message='无权访问该入库单')
@staticmethod
async def _validate_active_warehouse(
query_db: AsyncSession,
warehouse_id: int,
current_user: CurrentUserModel,
) -> Any:
await AccessService.assert_warehouse_access(query_db, current_user, warehouse_id)
warehouse = await MasterDao.get_warehouse(query_db, warehouse_id)
if warehouse is None:
raise ServiceException(message='目标仓库不存在')
if warehouse.status != '0':
raise ServiceException(message='目标仓库已停用')
await AccessService.assert_warehouse_access(query_db, current_user, warehouse_id)
return warehouse
@staticmethod
@@ -188,10 +197,14 @@ class InboundService:
inbound_id: int,
current_user: CurrentUserModel,
) -> InboundModel:
inbound = await OperationDao.get_inbound_by_id(query_db, inbound_id)
warehouse_ids = await cls._warehouse_scope(query_db, current_user)
inbound = await OperationDao.get_inbound_by_id(
query_db,
inbound_id,
warehouse_ids=warehouse_ids,
)
if inbound is None:
raise ServiceException(message='入库单不存在')
await AccessService.assert_warehouse_access(query_db, current_user, inbound.warehouse_id)
cls._raise_inbound_not_accessible(current_user)
return InboundModel.model_validate(inbound)
@classmethod
@@ -318,14 +331,14 @@ class InboundService:
) -> CrudResponseModel:
try:
_, user_name = cls._current_identity(current_user)
inbound = await OperationDao.get_inbound_for_update(query_db, page_object.inbound_id)
if inbound is None:
raise ServiceException(message='入库单不存在')
await AccessService.assert_warehouse_access(
warehouse_ids = await cls._warehouse_scope(query_db, current_user)
inbound = await OperationDao.get_inbound_for_update(
query_db,
current_user,
inbound.warehouse_id,
page_object.inbound_id,
warehouse_ids=warehouse_ids,
)
if inbound is None:
cls._raise_inbound_not_accessible(current_user)
if inbound.status != DocumentStatus.DRAFT.value:
raise ServiceException(message='已确认入库单不允许编辑')
await cls._validate_active_warehouse(
@@ -369,15 +382,15 @@ class InboundService:
raise ServiceException(message='入库单ID不能重复')
ordered_ids = sorted(inbound_ids)
warehouse_ids = await cls._warehouse_scope(query_db, current_user)
for inbound_id in ordered_ids:
inbound = await OperationDao.get_inbound_for_update(query_db, inbound_id)
if inbound is None:
raise ServiceException(message='入库单不存在')
await AccessService.assert_warehouse_access(
inbound = await OperationDao.get_inbound_for_update(
query_db,
current_user,
inbound.warehouse_id,
inbound_id,
warehouse_ids=warehouse_ids,
)
if inbound is None:
cls._raise_inbound_not_accessible(current_user)
if inbound.status != DocumentStatus.DRAFT.value:
raise ServiceException(message='已确认入库单不允许删除')
@@ -448,14 +461,14 @@ class InboundService:
) -> CrudResponseModel:
try:
user_id, user_name = cls._current_identity(current_user)
inbound = await OperationDao.get_inbound_by_id(query_db, inbound_id)
if inbound is None:
raise ServiceException(message='入库单不存在')
await AccessService.assert_warehouse_access(
warehouse_ids = await cls._warehouse_scope(query_db, current_user)
inbound = await OperationDao.get_inbound_by_id(
query_db,
current_user,
inbound.warehouse_id,
inbound_id,
warehouse_ids=warehouse_ids,
)
if inbound is None:
cls._raise_inbound_not_accessible(current_user)
request_hash = cls._build_confirm_request_hash(inbound_id)
idempotency_key = page_object.idempotency_key
@@ -477,14 +490,13 @@ class InboundService:
):
raise ServiceException(message='确认入库失败,幂等键已被其他请求使用')
locked_inbound = await OperationDao.get_inbound_for_update(query_db, inbound_id)
if locked_inbound is None:
raise ServiceException(message='入库单不存在')
await AccessService.assert_warehouse_access(
locked_inbound = await OperationDao.get_inbound_for_update(
query_db,
current_user,
locked_inbound.warehouse_id,
inbound_id,
warehouse_ids=warehouse_ids,
)
if locked_inbound is None:
cls._raise_inbound_not_accessible(current_user)
if locked_inbound.status == DocumentStatus.CONFIRMED.value:
if cls._is_exact_confirmed(
locked_inbound,