ai_v/models.py

142 lines
6.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from extensions import db
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
# 角色与权限的多对多关联表
role_permissions = db.Table('role_permissions',
db.Column('role_id', db.Integer, db.ForeignKey('roles.id'), primary_key=True),
db.Column('permission_id', db.Integer, db.ForeignKey('permissions.id'), primary_key=True)
)
class Permission(db.Model):
__tablename__ = 'permissions'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), unique=True, nullable=False) # 如: 'view_logs', 'manage_users'
description = db.Column(db.String(100))
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), unique=True, nullable=False) # 如: '超级管理员', '普通用户'
description = db.Column(db.String(100))
# 角色拥有的权限
permissions = db.relationship('Permission', secondary=role_permissions, backref=db.backref('roles', lazy='dynamic'))
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
phone = db.Column(db.String(20), unique=True, nullable=False)
password_hash = db.Column(db.String(255), nullable=False)
api_key = db.Column(db.String(255)) # 存储用户的 API Key
points = db.Column(db.Integer, default=2) # 账户积分默认赠送2次试用
has_used_points = db.Column(db.Boolean, default=False) # 是否使用过积分
# 关联角色 ID
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
created_at = db.Column(db.DateTime, default=datetime.utcnow)
# 关系映射
role = db.relationship('Role', backref=db.backref('users', lazy='dynamic'))
def has_permission(self, perm_name):
"""动态检查用户是否拥有某项权限"""
if not self.role:
return False
# 获取用户拥有的所有权限名称
perms = [p.name for p in self.role.permissions]
# 核心修复:如果是超级管理员(拥有 manage_system则豁免所有具体权限检查
if 'manage_system' in perms:
return True
return perm_name in perms
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
class SystemDict(db.Model):
"""通用字典管理系统"""
__tablename__ = 'system_dicts'
id = db.Column(db.Integer, primary_key=True)
dict_type = db.Column(db.String(50), nullable=False) # 如: 'ai_model', 'aspect_ratio', 'prompt_tpl'
label = db.Column(db.String(100), nullable=False) # 显示名称
value = db.Column(db.Text, nullable=False) # 存储值或提示词内容
cost = db.Column(db.Integer, default=0) # 消耗积分 (仅针对 ai_model 有效)
is_active = db.Column(db.Boolean, default=True)
sort_order = db.Column(db.Integer, default=0) # 排序权重
class GenerationRecord(db.Model):
"""AI 生成记录"""
__tablename__ = 'generation_records'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
prompt = db.Column(db.Text)
model = db.Column(db.String(100))
# 存储生成的图片 URL 列表 (JSON 字符串)
image_urls = db.Column(db.Text)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
user = db.relationship('User', backref=db.backref('records', lazy='dynamic', order_by='GenerationRecord.created_at.desc()'))
# 用户已读通知关联表
notification_reads = db.Table('notification_reads',
db.Column('user_id', db.Integer, db.ForeignKey('users.id'), primary_key=True),
db.Column('notification_id', db.Integer, db.ForeignKey('system_notifications.id'), primary_key=True)
)
class SystemNotification(db.Model):
"""系统全局通知"""
__tablename__ = 'system_notifications'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200), nullable=False)
content = db.Column(db.Text, nullable=False)
is_active = db.Column(db.Boolean, default=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
# 哪些用户已读
read_by_users = db.relationship('User', secondary=notification_reads, backref=db.backref('read_notifications', lazy='dynamic'))
class Order(db.Model):
"""订单模型"""
__tablename__ = 'orders'
id = db.Column(db.Integer, primary_key=True)
out_trade_no = db.Column(db.String(64), unique=True, nullable=False) # 系统订单号
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
amount = db.Column(db.Numeric(10, 2), nullable=False) # 金额
points = db.Column(db.Integer, nullable=False) # 购买的积分
status = db.Column(db.String(20), default='PENDING') # PENDING, PAID, CANCELLED
trade_no = db.Column(db.String(64)) # 支付宝交易号
created_at = db.Column(db.DateTime, default=datetime.utcnow)
paid_at = db.Column(db.DateTime)
user = db.relationship('User', backref=db.backref('orders', lazy='dynamic', order_by='Order.created_at.desc()'))
class SystemLog(db.Model):
"""系统精细化日志记录"""
__tablename__ = 'system_logs'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True) # 可能没有登录用户
level = db.Column(db.String(20), nullable=False) # INFO, WARNING, ERROR, DEBUG
module = db.Column(db.String(50)) # 模块名
message = db.Column(db.Text, nullable=False) # 日志内容
extra = db.Column(db.Text) # 额外信息的 JSON 字符串
# 请求上下文信息
ip = db.Column(db.String(50))
path = db.Column(db.String(255))
method = db.Column(db.String(10))
user_agent = db.Column(db.String(255))
created_at = db.Column(db.DateTime, default=datetime.now)
user = db.relationship('User', backref=db.backref('logs', lazy='dynamic', order_by='SystemLog.created_at.desc()'))