from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Boolean, Enum from sqlalchemy.sql import func from sqlalchemy.dialects.mysql import DECIMAL from pydantic import BaseModel, Field from .database import Base from typing import Optional from app.models.user import Gender # 复用用户模型中的性别枚举 import enum # 地址类型枚举 class AddressType(str, enum.Enum): PICKUP = "PICKUP" # 代取地址 COMMON = "COMMON" # 通用地址 # 数据库模型 class AddressDB(Base): __tablename__ = "delivery_addresses" id = Column(Integer, primary_key=True, autoincrement=True) user_id = Column(Integer, ForeignKey("users.userid"), index=True) community_id = Column(Integer, index=True) community_name = Column(String(100), nullable=True) community_building_id = Column(Integer, ForeignKey("community_buildings.id"), nullable=True) community_building_name = Column(String(100), nullable=True) address_detail = Column(String(200)) name = Column(String(50)) phone = Column(String(11)) gender = Column(Enum(Gender), nullable=False, default=Gender.UNKNOWN) is_default = Column(Boolean, default=False) address_type = Column(Enum(AddressType), nullable=False, default=AddressType.PICKUP) # 地址类型 longitude = Column(DECIMAL(9,6), nullable=True) # 经度,精确到小数点后6位 latitude = Column(DECIMAL(9,6), nullable=True) # 纬度,精确到小数点后6位 create_time = Column(DateTime(timezone=True), server_default=func.now()) update_time = Column(DateTime(timezone=True), onupdate=func.now()) # Pydantic 模型 class AddressCreate(BaseModel): community_id: Optional[int] = None community_name: Optional[str] = None community_building_id: Optional[int] = None address_detail: str = Field(..., max_length=200) name: str = Field(..., max_length=50) phone: str = Field(..., pattern="^1[3-9]\d{9}$") gender: Gender = Gender.UNKNOWN is_default: bool = True address_type: AddressType = AddressType.PICKUP # 地址类型,默认为代取 longitude: Optional[float] = Field(None, ge=-180, le=180) # 经度 latitude: Optional[float] = Field(None, ge=-90, le=90) # 纬度 class AddressUpdate(BaseModel): community_id: Optional[int] = None community_building_id: Optional[int] = None address_detail: Optional[str] = Field(None, max_length=200) name: Optional[str] = Field(None, max_length=50) phone: Optional[str] = Field(None, pattern="^1[3-9]\d{9}$") gender: Optional[Gender] = None is_default: Optional[bool] = None address_type: Optional[AddressType] = AddressType.PICKUP # 地址类型 longitude: Optional[float] = Field(None, ge=-180, le=180) # 经度 latitude: Optional[float] = Field(None, ge=-90, le=90) # 纬度 class AddressInfo(BaseModel): id: int community_id: Optional[int] = None community_name: Optional[str] = None community_building_id: Optional[int] = None community_building_name: Optional[str] = None address_detail: str name: str phone: str gender: Gender is_default: bool address_type: Optional[AddressType] = AddressType.PICKUP # 地址类型 longitude: Optional[float] = None # 经度 latitude: Optional[float] = None # 纬度 class Config: from_attributes = True