from datetime import datetime from typing import Optional from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey, Enum from sqlalchemy.sql import func from pydantic import BaseModel, Field from .database import Base import enum from sqlalchemy.orm import relationship class CouponStatus(str, enum.Enum): UNUSED = "UNUSED" USED = "USED" EXPIRED = "EXPIRED" class CouponType(str, enum.Enum): PRODUCT = "PRODUCT" # 商品 CASH = "CASH" # 现金 # 数据库模型 class CouponDB(Base): __tablename__ = "coupons" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(100), nullable=False) amount = Column(Float, nullable=False) coupon_type = Column(Enum(CouponType), nullable=False, default=CouponType.CASH) create_time = Column(DateTime(timezone=True), server_default=func.now()) update_time = Column(DateTime(timezone=True), onupdate=func.now()) class UserCouponDB(Base): __tablename__ = "user_coupons" id = Column(Integer, primary_key=True, autoincrement=True) user_id = Column(Integer, ForeignKey("users.userid"), index=True) coupon_id = Column(Integer, ForeignKey("coupons.id"), index=True) coupon_name = Column(String(100), nullable=False) coupon_type = Column(Enum(CouponType), nullable=False) coupon_amount = Column(Float, nullable=False) expire_time = Column(DateTime(timezone=True), nullable=False) used_time = Column(DateTime(timezone=True), nullable=True) status = Column(Enum(CouponStatus), default=CouponStatus.UNUSED) create_time = Column(DateTime(timezone=True), server_default=func.now()) update_time = Column(DateTime(timezone=True), onupdate=func.now()) class CouponIssueRecordDB(Base): """优惠券发放记录表""" __tablename__ = "coupon_issue_records" id = Column(Integer, primary_key=True, autoincrement=True) coupon_id = Column(Integer, ForeignKey("coupons.id"), nullable=False) user_id = Column(Integer, ForeignKey("users.userid"), nullable=False) operator_id = Column(Integer, ForeignKey("users.userid"), nullable=False) # 操作人ID count = Column(Integer, nullable=False, default=1) # 发放数量 issue_time = Column(DateTime(timezone=True), nullable=False, server_default=func.now()) remark = Column(String(200), nullable=True) # 备注信息 # 关联关系 coupon = relationship("CouponDB", backref="issue_records") user = relationship("UserDB", foreign_keys=[user_id], backref="received_coupon_records") operator = relationship("UserDB", foreign_keys=[operator_id], backref="operated_coupon_records") # Pydantic 模型 class CouponCreate(BaseModel): name: str = Field(..., max_length=100) amount: Optional[float] = Field(None) coupon_type: CouponType = Field(CouponType.CASH) class CouponUpdate(BaseModel): name: Optional[str] = Field(None, max_length=100) amount: Optional[float] = Field(None) coupon_type: CouponType = Field(CouponType.CASH) class CouponInfo(BaseModel): id: int name: str amount: float coupon_type: CouponType create_time: datetime class Config: from_attributes = True class UserCouponCreate(BaseModel): user_id: int coupon_id: int expire_time: datetime remark: Optional[str] = None count: int = Field(..., gt=0, description="发放数量") class UserCouponInfo(BaseModel): id: int user_id: int coupon_id: int coupon_name: str coupon_amount: float coupon_type: CouponType expire_time: datetime used_time: Optional[datetime] = None status: CouponStatus create_time: datetime class Config: from_attributes = True class CouponIssueRecordCreate(BaseModel): coupon_id: int user_id: int count: int = 1 remark: Optional[str] = None class CouponIssueRecordInfo(BaseModel): id: int coupon_id: int user_id: int operator_id: int count: int issue_time: datetime remark: Optional[str] = None coupon_name: Optional[str] = None user_nickname: Optional[str] = None operator_nickname: Optional[str] = None class Config: from_attributes = True