from sqlalchemy import Column, String, Integer, Float, DateTime, ForeignKey, Enum, Boolean, Date, Text, Time from sqlalchemy.dialects.mysql import DECIMAL from sqlalchemy.sql import func from pydantic import BaseModel, Field from typing import Optional, List from datetime import datetime, date, time from .database import Base from sqlalchemy.orm import relationship import enum from app.core.utils import CommonUtils from app.core.imageprocessor import process_image, ImageFormat class ProductStatus(str, enum.Enum): LISTING = "LISTING" # 上架 UNLISTING = "UNLISTING" # 下架 class DeliveryType(str, enum.Enum): """配送类型枚举""" DELIVERY = "DELIVERY" # 配送到家 PICKUP = "PICKUP" # 自提 class DeliveryTimeType(str, enum.Enum): """配送时间类型枚举""" IMMEDIATE = "IMMEDIATE" # 立即送 SCHEDULED = "SCHEDULED" # 定时送 class OperationType(str, enum.Enum): """经营类型枚举""" SELF_OPERATED = "SELF_OPERATED" # 自营 MERCHANT = "MERCHANT" # 商家 class MerchantProductDB(Base): __tablename__ = "merchant_products" id = Column(Integer, primary_key=True, autoincrement=True) merchant_id = Column(Integer, ForeignKey("merchants.id"), nullable=False) name = Column(String(100), nullable=False) image_url = Column(String(500), nullable=False) product_price = Column(Float, nullable=False) # 原价 sale_price = Column(DECIMAL(10,2), nullable=False) # 售价 settlement_amount = Column(DECIMAL(10,2), nullable=False) # 商家结算金额 tags = Column(String(200)) # 标签,逗号分隔 purchase_limit = Column(Integer, nullable=False, default=0) # 限购次数,0表示不限购 gift_points_rate = Column(DECIMAL(4,2), nullable=False, default=0.00) # 购买赠送积分比例,默认0% promotion_text = Column(String(100)) # 促销文本 product_detail = Column(Text, nullable=True) # 产品详细描述,Markdown格式 purchase_note = Column(Text, nullable=True) # 购买须知,用于提供商品购买相关注意事项 operation_type = Column(Enum(OperationType), nullable=False, default=OperationType.MERCHANT) # 经营类型:自营或商家 longitude = Column(DECIMAL(9,6), nullable=True) # 经度,精确到小数点后6位 latitude = Column(DECIMAL(9,6), nullable=True) # 纬度,精确到小数点后6位 qty = Column(Integer, nullable=False, default=0) # 库存 sold_total = Column(Integer, nullable=False, default=0) # 已售数量 is_sellout = Column(Boolean, nullable=False, default=False) # 是否售罄 delivery_type = Column(Enum(DeliveryType), nullable=False, default=DeliveryType.DELIVERY) # 配送类型 pickup_place = Column(String(200), nullable=True) # 自提点 pickup_time_from = Column(Time, nullable=True) # 自提开始时间 pickup_time_to = Column(Time, nullable=True) # 自提结束时间 delivery_time_type = Column(Enum(DeliveryTimeType), nullable=False, default=DeliveryTimeType.IMMEDIATE) # 配送时间类型 delivery_date = Column(Date, nullable=True) # 配送日期,仅对定时送有效 recommend = Column(Boolean, nullable=False, default=False) # 是否为平台推荐商品 create_time = Column(DateTime(timezone=True), server_default=func.now()) update_time = Column(DateTime(timezone=True), onupdate=func.now()) status = Column(Enum(ProductStatus), nullable=False, default=ProductStatus.UNLISTING) merchant = relationship("MerchantDB", backref="products") @property def optimized_image_url(self): return process_image(self.image_url).thumbnail(width=800, height=800).format(ImageFormat.WEBP).build() # Pydantic 模型 class MerchantProductCreate(BaseModel): merchant_id: int name: str = Field(..., max_length=100) image_url: str = Field(..., max_length=500) product_price: float = Field(..., gt=0) sale_price: float = Field(..., gt=0) settlement_amount: float = Field(..., gt=0) tags: str = Field("", max_length=200) purchase_limit: int = Field(0, ge=0) # 限购次数,默认0表示不限购 product_detail: Optional[str] = None # 产品详细描述,Markdown格式 purchase_note: Optional[str] = None # 购买须知,用于提供商品购买相关注意事项 operation_type: OperationType = Field(OperationType.MERCHANT) # 经营类型:自营或商家 longitude: Optional[float] = Field(None, ge=-180, le=180) # 经度 latitude: Optional[float] = Field(None, ge=-90, le=90) # 纬度 qty: int = Field(0, ge=0) # 库存 sold_total: int = Field(0, ge=0) # 已售数量 is_sellout: bool = Field(False) # 是否售罄 delivery_type: DeliveryType = Field(DeliveryType.DELIVERY) # 配送类型 pickup_place: Optional[str] = Field(None, max_length=200) # 自提点 pickup_time_from: Optional[time] = Field(None) # 自提开始时间 pickup_time_to: Optional[time] = Field(None) # 自提结束时间 delivery_time_type: DeliveryTimeType = Field(DeliveryTimeType.IMMEDIATE) # 配送时间类型 delivery_date: Optional[date] = Field(None) # 配送日期 status: ProductStatus = ProductStatus.UNLISTING promotion_text: Optional[str] = Field(None, max_length=100) # 促销文本 gift_points_rate: Optional[float] = Field(10.00, ge=0, le=100) # 购买赠送积分比例 recommend: bool = Field(False) # 是否为平台推荐商品 class MerchantProductUpdate(BaseModel): name: Optional[str] = Field(None, max_length=100) image_url: Optional[str] = Field(None, max_length=500) product_price: Optional[float] = Field(None, gt=0) sale_price: Optional[float] = Field(None, gt=0) settlement_amount: Optional[float] = Field(None, gt=0) tags: Optional[str] = Field(None, max_length=200) purchase_limit: Optional[int] = Field(None, ge=0) # 限购次数,可选字段 product_detail: Optional[str] = None # 产品详细描述,Markdown格式 purchase_note: Optional[str] = None # 购买须知,用于提供商品购买相关注意事项 operation_type: Optional[OperationType] = None # 经营类型:自营或商家 longitude: Optional[float] = Field(None, ge=-180, le=180) # 经度 latitude: Optional[float] = Field(None, ge=-90, le=90) # 纬度 qty: Optional[int] = Field(None, ge=0) # 库存 sold_total: Optional[int] = Field(None, ge=0) # 已售数量 is_sellout: Optional[bool] = None # 是否售罄 delivery_type: Optional[DeliveryType] = None # 配送类型 pickup_place: Optional[str] = Field(None, max_length=200) # 自提点 pickup_time_from: Optional[time] = None # 自提开始时间 pickup_time_to: Optional[time] = None # 自提结束时间 delivery_time_type: Optional[DeliveryTimeType] = None # 配送时间类型 delivery_date: Optional[date] = None # 配送日期 status: Optional[ProductStatus] = None promotion_text: Optional[str] = Field(None, max_length=100) # 促销文本 gift_points_rate: Optional[float] = Field(None, ge=0, le=100) # 购买赠送积分比例 recommend: Optional[bool] = None # 是否为平台推荐商品 class MerchantProductInfo(BaseModel): id: int merchant_id: int merchant_name: Optional[str] = None # 添加商家名称字段 name: str image_url: str optimized_image_url: Optional[str] = None product_price: float sale_price: float settlement_amount: float tags: str purchase_limit: int # 限购次数 product_detail: Optional[str] = None # 产品详细描述,Markdown格式 purchase_note: Optional[str] = None # 购买须知,用于提供商品购买相关注意事项 operation_type: OperationType # 经营类型:自营或商家 longitude: Optional[float] = None # 经度 latitude: Optional[float] = None # 纬度 qty: int # 库存 sold_total: int = 0 # 已售数量 is_sellout: bool # 是否售罄 delivery_type: DeliveryType # 配送类型 pickup_place: Optional[str] = None # 自提点 pickup_time_from: Optional[time] = None # 自提开始时间 pickup_time_to: Optional[time] = None # 自提结束时间 delivery_time_type: DeliveryTimeType # 配送时间类型 delivery_date: Optional[date] = None # 配送日期 gift_points_rate: float promotion_text: Optional[str] = None # 促销文本 recommend: bool = False # 是否为平台推荐商品 create_time: datetime update_time: Optional[datetime] status: ProductStatus class Config: from_attributes = True