Download apps/automation/services/document_delivery/data_classes.py from jun2024/fc: direct link, hf CLI and curl.
- Browser
- Download file 8.4 kB
-
https://huggingface.co/spaces/jun2024/fc/resolve/main/apps/automation/services/document_delivery/data_classes.py
- Command line
-
hf download hf://spaces/jun2024/fc/apps/automation/services/document_delivery/data_classes.py
-
curl -L -o data_classes.py https://huggingface.co/spaces/jun2024/fc/resolve/main/apps/automation/services/document_delivery/data_classes.py
8.4 kB
| """ | |
| 文书送达数据类 | |
| 定义文书送达相关的数据传输对象 | |
| """ | |
| from dataclasses import dataclass, field | |
| from datetime import datetime | |
| from typing import Any | |
| # ============================================================ | |
| # API 响应数据类 (来自法院一张网 API) | |
| # ============================================================ | |
| class DocumentRecord: | |
| """ | |
| 单个文书记录 - 来自 getSdListByZjhmAndAhdmNew API | |
| 对应 Requirements 1.2, 3.1 | |
| """ | |
| ah: str # 案号,如"(2025)粤0604民初41257号" | |
| sdbh: str # 送达编号 - 用于获取文书详情 | |
| ajzybh: str # 案件主要编号 | |
| fssj: str # 发送时间,如"2025-12-10 16:25:37" - 用于时间过滤 | |
| fymc: str # 法院名称 | |
| ahdm: str = "" # 案号代码 | |
| fybh: str = "" # 法院编号 | |
| ssdrxm: str = "" # 送达人姓名 | |
| ssdrsjhm: str = "" # 送达人手机号 | |
| ssdrzjhm: str = "" # 送达人证件号码 | |
| wsmc: str = "" # 文书名称(多个用逗号分隔) | |
| sdzt: str = "" # 送达状态 | |
| qdzt: str = "" # 签到状态 | |
| qdbh: str = "" # 签到编号 | |
| fqr: str = "" # 发起人 | |
| cjsj: str = "" # 创建时间 | |
| zhxgsj: str = "" # 最后修改时间 | |
| def parse_fssj(self) -> datetime | None: | |
| """ | |
| 解析 fssj(发送时间)字符串为 datetime 对象 | |
| Returns: | |
| datetime 对象,解析失败返回 None | |
| """ | |
| if not self.fssj: | |
| return None | |
| try: | |
| return datetime.strptime(self.fssj, "%Y-%m-%d %H:%M:%S") | |
| except ValueError: | |
| # 尝试其他格式 | |
| try: | |
| return datetime.fromisoformat(self.fssj) | |
| except ValueError: | |
| return None | |
| def from_api_response(cls, data: dict[str, Any]) -> "DocumentRecord": | |
| """从 API 响应字典创建实例""" | |
| return cls( | |
| ah=data.get("ah", ""), | |
| sdbh=data.get("sdbh", ""), | |
| ajzybh=data.get("ajzybh", ""), | |
| fssj=data.get("fssj", ""), | |
| fymc=data.get("fymc", ""), | |
| ahdm=data.get("ahdm", ""), | |
| fybh=data.get("fybh", ""), | |
| ssdrxm=data.get("ssdrxm", ""), | |
| ssdrsjhm=data.get("ssdrsjhm", ""), | |
| ssdrzjhm=data.get("ssdrzjhm", ""), | |
| wsmc=data.get("wsmc", ""), | |
| sdzt=data.get("sdzt", ""), | |
| qdzt=data.get("qdzt", ""), | |
| qdbh=data.get("qdbh", ""), | |
| fqr=data.get("fqr", ""), | |
| cjsj=data.get("cjsj", ""), | |
| zhxgsj=data.get("zhxgsj", ""), | |
| ) | |
| def to_dict(self) -> dict[str, Any]: | |
| """序列化为字典""" | |
| return { | |
| "ah": self.ah, | |
| "sdbh": self.sdbh, | |
| "ajzybh": self.ajzybh, | |
| "fssj": self.fssj, | |
| "fymc": self.fymc, | |
| "ahdm": self.ahdm, | |
| "fybh": self.fybh, | |
| "ssdrxm": self.ssdrxm, | |
| "ssdrsjhm": self.ssdrsjhm, | |
| "ssdrzjhm": self.ssdrzjhm, | |
| "wsmc": self.wsmc, | |
| "sdzt": self.sdzt, | |
| "qdzt": self.qdzt, | |
| "qdbh": self.qdbh, | |
| "fqr": self.fqr, | |
| "cjsj": self.cjsj, | |
| "zhxgsj": self.zhxgsj, | |
| } | |
| class DocumentDetail: | |
| """ | |
| 文书详情(下载信息)- 来自 getWsListBySdbhNew API | |
| 对应 Requirements 2.2 | |
| """ | |
| c_sdbh: str # 送达编号 | |
| c_wsmc: str # 文书名称 | |
| c_wjgs: str # 文件格式(如 pdf) | |
| wjlj: str # 文件链接(OSS URL,带签名) | |
| c_stbh: str = "" # 上传编号(文件路径) | |
| c_wsbh: str = "" # 文书编号 | |
| c_fybh: str = "" # 法院编号 | |
| c_fymc: str = "" # 法院名称 | |
| dt_cjsj: str = "" # 创建时间(ISO格式) | |
| def from_api_response(cls, data: dict[str, Any]) -> "DocumentDetail": | |
| """从 API 响应字典创建实例""" | |
| return cls( | |
| c_sdbh=data.get("c_sdbh", ""), | |
| c_wsmc=data.get("c_wsmc", ""), | |
| c_wjgs=data.get("c_wjgs", ""), | |
| wjlj=data.get("wjlj", ""), | |
| c_stbh=data.get("c_stbh", ""), | |
| c_wsbh=data.get("c_wsbh", ""), | |
| c_fybh=data.get("c_fybh", ""), | |
| c_fymc=data.get("c_fymc", ""), | |
| dt_cjsj=data.get("dt_cjsj", ""), | |
| ) | |
| def to_dict(self) -> dict[str, Any]: | |
| """序列化为字典""" | |
| return { | |
| "c_sdbh": self.c_sdbh, | |
| "c_wsmc": self.c_wsmc, | |
| "c_wjgs": self.c_wjgs, | |
| "wjlj": self.wjlj, | |
| "c_stbh": self.c_stbh, | |
| "c_wsbh": self.c_wsbh, | |
| "c_fybh": self.c_fybh, | |
| "c_fymc": self.c_fymc, | |
| "dt_cjsj": self.dt_cjsj, | |
| } | |
| class DocumentListResponse: | |
| """ | |
| 文书列表 API 响应 | |
| 对应 Requirements 1.4, 3.4 | |
| """ | |
| total: int # data.total - 总数量,用于分页计算 | |
| documents: list[DocumentRecord] = field(default_factory=list) # data.data - 文书记录列表 | |
| def from_api_response(cls, data: dict[str, Any]) -> "DocumentListResponse": | |
| """ | |
| 从 API 响应字典创建实例 | |
| API 响应格式: | |
| { | |
| "code": 200, | |
| "msg": "成功!", | |
| "success": true, | |
| "data": { | |
| "total": 19, | |
| "data": [...] | |
| } | |
| } | |
| """ | |
| inner_data = data.get("data", {}) | |
| total = inner_data.get("total", 0) | |
| documents_data = inner_data.get("data", []) | |
| documents = [DocumentRecord.from_api_response(doc) for doc in documents_data] | |
| return cls(total=total, documents=documents) | |
| def to_dict(self) -> dict[str, Any]: | |
| """序列化为字典""" | |
| return { | |
| "total": self.total, | |
| "documents": [doc.to_dict() for doc in self.documents], | |
| } | |
| # ============================================================ | |
| # 原有数据类 (Playwright 方式使用) | |
| # ============================================================ | |
| class DocumentDeliveryRecord: | |
| """文书送达记录""" | |
| case_number: str # 案号 | |
| send_time: datetime | None # 发送时间 | |
| element_index: int # 页面元素索引(用于定位下载按钮) | |
| document_name: str = "" # 文书名称(可选) | |
| court_name: str = "" # 法院名称(可选) | |
| delivery_event_id: str = "" # 送达事件标识(优先使用 sdbh) | |
| def to_dict(self) -> dict[str, Any]: | |
| """序列化为字典""" | |
| return { | |
| "case_number": self.case_number, | |
| "send_time": self.send_time.isoformat() if self.send_time else None, | |
| "element_index": self.element_index, | |
| "document_name": self.document_name, | |
| "court_name": self.court_name, | |
| "delivery_event_id": self.delivery_event_id, | |
| } | |
| def from_dict(cls, data: dict[str, Any]) -> "DocumentDeliveryRecord": | |
| """从字典反序列化""" | |
| send_time = None | |
| if data.get("send_time"): | |
| if isinstance(data["send_time"], str): | |
| send_time = datetime.fromisoformat(data["send_time"]) | |
| else: | |
| send_time = data["send_time"] | |
| return cls( | |
| case_number=data["case_number"], | |
| send_time=send_time, | |
| element_index=data["element_index"], | |
| document_name=data.get("document_name", ""), | |
| court_name=data.get("court_name", ""), | |
| delivery_event_id=data.get("delivery_event_id", ""), | |
| ) | |
| class DocumentQueryResult: | |
| """文书查询结果""" | |
| total_found: int # 发现的文书总数 | |
| processed_count: int # 处理的文书数 | |
| skipped_count: int # 跳过的文书数(时间过滤或已处理) | |
| failed_count: int # 处理失败数 | |
| case_log_ids: list[int] # 创建的案件日志 ID 列表 | |
| errors: list[str] # 错误信息列表 | |
| class DocumentProcessResult: | |
| """单个文书处理结果""" | |
| success: bool # 是否成功 | |
| case_id: int | None # 匹配的案件ID | |
| case_log_id: int | None # 创建的案件日志ID | |
| renamed_path: str | None # 重命名后的文件路径 | |
| notification_sent: bool # 是否发送了通知 | |
| error_message: str | None # 错误信息 | |