Files
WonderQ-Project/WonderQ-Admin/app/schemas.py
T
duanshuwen 548f91c37f refactor: 清理废弃业务模块并更新全栈配置
- 移除后端产品、目的地、活动专题等废弃模块的数据库表与业务代码,删除冗余API接口
- 删除小程序端详情页、线路组件等冗余代码,移除搜索工具与测试用例,调整导航逻辑
- 清理管理端废弃的类型定义、编辑器与测试代码
- 更新项目文档,修正模块维护说明与接口文档内容
2026-08-17 22:43:49 +08:00

94 lines
2.9 KiB
Python

from datetime import datetime, timedelta
from typing import Literal
from pydantic import BaseModel, EmailStr, Field, ValidationInfo, field_validator
LeadStatus = Literal["new", "assigned", "contacted", "planning", "won", "invalid"]
class LoginIn(BaseModel):
email: EmailStr
password: str = Field(min_length=6)
class PhoneLoginIn(BaseModel):
code: str = Field(min_length=1, max_length=256)
class LeadCreateIn(BaseModel):
destination: str | None = None
phone: str = Field(min_length=2, max_length=64)
travelDate: datetime | None = None
peopleCount: int | None = Field(default=None, gt=0)
budgetMin: int | None = Field(default=None, ge=0)
budgetMax: int | None = Field(default=None, ge=0)
note: str | None = Field(default=None, max_length=1000)
sourcePage: str | None = None
@field_validator("phone")
@classmethod
def normalize_phone(cls, value: str) -> str:
normalized = " ".join(value.strip().split())
if not normalized:
raise ValueError("联系方式不能为空")
return normalized
@field_validator("travelDate", mode="before")
@classmethod
def parse_date_only_travel_date(cls, value):
if isinstance(value, str) and len(value) == 10:
try:
return datetime.strptime(value, "%Y-%m-%d")
except ValueError:
return value
return value
class LeadStatusIn(BaseModel):
status: LeadStatus
class LeadQuery(BaseModel):
status: LeadStatus | None = None
sourcePage: str | None = None
keyword: str | None = None
createdFrom: datetime | None = None
createdTo: datetime | None = None
take: int = Field(default=100, ge=1, le=200)
@field_validator("createdFrom", "createdTo", mode="before")
@classmethod
def parse_date_only_range(cls, value, info: ValidationInfo):
if isinstance(value, str) and len(value) == 10:
try:
parsed = datetime.strptime(value, "%Y-%m-%d")
return parsed + timedelta(days=1) if info.field_name == "createdTo" else parsed
except ValueError:
return value
return value
class SiteConfigPatchIn(BaseModel):
title: str | None = None
kicker: str | None = None
subtitle: str | None = None
image: str | None = None
description: str | None = None
steps: list[str] | None = None
destinationLabel: str | None = None
destinationPlaceholder: str | None = None
phoneLabel: str | None = None
phonePlaceholder: str | None = None
noteLabel: str | None = None
notePlaceholder: str | None = None
submitLabel: str | None = None
chips: list[str] | None = None
targetType: str | None = None
targetValue: str | None = None
isActive: bool | None = None
sortOrder: int | None = None
class SiteConfigReorderIn(BaseModel):
itemIds: list[str] = Field(default_factory=list)