95 lines
3.2 KiB
Python
95 lines
3.2 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, Field, model_validator
|
|
|
|
from app.enums.common import (
|
|
OFFLINE_PAYMENT_METHOD_LABELS,
|
|
PAYMENT_ORDER_SOURCE_LABELS,
|
|
)
|
|
from app.enums.credit_product import CREDIT_PRODUCT_TYPE_LABELS, PRODUCT_PRICE_TYPE_LABELS
|
|
|
|
|
|
PAYMENT_METHOD_LABELS = {
|
|
"alipay": "支付宝",
|
|
"wechat": "微信支付",
|
|
**OFFLINE_PAYMENT_METHOD_LABELS,
|
|
}
|
|
PAYMENT_STATUS_LABELS = {
|
|
"pending": "待支付",
|
|
"paid": "已支付",
|
|
"fulfilled": "已履约",
|
|
"refunded": "已退款",
|
|
"cancelled": "已取消",
|
|
"expired": "已过期",
|
|
"failed": "失败",
|
|
}
|
|
FULFILLMENT_STATUS_LABELS = {
|
|
"pending": "待履约",
|
|
"fulfilled": "已履约",
|
|
"failed": "履约失败",
|
|
}
|
|
|
|
|
|
class RechargeRequest(BaseModel):
|
|
plan: str = Field(..., description="积分商品ID;兼容旧字段名plan")
|
|
method: str = Field(default="wechat", pattern="^(wechat|alipay)$")
|
|
quantity: int = Field(default=1, ge=1, le=20, description="团队订阅购买席位数;个人商品固定为1")
|
|
|
|
|
|
class PaymentOrderOut(BaseModel):
|
|
id: str
|
|
order_no: str
|
|
amount: float
|
|
credits: float
|
|
payment_method: str
|
|
payment_method_label: str = ""
|
|
order_source: str = "online_payment"
|
|
order_source_label: str = ""
|
|
status: str
|
|
status_label: str = ""
|
|
product_id: str | None = None
|
|
product_type: str | None = None
|
|
product_type_label: str | None = None
|
|
purchase_scene: str | None = None
|
|
price_type: str | None = None
|
|
price_type_label: str | None = None
|
|
product_name_snapshot: str | None = None
|
|
quantity: int = 1
|
|
quoted_unit_price_snapshot: float | None = None
|
|
quoted_amount_snapshot: float | None = None
|
|
actual_unit_price_snapshot: float | None = None
|
|
team_id_snapshot: str | None = None
|
|
fulfillment_status: str | None = None
|
|
fulfillment_status_label: str | None = None
|
|
offline_trade_no: str | None = None
|
|
offline_payment_detail: str | None = None
|
|
remark: str | None = None
|
|
qr_url: str | None = None
|
|
created_at: datetime
|
|
paid_at: datetime | None = None
|
|
refund_amount: float | None = None
|
|
refunded_at: datetime | None = None
|
|
refund_trade_no: str | None = None
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
@model_validator(mode="after")
|
|
def fill_chinese_labels(self):
|
|
if self.payment_method == "other" and self.offline_payment_detail:
|
|
self.payment_method_label = self.offline_payment_detail
|
|
else:
|
|
self.payment_method_label = PAYMENT_METHOD_LABELS.get(self.payment_method, "其他支付方式")
|
|
self.order_source_label = PAYMENT_ORDER_SOURCE_LABELS.get(self.order_source, "其他订单来源")
|
|
self.status_label = PAYMENT_STATUS_LABELS.get(self.status, "其他状态")
|
|
if self.product_type:
|
|
self.product_type_label = CREDIT_PRODUCT_TYPE_LABELS.get(self.product_type, "其他商品")
|
|
if self.price_type:
|
|
self.price_type_label = PRODUCT_PRICE_TYPE_LABELS.get(self.price_type, "其他价格")
|
|
if self.fulfillment_status:
|
|
self.fulfillment_status_label = FULFILLMENT_STATUS_LABELS.get(
|
|
self.fulfillment_status, "其他履约状态"
|
|
)
|
|
return self
|