diff --git a/src/web/blueprints/alerts.py b/src/web/blueprints/alerts.py index 69b4b4a..41083d8 100644 --- a/src/web/blueprints/alerts.py +++ b/src/web/blueprints/alerts.py @@ -14,9 +14,68 @@ alerts_bp = Blueprint('alerts', __name__, url_prefix='/api/alerts') @alerts_bp.route('') @handle_api_errors def get_alerts(): - """获取预警列表""" - alerts = service_manager.get_assistant().get_active_alerts() - return jsonify(alerts) + """获取预警列表(分页)""" + try: + # 获取分页参数 + page = request.args.get('page', 1, type=int) + per_page = request.args.get('per_page', 10, type=int) + level_filter = request.args.get('level', '') + status_filter = request.args.get('status', '') + + # 从数据库获取分页数据 + from src.core.database import db_manager + from src.core.models import Alert + + with db_manager.get_session() as session: + # 构建查询 + query = session.query(Alert) + + # 应用过滤器 + if level_filter: + query = query.filter(Alert.level == level_filter) + if status_filter: + if status_filter == 'active': + query = query.filter(Alert.status == 'active') + elif status_filter == 'resolved': + query = query.filter(Alert.status == 'resolved') + + # 按创建时间倒序排列 + query = query.order_by(Alert.created_at.desc()) + + # 计算总数 + total = query.count() + + # 分页查询 + alerts = query.offset((page - 1) * per_page).limit(per_page).all() + + # 转换为字典 + alerts_data = [] + for alert in alerts: + alerts_data.append({ + 'id': alert.id, + 'rule_name': alert.rule_name, + 'message': alert.message, + 'level': alert.level, + 'status': alert.status, + 'source': alert.source, + 'metadata': alert.metadata, + 'created_at': alert.created_at.isoformat() if alert.created_at else None, + 'resolved_at': alert.resolved_at.isoformat() if alert.resolved_at else None + }) + + # 计算分页信息 + total_pages = (total + per_page - 1) // per_page + + return jsonify({ + 'alerts': alerts_data, + 'page': page, + 'per_page': per_page, + 'total': total, + 'total_pages': total_pages + }) + + except Exception as e: + return create_error_response(f"获取预警列表失败: {str(e)}", 500) @alerts_bp.route('', methods=['POST']) def create_alert(): diff --git a/src/web/blueprints/knowledge.py b/src/web/blueprints/knowledge.py index 9a9853e..094aade 100644 --- a/src/web/blueprints/knowledge.py +++ b/src/web/blueprints/knowledge.py @@ -29,18 +29,67 @@ def get_agent_assistant(): @knowledge_bp.route('') def get_knowledge(): - """获取知识库列表""" + """获取知识库列表(分页)""" try: # 获取分页参数 page = request.args.get('page', 1, type=int) per_page = request.args.get('per_page', 10, type=int) + category_filter = request.args.get('category', '') + verified_filter = request.args.get('verified', '') # 从数据库获取知识库数据 - knowledge_entries = get_assistant().knowledge_manager.get_knowledge_entries( - page=page, per_page=per_page - ) + from src.core.database import db_manager + from src.core.models import KnowledgeEntry - return jsonify(knowledge_entries) + with db_manager.get_session() as session: + # 构建查询 + query = session.query(KnowledgeEntry).filter(KnowledgeEntry.is_active == True) + + # 应用过滤器 + if category_filter: + query = query.filter(KnowledgeEntry.category == category_filter) + if verified_filter: + if verified_filter == 'true': + query = query.filter(KnowledgeEntry.is_verified == True) + elif verified_filter == 'false': + query = query.filter(KnowledgeEntry.is_verified == False) + + # 按创建时间倒序排列 + query = query.order_by(KnowledgeEntry.created_at.desc()) + + # 计算总数 + total = query.count() + + # 分页查询 + knowledge_entries = query.offset((page - 1) * per_page).limit(per_page).all() + + # 转换为字典 + knowledge_data = [] + for entry in knowledge_entries: + knowledge_data.append({ + 'id': entry.id, + 'question': entry.question, + 'answer': entry.answer, + 'category': entry.category, + 'confidence_score': entry.confidence_score, + 'usage_count': entry.usage_count, + 'is_verified': entry.is_verified, + 'is_active': entry.is_active, + 'created_at': entry.created_at.isoformat() if entry.created_at else None, + 'updated_at': entry.updated_at.isoformat() if entry.updated_at else None + }) + + # 计算分页信息 + total_pages = (total + per_page - 1) // per_page + + return jsonify({ + 'knowledge': knowledge_data, + 'page': page, + 'per_page': per_page, + 'total': total, + 'total_pages': total_pages + }) + except Exception as e: return jsonify({"error": str(e)}), 500 diff --git a/src/web/blueprints/workorders.py b/src/web/blueprints/workorders.py index 8ada1d0..8f9395c 100644 --- a/src/web/blueprints/workorders.py +++ b/src/web/blueprints/workorders.py @@ -100,17 +100,66 @@ def _ensure_workorder_template_file() -> str: @workorders_bp.route('') def get_workorders(): - """获取工单列表(优化版)""" + """获取工单列表(分页)""" try: + # 获取分页参数 + page = request.args.get('page', 1, type=int) + per_page = request.args.get('per_page', 10, type=int) status_filter = request.args.get('status', '') priority_filter = request.args.get('priority', '') - # 使用优化后的查询 - result = query_optimizer.get_workorders_optimized( - status_filter=status_filter, priority_filter=priority_filter - ) + # 从数据库获取分页数据 + from src.core.database import db_manager + from src.core.models import WorkOrder - return jsonify(result) + with db_manager.get_session() as session: + # 构建查询 + query = session.query(WorkOrder) + + # 应用过滤器 + if status_filter: + query = query.filter(WorkOrder.status == status_filter) + if priority_filter: + query = query.filter(WorkOrder.priority == priority_filter) + + # 按创建时间倒序排列 + query = query.order_by(WorkOrder.created_at.desc()) + + # 计算总数 + total = query.count() + + # 分页查询 + workorders = query.offset((page - 1) * per_page).limit(per_page).all() + + # 转换为字典 + workorders_data = [] + for workorder in workorders: + workorders_data.append({ + 'id': workorder.id, + 'order_id': workorder.order_id, + 'title': workorder.title, + 'description': workorder.description, + 'category': workorder.category, + 'priority': workorder.priority, + 'status': workorder.status, + 'user_id': workorder.user_id, + 'assigned_to': workorder.assigned_to, + 'created_at': workorder.created_at.isoformat() if workorder.created_at else None, + 'updated_at': workorder.updated_at.isoformat() if workorder.updated_at else None, + 'resolved_at': workorder.resolved_at.isoformat() if workorder.resolved_at else None + }) + + # 计算分页信息 + total_pages = (total + per_page - 1) // per_page + + return jsonify({ + 'workorders': workorders_data, + 'page': page, + 'per_page': per_page, + 'total': total, + 'total_pages': total_pages + }) + except Exception as e: return jsonify({"error": str(e)}), 500 diff --git a/src/web/static/js/dashboard.js b/src/web/static/js/dashboard.js index b0cf150..5f48995 100644 --- a/src/web/static/js/dashboard.js +++ b/src/web/static/js/dashboard.js @@ -149,6 +149,13 @@ class TSPDashboard { this.cache = new Map(); this.cacheTimeout = 30000; // 30秒缓存 + // 分页配置 + this.paginationConfig = { + defaultPageSize: 10, + pageSizeOptions: [5, 10, 20, 50], + maxVisiblePages: 5 + }; + this.init(); this.restorePageState(); this.initLanguage(); @@ -342,6 +349,123 @@ class TSPDashboard { } return null; } + + // 统一分页组件 + createPaginationComponent(data, containerId, loadFunction, itemName = '条记录') { + const paginationContainer = document.getElementById(containerId); + if (!paginationContainer) return; + + const { page, total_pages, total, per_page } = data; + + if (total_pages <= 1) { + paginationContainer.innerHTML = ''; + return; + } + + let paginationHtml = ` +