添加后台管理功能

功能:
- 数据概览仪表盘
- 用户管理(列表/编辑/删除)
- 翻译记录管理
- 缓存管理
- 统计报表(图表)
- 操作日志

管理员账号: admin / admin123
后台地址: /admin/
This commit is contained in:
2026-04-07 23:08:49 +08:00
parent be1e01a8c6
commit 236b202e3e
17 changed files with 1896 additions and 3 deletions
+74 -2
View File
@@ -19,7 +19,7 @@ class User(db.Model):
email = db.Column(db.String(120), unique=True, nullable=False)
password_hash = db.Column(db.String(256), nullable=False)
# 用户类型: guest, free, vip_basic, vip_pro, vip_enterprise
# 用户类型: guest, free, vip_basic, vip_pro, vip_enterprise, admin
user_type = db.Column(db.String(20), default='free')
# 会员信息
@@ -34,6 +34,10 @@ class User(db.Model):
created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# 状态
is_active = db.Column(db.Boolean, default=True) # 是否启用
is_admin = db.Column(db.Boolean, default=False) # 是否管理员
# 关系
translations = db.relationship('Translation', backref='user', lazy=True)
@@ -92,8 +96,12 @@ class User(db.Model):
'email': self.email,
'user_type': self.user_type,
'is_vip': self.is_vip(),
'is_admin': self.is_admin,
'is_active': self.is_active,
'daily_count': self.daily_count,
'total_count': self.total_count,
'created_at': self.created_at.isoformat() if self.created_at else None,
'membership_expire': self.membership_expire.isoformat() if self.membership_expire else None,
}
@@ -145,8 +153,10 @@ class Translation(db.Model):
'status': self.status,
'progress': self.progress,
'from_cache': self.from_cache,
'file_size': self.file_size,
'created_at': self.created_at.isoformat() if self.created_at else None,
'completed_at': self.completed_at.isoformat() if self.completed_at else None,
'user_id': self.user_id,
}
@@ -163,6 +173,7 @@ class TranslationCache(db.Model):
# 缓存信息
cache_path = db.Column(db.String(255), nullable=False) # 缓存文件路径
page_count = db.Column(db.Integer, nullable=False)
file_size = db.Column(db.Integer, default=0)
# 统计
hit_count = db.Column(db.Integer, default=0) # 缓存命中次数
@@ -194,6 +205,67 @@ class GuestTranslation(db.Model):
# 统计
daily_count = db.Column(db.Integer, default=0)
total_count = db.Column(db.Integer, default=0)
last_translate_date = db.Column(db.Date, nullable=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
# ==================== 系统配置模型 ====================
class SystemConfig(db.Model):
"""系统配置表"""
__tablename__ = 'system_config'
id = db.Column(db.Integer, primary_key=True)
key = db.Column(db.String(100), unique=True, nullable=False)
value = db.Column(db.Text, nullable=True)
description = db.Column(db.String(255), nullable=True)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
@staticmethod
def get(key, default=None):
config = SystemConfig.query.filter_by(key=key).first()
return config.value if config else default
@staticmethod
def set(key, value, description=None):
config = SystemConfig.query.filter_by(key=key).first()
if config:
config.value = value
else:
config = SystemConfig(key=key, value=value, description=description)
db.session.add(config)
db.session.commit()
# ==================== 操作日志模型 ====================
class OperationLog(db.Model):
"""操作日志表"""
__tablename__ = 'operation_logs'
id = db.Column(db.Integer, primary_key=True)
# 操作者
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
username = db.Column(db.String(80), nullable=True)
# 操作信息
action = db.Column(db.String(50), nullable=False) # login, translate, register, etc.
target = db.Column(db.String(100), nullable=True) # 操作对象
detail = db.Column(db.Text, nullable=True) # 详细信息(JSON)
# IP地址
ip_address = db.Column(db.String(45), nullable=True)
# 时间
created_at = db.Column(db.DateTime, default=datetime.utcnow)
def to_dict(self):
return {
'id': self.id,
'username': self.username,
'action': self.action,
'target': self.target,
'ip_address': self.ip_address,
'created_at': self.created_at.isoformat() if self.created_at else None,
}