171 lines
9.8 KiB
Python
171 lines
9.8 KiB
Python
from pydantic import BaseModel, Field, field_validator
|
|
from typing import Optional, Any
|
|
from datetime import datetime # 如果需要 datetime 对象
|
|
|
|
# 如果你有 TimestampMixin,需要在这里导入或定义
|
|
# class TimestampMixin(BaseModel):
|
|
# created_at: Optional[datetime] = None
|
|
# updated_at: Optional[datetime] = None
|
|
|
|
class CrmCustomerBase(BaseModel):
|
|
# 保留 JSON 中存在的字段,并添加 alias
|
|
customer_name: Optional[str] = Field(default=None, alias="customerName")
|
|
province: Optional[str] = Field(default=None, alias="province")
|
|
city: Optional[str] = Field(default=None, alias="city")
|
|
area: Optional[str] = Field(default=None, alias="area")
|
|
clinch_order: Optional[str] = Field(default=None, alias="clinchOrder")
|
|
clinch_price: Optional[str] = Field(default=None, alias="clinchPrice")
|
|
first_clinch_time: Optional[str] = Field(default=None, alias="firstClinchTime")
|
|
last_clinch_time: Optional[str] = Field(default=None, alias="lastClinchTime")
|
|
refund_order_times: Optional[str] = Field(default=None, alias="refundOrderTimes")
|
|
refund_amount: Optional[str] = Field(default=None, alias="refundAmount")
|
|
private_flag: Optional[int] = Field(default=None, alias="privateFlag") # JSON 中是 int
|
|
touch_flag: Optional[int] = Field(default=None, alias="touchFlag") # JSON 中是 int
|
|
open_id: Optional[str] = Field(default=None, alias="openId")
|
|
xy_id: Optional[int] = Field(default=None, alias="xyId") # JSON 中是 int
|
|
last_touch_time: Optional[str] = Field(default=None, alias="lastTouchTime")
|
|
add_wechat_time: Optional[str] = Field(default=None, alias="addWeChatTime")
|
|
mobile: Optional[str] = Field(default=None, alias="mobile")
|
|
source: Optional[str] = Field(default=None, alias="source")
|
|
we_chat_image: Optional[str] = Field(default=None, alias="weChatImage")
|
|
cid: Optional[int] = Field(default=None, alias="cid") # JSON 中是 int
|
|
last_trade_time: Optional[str] = Field(default=None, alias="lastTradeTime")
|
|
private_jump: Optional[int] = Field(default=None, alias="privateJump") # JSON 中是 int
|
|
lst_pay_ord_amt: Optional[float] = Field(default=None, alias="lstPayOrdAmt") # JSON 中是 float
|
|
pay_avg_ord_amt_td: Optional[float] = Field(default=None, alias="payAvgOrdAmtTd") # JSON 中是 float
|
|
refund_ord_rate_td: Optional[str] = Field(default=None, alias="refundOrdRateTd") # JSON 中是 string like '0.00%'
|
|
touch_cnt_td: Optional[int] = Field(default=None, alias="touchCntTd") # JSON 中是 int
|
|
pay_ord_day_cnt_1y: Optional[int] = Field(default=None, alias="payOrdDayCnt1y") # JSON 中是 int
|
|
pay_same_item_max_cnt_td: Optional[int] = Field(default=None, alias="paySameItemMaxCntTd") # JSON 中是 int
|
|
pay_diff_item_cnt_td: Optional[int] = Field(default=None, alias="payDiffItemCntTd") # JSON 中是 int
|
|
pay_item_max_cnt_td: Optional[int] = Field(default=None, alias="payItemMaxCntTd") # JSON 中是 int
|
|
user_type_90d: Optional[int] = Field(default=None, alias="userType90d") # JSON 中是 int
|
|
# shop_id 和 shop_name 不在 JSON 中,但根据你的 Tortoise 模型定义,它们是 CrmCustomer 特有的,所以不加 alias
|
|
shop_id: Optional[int] = Field(default=None) # 没有 alias,因为它在 JSON 中不存在
|
|
shop_name: Optional[str] = Field(default=None) # 没有 alias,因为它在 JSON 中不存在
|
|
|
|
class Config:
|
|
populate_by_name = True # 允许使用别名或字段名创建实例
|
|
|
|
class CrmCustomerCreate(CrmCustomerBase):
|
|
pass
|
|
|
|
class CrmCustomerUpdate(BaseModel):
|
|
# 这个模型的字段与 JSON 结构无关,保留原有定义
|
|
customer_name: Optional[str] = None
|
|
customer_remark: Optional[str] = None
|
|
customer_desc: Optional[str] = None
|
|
mobiles: Optional[list[str]] = None
|
|
labels: Optional[list[dict[str, Any]]] = None
|
|
follow_member_name: Optional[str] = None
|
|
follow_member_mobile: Optional[str] = None
|
|
follow_member_dept: Optional[str] = None
|
|
source_tips: Optional[str] = None
|
|
cus_channel: Optional[str] = None
|
|
|
|
class CrmCustomer(CrmCustomerBase):
|
|
id: int = Field(alias="id") # JSON 中的 'id' 字段
|
|
data_source: Optional[str] = None
|
|
last_updated_from: Optional[str] = None
|
|
# updated_at: Optional[datetime] = Field(default=None, alias="updatedAt") # 如果需要 datetime 对象
|
|
updated_at: Optional[str] = Field(default=None, alias="updatedAt") # 使用 str 匹配 JSON 格式
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
populate_by_name = True
|
|
|
|
def convert_to_str(v) -> Optional[str]:
|
|
"""将输入值转换为字符串"""
|
|
if v is None:
|
|
return v
|
|
return str(v)
|
|
|
|
class CrmCustomerBase(BaseModel):
|
|
# 对应 Tortoise 模型字段,并使用 JSON 中的键作为 alias
|
|
cid: Optional[int] = Field(default=None, alias="cid", description="CID")
|
|
customer_name: Optional[str] = Field(default=None, max_length=64, alias="customerName", description="客户名称")
|
|
clinch_order: Optional[str] = Field(default=None, max_length=64, alias="clinchOrder", description="成交订单数")
|
|
clinch_price: Optional[str] = Field(default=None, max_length=64, alias="clinchPrice", description="成交金额")
|
|
first_clinch_time: Optional[datetime] = Field(default=None, alias="firstClinchTime", description="首次成交时间")
|
|
last_clinch_time: Optional[datetime] = Field(default=None, alias="lastClinchTime", description="最后成交时间")
|
|
refund_order_times: Optional[str] = Field(default=None, max_length=64, alias="refundOrderTimes", description="退款订单数")
|
|
refund_amount: Optional[str] = Field(default=None, max_length=64, alias="refundAmount", description="退款金额")
|
|
private_flag: Optional[bool] = Field(default=False, alias="privateFlag", description="是否私有")
|
|
touch_flag: Optional[bool] = Field(default=False, alias="touchFlag", description="是否触达")
|
|
open_id: Optional[str] = Field(default=None, max_length=64, alias="openId", description="微信openid")
|
|
xy_id: Optional[int] = Field(default=None, alias="xyId", description="星云有客中的用户ID", index=True)
|
|
last_touch_time: Optional[datetime] = Field(default=None, alias="lastTouchTime", description="最后触达时间")
|
|
add_wechat_time: Optional[datetime] = Field(default=None, alias="addWeChatTime", description="添加微信时间")
|
|
mobile: Optional[str] = Field(default=None, max_length=64, alias="mobile", description="手机号")
|
|
source: Optional[str] = Field(default=None, max_length=64, alias="source", description="来源")
|
|
we_chat_image: Optional[str] = Field(default=None, max_length=512, alias="weChatImage", description="微信头像")
|
|
last_trade_time: Optional[datetime] = Field(default=None, alias="lastTradeTime", description="最后交易时间")
|
|
private_jump: Optional[bool] = Field(default=False, alias="privateJump", description="是否跳转")
|
|
lst_pay_ord_amt: Optional[str] = Field(default=None, alias="lstPayOrdAmt", description="最近一次支付金额")
|
|
pay_avg_ord_amt_td: Optional[str] = Field(default=None, alias="payAvgOrdAmtTd", description="最近30天平均支付金额")
|
|
refund_ord_rate_td: Optional[str] = Field(default=None, alias="refundOrdRateTd", description="最近30天退款订单数")
|
|
touch_cnt_td: Optional[int] = Field(default=None, alias="touchCntTd", description="最近30天触达次数")
|
|
pay_ord_day_cnt_1y: Optional[int] = Field(default=None, alias="payOrdDayCnt1y", description="最近一年支付订单数")
|
|
pay_same_item_max_cnt_td: Optional[int] = Field(default=None, alias="paySameItemMaxCntTd", description="最近30天相同商品最大购买数量")
|
|
pay_diff_item_cnt_td: Optional[int] = Field(default=None, alias="payDiffItemCntTd", description="最近30天不同商品购买数量")
|
|
pay_item_max_cnt_td: Optional[int] = Field(default=None, alias="payItemMaxCntTd", description="最近30天最大购买商品数量")
|
|
user_type_90d: Optional[int] = Field(default=None, alias="userType90d", description="最近90天用户类型")
|
|
# shop_id 和 shop_name 在 JSON 中不存在,因此不设置 alias
|
|
shop_id: Optional[int] = Field(default=None, description="店铺ID", index=True)
|
|
shop_name: Optional[str] = Field(default=None, max_length=64, description="店铺名称")
|
|
|
|
@field_validator('lst_pay_ord_amt', 'pay_avg_ord_amt_td', 'refund_ord_rate_td', mode='before')
|
|
def validate_and_convert_to_str(cls, v):
|
|
return convert_to_str(v)
|
|
|
|
class Config:
|
|
populate_by_name = True # 允许使用别名或字段名创建实例
|
|
|
|
class CrmCustomerCreate(CrmCustomerBase):
|
|
pass
|
|
|
|
class CrmCustomerUpdate(BaseModel):
|
|
# 保留原始定义(如果需要)
|
|
customer_name: Optional[str] = None
|
|
customer_remark: Optional[str] = None
|
|
customer_desc: Optional[str] = None
|
|
mobiles: Optional[list[str]] = None
|
|
labels: Optional[list[dict[str, Any]]] = None
|
|
follow_member_name: Optional[str] = None
|
|
follow_member_mobile: Optional[str] = None
|
|
follow_member_dept: Optional[str] = None
|
|
source_tips: Optional[str] = None
|
|
cus_channel: Optional[str] = None
|
|
|
|
|
|
|
|
class BaseCrmBindInfo(BaseModel):
|
|
platform: Optional[str]= None
|
|
customer_id: Optional[int]= None
|
|
orderId: Optional[str]= None
|
|
buyer_id: Optional[str]= None
|
|
userid: Optional[str]= None
|
|
name: Optional[str]= None
|
|
nick_name: Optional[str]= None
|
|
avatar: Optional[str]= None
|
|
platform_id: Optional[str]= None
|
|
need_confirm: Optional[bool]= None
|
|
tenant_name: Optional[str]= None
|
|
tenant_id: Optional[str]= None
|
|
remark: Optional[str]= None
|
|
extra: Optional[str]= None
|
|
|
|
|
|
class CrmBindInfoCreate(BaseCrmBindInfo):
|
|
id: Optional[int] = None
|
|
pass
|
|
|
|
|
|
class CrmBindInfoUpdate(BaseCrmBindInfo):
|
|
id: int = Field(..., description="绑定信息ID")
|
|
orderId: str = Field(..., description="订单ID")
|
|
customer_id: int = Field(..., description="客户ID")
|
|
name: str = Field(..., description="客户名称")
|
|
|
|
|