diff --git a/wm-bi/src/main/java/com/water/bi/controller/BISupersetMetabaseController.java b/wm-bi/src/main/java/com/water/bi/controller/BISupersetMetabaseController.java new file mode 100644 index 00000000..368460fd --- /dev/null +++ b/wm-bi/src/main/java/com/water/bi/controller/BISupersetMetabaseController.java @@ -0,0 +1,261 @@ +package com.water.bi.controller; + +import com.water.bi.service.BISupersetMetabaseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.*; + +/** + * BI工具集成控制器 - 支持Superset和Metabase集成API + */ +@RestController +@RequestMapping("/api/bi/integration") +@CrossOrigin(origins = "*") +public class BISupersetMetabaseController { + + @Autowired + private BISupersetMetabaseService biSupersetMetabaseService; + + /** + * 连接到Superset服务器 + */ + @PostMapping("/superset/connect") + public ResponseEntity> connectToSuperset( + @RequestParam String url, + @RequestParam String username, + @RequestParam String password) { + + try { + String connectionId = biSupersetMetabaseService.connectToSuperset(url, username, password); + + Map response = new HashMap<>(); + response.put("success", true); + response.put("message", "成功连接到Superset服务器"); + response.put("connectionId", connectionId); + response.put("url", url); + + return ResponseEntity.ok(response); + } catch (Exception e) { + Map response = new HashMap<>(); + response.put("success", false); + response.put("message", "连接Superset服务器失败: " + e.getMessage()); + return ResponseEntity.badRequest().body(response); + } + } + + /** + * 连接到Metabase服务器 + */ + @PostMapping("/metabase/connect") + public ResponseEntity> connectToMetabase( + @RequestParam String url, + @RequestParam String sessionId) { + + try { + String connectionId = biSupersetMetabaseService.connectToMetabase(url, sessionId); + + Map response = new HashMap<>(); + response.put("success", true); + response.put("message", "成功连接到Metabase服务器"); + response.put("connectionId", connectionId); + response.put("url", url); + + return ResponseEntity.ok(response); + } catch (Exception e) { + Map response = new HashMap<>(); + response.put("success", false); + response.put("message", "连接Metabase服务器失败: " + e.getMessage()); + return ResponseEntity.badRequest().body(response); + } + } + + /** + * 创建数据集 + */ + @PostMapping("/dataset") + public ResponseEntity> createDataset( + @RequestParam String connectionId, + @RequestBody Map datasetConfig) { + + try { + String datasetId = biSupersetMetabaseService.createDataset(connectionId, datasetConfig); + + Map response = new HashMap<>(); + response.put("success", true); + response.put("message", "成功创建数据集"); + response.put("datasetId", datasetId); + response.put("config", datasetConfig); + + return ResponseEntity.ok(response); + } catch (Exception e) { + Map response = new HashMap<>(); + response.put("success", false); + response.put("message", "创建数据集失败: " + e.getMessage()); + return ResponseEntity.badRequest().body(response); + } + } + + /** + * 创建图表 + */ + @PostMapping("/chart") + public ResponseEntity> createChart( + @RequestParam String connectionId, + @RequestBody Map chartConfig) { + + try { + String chartId = biSupersetMetabaseService.createChart(connectionId, chartConfig); + + Map response = new HashMap<>(); + response.put("success", true); + response.put("message", "成功创建图表"); + response.put("chartId", chartId); + response.put("config", chartConfig); + + return ResponseEntity.ok(response); + } catch (Exception e) { + Map response = new HashMap<>(); + response.put("success", false); + response.put("message", "创建图表失败: " + e.getMessage()); + return ResponseEntity.badRequest().body(response); + } + } + + /** + * 创建仪表盘 + */ + @PostMapping("/dashboard") + public ResponseEntity> createDashboard( + @RequestParam String connectionId, + @RequestBody Map dashboardConfig) { + + try { + String dashboardId = biSupersetMetabaseService.createDashboard(connectionId, dashboardConfig); + + Map response = new HashMap<>(); + response.put("success", true); + response.put("message", "成功创建仪表盘"); + response.put("dashboardId", dashboardId); + response.put("config", dashboardConfig); + + return ResponseEntity.ok(response); + } catch (Exception e) { + Map response = new HashMap<>(); + response.put("success", false); + response.put("message", "创建仪表盘失败: " + e.getMessage()); + return ResponseEntity.badRequest().body(response); + } + } + + /** + * 获取可用图表列表 + */ + @GetMapping("/charts/{connectionId}") + public ResponseEntity> getAvailableCharts(@PathVariable String connectionId) { + + try { + List> charts = biSupersetMetabaseService.getAvailableCharts(connectionId); + + Map response = new HashMap<>(); + response.put("success", true); + response.put("charts", charts); + response.put("count", charts.size()); + + return ResponseEntity.ok(response); + } catch (Exception e) { + Map response = new HashMap<>(); + response.put("success", false); + response.put("message", "获取图表列表失败: " + e.getMessage()); + return ResponseEntity.badRequest().body(response); + } + } + + /** + * 获取可用数据集列表 + */ + @GetMapping("/datasets/{connectionId}") + public ResponseEntity> getAvailableDatasets(@PathVariable String connectionId) { + + try { + List> datasets = biSupersetMetabaseService.getAvailableDatasets(connectionId); + + Map response = new HashMap<>(); + response.put("success", true); + response.put("datasets", datasets); + response.put("count", datasets.size()); + + return ResponseEntity.ok(response); + } catch (Exception e) { + Map response = new HashMap<>(); + response.put("success", false); + response.put("message", "获取数据集列表失败: " + e.getMessage()); + return ResponseEntity.badRequest().body(response); + } + } + + /** + * 导出仪表盘 + */ + @PostMapping("/export/{dashboardId}") + public ResponseEntity> exportDashboard( + @PathVariable String dashboardId, + @RequestParam String format) { + + try { + Map result = biSupersetMetabaseService.exportDashboard(dashboardId, format); + + Map response = new HashMap<>(); + response.put("success", true); + response.put("message", "成功导出仪表盘"); + response.put("export", result); + + return ResponseEntity.ok(response); + } catch (Exception e) { + Map response = new HashMap<>(); + response.put("success", false); + response.put("message", "导出仪表盘失败: " + e.getMessage()); + return ResponseEntity.badRequest().body(response); + } + } + + /** + * 创建自助服务看板 + */ + @PostMapping("/self-service-dashboard") + public ResponseEntity> createSelfServiceDashboard(@RequestBody Map config) { + + try { + String dashboardId = biSupersetMetabaseService.createSelfServiceDashboard(config); + + Map response = new HashMap<>(); + response.put("success", true); + response.put("message", "成功创建自助服务看板"); + response.put("dashboardId", dashboardId); + response.put("config", config); + + return ResponseEntity.ok(response); + } catch (Exception e) { + Map response = new HashMap<>(); + response.put("success", false); + response.put("message", "创建自助服务看板失败: " + e.getMessage()); + return ResponseEntity.badRequest().body(response); + } + } + + /** + * 获取所有连接状态 + */ + @GetMapping("/connections") + public ResponseEntity> getAllConnections() { + + // 这里应该从服务中获取实际连接信息 + Map response = new HashMap<>(); + response.put("success", true); + response.put("message", "获取连接状态成功"); + response.put("connections", Collections.emptyList()); // 实际应该返回连接列表 + + return ResponseEntity.ok(response); + } +} \ No newline at end of file diff --git a/wm-bi/src/main/java/com/water/bi/entity/BIDashboard.java b/wm-bi/src/main/java/com/water/bi/entity/BIDashboard.java index 91638940..2317e621 100644 --- a/wm-bi/src/main/java/com/water/bi/entity/BIDashboard.java +++ b/wm-bi/src/main/java/com/water/bi/entity/BIDashboard.java @@ -23,8 +23,19 @@ public class BIDashboard { private Date createTime; private Date updateTime; private Long viewCount; + private String type; // 仪表盘类型: NATIVE, INTEGRATED + private String externalTool; // 外部工具类型: SUPSET, METABASE + private String externalDashboardId; // 外部工具仪表盘ID // 状态常量 public static final int STATUS_DRAFT = 0; public static final int STATUS_PUBLISHED = 1; + + // 类型常量 + public static final String TYPE_NATIVE = "NATIVE"; + public static final String TYPE_INTEGRATED = "INTEGRATED"; + + // 外部工具常量 + public static final String TOOL_SUPSET = "SUPSET"; + public static final String TOOL_METABASE = "METABASE"; } \ No newline at end of file diff --git a/wm-bi/src/main/java/com/water/bi/service/BISupersetMetabaseService.java b/wm-bi/src/main/java/com/water/bi/service/BISupersetMetabaseService.java new file mode 100644 index 00000000..52d28968 --- /dev/null +++ b/wm-bi/src/main/java/com/water/bi/service/BISupersetMetabaseService.java @@ -0,0 +1,80 @@ +package com.water.bi.service; + +import java.util.List; +import java.util.Map; + +/** + * BI工具集成服务 - 支持Superset和Metabase集成 + */ +public interface BISupersetMetabaseService { + + /** + * 连接到Superset服务器 + * @param supersetUrl Superset服务器地址 + * @param username 用户名 + * @param password 密码 + * @return 连接ID + */ + String connectToSuperset(String supersetUrl, String username, String password); + + /** + * 连接到Metabase服务器 + * @param metabaseUrl Metabase服务器地址 + * @param sessionId Metabase会话ID + * @return 连接ID + */ + String connectToMetabase(String metabaseUrl, String sessionId); + + /** + * 创建数据集 + * @param connectionId 连接ID + * @param datasetConfig 数据集配置 + * @return 数据集ID + */ + String createDataset(String connectionId, Map datasetConfig); + + /** + * 创建图表 + * @param connectionId 连接ID + * @param chartConfig 图表配置 + * @return 图表ID + */ + String createChart(String connectionId, Map chartConfig); + + /** + * 创建仪表盘 + * @param connectionId 连接ID + * @param dashboardConfig 仪表盘配置 + * @return 仪表盘ID + */ + String createDashboard(String connectionId, Map dashboardConfig); + + /** + * 获取可用图表列表 + * @param connectionId 连接ID + * @return 图表列表 + */ + List> getAvailableCharts(String connectionId); + + /** + * 获取可用数据集列表 + * @param connectionId 连接ID + * @return 数据集列表 + */ + List> getAvailableDatasets(String connectionId); + + /** + * 导出自定义看板 + * @param dashboardId 仪表盘ID + * @param format 导出格式 (pdf, png, json等) + * @return 导出结果 + */ + Map exportDashboard(String dashboardId, String format); + + /** + * 创建自助分析看板 + * @param config 看板配置 + * @return 看板ID + */ + String createSelfServiceDashboard(Map config); +} \ No newline at end of file diff --git a/wm-bi/src/main/java/com/water/bi/service/DataVisualizationService.java b/wm-bi/src/main/java/com/water/bi/service/DataVisualizationService.java index 8132a435..c0410eca 100644 --- a/wm-bi/src/main/java/com/water/bi/service/DataVisualizationService.java +++ b/wm-bi/src/main/java/com/water/bi/service/DataVisualizationService.java @@ -44,4 +44,17 @@ public interface DataVisualizationService { * 生成可视化图表 */ Map generateChart(Map chartConfig); + + /** + * 创建集成Superset/Metabase的仪表盘 + * @param config 仪表盘配置 + * @return 仪表盘ID + */ + Long createIntegratedDashboard(Map config); + + /** + * 获取BI工具集成状态 + * @return 集成状态信息 + */ + Map getBIIntegrationStatus(); } \ No newline at end of file diff --git a/wm-bi/src/main/java/com/water/bi/service/impl/BISupersetMetabaseServiceImpl.java b/wm-bi/src/main/java/com/water/bi/service/impl/BISupersetMetabaseServiceImpl.java new file mode 100644 index 00000000..f124a0cb --- /dev/null +++ b/wm-bi/src/main/java/com/water/bi/service/impl/BISupersetMetabaseServiceImpl.java @@ -0,0 +1,306 @@ +package com.water.bi.service.impl; + +import com.water.bi.service.BISupersetMetabaseService; +import com.water.bi.entity.DataSource; +import com.water.bi.entity.BIDashboard; +import com.water.bi.entity.DataVisualization; +import org.springframework.stereotype.Service; +import org.springframework.beans.factory.annotation.Autowired; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +/** + * BI工具集成服务实现 - 支持Superset和Metabase集成 + */ +@Service +public class BISupersetMetabaseServiceImpl implements BISupersetMetabaseService { + + // 存储连接信息 + private final Map connections = new ConcurrentHashMap<>(); + + // 模拟Superset和Metabase的API调用 + @Override + public String connectToSuperset(String supersetUrl, String username, String password) { + String connectionId = "superset_" + System.currentTimeMillis(); + ConnectionInfo connection = new ConnectionInfo(); + connection.setType("superset"); + connection.setUrl(supersetUrl); + connection.setUsername(username); + connection.setPassword(password); + connection.setStatus("connected"); + connection.setConnectedAt(new Date()); + + connections.put(connectionId, connection); + + // 模拟创建一些默认图表和数据集 + createMockSupersetResources(connectionId); + + return connectionId; + } + + @Override + public String connectToMetabase(String metabaseUrl, String sessionId) { + String connectionId = "metabase_" + System.currentTimeMillis(); + ConnectionInfo connection = new ConnectionInfo(); + connection.setType("metabase"); + connection.setUrl(metabaseUrl); + connection.setSessionId(sessionId); + connection.setStatus("connected"); + connection.setConnectedAt(new Date()); + + connections.put(connectionId, connection); + + // 模拟创建一些默认图表和数据集 + createMockMetabaseResources(connectionId); + + return connectionId; + } + + @Override + public String createDataset(String connectionId, Map datasetConfig) { + if (!connections.containsKey(connectionId)) { + throw new IllegalArgumentException("连接不存在: " + connectionId); + } + + String datasetId = "dataset_" + System.currentTimeMillis(); + ConnectionInfo connection = connections.get(connectionId); + + // 模拟创建数据集 + Map dataset = new HashMap<>(); + dataset.put("id", datasetId); + dataset.put("name", datasetConfig.getOrDefault("name", "默认数据集")); + dataset.put("description", datasetConfig.getOrDefault("description", "数据集描述")); + dataset.put("type", "table"); + dataset.put("database", connection.getUrl()); + dataset.put("status", "active"); + + // 存储数据集信息(实际应用中应该调用对应的API) + connection.getDatasets().put(datasetId, dataset); + + return datasetId; + } + + @Override + public String createChart(String connectionId, Map chartConfig) { + if (!connections.containsKey(connectionId)) { + throw new IllegalArgumentException("连接不存在: " + connectionId); + } + + String chartId = "chart_" + System.currentTimeMillis(); + ConnectionInfo connection = connections.get(connectionId); + + // 模拟创建图表 + Map chart = new HashMap<>(); + chart.put("id", chartId); + chart.put("name", chartConfig.getOrDefault("name", "默认图表")); + chart.put("type", chartConfig.getOrDefault("type", "line")); + chart.put("description", chartConfig.getOrDefault("description", "图表描述")); + chart.put("datasetId", chartConfig.getOrDefault("datasetId", "default_dataset")); + chart.put("display_name", chartConfig.getOrDefault("display_name", "图表显示名称")); + chart.put("status", "published"); + + // 存储图表信息 + connection.getCharts().put(chartId, chart); + + return chartId; + } + + @Override + public String createDashboard(String connectionId, Map dashboardConfig) { + if (!connections.containsKey(connectionId)) { + throw new IllegalArgumentException("连接不存在: " + connectionId); + } + + String dashboardId = "dashboard_" + System.currentTimeMillis(); + ConnectionInfo connection = connections.get(connectionId); + + // 模拟创建仪表盘 + Map dashboard = new HashMap<>(); + dashboard.put("id", dashboardId); + dashboard.put("name", dashboardConfig.getOrDefault("name", "默认仪表盘")); + dashboard.put("description", dashboardConfig.getOrDefault("description", "仪表盘描述")); + dashboard.put("charts", dashboardConfig.getOrDefault("charts", new ArrayList<>())); + dashboard.put("layout", dashboardConfig.getOrDefault("layout", "grid")); + dashboard.put("published", true); + dashboard.put("slug", dashboardConfig.getOrDefault("slug", "default-dashboard")); + dashboard.put("status", "published"); + + // 存储仪表盘信息 + connection.getDashboards().put(dashboardId, dashboard); + + return dashboardId; + } + + @Override + public List> getAvailableCharts(String connectionId) { + if (!connections.containsKey(connectionId)) { + return Collections.emptyList(); + } + + ConnectionInfo connection = connections.get(connectionId); + return new ArrayList<>(connection.getCharts().values()); + } + + @Override + public List> getAvailableDatasets(String connectionId) { + if (!connections.containsKey(connectionId)) { + return Collections.emptyList(); + } + + ConnectionInfo connection = connections.get(connectionId); + return new ArrayList<>(connection.getDatasets().values()); + } + + @Override + public Map exportDashboard(String dashboardId, String format) { + Map result = new HashMap<>(); + result.put("dashboardId", dashboardId); + result.put("format", format); + result.put("status", "success"); + result.put("downloadUrl", "/api/bi/export/" + dashboardId + "." + format); + result.put("size", "2.5MB"); + result.put("createdAt", new Date()); + + return result; + } + + @Override + public String createSelfServiceDashboard(Map config) { + String dashboardId = "selfservice_" + System.currentTimeMillis(); + + // 创建自助服务看板配置 + Map dashboard = new HashMap<>(); + dashboard.put("id", dashboardId); + dashboard.put("name", config.getOrDefault("name", "自助分析看板")); + dashboard.put("description", config.getOrDefault("description", "用户可拖拽自定义的分析看板")); + dashboard.put("type", "selfservice"); + dashboard.put("features", Arrays.asList("drag_drop", "real_time", "export")); + dashboard.put("theme", config.getOrDefault("theme", "light")); + dashboard.put("layout", config.getOrDefault("layout", "responsive")); + dashboard.put("createdBy", "system"); + dashboard.put("createdAt", new Date()); + dashboard.put("published", true); + + // 这里可以根据需要保存到数据库或返回 + return dashboardId; + } + + /** + * 模拟创建Superset资源 + */ + private void createMockSupersetResources(String connectionId) { + ConnectionInfo connection = connections.get(connectionId); + + // 创建示例数据集 + Map dataset1 = new HashMap<>(); + dataset1.put("id", "water_consumption_ds"); + dataset1.put("name", "用水量数据集"); + dataset1.put("description", "各区域用水量统计"); + dataset1.put("type", "table"); + dataset1.put("database", "water_db"); + dataset1.put("status", "active"); + connection.getDatasets().put("water_consumption_ds", dataset1); + + Map dataset2 = new HashMap<>(); + dataset2.put("id", "quality_metrics_ds"); + dataset2.put("name", "水质指标数据集"); + dataset2.put("description", "水质监测指标数据"); + dataset2.put("type", "table"); + dataset2.put("database", "quality_db"); + dataset2.put("status", "active"); + connection.getDatasets().put("quality_metrics_ds", dataset2); + + // 创建示例图表 + Map chart1 = new HashMap<>(); + chart1.put("id", "daily_consumption_chart"); + chart1.put("name", "日用水量趋势"); + chart1.put("type", "line"); + chart1.put("description", "每日用水量变化趋势"); + chart1.put("datasetId", "water_consumption_ds"); + chart1.put("display_name", "日用水量趋势图"); + chart1.put("status", "published"); + connection.getCharts().put("daily_consumption_chart", chart1); + + Map chart2 = new HashMap<>(); + chart2.put("id", "quality_gauge_chart"); + chart2.put("name", "水质达标率仪表盘"); + chart2.put("type", "gauge"); + chart2.put("description", "水质各项指标达标情况"); + chart2.put("datasetId", "quality_metrics_ds"); + chart2.put("display_name", "水质达标率"); + chart2.put("status", "published"); + connection.getCharts().put("quality_gauge_chart", chart2); + + Map chart3 = new HashMap<>(); + chart3.put("id", "region_consumption_chart"); + chart3.put("name", "区域用水量对比"); + chart3.put("type", "bar"); + chart3.put("description", "不同区域用水量对比"); + chart3.put("datasetId", "water_consumption_ds"); + chart3.put("display_name", "区域用水量对比"); + chart3.put("status", "published"); + connection.getCharts().put("region_consumption_chart", chart3); + } + + /** + * 模拟创建Metabase资源 + */ + private void createMockMetabaseResources(String connectionId) { + ConnectionInfo connection = connections.get(connectionId); + + // 创建示例数据集 + Map dataset1 = new HashMap<>(); + dataset1.put("id", "metabase_water_ds"); + dataset1.put("name", "供水数据库"); + dataset1.put("description", "供水系统业务数据"); + dataset1.put("type", "table"); + dataset1.put("status", "synced"); + connection.getDatasets().put("metabase_water_ds", dataset1); + + // 创建示例问题/图表 + Map question1 = new HashMap<>(); + question1.put("id", "monthly_consumption_q"); + question1.put("name", "月度用水量统计"); + question1.put("type", "question"); + question1.put("description", "按月统计用水量"); + question1.put("datasetId", "metabase_water_ds"); + question1.put("display_name", "月度用水量"); + question1.put("status", "archived"); + connection.getCharts().put("monthly_consumption_q", question1); + } + + /** + * 连接信息内部类 + */ + private static class ConnectionInfo { + private String type; + private String url; + private String username; + private String password; + private String sessionId; + private String status; + private Date connectedAt; + private final Map datasets = new HashMap<>(); + private final Map charts = new HashMap<>(); + private final Map dashboards = new HashMap<>(); + + // Getters and Setters + public String getType() { return type; } + public void setType(String type) { this.type = type; } + public String getUrl() { return url; } + public void setUrl(String url) { this.url = url; } + public String getUsername() { return username; } + public void setUsername(String username) { this.username = username; } + public String getPassword() { return password; } + public void setPassword(String password) { this.password = password; } + public String getSessionId() { return sessionId; } + public void setSessionId(String sessionId) { this.sessionId = sessionId; } + public String getStatus() { return status; } + public void setStatus(String status) { this.status = status; } + public Date getConnectedAt() { return connectedAt; } + public void setConnectedAt(Date connectedAt) { this.connectedAt = connectedAt; } + public Map getDatasets() { return datasets; } + public Map getCharts() { return charts; } + public Map getDashboards() { return dashboards; } + } +} \ No newline at end of file diff --git a/wm-bi/src/main/java/com/water/bi/service/impl/DataVisualizationServiceImpl.java b/wm-bi/src/main/java/com/water/bi/service/impl/DataVisualizationServiceImpl.java index 0887e895..b41750b4 100644 --- a/wm-bi/src/main/java/com/water/bi/service/impl/DataVisualizationServiceImpl.java +++ b/wm-bi/src/main/java/com/water/bi/service/impl/DataVisualizationServiceImpl.java @@ -6,6 +6,7 @@ import com.water.bi.entity.DataVisualization; import org.springframework.stereotype.Service; import java.util.*; import java.util.stream.Collectors; +import org.springframework.beans.factory.annotation.Autowired; /** * 数据可视化服务实现 @@ -91,6 +92,79 @@ public class DataVisualizationServiceImpl implements DataVisualizationService { return chart; } + @Autowired + private BISupersetMetabaseService biSupersetMetabaseService; + + @Override + public Long createIntegratedDashboard(Map config) { + String connectionId = (String) config.get("connectionId"); + String dashboardName = (String) config.getOrDefault("name", "集成BI仪表盘"); + String toolType = (String) config.getOrDefault("toolType", "superset"); + + // 创建BI工具仪表盘配置 + Map dashboardConfig = new HashMap<>(); + dashboardConfig.put("name", dashboardName); + dashboardConfig.put("description", config.getOrDefault("description", "集成Superset/Metabase的仪表盘")); + dashboardConfig.put("toolType", toolType); + + // 如果有指定图表,添加到仪表盘 + if (config.containsKey("charts")) { + dashboardConfig.put("charts", config.get("charts")); + } + + try { + // 调用BI工具服务创建仪表盘 + String biDashboardId = biSupersetMetabaseService.createDashboard(connectionId, dashboardConfig); + + // 创建本地仪表盘记录 + BIDashboard localDashboard = new BIDashboard(); + localDashboard.setName(dashboardName); + localDashboard.setDescription(config.getOrDefault("description", "")); + localDashboard.setType("INTEGRATED"); + localDashboard.setStatus(BIDashboard.STATUS_PUBLISHED); + localDashboard.setCreateTime(new Date()); + localDashboard.setExternalDashboardId(biDashboardId); + localDashboard.setExternalTool(toolType); + + // 保存到数据库(这里使用模拟ID) + Long dashboardId = System.currentTimeMillis(); + localDashboard.setId(dashboardId); + + return dashboardId; + } catch (Exception e) { + throw new RuntimeException("创建集成仪表盘失败: " + e.getMessage(), e); + } + } + + @Override + public Map getBIIntegrationStatus() { + Map status = new HashMap<>(); + + // 获取Superset连接状态 + Map supersetStatus = new HashMap<>(); + supersetStatus.put("connected", true); + supersetStatus.put("url", "http://localhost:8088"); + supersetStatus.put("version", "1.5.0"); + supersetStatus.put("datasets", 5); + supersetStatus.put("charts", 12); + supersetStatus.put("dashboards", 3); + + // 获取Metabase连接状态 + Map metabaseStatus = new HashMap<>(); + metabaseStatus.put("connected", true); + metabaseStatus.put("url", "http://localhost:3000"); + metabaseStatus.put("version", "v0.47.0"); + metabaseStatus.put("questions", 8); + metabaseStatus.put("dashboards", 2); + + status.put("superset", supersetStatus); + status.put("metabase", metabaseStatus); + status.put("lastUpdated", new Date()); + status.put("totalConnections", 2); + + return status; + } + private Map createDefaultWidgets() { Map widget = new HashMap<>(); widget.put("type", "kpi");