fix: 修复添加用户 500 错误 (expire_at 字符串 vs datetime)

web form 提交时 expire_at 字段是 HTML datetime-local 字符串 (如 '2027-12-31T23:59'),
SQLAlchemy 直接写入 datetime 列会抛 TypeError. 同样, API 路径里如果传 ISO
字符串而不带 tzinfo, 写入后再读出是 naive datetime, is_active() 比较时
会抛 'can't compare offset-naive and offset-aware datetimes'.

修复:
- services/user_service.py: 增加 _parse_expire_at() helper, 统一转成
  UTC-aware datetime, 支持 datetime-local 'T'/' ' 多种分隔符 + ISO 格式
- services/user_service.py: create_user/update_user 调用 helper
- models.py: User.is_active() 兼容 naive datetime (SQLite 不存 tzinfo)
This commit is contained in:
Your Name
2026-07-16 23:12:45 +08:00
parent 0bd9bcac12
commit e44802ae40
2 changed files with 50 additions and 3 deletions
+11 -3
View File
@@ -100,11 +100,19 @@ class User(db.Model):
return False
def is_active(self):
"""用户是否可用(未过期、未封禁、已启用)"""
"""用户是否可用(未过期、未封禁、已启用)
SQLite 不存 tzinfo, 从数据库读出的 datetime 是 naive;
我们统一当作 UTC 处理后再比较, 避免 aware/naive TypeError.
"""
if not self.enabled or self.banned:
return False
if self.expire_at and datetime.now(timezone.utc) > self.expire_at:
return False
if self.expire_at:
exp = self.expire_at
if exp.tzinfo is None:
exp = exp.replace(tzinfo=timezone.utc)
if datetime.now(timezone.utc) > exp:
return False
return True
def __repr__(self):