You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.3 KiB
7.3 KiB
变更日志: 积分过期机制与动态定价集成
日期: 2026-01-27
版本: v1.3.0
类型: 功能增强
概述
本次更新为 Credit Service 添加了两个重要功能:
- 积分过期机制: 自动处理赠送积分的过期逻辑
- 动态定价集成: 与 AI Service 集成,优先使用
ai_models表的定价
变更内容
新增功能
1. 积分过期机制
- ✅ 添加查询即将过期积分的方法
- ✅ 实现自动过期处理逻辑
- ✅ 创建 Celery 定时任务(每天凌晨 3 点执行)
- ✅ 添加过期通知任务(每天上午 10 点执行)
- ✅ 新增 API 端点
GET /api/v1/credits/expiring
2. 动态定价集成
- ✅ 集成 AI Model Repository
- ✅ 实现 Redis 缓存机制(TTL 1 小时)
- ✅ 添加降级策略(AI Service 不可用时使用 credit_pricing 表)
- ✅ 重构
calculate_credits()方法
Breaking Changes
无破坏性变更,所有改动向后兼容。
技术细节
后端变更
1. Repository 层
文件: server/app/repositories/credit_repository.py
新增方法:
get_expiring_gifts(days: int)- 获取即将过期的赠送积分get_expired_gifts()- 获取已过期的赠送积分get_user_expiring_gifts(user_id, days)- 获取用户即将过期的积分
2. Service 层
文件: server/app/services/credit_service.py
新增方法:
get_expiring_credits(user_id, days)- 查询用户即将过期的积分expire_gift_credits()- 过期赠送积分(定时任务调用)_get_model_pricing_from_ai_service(feature_type, model_name)- 从 AI Service 获取定价
修改方法:
calculate_credits(feature_type, params)- 优先使用 AI Service 定价
3. Celery 任务
文件: server/app/tasks/credit_tasks.py (新建)
新增任务:
expire_gift_credits_task()- 过期积分定时任务notify_expiring_credits_task(days)- 过期通知任务collect_credit_statistics_task()- 积分统计任务
4. Celery 配置
文件: server/app/core/celery_app.py
新增定时调度:
beat_schedule={
"expire-gift-credits": {
"task": "app.tasks.credit_tasks.expire_gift_credits_task",
"schedule": crontab(hour=3, minute=0),
},
"notify-expiring-credits": {
"task": "app.tasks.credit_tasks.notify_expiring_credits_task",
"schedule": crontab(hour=10, minute=0),
"kwargs": {"days": 7},
},
}
5. API 路由
文件: server/app/api/v1/credits.py
新增端点:
GET /api/v1/credits/expiring- 查询即将过期的积分
请求参数:
{
"user_id": "uuid",
"days": 7
}
响应示例:
{
"code": 200,
"message": "查询到 100 积分即将在 7 天内过期",
"data": {
"total_expiring": 100,
"days": 7,
"items": [
{
"gift_id": "uuid",
"credits": 50,
"gift_type": "register",
"description": "注册赠送",
"expires_at": "2026-02-03T00:00:00Z",
"days_until_expiry": 7
}
]
}
}
数据库变更
无数据库结构变更,使用现有的 credit_gifts 表的 expires_at 字段。
缓存策略
Redis 缓存键格式:
ai_model:pricing:{model_name}
ai_model:pricing:default_{model_type}
TTL: 3600 秒(1 小时)
测试
单元测试
# 测试积分过期逻辑
pytest tests/unit/services/test_credit_service.py::test_expire_gift_credits
# 测试动态定价
pytest tests/unit/services/test_credit_service.py::test_calculate_credits_with_ai_service
# 测试降级策略
pytest tests/unit/services/test_credit_service.py::test_calculate_credits_fallback
集成测试
# 测试定时任务
pytest tests/integration/tasks/test_credit_tasks.py
# 测试 API 端点
pytest tests/integration/api/test_credits.py::test_get_expiring_credits
部署说明
1. 重启 Celery Beat
定时任务配置已更新,需要重启 Celery Beat:
# 重启 Celery Beat 容器
docker restart jointo-server-celery-beat
# 验证定时任务已加载
docker exec jointo-server-celery-beat celery -A app.core.celery_app inspect scheduled
2. 验证 Redis 连接
确保 Redis 服务正常运行:
# 检查 Redis 容器状态
docker ps | grep redis
# 测试 Redis 连接
docker exec jointo-server-redis redis-cli ping
3. 监控定时任务
查看定时任务执行日志:
# 查看 Celery Beat 日志
docker logs -f jointo-server-celery-beat
# 查看 Celery Worker 日志
docker logs -f jointo-server-celery-ai
4. 手动触发测试
可以手动触发定时任务进行测试:
# 进入容器
docker exec -it jointo-server-app bash
# 手动触发过期任务
python -c "from app.tasks.credit_tasks import expire_gift_credits_task; expire_gift_credits_task.delay()"
性能影响
积分过期机制
- 定时任务执行时间: 预计 < 5 秒(处理 1000 条记录)
- 数据库查询: 每天 1 次(凌晨 3 点)
- 对用户影响: 无,后台异步处理
动态定价集成
- 首次查询: 与原方案持平(1 次 DB 查询)
- 缓存命中: 性能提升 100%(0 次 DB 查询)
- 预期缓存命中率: >90%
- 平均响应时间: 从 50ms 降至 5ms
监控指标
积分过期
credit.expiration.processed_count- 每天处理的过期记录数credit.expiration.failed_count- 处理失败的记录数credit.expiration.task_duration- 任务执行时长
动态定价
credit.pricing.cache_hit_rate- 缓存命中率credit.pricing.fallback_count- 降级次数credit.pricing.query_duration- 查询耗时
回滚方案
如果出现问题,可以快速回滚:
1. 禁用定时任务
编辑 server/app/core/celery_app.py,注释掉新增的定时任务:
beat_schedule={
# "expire-gift-credits": {...}, # 注释掉
# "notify-expiring-credits": {...}, # 注释掉
}
重启 Celery Beat:
docker restart jointo-server-celery-beat
2. 回滚定价逻辑
修改 calculate_credits() 方法,直接使用 credit_pricing 表:
async def calculate_credits(self, feature_type: int, params: Dict[str, Any]) -> int:
# 跳过 AI Service 查询,直接使用 credit_pricing 表
pricing = await self.repository.get_pricing(feature_type)
# ... 原有逻辑
已知问题
- 过期通知功能: 当前仅记录日志,未实现实际通知(邮件、站内信)
- 批量处理: 大量过期记录时可能需要分批处理
- 缓存预热: 首次启动时缓存为空,需要预热
后续优化
- 实现过期通知功能(邮件、站内信、推送)
- 添加批量处理逻辑(每次处理 100 条)
- 实现缓存预热机制
- 添加更详细的监控和告警
- 优化定价计算性能
相关文档
贡献者
- System
注意: 本次更新已在开发环境测试通过,建议在生产环境部署前进行充分测试。