diff --git a/packages/surugaya_common/src/surugaya_common/models/__init__.py b/packages/surugaya_common/src/surugaya_common/models/__init__.py new file mode 100644 index 0000000..e2e74e6 --- /dev/null +++ b/packages/surugaya_common/src/surugaya_common/models/__init__.py @@ -0,0 +1,17 @@ +"""surugaya_common 共享数据模型。""" + +from surugaya_common.models.order import ( + SurugayaOrderDetail, + SurugayaOrderItem, + SurugayaOrderStatus, + SurugayaOrderSummary, + SurugayaShippingInfo, +) + +__all__ = [ + "SurugayaOrderDetail", + "SurugayaOrderItem", + "SurugayaOrderStatus", + "SurugayaOrderSummary", + "SurugayaShippingInfo", +] diff --git a/packages/surugaya_common/src/surugaya_common/models/order.py b/packages/surugaya_common/src/surugaya_common/models/order.py new file mode 100644 index 0000000..2b7b87e --- /dev/null +++ b/packages/surugaya_common/src/surugaya_common/models/order.py @@ -0,0 +1,77 @@ +"""骏河屋订单详情的结构化模型(pydantic + typing only)。 + +从 jp_pruchase_zdh_5/src/parsers/surugaya/models.py 迁移而来,作为 API 服务与 +worker 共享的订单契约统一维护。worker 端解析订单详情页后产出这些结构,写入 +Redis Hash(见 surugaya_common.redis_keys.trade_hash);API 的 /api/trade 读取 +同一份数据。 +""" + +from typing import Any, Literal + +from pydantic import BaseModel, Field + + +class SurugayaOrderStatus(BaseModel): + """交易状态表的结构化结果。""" + + trade_status: str | None = None + status_message: str | None = None + # 保留日文原始键值,便于排障和后续补字段。 + raw: dict[str, str] = Field(default_factory=dict) + + +class SurugayaOrderSummary(BaseModel): + """订单摘要表的结构化结果。""" + + trade_number: str | None = None + order_date: str | None = None + items_subtotal: int | None = None + item_count: int | None = None + payment_method: str | None = None + cash_on_delivery_fee: int | None = None + shipping_date: str | None = None + inquiry_number: str | None = None + shipping_and_handling_fee: int | None = None + digital_gift_certificate_amount: int | None = None + grand_total: int | None = None + # 保留订单摘要表的原始日文字段。 + raw: dict[str, str] = Field(default_factory=dict) + + +class SurugayaShippingInfo(BaseModel): + """收件信息表的结构化结果。""" + + recipient_name: str | None = None + recipient_address: str | None = None + recipient_phone_number: str | None = None + recipient_email: str | None = None + # 保留配送信息表的原始日文字段。 + raw: dict[str, str] = Field(default_factory=dict) + + +class SurugayaOrderItem(BaseModel): + """商品明细表中的单行商品记录。""" + + product_code: str | None = None + condition: str | None = None + branch_number: str | None = None + product_title: str | None = None + unit_price: int | None = None + quantity: int | None = None + discount_amount: int | None = None + line_total: int | None = None + remarks: str | None = None + # 每一行商品同时保留原始列名和值。 + raw: dict[str, str] = Field(default_factory=dict) + + +class SurugayaOrderDetail(BaseModel): + """骏河屋交易详情页的完整结构化结果。""" + + site: Literal["surugaya"] = "surugaya" + status: SurugayaOrderStatus + summary: SurugayaOrderSummary + shipping: SurugayaShippingInfo + items: list[SurugayaOrderItem] = Field(default_factory=list) + # 以业务分段聚合保留原始表格结果。 + raw_tables: dict[str, Any] = Field(default_factory=dict)