from flask import Blueprint, request, jsonify, render_template from flask_login import login_required, current_user from models import db, UserApiKey, ApiKeyDailyStat from datetime import datetime, date import secrets apikey_bp = Blueprint('apikey', __name__, url_prefix='/user/apikey') def generate_api_key(): """生成 API Key""" return f"sk_{secrets.token_hex(24)}" @apikey_bp.route('/') @login_required def manage_page(): """API Key 管理页面""" return render_template('apikey/manage.html') @apikey_bp.route('/list', methods=['GET']) @login_required def list_keys(): """获取用户的 API Key 列表""" keys = UserApiKey.query.filter_by(user_id=current_user.id).order_by(UserApiKey.created_at.desc()).all() result = [] for key in keys: # 获取今日调用次数 today_stat = ApiKeyDailyStat.query.filter_by( api_key_id=key.id, date=date.today() ).first() result.append({ 'id': key.id, 'name': key.name, 'api_key': key.api_key[:12] + '...' + key.api_key[-4:], # 隐藏中间部分 'is_active': key.is_active, 'daily_limit': key.daily_limit, 'total_calls': key.total_calls, 'today_calls': today_stat.call_count if today_stat else 0, 'last_used_at': key.last_used_at.strftime('%Y-%m-%d %H:%M:%S') if key.last_used_at else None, 'created_at': key.created_at.strftime('%Y-%m-%d %H:%M:%S') }) return jsonify({ 'success': True, 'data': result }) @apikey_bp.route('/create', methods=['POST']) @login_required def create_key(): """创建新的 API Key""" data = request.get_json() name = data.get('name', '').strip() if not name: return jsonify({'success': False, 'message': '请输入 Key 名称'}), 400 if len(name) > 100: return jsonify({'success': False, 'message': 'Key 名称不能超过100个字符'}), 400 # 检查用户已有的 Key 数量(限制每个用户最多5个) key_count = UserApiKey.query.filter_by(user_id=current_user.id).count() if key_count >= 5: return jsonify({'success': False, 'message': '每个用户最多创建5个 API Key'}), 400 # 生成新的 API Key api_key = generate_api_key() # 根据用户等级设置每日限制 daily_limit = 100 # 默认 if current_user.group: if current_user.group.id == 3: # VIP daily_limit = 500 elif current_user.group.id == 4: # SVIP daily_limit = 2000 new_key = UserApiKey( user_id=current_user.id, name=name, api_key=api_key, daily_limit=daily_limit ) db.session.add(new_key) db.session.commit() return jsonify({ 'success': True, 'message': 'API Key 创建成功', 'data': { 'id': new_key.id, 'name': new_key.name, 'api_key': api_key, # 只在创建时返回完整的 Key 'daily_limit': new_key.daily_limit } }) @apikey_bp.route('/delete/', methods=['DELETE']) @login_required def delete_key(key_id): """删除 API Key""" key = UserApiKey.query.filter_by(id=key_id, user_id=current_user.id).first() if not key: return jsonify({'success': False, 'message': 'API Key 不存在'}), 404 db.session.delete(key) db.session.commit() return jsonify({ 'success': True, 'message': 'API Key 已删除' }) @apikey_bp.route('/toggle/', methods=['POST']) @login_required def toggle_key(key_id): """启用/禁用 API Key""" key = UserApiKey.query.filter_by(id=key_id, user_id=current_user.id).first() if not key: return jsonify({'success': False, 'message': 'API Key 不存在'}), 404 key.is_active = not key.is_active db.session.commit() return jsonify({ 'success': True, 'message': f"API Key 已{'启用' if key.is_active else '禁用'}", 'is_active': key.is_active }) @apikey_bp.route('/stats/', methods=['GET']) @login_required def get_stats(key_id): """获取 API Key 统计数据""" key = UserApiKey.query.filter_by(id=key_id, user_id=current_user.id).first() if not key: return jsonify({'success': False, 'message': 'API Key 不存在'}), 404 # 获取最近7天的统计 from datetime import timedelta stats = ApiKeyDailyStat.query.filter( ApiKeyDailyStat.api_key_id == key_id, ApiKeyDailyStat.date >= date.today() - timedelta(days=6) ).order_by(ApiKeyDailyStat.date.asc()).all() result = [] for stat in stats: result.append({ 'date': stat.date.strftime('%Y-%m-%d'), 'call_count': stat.call_count, 'success_count': stat.success_count, 'fail_count': stat.fail_count }) return jsonify({ 'success': True, 'data': { 'key_name': key.name, 'total_calls': key.total_calls, 'daily_stats': result } })