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