5.4 KiB
5.4 KiB
卡密过期状态自动更新方案
问题描述
之前卡密系统存在一个严重问题:卡密激活后即使到期,状态也不会自动更新为"已过期",导致用户可以一直使用已过期的卡密。
问题根源
- 只有在用户主动调用
verify()方法验证时,才会检查过期状态 - 如果用户不验证(离线使用、关闭验证等),卡密状态不会更新
- 缺少定期检查过期卡密的后台任务
解决方案
1. 新增功能
后台定时任务
- 每小时检查一次:自动将已激活但已过期的卡密状态更新为2(已过期)
- 每天凌晨2点:执行全面的卡密健康检查和统计
- 每周清理:清理过期的审计日志
手动触发接口
管理员可以通过API手动触发检查,立即更新过期卡密状态。
2. 文件变更
新增文件
-
app/utils/background_tasks.py- 后台任务模块update_expired_licenses()- 更新过期卡密状态check_licenses_batch()- 批量检查所有卡密状态cleanup_old_license_logs()- 清理旧日志
-
app/utils/scheduler.py- 定时任务调度器- 管理所有后台定时任务
- 提供任务状态查询功能
修改文件
requirements.txt- 添加 APScheduler 依赖app/__init__.py- 应用启动时初始化调度器app/api/license.py- 新增4个API接口
3. 新增API接口
3.1 手动检查过期卡密
POST /api/v1/licenses/check-expired
权限:管理员
响应示例:
{
"success": true,
"message": "成功更新 5 个过期卡密状态",
"data": {
"updated_count": 5
}
}
3.2 批量检查所有卡密状态
POST /api/v1/licenses/batch-check
权限:管理员
响应示例:
{
"success": true,
"message": "批量检查完成",
"data": {
"active_but_expired": 5,
"expired_and_marked": 12,
"active_and_valid": 158,
"inactive": 45,
"disabled": 3
}
}
3.3 获取定时任务状态
GET /api/v1/scheduler/status
权限:管理员
响应示例:
{
"success": true,
"data": {
"running": true,
"jobs": [
{
"id": "update_expired_licenses_hourly",
"name": "每小时更新过期卡密状态",
"next_run_time": "2024-01-15T10:00:00",
"trigger": "interval[1:00:00]"
},
{
"id": "daily_license_health_check",
"name": "每日卡密健康检查",
"next_run_time": "2024-01-16T02:00:00",
"trigger": "cron[hour:2]"
}
]
}
}
3.4 手动触发定时任务检查
POST /api/v1/scheduler/trigger-check
权限:管理员
响应示例:
{
"success": true,
"message": "成功更新 5 个过期卡密状态"
}
部署步骤
1. 安装依赖
pip install APScheduler==3.10.4
2. 重启应用
重启Flask应用,调度器会自动启动。
3. 验证部署
- 查看应用日志,确认调度器启动成功
- 调用
/api/v1/scheduler/status查看任务状态 - 调用
/api/v1/licenses/batch-check进行一次全面检查
配置选项
禁用调度器
如果需要禁用定时任务,可以设置环境变量:
export DISABLE_SCHEDULER=true
修改检查频率
如需修改定时任务的执行频率,编辑 app/utils/scheduler.py 文件中的调度器配置:
# 每30分钟检查一次
scheduler.add_job(
func=check_and_update_expired_licenses,
trigger=IntervalTrigger(minutes=30),
id='update_expired_licenses_half_hourly',
name='每30分钟更新过期卡密状态',
replace_existing=True,
max_instances=1
)
日志监控
所有定时任务的执行都会记录到应用日志中:
INFO - 开始检查过期卡密...
INFO - 成功更新 5 个过期卡密状态
INFO - 定时任务调度器已启动
测试验证
手动测试步骤
-
创建测试卡密
- 生成一个短期卡密(如1天有效期)
- 记录卡密ID
-
激活卡密
- 通过客户端激活卡密
- 确认状态为1(已激活)
-
模拟过期
- 修改数据库中的
expire_time为过去时间 - 或等待卡密自然过期
- 修改数据库中的
-
触发检查
- 调用
POST /api/v1/licenses/check-expired - 确认返回更新的卡密数量
- 调用
-
验证状态
- 查询卡密详情,确认状态变为2(已过期)
自动化测试
可以编写自动化测试脚本,定期调用检查接口并验证结果。
注意事项
- 数据库事务:所有状态更新都在事务中执行,确保数据一致性
- 错误处理:定时任务失败不会影响应用正常运行
- 并发安全:使用
max_instances=1防止并发执行 - 日志记录:所有操作都有审计日志,便于追踪
- 性能考虑:大批量更新时,建议分批处理以避免锁表
监控建议
- 设置告警:当定时任务连续失败时发送告警
- 定期检查:每周查看一次定时任务执行日志
- 统计报告:每月统计过期卡密数量和趋势
总结
通过添加后台定时任务和手动触发接口,彻底解决了卡密过期状态不更新的问题。系统现在可以:
✅ 自动检测过期卡密并更新状态 ✅ 提供管理员手动检查接口 ✅ 记录详细的执行日志 ✅ 支持灵活的配置和监控
确保用户无法继续使用已过期的卡密,提升了系统的安全性和可靠性。