""" BI前端API模块 为前端提供BI相关的API接口,简化前端调用 """ from fastapi import APIRouter, HTTPException, Query from typing import List, Optional, Dict, Any import json # 创建BI路由器 router = APIRouter(prefix="/bi-api", tags=["BI API"]) @router.get("/dashboards/overview") async def get_overview_dashboards(): """获取概览看板数据""" return { "dashboards": [ { "id": "operation_overview", "name": "水务运营总览", "description": "水务系统整体运营情况综合看板", "charts_count": 4, "is_public": True, "tags": ["运营", "总览", "综合"] }, { "id": "device_management", "name": "设备管理看板", "description": "设备状态监控和维护管理", "charts_count": 1, "is_public": False, "tags": ["设备", "管理", "监控"] }, { "id": "security_monitoring", "name": "安全监控看板", "description": "系统安全和警报监控", "charts_count": 1, "is_public": False, "tags": ["安全", "监控", "警报"] } ] } @router.get("/charts/{chart_id}/data") async def get_chart_data_frontend(chart_id: str): """获取图表数据(前端友好格式)""" # 这里调用BI服务获取数据,简化前端调用 try: from ..bi.services import BIService bi_service = BIService() data = bi_service.get_chart_data_api(chart_id) if "error" in data: raise HTTPException(status_code=404, detail=data["error"]) # 格式化为前端友好的数据格式 formatted_data = { "chartId": chart_id, "chartName": data.get("chart_name", ""), "chartType": data.get("chart_type", ""), "data": data.get("data", []), "options": data.get("options", {}), "columns": data.get("columns", []) } return formatted_data except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/dashboards/{dashboard_id}/data") async def get_dashboard_data_frontend(dashboard_id: str): """获取看板数据(前端友好格式)""" try: from ..bi.services import BIService bi_service = BIService() data = bi_service.get_dashboard_data_api(dashboard_id) if "error" in data: raise HTTPException(status_code=404, detail=data["error"]) return data except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/charts/types") async def get_chart_types(): """获取支持的图表类型""" return { "line": {"name": "折线图", "description": "适合展示趋势数据"}, "bar": {"name": "柱状图", "description": "适合展示分类数据"}, "pie": {"name": "饼图", "description": "适合展示比例数据"}, "scatter": {"name": "散点图", "description": "适合展示关系数据"}, "area": {"name": "面积图", "description": "适合展示累计数据"}, "gauge": {"name": "仪表盘", "description": "适合展示进度或状态"}, "table": {"name": "表格", "description": "适合展示详细数据"}, "heatmap": {"name": "热力图", "description": "适合展示密度数据"} } @router.get("/data-sources/types") async def get_data_source_types(): """获取支持的数据源类型""" return { "sensor_data": {"name": "传感器数据", "description": "IoT传感器实时和历史数据"}, "device_data": {"name": "设备数据", "description": "设备状态和配置信息"}, "alert_data": {"name": "警报数据", "description": "系统警报和通知记录"}, "system_stats": {"name": "系统统计", "description": "系统运行性能统计"}, "batch_data": {"name": "批量数据", "description": "批量导入的数据"} } @router.get("/search") async def search_bi_objects(keyword: str = Query(..., description="搜索关键词")): """搜索BI对象(图表和看板)""" try: from ..bi.services import BIService bi_service = BIService() # 搜索图表 charts = bi_service.search_charts(keyword) charts_data = [chart.to_dict() for chart in charts] # 搜索看板 dashboards = bi_service.search_dashboards(keyword) dashboards_data = [dashboard.to_dict() for dashboard in dashboards] return { "charts": charts_data, "dashboards": dashboards_data, "total": len(charts_data) + len(dashboards_data) } except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/popular-tags") async def get_popular_tags(): """获取热门标签""" try: from ..bi.services import BIService bi_service = BIService() # 收集所有标签 all_tags = set() for chart in bi_service.get_all_charts(): all_tags.update(chart.tags) for dashboard in bi_service.get_all_dashboards(): all_tags.update(dashboard.tags) # 返回热门标签(按字母排序) return {"tags": sorted(list(all_tags))} except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/quick-stats") async def get_quick_stats(): """获取快速统计信息""" try: from ..bi.services import BIService bi_service = BIService() charts = bi_service.get_all_charts() dashboards = bi_service.get_all_dashboards() public_dashboards = bi_service.get_public_dashboards() # 统计图表类型分布 chart_type_stats = {} for chart in charts: chart_type = chart.chart_type.value chart_type_stats[chart_type] = chart_type_stats.get(chart_type, 0) + 1 # 统计标签分布 tag_stats = {} for chart in charts: for tag in chart.tags: tag_stats[tag] = tag_stats.get(tag, 0) + 1 for dashboard in dashboards: for tag in dashboard.tags: tag_stats[tag] = tag_stats.get(tag, 0) + 1 return { "total_charts": len(charts), "total_dashboards": len(dashboards), "public_dashboards": len(public_dashboards), "chart_types": chart_type_stats, "popular_tags": dict(sorted(tag_stats.items(), key=lambda x: x[1], reverse=True)[:10]) } except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/chart-suggestions") async def get_chart_suggestions(): """获取图表建议""" return { "suggestions": [ { "id": "flow_analysis", "name": "流量分析建议", "description": "基于历史流量数据,分析流量趋势和异常", "charts": ["flow_trend", "flow_comparison"], "tags": ["流量", "分析", "趋势"] }, { "id": "device_performance", "name": "设备性能分析", "description": "分析设备运行状态和性能指标", "charts": ["device_status_distribution", "device_uptime"], "tags": ["设备", "性能", "分析"] }, { "id": "security_dashboard", "name": "安全监控看板", "description": "集中监控系统安全和警报信息", "charts": ["alert_level_stats", "alert_trend"], "tags": ["安全", "监控", "警报"] } ] }