first commit

This commit is contained in:
2026-06-25 17:41:06 +08:00
commit b2f23a933b
370 changed files with 30526 additions and 0 deletions
+170
View File
@@ -0,0 +1,170 @@
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="客户名称")