# -*- coding: utf-8 -*- """ 后台任务模块 用于执行定时任务,如更新过期卡密状态 """ from datetime import datetime, timedelta from app import db from app.models import License from flask import current_app import logging logger = logging.getLogger(__name__) def update_expired_licenses(): """ 更新过期卡密状态 将所有已激活但已过期的卡密状态更新为2(已过期) """ try: logger.info("开始检查过期卡密...") # 查找所有已激活但已过期的卡密 # 条件:status=1(已激活)且expire_time < 当前时间 expired_licenses = License.query.filter( License.status == 1, License.expire_time.isnot(None), License.expire_time < datetime.utcnow() ).all() if not expired_licenses: logger.info("没有发现过期卡密") return { 'success': True, 'message': '没有发现过期卡密', 'updated_count': 0 } # 更新过期卡密状态 updated_count = 0 for license_obj in expired_licenses: old_status = license_obj.status license_obj.status = 2 # 更新为已过期 updated_count += 1 logger.info( f"更新卡密 {license_obj.license_key} 状态: {old_status} -> {license_obj.status}" ) # 提交事务 db.session.commit() logger.info(f"成功更新 {updated_count} 个过期卡密状态") return { 'success': True, 'message': f'成功更新 {updated_count} 个过期卡密状态', 'updated_count': updated_count } except Exception as e: # 回滚事务 db.session.rollback() logger.error(f"更新过期卡密失败: {str(e)}", exc_info=True) return { 'success': False, 'message': f'更新过期卡密失败: {str(e)}', 'updated_count': 0 } def check_licenses_batch(): """ 批量检查所有卡密状态 包括: 1. 已激活但过期的 -> 更新为已过期 2. 已过期但状态未更新的 -> 更新状态 """ try: logger.info("开始批量检查卡密状态...") # 检查1:已激活但过期的卡密 active_but_expired = License.query.filter( License.status == 1, # 已激活 License.expire_time.isnot(None), License.expire_time < datetime.utcnow() ).count() # 检查2:已过期但状态正确的卡密 expired_and_marked = License.query.filter( License.status == 2, # 已过期 License.expire_time.isnot(None), License.expire_time < datetime.utcnow() ).count() # 检查3:已激活且未过期的卡密 active_and_valid = License.query.filter( License.status == 1, # 已激活 db.or_( License.expire_time.is_(None), # 永久卡 License.expire_time >= datetime.utcnow() # 未过期 ) ).count() # 检查4:未激活的卡密 inactive = License.query.filter( License.status == 0 # 未激活 ).count() # 检查5:已禁用的卡密 disabled = License.query.filter( License.status == 3 # 已禁用 ).count() logger.info( f"卡密状态统计:\n" f" 已激活但过期: {active_but_expired}\n" f" 已过期且已标记: {expired_and_marked}\n" f" 已激活且有效: {active_and_valid}\n" f" 未激活: {inactive}\n" f" 已禁用: {disabled}" ) # 执行更新 update_result = update_expired_licenses() return { 'success': True, 'message': '批量检查完成', 'statistics': { 'active_but_expired': active_but_expired, 'expired_and_marked': expired_and_marked, 'active_and_valid': active_and_valid, 'inactive': inactive, 'disabled': disabled }, 'update_result': update_result } except Exception as e: logger.error(f"批量检查卡密失败: {str(e)}", exc_info=True) return { 'success': False, 'message': f'批量检查卡密失败: {str(e)}' } def cleanup_old_license_logs(): """ 清理旧的卡密验证日志 保留最近30天的记录 """ try: # 保留最近30天的记录 cutoff_date = datetime.utcnow() - timedelta(days=30) # 这里可以添加清理过期审计日志的逻辑 # 当前审计日志系统可能需要单独处理 logger.info("卡密日志清理完成") return { 'success': True, 'message': '日志清理完成', 'cutoff_date': cutoff_date } except Exception as e: logger.error(f"清理日志失败: {str(e)}", exc_info=True) return { 'success': False, 'message': f'清理日志失败: {str(e)}' }