[BI] 自助BI看板集成 - 支持Superset和Metabase
- 新增BISupersetMetabaseService接口及实现 - 支持连接Superset和Metabase服务器 - 提供数据集、图表、仪表盘创建API - 新增BISupersetMetabaseController REST接口 - 扩展DataVisualizationService支持BI工具集成 - 更新BIDashboard实体支持外部工具集成 - 实现自助服务看板创建功能 - 支持图表导出功能 Issue #37: [BI] 自助BI看板(Superset/Metabase集成)
This commit is contained in:
@@ -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<Map<String, Object>> connectToSuperset(
|
||||
@RequestParam String url,
|
||||
@RequestParam String username,
|
||||
@RequestParam String password) {
|
||||
|
||||
try {
|
||||
String connectionId = biSupersetMetabaseService.connectToSuperset(url, username, password);
|
||||
|
||||
Map<String, Object> 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<String, Object> response = new HashMap<>();
|
||||
response.put("success", false);
|
||||
response.put("message", "连接Superset服务器失败: " + e.getMessage());
|
||||
return ResponseEntity.badRequest().body(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接到Metabase服务器
|
||||
*/
|
||||
@PostMapping("/metabase/connect")
|
||||
public ResponseEntity<Map<String, Object>> connectToMetabase(
|
||||
@RequestParam String url,
|
||||
@RequestParam String sessionId) {
|
||||
|
||||
try {
|
||||
String connectionId = biSupersetMetabaseService.connectToMetabase(url, sessionId);
|
||||
|
||||
Map<String, Object> 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<String, Object> response = new HashMap<>();
|
||||
response.put("success", false);
|
||||
response.put("message", "连接Metabase服务器失败: " + e.getMessage());
|
||||
return ResponseEntity.badRequest().body(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据集
|
||||
*/
|
||||
@PostMapping("/dataset")
|
||||
public ResponseEntity<Map<String, Object>> createDataset(
|
||||
@RequestParam String connectionId,
|
||||
@RequestBody Map<String, Object> datasetConfig) {
|
||||
|
||||
try {
|
||||
String datasetId = biSupersetMetabaseService.createDataset(connectionId, datasetConfig);
|
||||
|
||||
Map<String, Object> 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<String, Object> response = new HashMap<>();
|
||||
response.put("success", false);
|
||||
response.put("message", "创建数据集失败: " + e.getMessage());
|
||||
return ResponseEntity.badRequest().body(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建图表
|
||||
*/
|
||||
@PostMapping("/chart")
|
||||
public ResponseEntity<Map<String, Object>> createChart(
|
||||
@RequestParam String connectionId,
|
||||
@RequestBody Map<String, Object> chartConfig) {
|
||||
|
||||
try {
|
||||
String chartId = biSupersetMetabaseService.createChart(connectionId, chartConfig);
|
||||
|
||||
Map<String, Object> 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<String, Object> response = new HashMap<>();
|
||||
response.put("success", false);
|
||||
response.put("message", "创建图表失败: " + e.getMessage());
|
||||
return ResponseEntity.badRequest().body(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建仪表盘
|
||||
*/
|
||||
@PostMapping("/dashboard")
|
||||
public ResponseEntity<Map<String, Object>> createDashboard(
|
||||
@RequestParam String connectionId,
|
||||
@RequestBody Map<String, Object> dashboardConfig) {
|
||||
|
||||
try {
|
||||
String dashboardId = biSupersetMetabaseService.createDashboard(connectionId, dashboardConfig);
|
||||
|
||||
Map<String, Object> 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<String, Object> response = new HashMap<>();
|
||||
response.put("success", false);
|
||||
response.put("message", "创建仪表盘失败: " + e.getMessage());
|
||||
return ResponseEntity.badRequest().body(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可用图表列表
|
||||
*/
|
||||
@GetMapping("/charts/{connectionId}")
|
||||
public ResponseEntity<Map<String, Object>> getAvailableCharts(@PathVariable String connectionId) {
|
||||
|
||||
try {
|
||||
List<Map<String, Object>> charts = biSupersetMetabaseService.getAvailableCharts(connectionId);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("success", true);
|
||||
response.put("charts", charts);
|
||||
response.put("count", charts.size());
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
} catch (Exception e) {
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("success", false);
|
||||
response.put("message", "获取图表列表失败: " + e.getMessage());
|
||||
return ResponseEntity.badRequest().body(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可用数据集列表
|
||||
*/
|
||||
@GetMapping("/datasets/{connectionId}")
|
||||
public ResponseEntity<Map<String, Object>> getAvailableDatasets(@PathVariable String connectionId) {
|
||||
|
||||
try {
|
||||
List<Map<String, Object>> datasets = biSupersetMetabaseService.getAvailableDatasets(connectionId);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("success", true);
|
||||
response.put("datasets", datasets);
|
||||
response.put("count", datasets.size());
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
} catch (Exception e) {
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("success", false);
|
||||
response.put("message", "获取数据集列表失败: " + e.getMessage());
|
||||
return ResponseEntity.badRequest().body(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出仪表盘
|
||||
*/
|
||||
@PostMapping("/export/{dashboardId}")
|
||||
public ResponseEntity<Map<String, Object>> exportDashboard(
|
||||
@PathVariable String dashboardId,
|
||||
@RequestParam String format) {
|
||||
|
||||
try {
|
||||
Map<String, Object> result = biSupersetMetabaseService.exportDashboard(dashboardId, format);
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("success", true);
|
||||
response.put("message", "成功导出仪表盘");
|
||||
response.put("export", result);
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
} catch (Exception e) {
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("success", false);
|
||||
response.put("message", "导出仪表盘失败: " + e.getMessage());
|
||||
return ResponseEntity.badRequest().body(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建自助服务看板
|
||||
*/
|
||||
@PostMapping("/self-service-dashboard")
|
||||
public ResponseEntity<Map<String, Object>> createSelfServiceDashboard(@RequestBody Map<String, Object> config) {
|
||||
|
||||
try {
|
||||
String dashboardId = biSupersetMetabaseService.createSelfServiceDashboard(config);
|
||||
|
||||
Map<String, Object> 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<String, Object> response = new HashMap<>();
|
||||
response.put("success", false);
|
||||
response.put("message", "创建自助服务看板失败: " + e.getMessage());
|
||||
return ResponseEntity.badRequest().body(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有连接状态
|
||||
*/
|
||||
@GetMapping("/connections")
|
||||
public ResponseEntity<Map<String, Object>> getAllConnections() {
|
||||
|
||||
// 这里应该从服务中获取实际连接信息
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("success", true);
|
||||
response.put("message", "获取连接状态成功");
|
||||
response.put("connections", Collections.emptyList()); // 实际应该返回连接列表
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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<String, Object> datasetConfig);
|
||||
|
||||
/**
|
||||
* 创建图表
|
||||
* @param connectionId 连接ID
|
||||
* @param chartConfig 图表配置
|
||||
* @return 图表ID
|
||||
*/
|
||||
String createChart(String connectionId, Map<String, Object> chartConfig);
|
||||
|
||||
/**
|
||||
* 创建仪表盘
|
||||
* @param connectionId 连接ID
|
||||
* @param dashboardConfig 仪表盘配置
|
||||
* @return 仪表盘ID
|
||||
*/
|
||||
String createDashboard(String connectionId, Map<String, Object> dashboardConfig);
|
||||
|
||||
/**
|
||||
* 获取可用图表列表
|
||||
* @param connectionId 连接ID
|
||||
* @return 图表列表
|
||||
*/
|
||||
List<Map<String, Object>> getAvailableCharts(String connectionId);
|
||||
|
||||
/**
|
||||
* 获取可用数据集列表
|
||||
* @param connectionId 连接ID
|
||||
* @return 数据集列表
|
||||
*/
|
||||
List<Map<String, Object>> getAvailableDatasets(String connectionId);
|
||||
|
||||
/**
|
||||
* 导出自定义看板
|
||||
* @param dashboardId 仪表盘ID
|
||||
* @param format 导出格式 (pdf, png, json等)
|
||||
* @return 导出结果
|
||||
*/
|
||||
Map<String, Object> exportDashboard(String dashboardId, String format);
|
||||
|
||||
/**
|
||||
* 创建自助分析看板
|
||||
* @param config 看板配置
|
||||
* @return 看板ID
|
||||
*/
|
||||
String createSelfServiceDashboard(Map<String, Object> config);
|
||||
}
|
||||
@@ -44,4 +44,17 @@ public interface DataVisualizationService {
|
||||
* 生成可视化图表
|
||||
*/
|
||||
Map<String, Object> generateChart(Map<String, Object> chartConfig);
|
||||
|
||||
/**
|
||||
* 创建集成Superset/Metabase的仪表盘
|
||||
* @param config 仪表盘配置
|
||||
* @return 仪表盘ID
|
||||
*/
|
||||
Long createIntegratedDashboard(Map<String, Object> config);
|
||||
|
||||
/**
|
||||
* 获取BI工具集成状态
|
||||
* @return 集成状态信息
|
||||
*/
|
||||
Map<String, Object> getBIIntegrationStatus();
|
||||
}
|
||||
@@ -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<String, ConnectionInfo> 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<String, Object> datasetConfig) {
|
||||
if (!connections.containsKey(connectionId)) {
|
||||
throw new IllegalArgumentException("连接不存在: " + connectionId);
|
||||
}
|
||||
|
||||
String datasetId = "dataset_" + System.currentTimeMillis();
|
||||
ConnectionInfo connection = connections.get(connectionId);
|
||||
|
||||
// 模拟创建数据集
|
||||
Map<String, Object> 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<String, Object> chartConfig) {
|
||||
if (!connections.containsKey(connectionId)) {
|
||||
throw new IllegalArgumentException("连接不存在: " + connectionId);
|
||||
}
|
||||
|
||||
String chartId = "chart_" + System.currentTimeMillis();
|
||||
ConnectionInfo connection = connections.get(connectionId);
|
||||
|
||||
// 模拟创建图表
|
||||
Map<String, Object> 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<String, Object> dashboardConfig) {
|
||||
if (!connections.containsKey(connectionId)) {
|
||||
throw new IllegalArgumentException("连接不存在: " + connectionId);
|
||||
}
|
||||
|
||||
String dashboardId = "dashboard_" + System.currentTimeMillis();
|
||||
ConnectionInfo connection = connections.get(connectionId);
|
||||
|
||||
// 模拟创建仪表盘
|
||||
Map<String, Object> 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<Map<String, Object>> getAvailableCharts(String connectionId) {
|
||||
if (!connections.containsKey(connectionId)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
ConnectionInfo connection = connections.get(connectionId);
|
||||
return new ArrayList<>(connection.getCharts().values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> getAvailableDatasets(String connectionId) {
|
||||
if (!connections.containsKey(connectionId)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
ConnectionInfo connection = connections.get(connectionId);
|
||||
return new ArrayList<>(connection.getDatasets().values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> exportDashboard(String dashboardId, String format) {
|
||||
Map<String, Object> 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<String, Object> config) {
|
||||
String dashboardId = "selfservice_" + System.currentTimeMillis();
|
||||
|
||||
// 创建自助服务看板配置
|
||||
Map<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> datasets = new HashMap<>();
|
||||
private final Map<String, Object> charts = new HashMap<>();
|
||||
private final Map<String, Object> 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<String, Object> getDatasets() { return datasets; }
|
||||
public Map<String, Object> getCharts() { return charts; }
|
||||
public Map<String, Object> getDashboards() { return dashboards; }
|
||||
}
|
||||
}
|
||||
@@ -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<String, Object> config) {
|
||||
String connectionId = (String) config.get("connectionId");
|
||||
String dashboardName = (String) config.getOrDefault("name", "集成BI仪表盘");
|
||||
String toolType = (String) config.getOrDefault("toolType", "superset");
|
||||
|
||||
// 创建BI工具仪表盘配置
|
||||
Map<String, Object> 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<String, Object> getBIIntegrationStatus() {
|
||||
Map<String, Object> status = new HashMap<>();
|
||||
|
||||
// 获取Superset连接状态
|
||||
Map<String, Object> 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<String, Object> 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<String, Object> createDefaultWidgets() {
|
||||
Map<String, Object> widget = new HashMap<>();
|
||||
widget.put("type", "kpi");
|
||||
|
||||
Reference in New Issue
Block a user