package cn.iocoder.yudao.module.bi.service.dashboard; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.module.bi.dal.dataobject.BiChartConfigDO; import cn.iocoder.yudao.module.bi.dal.dataobject.BiDashboardDO; import cn.iocoder.yudao.module.bi.dal.mysql.BiChartConfigMapper; import cn.iocoder.yudao.module.bi.dal.mysql.BiDashboardMapper; import cn.iocoder.yudao.module.bi.enums.ErrorCodeConstants; import com.alibaba.fastjson.JSON; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; /** * 仪表盘 Service 实现 * * @author 超级管理员 */ @Slf4j @Service public class DashboardServiceImpl implements DashboardService { @Resource private BiDashboardMapper dashboardMapper; @Resource private BiChartConfigMapper chartConfigMapper; @Resource private JdbcTemplate jdbcTemplate; @Override public List getDashboardList() { return dashboardMapper.selectEnabledList(); } @Override public List> getDashboardData(String dashboardCode, Map params) { BiDashboardDO dashboard = dashboardMapper.selectByCode(dashboardCode); if (dashboard == null) { throw exception(ErrorCodeConstants.BI_DASHBOARD_NOT_EXISTS); } if (dashboard.getStatus() != null && dashboard.getStatus() == 0) { throw exception(ErrorCodeConstants.BI_DASHBOARD_IS_DISABLE); } List charts = chartConfigMapper.selectListByDashboardId(dashboard.getId()); List> result = new ArrayList<>(); for (BiChartConfigDO chart : charts) { Map chartData = new LinkedHashMap<>(); chartData.put("id", chart.getId()); chartData.put("name", chart.getName()); chartData.put("chartType", chart.getChartType()); chartData.put("refreshInterval", chart.getRefreshInterval()); // 解析布局位置 if (StrUtil.isNotBlank(chart.getPosition())) { chartData.put("position", JSON.parse(chart.getPosition())); } // 解析 ECharts 配置项 if (StrUtil.isNotBlank(chart.getChartOptions())) { chartData.put("chartOptions", JSON.parse(chart.getChartOptions())); } // 执行查询SQL if (StrUtil.isNotBlank(chart.getQuerySql())) { try { String sql = buildSql(chart.getQuerySql(), params); List> queryResult = jdbcTemplate.queryForList(sql); chartData.put("data", queryResult); } catch (Exception e) { log.error("[BI][图表: {}] 查询SQL执行失败", chart.getName(), e); chartData.put("data", Collections.emptyList()); chartData.put("error", "查询失败: " + e.getMessage()); } } else { chartData.put("data", Collections.emptyList()); } result.add(chartData); } return result; } /** * 构建SQL,替换参数占位符 */ private String buildSql(String querySql, Map params) { if (params == null || params.isEmpty()) { return querySql; } String sql = querySql; for (Map.Entry entry : params.entrySet()) { String placeholder = "{{" + entry.getKey() + "}}"; Object value = entry.getValue(); if (value instanceof String) { sql = sql.replace(placeholder, "'" + value.toString().replace("'", "''") + "'"); } else if (value instanceof Number) { sql = sql.replace(placeholder, value.toString()); } } return sql; } }