fc / apps /cases /services /case /case_query_service.py
jun2024's picture
Upload 2241 files
b4f2238 verified
Raw History Blame Contribute Delete
5.63 kB
"""案件查询服务 - 负责所有案件读取操作。"""
from __future__ import annotations
from typing import Any
from django.db.models import QuerySet
from django.utils.translation import gettext_lazy as _
from apps.cases.models import Case
from apps.core.exceptions import NotFoundError
from apps.core.security.access_context import AccessContext as SecurityAccessContext
from apps.core.security.permissions import PermissionMixin
from .case_access_policy import CaseAccessPolicy
from .case_queryset import get_case_queryset
from .case_search_service import CaseSearchService
class CaseQueryService(PermissionMixin):
"""案件查询服务,封装所有案件读取业务逻辑。"""
def __init__(
self,
search_service: CaseSearchService | None = None,
access_policy: CaseAccessPolicy | None = None,
) -> None:
self._access_policy = access_policy or CaseAccessPolicy()
self._search_service = search_service or CaseSearchService(access_policy=self._access_policy)
def get_case_queryset(self) -> QuerySet[Case, Case]:
"""获取带预加载的案件查询集。"""
return get_case_queryset()
def list_cases(
self,
case_type: str | None = None,
status: str | None = None,
user: Any | None = None,
org_access: dict[str, Any] | None = None,
perm_open_access: bool = False,
) -> QuerySet[Case, Case]:
"""获取案件列表(带权限过滤)。"""
return self._search_service.list_cases(
case_type=case_type,
status=status,
user=user,
org_access=org_access,
perm_open_access=perm_open_access,
)
def list_cases_ctx(
self,
*,
ctx: SecurityAccessContext,
case_type: str | None = None,
status: str | None = None,
) -> QuerySet[Case, Case]:
"""获取案件列表(AccessContext 版本)。"""
return self._search_service.list_cases_ctx(ctx=ctx, case_type=case_type, status=status)
def get_case(
self,
case_id: int,
user: Any | None = None,
org_access: dict[str, Any] | None = None,
perm_open_access: bool = False,
) -> Case:
"""获取单个案件(带权限检查)。
NotFoundError: 案件不存在
ForbiddenError: 无权限访问
"""
try:
case = get_case_queryset().get(id=case_id)
except Case.DoesNotExist:
raise NotFoundError(_("案件 %(id)s 不存在") % {"id": case_id}) from None
self._access_policy.ensure_access(
case_id=case.id,
user=user,
org_access=org_access,
perm_open_access=perm_open_access,
case=case,
)
return case
def get_case_ctx(self, *, case_id: int, ctx: SecurityAccessContext) -> Case:
"""获取单个案件(AccessContext 版本)。"""
try:
case = get_case_queryset().get(id=case_id)
except Case.DoesNotExist:
raise NotFoundError(_("案件 %(id)s 不存在") % {"id": case_id}) from None
self._access_policy.ensure_access_ctx(case_id=case.id, ctx=ctx, case=case)
return case
def search_cases(
self,
query: str,
limit: int = 10,
user: Any | None = None,
org_access: dict[str, Any] | None = None,
perm_open_access: bool = False,
) -> list[Case]:
"""综合搜索案件(案号、名称、当事人)。"""
return self._search_service.search_cases(
query=query,
limit=limit,
user=user,
org_access=org_access,
perm_open_access=perm_open_access,
)
def search_cases_ctx(self, *, ctx: SecurityAccessContext, query: str, limit: int = 10) -> list[Case]:
"""综合搜索案件(AccessContext 版本)。"""
return self._search_service.search_cases_ctx(ctx=ctx, query=query, limit=limit)
def search_by_case_number(
self,
case_number: str,
user: Any | None = None,
org_access: dict[str, Any] | None = None,
perm_open_access: bool = False,
exact_match: bool = False,
) -> QuerySet[Case, Case]:
"""通过案号搜索案件。"""
return self._search_service.search_by_case_number(
case_number=case_number,
user=user,
org_access=org_access,
perm_open_access=perm_open_access,
exact_match=exact_match,
)
def search_by_case_number_ctx(
self,
*,
ctx: SecurityAccessContext,
case_number: str,
exact_match: bool = False,
) -> QuerySet[Case, Case]:
"""通过案号搜索案件(AccessContext 版本)。"""
return self._search_service.search_by_case_number_ctx(
ctx=ctx,
case_number=case_number,
exact_match=exact_match,
)
def check_case_access(
self,
case: Case,
user: Any,
org_access: dict[str, Any] | None,
) -> bool:
"""检查用户是否有权访问案件。"""
return self._access_policy.has_access(
case_id=case.id,
user=user,
org_access=org_access,
case=case,
)
def check_case_access_ctx(self, *, case: Case, ctx: SecurityAccessContext) -> bool:
"""检查用户是否有权访问案件(AccessContext 版本)。"""
return self._access_policy.has_access_ctx(case_id=case.id, ctx=ctx, case=case)