# -*- coding = utf-8 -*- # @Time : 2025/2/13 下午12:17 # @File : models.py # @Software : PyCharm # @Author : xingc # @Desc : import enum import uuid from datetime import datetime import ujson from sqlalchemy import ( Column, Integer, String, Text, Date, ForeignKey, DECIMAL, CheckConstraint, UniqueConstraint, Index, Sequence, JSON, UUID, Enum, Boolean ) from sqlalchemy.orm import ( DeclarativeBase, Mapped, mapped_column, relationship ) from sqlalchemy.sql import func from sqlalchemy.ext.asyncio import AsyncAttrs from core.base import schema as base_schema class BaseModel(DeclarativeBase, AsyncAttrs): id: Mapped[int] = mapped_column( Integer, primary_key=True, autoincrement=True, comment='自增id' ) def dict(self, exclude: set = None): data = {} for column in self.__table__.columns: if exclude is not None and column.name in exclude: continue value = getattr(self, column.name) if isinstance(value, datetime): data[column.name] = value.strftime('%Y-%m-%d %H:%M:%S') elif isinstance(value, enum.Enum): data[column.name] = value.value else: data[column.name] = value return data def json(self, exclude: set = None): return ujson.dumps(self.dict(exclude=exclude)) class DateModel: created_at: Mapped[datetime] = mapped_column(server_default=func.current_timestamp(), comment='创建时间') updated_at: Mapped[datetime] = mapped_column(server_default=func.current_timestamp(), onupdate=func.current_timestamp(), comment='更新时间') class User(BaseModel, DateModel): __tablename__ = 'system_users' __table_args__ = ( UniqueConstraint('user_id', name='uniq_user_id'), {'comment': '用户表'} ) nickname: Mapped[str] = mapped_column(String(20), nullable=False, comment='昵称') user_id: Mapped[int] = mapped_column( Integer, Sequence('non_primary_id_seq', start=100000, increment=2), comment='用户id' ) head_avatar: Mapped[str] = mapped_column(String(500), comment='头像链接') wechat_openid = mapped_column(String(100), comment='微信openid') wechat_union_id = mapped_column(String(100), comment='微信unionid') phone: Mapped[int] = mapped_column(Integer, comment='手机号码') vip_expire_date: Mapped[datetime] = mapped_column(Date, comment='会员到期时间') integral: Mapped[int] = mapped_column(Integer, default=0, comment='会员积分') card_total: Mapped[int] = Column(Integer, default=0, comment='卡牌总数') card_show_total: Mapped[int] = Column(Integer, default=0, comment='卡片展示总数') collections: Mapped[list["UserCollection"]] = relationship( back_populates="user", cascade="all, delete-orphan" ) class Card(BaseModel, DateModel): __tablename__ = 'system_cards' __table_args__ = ( Index('cert_number_category_source', 'cert_number', 'category', 'source'), {'comment': '卡片表'} ) cert_number: Mapped[str] = mapped_column(String(50), comment='评级卡号') card_year: Mapped[int] = mapped_column(Integer, comment='卡片年份') card_brand: Mapped[str] = mapped_column(Integer, comment='卡片品牌') card_score: Mapped[float] = mapped_column(DECIMAL(10, 1), comment='卡片评分') auto_score: Mapped[float] = mapped_column(DECIMAL(10, 1), comment='签字评分') card_name: Mapped[str] = mapped_column(String(225), comment='卡片名称') card_number: Mapped[str] = mapped_column(String(225), comment='卡片编号') card_type: Mapped[str] = mapped_column(String(20), comment='卡片类型') card_picture: Mapped[dict] = mapped_column(JSON, default=dict, comment='卡片正、反图片(本地)') card_spare_picture: Mapped[dict] = mapped_column(JSON, default=dict, comment='卡片正、反图片(远程)') create_user_id: Mapped[int] = mapped_column(Integer, comment='创建者') category: Mapped[str] = mapped_column( Enum(base_schema.CardCategoryType, inherit_schema=True), default=base_schema.CardCategoryType.OTHER, comment='卡片分类' ) source: Mapped[str] = mapped_column( Enum(base_schema.PlatformSourceType, inherit_schema=True), comment='来源,PSA、BGS、CGC、GBTC、CCG、BCTC :采集 、OTHER:自定义' ) collections: Mapped[list["UserCollection"]] = relationship( back_populates="card", cascade="all, delete-orphan" ) class UserCollection(BaseModel, DateModel): __tablename__ = "system_user_collections" __table_args__ = ( UniqueConstraint('user_id', 'card_id', name='uniq_user_card'), CheckConstraint('purchase_price >= 0', name='check_purchase_price'), CheckConstraint('display_value >= 0', name='check_display_price') ) user_id: Mapped[int] = mapped_column( Integer, ForeignKey("system_users.id", ondelete="CASCADE"), nullable=False ) card_id: Mapped[int] = mapped_column( Integer, ForeignKey("system_cards.id", ondelete="CASCADE"), nullable=False ) purchase_price: Mapped[float] = mapped_column( DECIMAL(10, 2), nullable=False ) display_price: Mapped[float] = mapped_column( DECIMAL(10, 2), nullable=False ) displayed: Mapped[bool] = mapped_column( Boolean, default=True ) updated_at: Mapped[bool] = None user: Mapped["User"] = relationship(back_populates="collections") card: Mapped["Card"] = relationship(back_populates="collections") class SearchCardCache(BaseModel, DateModel): __tablename__ = 'system_cache_cards' __table_args__ = ( Index('cert_and_card_number_source', 'cert_number', 'card_number', 'source'), {'comment': '搜索卡片信息缓存表'} ) cert_number: Mapped[str] = mapped_column(String(50), comment='评级卡号') card_number: Mapped[str] = mapped_column(String(50), comment='卡片编号') data: Mapped[dict] = mapped_column(JSON, comment='标准数据') raw_data: Mapped[dict] = mapped_column(JSON, comment='原始数据') source: Mapped[str] = mapped_column( Enum(base_schema.SupportPlatformType, inherit_schema=True), comment='数据来源:PSA、BGS、CGC、GBTC、CCG、BCTC' ) # class Product(BaseModel, DateModel): # __tablename__ = 'system_products' # __table_args__ = {'comment': '产品信息表'} # # name: Mapped[str] = mapped_column(String(50), comment='产品名') # price: Mapped[float] = mapped_column(DECIMAL(10, 2), comment='价格') # action: Mapped[str] = mapped_column(String(10), comment='付款后的动作,会员续期:vip_renewal 积分:recharge_points') # number: Mapped[int] = mapped_column(Integer, comment='执行动作的增量值') # description: Mapped[str] = mapped_column(Text, comment='商品描述') # # # class Order(BaseModel, DateModel): # __tablename__ = 'system_orders' # __table_args__ = {'comment': '产品信息表'} # # order_id: Mapped[int] = mapped_column(String(20), comment='订单id') # user_id: Mapped[int] = mapped_column(Integer, comment='用户id') # product_id: Mapped[int] = mapped_column(Integer, comment='产品id') # price: Mapped[float] = mapped_column(DECIMAL(10, 2), comment='价格') # pay_url: Mapped[str] = mapped_column(String(255), comment='支付地址') # status: Mapped[int] = mapped_column(Integer, comment='订单状态,-1:初始化 0:失败 1:完成 2:待支付') # # class Message(BaseModel, DateModel): # __tablename__ = 'system_messages' # __table_args__ = {'comment': '聊天消息表'} # # guid: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), default=uuid.uuid4) # message_type: Mapped[str] = mapped_column( # Enum(base_schema.MessageType, inherit_schema=True), default=base_schema.MessageType.TEXT # ) # content: Mapped[str] = mapped_column(String(5000), comment='文本消息') # send_timestamp: Mapped[int] = mapped_column(Integer, comment='发送时间') # # user: Mapped["User"] = relationship(back_populates="system_messages")