File size: 5,000 Bytes
b4f2238 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | """当事人 Admin 服务层。"""
from __future__ import annotations
import logging
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any
from django.utils.translation import gettext_lazy as _
from apps.client.services.client_admin_file_mixin import _DOC_TYPE_DISPLAY, ClientAdminFileMixin
from apps.core.exceptions import ValidationException
if TYPE_CHECKING:
from apps.client.models import Client
from .client_identity_doc_service import ClientIdentityDocService
from .client_internal_query_service import ClientInternalQueryService
logger = logging.getLogger("apps.client")
@dataclass
class ImportResult:
"""JSON 导入结果"""
success: bool
client: Client | None = None
error_message: str | None = None
class ClientAdminService(ClientAdminFileMixin):
"""客户 Admin 服务:JSON 导入、表单集文件上传、事务管理。"""
def __init__(
self,
identity_doc_service: ClientIdentityDocService | None = None,
internal_query_service: ClientInternalQueryService | None = None,
) -> None:
self._identity_doc_service = identity_doc_service
self._internal_query_service = internal_query_service
@property
def identity_doc_service(self) -> ClientIdentityDocService:
"""延迟获取 ClientIdentityDocService"""
if self._identity_doc_service is None:
from .client_identity_doc_service import ClientIdentityDocService
self._identity_doc_service = ClientIdentityDocService()
return self._identity_doc_service
@property
def internal_query_service(self) -> ClientInternalQueryService:
"""延迟获取 ClientInternalQueryService"""
if self._internal_query_service is None:
from .client_internal_query_service import ClientInternalQueryService
self._internal_query_service = ClientInternalQueryService()
return self._internal_query_service
def import_from_json(self, json_data: dict[str, Any], admin_user: str) -> ImportResult:
"""从 JSON 导入客户,委托给 ClientJsonImporter。"""
from .importer import ClientJsonImporter
importer = ClientJsonImporter()
result = importer.import_from_json(json_data, admin_user=admin_user)
if result.success and result.client_id is not None:
client = self.internal_query_service.get_client(client_id=result.client_id)
return ImportResult(success=True, client=client)
return ImportResult(success=False, error_message=result.error_message)
def process_formset_files(self, client_id: int, formset_data: list[dict[str, Any]], admin_user: str) -> None:
"""处理表单集文件上传。"""
client = self.internal_query_service.get_client(client_id=client_id)
if not client:
raise ValidationException(
message=_("客户不存在"),
code="CLIENT_NOT_FOUND",
errors={"client_id": _("ID 为 %(id)s 的客户不存在") % {"id": client_id}},
)
processed_files = []
for form_data in formset_data:
if self._should_process_form(form_data):
file_info = self._process_single_form(client, form_data, admin_user)
if file_info:
processed_files.append(file_info)
logger.info(
"表单集文件处理完成",
extra={
"client_id": client_id,
"processed_count": len(processed_files),
"admin_user": admin_user,
"action": "process_formset_files",
},
)
def _should_process_form(self, form_data: dict[str, Any]) -> bool:
"""判断是否应该处理该表单项。"""
if form_data.get("DELETE"):
return False
return bool(form_data.get("file_path") or form_data.get("uploaded_file"))
def _process_single_form(self, client: Client, form_data: dict[str, Any], admin_user: str) -> dict[str, Any] | None:
"""处理单个表单项。"""
doc_type = form_data.get("doc_type")
if not doc_type:
logger.warning(
"表单项缺少证件类型",
extra={"client_id": client.pk, "admin_user": admin_user, "action": "process_single_form"},
)
return None
doc_type_display = _DOC_TYPE_DISPLAY.get(doc_type, doc_type)
file_path = self._handle_file_storage(form_data, client.name, doc_type_display)
if not file_path:
return None
doc_id = form_data.get("id")
if doc_id:
self._update_identity_doc(doc_id, file_path, admin_user)
else:
self.identity_doc_service.add_identity_doc(
client_id=client.pk,
doc_type=doc_type,
file_path=file_path,
)
return {"doc_type": doc_type, "file_path": file_path, "doc_id": doc_id}
|