from models import db, User, Order, ApiCall, Transaction from sqlalchemy import desc, func from datetime import datetime, timedelta class AdminService: @staticmethod def get_users(page=1, per_page=20, search=''): """获取用户列表""" query = User.query if search: query = query.filter( (User.email.contains(search)) | (User.username.contains(search)) ) # 分页查询 pagination = query.order_by(desc(User.created_at))\ .paginate(page=page, per_page=per_page, error_out=False) return { 'users': [user.to_dict() for user in pagination.items], 'total': pagination.total, 'page': page, 'per_page': per_page, 'pages': pagination.pages }, 200 @staticmethod def get_user_detail(user_id): """获取用户详情""" user = User.query.get(user_id) if not user: return {'error': '用户不存在'}, 404 # 统计信息 total_recharge = db.session.query(func.sum(Transaction.amount))\ .filter_by(user_id=user_id, type='recharge').scalar() or 0 total_consume = db.session.query(func.sum(Transaction.amount))\ .filter_by(user_id=user_id, type='consume').scalar() or 0 total_api_calls = ApiCall.query.filter_by(user_id=user_id).count() return { 'user': user.to_dict(), 'stats': { 'total_recharge': total_recharge, 'total_consume': abs(total_consume), 'total_api_calls': total_api_calls } }, 200 @staticmethod def toggle_user_status(admin_user_id, user_id): """启用/禁用用户""" user = User.query.get(user_id) if not user: return {'error': '用户不存在'}, 404 # 检查是否尝试禁用其他管理员 (需要传入当前管理员ID) if user.is_admin and user.id != admin_user_id: return {'error': '不能禁用其他管理员'}, 403 user.is_active = not user.is_active try: db.session.commit() return { 'message': f'用户已{"启用" if user.is_active else "禁用"}', 'user': user.to_dict() }, 200 except Exception as e: db.session.rollback() return {'error': '操作失败'}, 500 @staticmethod def adjust_balance(user_id, data): """调整用户余额""" user = User.query.get(user_id) if not user: return {'error': '用户不存在'}, 404 amount = data.get('amount') description = data.get('description', '管理员调整余额') if amount is None or amount == 0: return {'error': '金额不能为0'}, 400 try: balance_before = user.balance user.balance += amount balance_after = user.balance # 创建交易记录 transaction = Transaction( user_id=user_id, type='recharge' if amount > 0 else 'consume', amount=amount, balance_before=balance_before, balance_after=balance_after, description=description ) db.session.add(transaction) db.session.commit() return { 'message': '余额调整成功', 'user': user.to_dict(), 'transaction': transaction.to_dict() }, 200 except Exception as e: db.session.rollback() return {'error': '余额调整失败'}, 500 @staticmethod def get_all_orders(page=1, per_page=20, status=None): """获取所有订单""" query = Order.query if status: query = query.filter_by(status=status) # 分页查询 pagination = query.order_by(desc(Order.created_at))\ .paginate(page=page, per_page=per_page, error_out=False) return { 'orders': [order.to_dict() for order in pagination.items], 'total': pagination.total, 'page': page, 'per_page': per_page, 'pages': pagination.pages }, 200 @staticmethod def get_all_api_calls(page=1, per_page=20, status=None): """获取所有API调用记录""" query = ApiCall.query if status: query = query.filter_by(status=status) # 分页查询 pagination = query.order_by(desc(ApiCall.created_at))\ .paginate(page=page, per_page=per_page, error_out=False) return { 'api_calls': [call.to_dict() for call in pagination.items], 'total': pagination.total, 'page': page, 'per_page': per_page, 'pages': pagination.pages }, 200 @staticmethod def get_overview_stats(): """获取总览统计""" # 用户统计 total_users = User.query.count() active_users = User.query.filter_by(is_active=True).count() # 订单统计 total_orders = Order.query.count() paid_orders = Order.query.filter_by(status='paid').count() total_revenue = db.session.query(func.sum(Order.amount))\ .filter_by(status='paid').scalar() or 0 # API调用统计 total_api_calls = ApiCall.query.count() success_calls = ApiCall.query.filter_by(status='success').count() failed_calls = ApiCall.query.filter_by(status='failed').count() # 今日统计 today = datetime.utcnow().date() today_start = datetime.combine(today, datetime.min.time()) today_users = User.query.filter(User.created_at >= today_start).count() today_orders = Order.query.filter(Order.created_at >= today_start).count() today_revenue = db.session.query(func.sum(Order.amount))\ .filter(Order.created_at >= today_start, Order.status == 'paid').scalar() or 0 today_api_calls = ApiCall.query.filter(ApiCall.created_at >= today_start).count() return { 'total': { 'users': total_users, 'active_users': active_users, 'orders': total_orders, 'paid_orders': paid_orders, 'revenue': total_revenue, 'api_calls': total_api_calls, 'success_calls': success_calls, 'failed_calls': failed_calls }, 'today': { 'users': today_users, 'orders': today_orders, 'revenue': today_revenue, 'api_calls': today_api_calls } }, 200 @staticmethod def get_chart_data(days=7): """获取图表数据""" # 计算日期范围 end_date = datetime.utcnow().date() start_date = end_date - timedelta(days=days-1) chart_data = [] for i in range(days): date = start_date + timedelta(days=i) date_start = datetime.combine(date, datetime.min.time()) date_end = datetime.combine(date, datetime.max.time()) # 统计当天数据 users = User.query.filter( User.created_at >= date_start, User.created_at <= date_end ).count() revenue = db.session.query(func.sum(Order.amount))\ .filter( Order.created_at >= date_start, Order.created_at <= date_end, Order.status == 'paid' ).scalar() or 0 api_calls = ApiCall.query.filter( ApiCall.created_at >= date_start, ApiCall.created_at <= date_end ).count() chart_data.append({ 'date': date.isoformat(), 'users': users, 'revenue': float(revenue), 'api_calls': api_calls }) return { 'chart_data': chart_data }, 200