""" 主播和MCN机构相关模型 """ from datetime import date from typing import Optional, TYPE_CHECKING from sqlalchemy import ( Boolean, Column, Date, DateTime, ForeignKey, Integer, String, Text, JSON, ) from sqlalchemy.orm import Mapped, mapped_column, relationship from app.models.base import BaseModel if TYPE_CHECKING: from .user import User class McnAgency(BaseModel): """ MCN机构表 """ __tablename__ = "mcn_agency" mcn_id: Mapped[str] = mapped_column( String(50), unique=True, nullable=False, comment="MCN机构唯一标识" ) mcn_name: Mapped[str] = mapped_column( String(200), nullable=False, comment="MCN机构名称" ) unified_social_credit_code: Mapped[str] = mapped_column( String(18), unique=True, nullable=False, comment="统一社会信用代码" ) tax_registration_no: Mapped[Optional[str]] = mapped_column( String(30), nullable=True, comment="税务登记证号" ) tax_authority_code: Mapped[Optional[str]] = mapped_column( String(20), nullable=True, comment="主管税务机关代码" ) tax_authority_name: Mapped[Optional[str]] = mapped_column( String(200), nullable=True, comment="主管税务机关名称" ) legal_person_name: Mapped[str] = mapped_column( String(100), nullable=False, comment="法人姓名" ) legal_person_id_card: Mapped[str] = mapped_column( String(18), nullable=False, comment="法人身份证号" ) registered_capital: Mapped[Optional[float]] = mapped_column( nullable=True, comment="注册资本" ) establishment_date: Mapped[Optional[date]] = mapped_column( Date, nullable=True, comment="成立日期" ) registered_address: Mapped[str] = mapped_column( String(500), nullable=False, comment="注册地址" ) actual_address: Mapped[Optional[str]] = mapped_column( String(500), nullable=True, comment="实际经营地址" ) business_scope: Mapped[Optional[Text]] = mapped_column( Text, nullable=True, comment="经营范围" ) mcn_type: Mapped[str] = mapped_column( String(50), nullable=False, comment="MCN类型:tip_based-打赏类,ecommerce_based-带货类,mixed-混合型", ) streamer_count: Mapped[int] = mapped_column( Integer, default=0, comment="签约主播数量" ) annual_revenue: Mapped[float] = mapped_column( default=0, comment="年度营业收入" ) annual_tax_paid: Mapped[float] = mapped_column( default=0, comment="年度应纳税额" ) tax_burden_rate: Mapped[float] = mapped_column( default=0, comment="税负率" ) top_10_upstream_revenue: Mapped[float] = mapped_column( default=0, comment="十大上游企业营业收入" ) top_10_upstream_invoice_amount: Mapped[float] = mapped_column( default=0, comment="十大上游企业开票金额" ) contact_person: Mapped[Optional[str]] = mapped_column( String(100), nullable=True, comment="联系人" ) contact_phone: Mapped[Optional[str]] = mapped_column( String(20), nullable=True, comment="联系电话" ) contact_email: Mapped[Optional[str]] = mapped_column( String(100), nullable=True, comment="联系邮箱" ) bank_account_no: Mapped[str] = mapped_column( String(50), nullable=False, comment="银行账号" ) bank_name: Mapped[str] = mapped_column( String(100), nullable=False, comment="开户银行" ) status: Mapped[str] = mapped_column( String(20), default="active", comment="状态:active-活跃,inactive-停用,blacklist-黑名单", ) risk_level: Mapped[Optional[str]] = mapped_column( String(20), comment="风险等级:high-高风险,medium-中风险,low-低风险" ) # 关系 streamers: Mapped[list["StreamerInfo"]] = relationship( "StreamerInfo", back_populates="mcn_agency" ) class StreamerInfo(BaseModel): """ 主播信息表 """ __tablename__ = "streamer_info" streamer_id: Mapped[str] = mapped_column( String(50), unique=True, nullable=False, comment="主播唯一标识" ) streamer_name: Mapped[str] = mapped_column( String(100), nullable=False, comment="主播姓名/企业名称" ) entity_type: Mapped[str] = mapped_column( String(20), nullable=False, comment="主体类型:individual-个人,sole_proprietor-个体户,enterprise-企业", ) id_card_no: Mapped[Optional[str]] = mapped_column( String(18), unique=True, nullable=True, comment="身份证号(个人)" ) social_security_no: Mapped[Optional[str]] = mapped_column( String(30), nullable=True, comment="社会保障号" ) phone_number: Mapped[str] = mapped_column( String(20), nullable=False, comment="手机号码" ) unified_social_credit_code: Mapped[Optional[str]] = mapped_column( String(18), nullable=True, comment="统一社会信用代码(企业/个体户)" ) tax_registration_no: Mapped[Optional[str]] = mapped_column( String(30), nullable=True, comment="税务登记证号" ) legal_person_name: Mapped[Optional[str]] = mapped_column( String(100), nullable=True, comment="法人姓名(企业)" ) legal_person_id_card: Mapped[Optional[str]] = mapped_column( String(18), nullable=True, comment="法人身份证号(企业)" ) registered_address: Mapped[Optional[str]] = mapped_column( String(500), nullable=True, comment="注册地址(企业)" ) actual_address: Mapped[Optional[str]] = mapped_column( String(500), nullable=True, comment="实际经营地址" ) bank_account_no: Mapped[str] = mapped_column( String(50), nullable=False, comment="银行账号" ) bank_name: Mapped[str] = mapped_column( String(100), nullable=False, comment="开户银行" ) wechat_pay_account: Mapped[Optional[str]] = mapped_column( String(50), nullable=True, comment="微信支付账号" ) alipay_account: Mapped[Optional[str]] = mapped_column( String(50), nullable=True, comment="支付宝账号" ) douyin_account: Mapped[Optional[str]] = mapped_column( String(100), nullable=True, comment="抖音账号" ) kuaishou_account: Mapped[Optional[str]] = mapped_column( String(100), nullable=True, comment="快手账号" ) xiaohongshu_account: Mapped[Optional[str]] = mapped_column( String(100), nullable=True, comment="小红书账号" ) weibo_account: Mapped[Optional[str]] = mapped_column( String(100), nullable=True, comment="微博账号" ) bilibili_account: Mapped[Optional[str]] = mapped_column( String(100), nullable=True, comment="B站账号" ) streamer_certificate_no: Mapped[Optional[str]] = mapped_column( String(50), nullable=True, comment="主播证书号" ) certificate_issuing_authority: Mapped[Optional[str]] = mapped_column( String(200), nullable=True, comment="证书颁发机构" ) certificate_issue_date: Mapped[Optional[date]] = mapped_column( Date, nullable=True, comment="证书颁发日期" ) certificate_expiry_date: Mapped[Optional[date]] = mapped_column( Date, nullable=True, comment="证书有效期至" ) mcn_agency_id: Mapped[Optional[int]] = mapped_column( Integer, ForeignKey("mcn_agency.id"), nullable=True, comment="所属MCN机构ID" ) related_persons: Mapped[Optional[dict]] = mapped_column( JSON, nullable=True, comment="关联人员名单(JSON格式)" ) status: Mapped[str] = mapped_column( String(20), default="active", comment="状态:active-活跃,inactive-停用,blacklist-黑名单", ) registration_date: Mapped[date] = mapped_column( Date, default=date.today, comment="入驻时间" ) # 关系 mcn_agency: Mapped[Optional[McnAgency]] = relationship( "McnAgency", back_populates="streamers" ) class PlatformRecharge(BaseModel): """ 平台充值记录表 """ __tablename__ = "platform_recharge" recharge_id: Mapped[str] = mapped_column( String(50), unique=True, nullable=False, comment="充值记录ID" ) user_id: Mapped[str] = mapped_column( String(50), nullable=False, comment="用户ID" ) user_name: Mapped[Optional[str]] = mapped_column( String(100), nullable=True, comment="用户昵称" ) user_phone: Mapped[Optional[str]] = mapped_column( String(20), nullable=True, comment="用户手机号" ) recharge_amount: Mapped[float] = mapped_column( nullable=False, comment="充值金额" ) recharge_time: Mapped[Optional[DateTime]] = mapped_column( DateTime(timezone=True), nullable=True, comment="充值时间" ) payment_method: Mapped[str] = mapped_column( String(50), nullable=False, comment="支付方式:wechat-微信,alipay-支付宝,unionpay-银联,applepay-苹果支付", ) payment_channel: Mapped[Optional[str]] = mapped_column( String(100), nullable=True, comment="支付渠道" ) transaction_no: Mapped[str] = mapped_column( String(100), nullable=False, comment="交易流水号" ) platform_order_no: Mapped[str] = mapped_column( String(100), nullable=False, comment="平台订单号" ) currency_type: Mapped[str] = mapped_column( String(10), default="CNY", comment="币种" ) exchange_rate: Mapped[float] = mapped_column( default=1.0000, comment="汇率" ) actual_amount_cny: Mapped[float] = mapped_column( nullable=False, comment="折算人民币金额" ) recharge_type: Mapped[str] = mapped_column( String(50), default="normal", comment="充值类型:normal-正常,activity-活动,gift-赠送", ) bonus_coins: Mapped[float] = mapped_column( default=0, comment="赠送虚拟币" ) total_coins: Mapped[float] = mapped_column( nullable=False, comment="到账虚拟币" ) is_first_recharge: Mapped[bool] = mapped_column( default=False, comment="是否首充" ) ip_address: Mapped[Optional[str]] = mapped_column( String(50), nullable=True, comment="充值IP地址" ) device_type: Mapped[Optional[str]] = mapped_column( String(50), nullable=True, comment="设备类型:iOS,Android,Web" ) device_id: Mapped[Optional[str]] = mapped_column( String(100), nullable=True, comment="设备ID" ) province: Mapped[Optional[str]] = mapped_column( String(50), nullable=True, comment="省份" ) city: Mapped[Optional[str]] = mapped_column( String(50), nullable=True, comment="城市" ) status: Mapped[str] = mapped_column( String(20), nullable=False, comment="充值状态:success-成功,pending-处理中,failed-失败,refunded-已退款", ) refund_amount: Mapped[float] = mapped_column( default=0, comment="退款金额" ) refund_time: Mapped[Optional[DateTime]] = mapped_column( DateTime(timezone=True), nullable=True, comment="退款时间" ) withdrawal_status: Mapped[str] = mapped_column( String(20), nullable=False, comment="提现状态:not_withdrawn-未提现,withdrawn-已提现,partial-部分提现", ) withdrawn_amount: Mapped[float] = mapped_column( default=0, comment="已提现金额" )