jun2024's picture
Upload 2241 files
f8b03c1 verified
Raw History Blame Contribute Delete
8.22 kB
"""
法院文书智能识别数据类
定义文书识别相关的数据传输对象(DTO)
Requirements: 4.5, 7.4
"""
from dataclasses import dataclass
from datetime import datetime
from enum import Enum
from typing import Any
from django.utils.translation import gettext_lazy as _
class DocumentType(str, Enum):
"""
文书类型枚举
Requirements: 4.2
"""
SUMMONS = "summons" # 传票
EXECUTION_RULING = "execution" # 执行裁定书
OTHER = "other" # 其他
@dataclass
class RecognitionResult:
"""
识别结果 DTO
包含文书类型识别和关键信息提取的结果。
Requirements: 4.5, 7.4
Attributes:
document_type: 文书类型(传票/执行裁定书/其他)
case_number: 识别出的案号,可能为空
key_time: 关键时间(开庭时间/保全到期时间),可能为空
raw_text: 从文书中提取的原始文字
confidence: 识别置信度,范围 0-1
extraction_method: 文本提取方式("pdf_direct" 或 "ocr")
"""
document_type: DocumentType
case_number: str | None
key_time: datetime | None
raw_text: str
confidence: float
extraction_method: str
def to_dict(self) -> dict[str, Any]:
"""序列化为字典"""
return {
"document_type": self.document_type.value,
"case_number": self.case_number,
"key_time": self.key_time.isoformat() if self.key_time else None,
"raw_text": self.raw_text,
"confidence": self.confidence,
"extraction_method": self.extraction_method,
}
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "RecognitionResult":
"""从字典反序列化"""
key_time = None
if data.get("key_time"):
if isinstance(data["key_time"], str):
key_time = datetime.fromisoformat(data["key_time"])
else:
key_time = data["key_time"]
return cls(
document_type=DocumentType(data["document_type"]),
case_number=data.get("case_number"),
key_time=key_time,
raw_text=data.get("raw_text", ""),
confidence=data.get("confidence", 0.0),
extraction_method=data.get("extraction_method", ""),
)
@dataclass
class BindingResult:
"""
绑定结果 DTO
包含文书与案件绑定的结果信息。
Requirements: 5.7, 5.8
Attributes:
success: 绑定是否成功
case_id: 匹配到的案件 ID,绑定失败时为空
case_name: 匹配到的案件名称,绑定失败时为空
case_log_id: 创建的案件日志 ID,绑定失败时为空
message: 结果消息(成功或失败原因)
error_code: 错误代码,成功时为空
"""
success: bool
case_id: int | None
case_name: str | None
case_log_id: int | None
message: str
error_code: str | None = None
def to_dict(self) -> dict[str, Any]:
"""序列化为字典"""
return {
"success": self.success,
"case_id": self.case_id,
"case_name": self.case_name,
"case_log_id": self.case_log_id,
"message": self.message,
"error_code": self.error_code,
}
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "BindingResult":
"""从字典反序列化"""
return cls(
success=data.get("success", False),
case_id=data.get("case_id"),
case_name=data.get("case_name"),
case_log_id=data.get("case_log_id"),
message=data.get("message", ""),
error_code=data.get("error_code"),
)
@classmethod
def success_result(
cls,
case_id: int,
case_name: str,
case_log_id: int,
) -> "BindingResult":
"""创建成功的绑定结果"""
return cls(
success=True,
case_id=case_id,
case_name=case_name,
case_log_id=case_log_id,
message=f"文书已绑定到案件 {case_name}",
)
@classmethod
def failure_result(
cls,
message: str,
error_code: str,
) -> "BindingResult":
"""创建失败的绑定结果"""
return cls(
success=False,
case_id=None,
case_name=None,
case_log_id=None,
message=message,
error_code=error_code,
)
@dataclass
class NotificationResult:
"""
通知发送结果 DTO
包含飞书群通知发送的结果信息。
Requirements: 5.1, 5.2
Attributes:
success: 通知是否发送成功
message: 结果消息(成功或失败原因)
error_code: 错误代码,成功时为空
sent_at: 通知发送时间,失败时为空
file_sent: 文件是否发送成功
"""
success: bool
message: str | None = None
error_code: str | None = None
sent_at: datetime | None = None
file_sent: bool = False
def to_dict(self) -> dict[str, Any]:
"""序列化为字典"""
return {
"success": self.success,
"message": self.message,
"error_code": self.error_code,
"sent_at": self.sent_at.isoformat() if self.sent_at else None,
"file_sent": self.file_sent,
}
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "NotificationResult":
"""从字典反序列化"""
sent_at = None
if data.get("sent_at"):
if isinstance(data["sent_at"], str):
sent_at = datetime.fromisoformat(data["sent_at"])
else:
sent_at = data["sent_at"]
return cls(
success=data.get("success", False),
message=data.get("message"),
error_code=data.get("error_code"),
sent_at=sent_at,
file_sent=data.get("file_sent", False),
)
@classmethod
def success_result(
cls,
sent_at: datetime,
file_sent: bool = False,
) -> "NotificationResult":
"""
创建成功的通知结果
Args:
sent_at: 通知发送时间
file_sent: 文件是否发送成功
Returns:
NotificationResult: 成功的通知结果
"""
return cls(
success=True,
message=str(_("通知发送成功")),
sent_at=sent_at,
file_sent=file_sent,
)
@classmethod
def failure_result(
cls,
message: str,
error_code: str,
) -> "NotificationResult":
"""
创建失败的通知结果
Args:
message: 失败原因描述
error_code: 错误代码
Returns:
NotificationResult: 失败的通知结果
"""
return cls(
success=False,
message=message,
error_code=error_code,
)
@dataclass
class RecognitionResponse:
"""
完整响应 DTO
包含识别结果、绑定结果和文件路径的完整响应。
Requirements: 4.5, 7.4
Attributes:
recognition: 识别结果
binding: 绑定结果,非支持文书类型时为空
file_path: 上传文件的保存路径
"""
recognition: RecognitionResult
binding: BindingResult | None
file_path: str
def to_dict(self) -> dict[str, Any]:
"""序列化为字典"""
return {
"recognition": self.recognition.to_dict(),
"binding": self.binding.to_dict() if self.binding else None,
"file_path": self.file_path,
}
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "RecognitionResponse":
"""从字典反序列化"""
binding = None
if data.get("binding"):
binding = BindingResult.from_dict(data["binding"])
return cls(
recognition=RecognitionResult.from_dict(data["recognition"]),
binding=binding,
file_path=data.get("file_path", ""),
)