from datetime import date, datetime from sqlalchemy import JSON, Boolean, Column, Date, DateTime, Enum, Integer, String, Text, BigInteger, DECIMAL from sqlalchemy import Text as SAText from .db import Base class User(Base): __tablename__ = "nf_user" # 仅映射业务需要的字段,并与现有表结构对齐(createtime/updatetime 为 bigint 时间戳) id = Column(BigInteger, primary_key=True, autoincrement=True) username = Column(String(32)) nickname = Column(String(50)) avatar = Column(String(255)) mobile = Column(String(11)) gender = Column(Integer) # 0/1/2 reg_step = Column(Integer, default=1) # 1个人信息 2创建恋人 3生成恋人 money = Column(DECIMAL(10, 2), default=0.00) clothes_num = Column(Integer, default=0) token = Column(String(50)) createtime = Column("createtime", BigInteger) updatetime = Column("updatetime", BigInteger) chat_limit_daily = Column(Integer, default=80) chat_used_today = Column(Integer, default=0) chat_reset_date = Column(Date) video_gen_remaining = Column(Integer, default=0) inner_voice_enabled = Column(Boolean, default=False) outfit_slots = Column(Integer, default=5) owned_outfit_ids = Column(JSON) owned_voice_ids = Column(JSON) vip_endtime = Column(BigInteger, default=0) # 邀请码相关 invite_code = Column(String(10), unique=True) invited_by = Column(String(10)) invite_count = Column(Integer, default=0) invite_reward_total = Column(DECIMAL(10, 2), default=0.00) class VoiceLibrary(Base): __tablename__ = "nf_voice_library" id = Column(BigInteger, primary_key=True, autoincrement=True) name = Column(String(64), nullable=False) gender = Column(Enum("male", "female"), nullable=False) style_tag = Column(String(32)) avatar_url = Column(String(255)) sample_audio_url = Column(String(255)) tts_model_id = Column(String(64)) is_default = Column(Boolean, default=False) voice_code = Column(String(64), nullable=False) is_owned = Column(Boolean, default=True) price_gold = Column(Integer, default=0) class SongLibrary(Base): __tablename__ = "nf_song_library" id = Column(BigInteger, primary_key=True, autoincrement=True) title = Column(String(128), nullable=False, default="") artist = Column(String(64)) gender = Column(Enum("male", "female"), nullable=False) audio_url = Column(String(255), nullable=False) status = Column(Boolean, default=True) weigh = Column(Integer, default=0) createtime = Column(BigInteger) updatetime = Column(BigInteger) deletetime = Column(BigInteger) audio_hash = Column(String(64)) duration_sec = Column(Integer) class SingBaseVideo(Base): __tablename__ = "nf_sing_base_video" id = Column(BigInteger, primary_key=True, autoincrement=True) user_id = Column(BigInteger, nullable=False) lover_id = Column(BigInteger, nullable=False) image_url = Column(String(255)) image_hash = Column(String(64), nullable=False) prompt = Column(String(400)) prompt_hash = Column(String(64), nullable=False) model = Column(String(64), nullable=False, default="wan2.2-i2v-flash") resolution = Column(String(16), nullable=False, default="480P") duration = Column(Integer, default=5) dashscope_task_id = Column(String(64)) status = Column(Enum("pending", "running", "succeeded", "failed"), default="pending") base_video_url = Column(String(255)) error_msg = Column(String(255)) generation_task_id = Column(BigInteger) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class SingSongVideo(Base): __tablename__ = "nf_sing_song_video" id = Column(BigInteger, primary_key=True, autoincrement=True) user_id = Column(BigInteger, nullable=False) lover_id = Column(BigInteger, nullable=False) song_id = Column(BigInteger, nullable=False) base_video_id = Column(BigInteger) audio_url = Column(String(255), nullable=False) audio_hash = Column(String(64), nullable=False) image_hash = Column(String(64)) ratio = Column(Enum("1:1", "3:4"), default="3:4") style_level = Column(Enum("normal", "calm", "active"), default="normal") merged_video_url = Column(String(255)) status = Column(Enum("pending", "running", "succeeded", "failed"), default="pending") error_msg = Column(String(255)) generation_task_id = Column(BigInteger) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class EmoDetectCache(Base): __tablename__ = "nf_emo_detect_cache" id = Column(BigInteger, primary_key=True, autoincrement=True) lover_id = Column(BigInteger, nullable=False) image_url = Column(String(255), nullable=False) image_hash = Column(String(64), nullable=False) ratio = Column(Enum("1:1", "3:4"), nullable=False) check_pass = Column(Boolean, default=False) face_bbox = Column(JSON) ext_bbox = Column(JSON) raw_response = Column(JSON) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class SongSegment(Base): __tablename__ = "nf_song_segments" id = Column(BigInteger, primary_key=True, autoincrement=True) song_id = Column(BigInteger, nullable=False) audio_hash = Column(String(64), nullable=False) segment_index = Column(Integer, nullable=False) start_ms = Column(Integer, nullable=False) duration_ms = Column(Integer, nullable=False) audio_url = Column(String(255), nullable=False) audio_size = Column(Integer) status = Column(Enum("pending", "running", "succeeded", "failed"), default="pending") error_msg = Column(String(255)) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class SongSegmentVideo(Base): __tablename__ = "nf_song_segment_video" id = Column(BigInteger, primary_key=True, autoincrement=True) user_id = Column(BigInteger, nullable=False) lover_id = Column(BigInteger, nullable=False) song_id = Column(BigInteger, nullable=False) segment_id = Column(BigInteger, nullable=False) image_hash = Column(String(64), nullable=False) model = Column(String(64), nullable=False, default="emo-v1") ratio = Column(Enum("1:1", "3:4"), nullable=False, default="3:4") style_level = Column(Enum("normal", "calm", "active"), nullable=False, default="normal") dashscope_task_id = Column(String(64)) video_url = Column(String(255)) status = Column(Enum("pending", "running", "succeeded", "failed"), default="pending") error_msg = Column(String(255)) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class Lover(Base): __tablename__ = "nf_lovers" id = Column(BigInteger, primary_key=True, autoincrement=True) user_id = Column(BigInteger, nullable=False, unique=True, index=True) name = Column(String(64)) gender = Column(Enum("male", "female"), nullable=False) intro = Column(Text) story_background = Column(Text) personality_tag = Column(Integer) interest_tags = Column(JSON) opening_line = Column(Text) personality_prompt = Column(Text) appearance_prompt = Column(Text) appearance_params = Column(JSON) hair_style_id = Column(Integer) eye_color_id = Column(Integer) outfit_desc = Column(String(50)) outfit_top_id = Column(BigInteger) outfit_bottom_id = Column(BigInteger) outfit_dress_id = Column(BigInteger) voice_id = Column(BigInteger) image_url = Column(String(255)) last_image_task_id = Column(BigInteger) image_gen_used = Column(Integer, default=0) image_gen_limit = Column(Integer, default=10) image_gen_reset_date = Column(Date) init_model = Column(String(64)) init_at = Column(DateTime) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow) class GenerationTask(Base): __tablename__ = "nf_generation_tasks" id = Column(BigInteger, primary_key=True, autoincrement=True) user_id = Column(BigInteger, nullable=False) lover_id = Column(BigInteger) message_id = Column(BigInteger) task_type = Column(Enum("image", "video", "outfit", "voice"), nullable=False) idempotency_key = Column(String(64)) status = Column(Enum("pending", "running", "succeeded", "failed", "refunded"), default="pending") attempts = Column(Integer, default=0) payload = Column(JSON) result_url = Column(String(255)) error_msg = Column(String(255)) pre_deduct = Column(Boolean, default=False) refunded = Column(Boolean, default=False) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow) class FriendRelation(Base): __tablename__ = "nf_friend_relations" id = Column(BigInteger, primary_key=True, autoincrement=True) user_id = Column(BigInteger) friend_id = Column(BigInteger) status = Column(Enum("1", "2", "3"), default="1") intimacy = Column(Integer) intimacy_level = Column(Integer) createtime = Column(BigInteger) updatetime = Column(BigInteger) class Dynamic(Base): __tablename__ = "nf_dynamics" id = Column(BigInteger, primary_key=True, autoincrement=True) user_id = Column(BigInteger, nullable=False) lover_id = Column(BigInteger) source_message_id = Column(BigInteger, nullable=False) video_url = Column(String(255), nullable=False) content = Column(String(50), nullable=False) visibility = Column(Enum("friends", "public", "private"), default="friends", nullable=False) like_count = Column(Integer, default=0) comment_count = Column(Integer, default=0) deleted_at = Column(DateTime) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class DynamicLike(Base): __tablename__ = "nf_dynamic_likes" id = Column(BigInteger, primary_key=True, autoincrement=True) dynamic_id = Column(BigInteger, nullable=False) user_id = Column(BigInteger, nullable=False) created_at = Column(DateTime, default=datetime.utcnow) deleted_at = Column(DateTime) class DynamicComment(Base): __tablename__ = "nf_dynamic_comments" id = Column(BigInteger, primary_key=True, autoincrement=True) dynamic_id = Column(BigInteger, nullable=False) user_id = Column(BigInteger, nullable=False) content = Column(String(50), nullable=False) created_at = Column(DateTime, default=datetime.utcnow) deleted_at = Column(DateTime) class MotionTemplate(Base): __tablename__ = "nf_motion_templates" id = Column(BigInteger, primary_key=True, autoincrement=True) name = Column(String(100)) gender = Column(Enum("male", "female"), nullable=False) template_id = Column(String(128), nullable=False) ref_video_url = Column(String(255)) template_url = Column(String(255)) cover_url = Column(String(255)) status = Column(Enum("active", "inactive"), default="active") description = Column(String(255)) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class ChatSession(Base): __tablename__ = "nf_chat_session" id = Column(BigInteger, primary_key=True, autoincrement=True) user_id = Column(BigInteger, nullable=False) lover_id = Column(BigInteger, nullable=False) title = Column(String(100)) model = Column(String(64)) status = Column(Enum("active", "archived"), default="active") inner_voice_enabled = Column(Boolean, default=False) last_message_at = Column(DateTime) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class ChatMessage(Base): __tablename__ = "nf_chat_message" id = Column(BigInteger, primary_key=True, autoincrement=True) session_id = Column(BigInteger, nullable=False) user_id = Column(BigInteger, nullable=False) lover_id = Column(BigInteger, nullable=False) role = Column(Enum("user", "lover", "system"), nullable=False) content_type = Column(Enum("text", "audio", "image"), default="text") content = Column(Text, nullable=False) seq = Column(BigInteger) token_input = Column(Integer) token_output = Column(Integer) model = Column(String(64)) extra = Column(JSON) tts_url = Column(String(255)) tts_status = Column(Enum("pending", "succeeded", "failed"), default="pending") tts_voice_id = Column(BigInteger) tts_model_id = Column(String(64)) tts_format = Column(String(32)) tts_duration_ms = Column(Integer) tts_error = Column(String(255)) created_at = Column(DateTime, default=datetime.utcnow) # 编辑相关字段 is_edited = Column(Boolean, default=False) original_content = Column(Text) edited_at = Column(DateTime) class ChatSummary(Base): __tablename__ = "nf_chat_summary" id = Column(BigInteger, primary_key=True, autoincrement=True) session_id = Column(BigInteger, nullable=False) upto_seq = Column(BigInteger, nullable=False) summary_text = Column(Text, nullable=False) model = Column(String(64)) token_input = Column(Integer) token_output = Column(Integer) created_at = Column(DateTime, default=datetime.utcnow) class ChatFact(Base): __tablename__ = "nf_chat_fact" id = Column(BigInteger, primary_key=True, autoincrement=True) user_id = Column(BigInteger, nullable=False) lover_id = Column(BigInteger, nullable=False) kind = Column(Enum("fact", "event", "preference", "boundary"), default="fact") content = Column(Text, nullable=False) weight = Column(Integer, default=0) source_session_id = Column(BigInteger) source_message_id = Column(BigInteger) created_at = Column(DateTime, default=datetime.utcnow) class GirlfriendMould(Base): __tablename__ = "nf_girlfriend_mould" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(100), default="") weigh = Column(Integer, default=0) gender = Column(Enum("male", "female"), nullable=True) createtime = Column(BigInteger) updatetime = Column(BigInteger) deletetime = Column(BigInteger) class GirlfriendHobbies(Base): __tablename__ = "nf_girlfriend_hobbies" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(100), default="") weigh = Column(Integer, default=0) createtime = Column(BigInteger) updatetime = Column(BigInteger) deletetime = Column(BigInteger) class GirlfriendEyeColor(Base): __tablename__ = "nf_girlfriend_eyecolor" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(100), default="") weigh = Column(Integer, default=0) createtime = Column(BigInteger) updatetime = Column(BigInteger) deletetime = Column(BigInteger) class GirlfriendHairStyle(Base): __tablename__ = "nf_girlfriend_hairstyles" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(100), default="") weigh = Column(Integer, default=0) gender = Column(Enum("male", "female"), nullable=True) createtime = Column(BigInteger) updatetime = Column(BigInteger) deletetime = Column(BigInteger) class OutfitItem(Base): __tablename__ = "nf_outfit_items" id = Column(BigInteger, primary_key=True, autoincrement=True) name = Column(String(100), default="") category = Column(Enum("top", "bottom", "dress"), nullable=False) gender = Column(Enum("male", "female", "unisex"), default="unisex", nullable=False) image_url = Column(String(255), nullable=False) is_free = Column(Boolean, default=False) price_gold = Column(Integer, default=0) is_vip_only = Column(Boolean, default=False) status = Column(Enum("0", "1"), default="1", nullable=False) weigh = Column(Integer, default=0) createtime = Column(BigInteger) updatetime = Column(BigInteger) class OutfitLook(Base): __tablename__ = "nf_outfit_looks" id = Column(BigInteger, primary_key=True, autoincrement=True) user_id = Column(BigInteger, nullable=False) lover_id = Column(BigInteger, nullable=False) name = Column(String(100), default="") image_url = Column(String(255), nullable=False) top_item_id = Column(BigInteger) bottom_item_id = Column(BigInteger) dress_item_id = Column(BigInteger) deleted_at = Column(DateTime) createtime = Column(DateTime, default=datetime.utcnow) updatetime = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class UserOutfitItem(Base): __tablename__ = "nf_user_outfit_items" id = Column(BigInteger, primary_key=True, autoincrement=True) user_id = Column(BigInteger, nullable=False) item_id = Column(BigInteger, nullable=False) source = Column(Enum("default", "purchase", "vip", "gift"), default="purchase") platform_limit = Column(Enum("all", "android", "ios"), default="all") createtime = Column(BigInteger) class OutfitPurchaseLog(Base): __tablename__ = "nf_outfit_purchase_log" id = Column(BigInteger, primary_key=True, autoincrement=True) user_id = Column(BigInteger, nullable=False) item_id = Column(BigInteger, nullable=False) price_gold = Column(Integer, default=0) platform = Column(Enum("android", "ios", "miniapp"), default="miniapp") status = Column(Enum("pending", "success", "failed", "refund"), default="success") remark = Column(String(255)) createtime = Column(BigInteger) updatetime = Column(BigInteger) class UserMoneyLog(Base): __tablename__ = "nf_user_money_log" id = Column(Integer, primary_key=True, autoincrement=True) user_id = Column(Integer, nullable=False, default=0) money = Column(DECIMAL(10, 2), default=0.00) before = Column(DECIMAL(10, 2), default=0.00) after = Column(DECIMAL(10, 2), default=0.00) memo = Column(String(255), default="") createtime = Column(BigInteger)