diff --git a/backend/src/main/java/io/dataease/config/CommonConfig.java b/backend/src/main/java/io/dataease/config/CommonConfig.java index f22c749e62..6e98754712 100644 --- a/backend/src/main/java/io/dataease/config/CommonConfig.java +++ b/backend/src/main/java/io/dataease/config/CommonConfig.java @@ -2,8 +2,6 @@ package io.dataease.config; import com.fit2cloud.autoconfigure.QuartzAutoConfiguration; import io.dataease.commons.utils.CommonThreadPool; -import org.apache.spark.api.java.JavaSparkContext; -import org.apache.spark.sql.SQLContext; import org.apache.spark.sql.SparkSession; import org.pentaho.di.core.KettleEnvironment; import org.pentaho.di.repository.filerep.KettleFileRepository; @@ -40,7 +38,22 @@ public class CommonConfig { SparkSession spark = SparkSession.builder() .appName(env.getProperty("spark.appName", "DataeaseJob")) .master(env.getProperty("spark.master", "local[*]")) - .config("spark.scheduler.mode", "FAIR") + .config("spark.scheduler.mode", env.getProperty("spark.scheduler.mode", "FAIR")) + .config("spark.serializer", env.getProperty("spark.serializer", "org.apache.spark.serializer.KryoSerializer")) + .config("spark.executor.cores", env.getProperty("spark.executor.cores", "8")) + .config("spark.executor.memory", env.getProperty("spark.executor.memory", "6442450944b")) + .config("spark.locality.wait", env.getProperty("spark.locality.wait", "600000")) + .config("spark.maxRemoteBlockSizeFetchToMem", env.getProperty("spark.maxRemoteBlockSizeFetchToMem", "2000m")) + .config("spark.shuffle.detectCorrupt", env.getProperty("spark.shuffle.detectCorrupt", "false")) + .config("spark.shuffle.service.enabled", env.getProperty("spark.shuffle.service.enabled", "true")) + .config("spark.sql.adaptive.enabled", env.getProperty("spark.sql.adaptive.enabled", "true")) + .config("spark.sql.adaptive.shuffle.targetPostShuffleInputSize", env.getProperty("spark.sql.adaptive.shuffle.targetPostShuffleInputSize", "200M")) + .config("spark.sql.broadcastTimeout", env.getProperty("spark.sql.broadcastTimeout", "12000")) + .config("spark.sql.retainGroupColumns", env.getProperty("spark.sql.retainGroupColumns", "false")) + .config("spark.sql.sortMergeJoinExec.buffer.in.memory.threshold", env.getProperty("spark.sql.sortMergeJoinExec.buffer.in.memory.threshold", "100000")) + .config("spark.sql.sortMergeJoinExec.buffer.spill.threshold", env.getProperty("spark.sql.sortMergeJoinExec.buffer.spill.threshold", "100000")) + .config("spark.sql.variable.substitute", env.getProperty("spark.sql.variable.substitute", "false")) + .config("spark.temp.expired.time", env.getProperty("spark.temp.expired.time", "3600")) .getOrCreate(); return spark; } diff --git a/backend/src/main/java/io/dataease/controller/chart/ChartViewController.java b/backend/src/main/java/io/dataease/controller/chart/ChartViewController.java index 9c2cfcd498..659ca03f58 100644 --- a/backend/src/main/java/io/dataease/controller/chart/ChartViewController.java +++ b/backend/src/main/java/io/dataease/controller/chart/ChartViewController.java @@ -1,6 +1,8 @@ package io.dataease.controller.chart; import io.dataease.base.domain.ChartViewWithBLOBs; +import io.dataease.controller.request.chart.ChartExtFilterRequest; +import io.dataease.controller.request.chart.ChartExtRequest; import io.dataease.controller.request.chart.ChartViewRequest; import io.dataease.dto.chart.ChartViewDTO; import io.dataease.service.chart.ChartViewService; @@ -41,7 +43,12 @@ public class ChartViewController { } @PostMapping("/getData/{id}") - public ChartViewDTO getData(@PathVariable String id) throws Exception { - return chartViewService.getData(id); + public ChartViewDTO getData(@PathVariable String id, @RequestBody ChartExtRequest requestList) throws Exception { + return chartViewService.getData(id, requestList); + } + + @PostMapping("chartDetail/{id}") + public Map chartDetail(@PathVariable String id) { + return chartViewService.getChartDetail(id); } } diff --git a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java index 7a902aa505..91e8d5a3dc 100644 --- a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java +++ b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java @@ -82,4 +82,8 @@ public class DataSetTableController { dataSetTableService.saveIncrementalConfig(datasetTableIncrementalConfig); } + @PostMapping("datasetDetail/{id}") + public Map datasetDetail(@PathVariable String id) { + return dataSetTableService.getDatasetDetail(id); + } } diff --git a/backend/src/main/java/io/dataease/controller/request/chart/ChartExtFilterRequest.java b/backend/src/main/java/io/dataease/controller/request/chart/ChartExtFilterRequest.java new file mode 100644 index 0000000000..8853b8232b --- /dev/null +++ b/backend/src/main/java/io/dataease/controller/request/chart/ChartExtFilterRequest.java @@ -0,0 +1,22 @@ +package io.dataease.controller.request.chart; + +import io.dataease.base.domain.DatasetTableField; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +/** + * @Author gin + * @Date 2021/4/19 10:24 上午 + */ +@Getter +@Setter +public class ChartExtFilterRequest { + private String componentId; + private String fieldId; + private String operator; + private List value; + private List viewIds; + private DatasetTableField datasetTableField; +} diff --git a/backend/src/main/java/io/dataease/controller/request/chart/ChartExtRequest.java b/backend/src/main/java/io/dataease/controller/request/chart/ChartExtRequest.java new file mode 100644 index 0000000000..3806316bd6 --- /dev/null +++ b/backend/src/main/java/io/dataease/controller/request/chart/ChartExtRequest.java @@ -0,0 +1,16 @@ +package io.dataease.controller.request.chart; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +/** + * @Author gin + * @Date 2021/4/19 11:29 上午 + */ +@Getter +@Setter +public class ChartExtRequest { + private List filter; +} diff --git a/backend/src/main/java/io/dataease/datasource/provider/DatasourceProvider.java b/backend/src/main/java/io/dataease/datasource/provider/DatasourceProvider.java index 71b513471f..05bb3c86e6 100644 --- a/backend/src/main/java/io/dataease/datasource/provider/DatasourceProvider.java +++ b/backend/src/main/java/io/dataease/datasource/provider/DatasourceProvider.java @@ -19,7 +19,7 @@ public abstract class DatasourceProvider { abstract public List getTables(DatasourceRequest datasourceRequest) throws Exception; - public List getTableFileds(DatasourceRequest datasourceRequest) throws Exception{ + public List getTableFileds(DatasourceRequest datasourceRequest) throws Exception { return new ArrayList<>(); }; @@ -27,7 +27,7 @@ public abstract class DatasourceProvider { getData(datasourceRequest); } - abstract public Long count(DatasourceRequest datasourceRequest)throws Exception; + abstract public Long count(DatasourceRequest datasourceRequest) throws Exception; abstract public List getPageData(DatasourceRequest datasourceRequest) throws Exception; @@ -35,4 +35,5 @@ public abstract class DatasourceProvider { abstract public List fetchResultField(ResultSet rs) throws Exception; + abstract public void initConnectionPool(DatasourceRequest datasourceRequest) throws Exception; } diff --git a/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java b/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java index 6ef5ee0b1d..6517233c45 100644 --- a/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java +++ b/backend/src/main/java/io/dataease/datasource/provider/JdbcProvider.java @@ -13,24 +13,28 @@ import org.springframework.stereotype.Service; import java.sql.*; import java.text.MessageFormat; import java.util.*; +import java.util.concurrent.ArrayBlockingQueue; @Service("jdbc") public class JdbcProvider extends DatasourceProvider { - + private static Map> jdbcConnection = new HashMap<>(); + private static int poolSize = 20; @Override public List getData(DatasourceRequest datasourceRequest) throws Exception { List list = new LinkedList<>(); - try ( - Connection connection = getConnection(datasourceRequest); - Statement stat = connection.createStatement(); - ResultSet rs = stat.executeQuery(datasourceRequest.getQuery()) - ) { + Connection connection = null; + try { + connection = getConnectionFromPool(datasourceRequest); + Statement stat = connection.createStatement(); + ResultSet rs = stat.executeQuery(datasourceRequest.getQuery()); list = fetchResult(rs); } catch (SQLException e) { throw new Exception("ERROR:" + e.getMessage(), e); } catch (Exception e) { throw new Exception("ERROR:" + e.getMessage(), e); + }finally { + returnSource(connection, datasourceRequest.getDatasource().getId()); } return list; } @@ -38,14 +42,18 @@ public class JdbcProvider extends DatasourceProvider { @Override public ResultSet getDataResultSet(DatasourceRequest datasourceRequest) throws Exception { ResultSet rs; + Connection connection = null; try { - Connection connection = getConnection(datasourceRequest); + connection = getConnectionFromPool(datasourceRequest); Statement stat = connection.createStatement(); rs = stat.executeQuery(datasourceRequest.getQuery()); + returnSource(connection, datasourceRequest.getDatasource().getId()); } catch (SQLException e) { throw new Exception("ERROR:" + e.getMessage(), e); } catch (Exception e) { throw new Exception("ERROR:" + e.getMessage(), e); + }finally { + returnSource(connection, datasourceRequest.getDatasource().getId()); } return rs; } @@ -53,16 +61,19 @@ public class JdbcProvider extends DatasourceProvider { @Override public List getPageData(DatasourceRequest datasourceRequest) throws Exception { List list = new LinkedList<>(); - try ( - Connection connection = getConnection(datasourceRequest); - Statement stat = connection.createStatement(); - ResultSet rs = stat.executeQuery(datasourceRequest.getQuery() + MessageFormat.format(" LIMIT {0}, {1}", (datasourceRequest.getStartPage() - 1) * datasourceRequest.getPageSize(), datasourceRequest.getPageSize())) - ) { + Connection connection = null; + try { + connection = getConnectionFromPool(datasourceRequest); + Statement stat = connection.createStatement(); + ResultSet rs = stat.executeQuery(datasourceRequest.getQuery() + MessageFormat.format(" LIMIT {0}, {1}", (datasourceRequest.getStartPage() - 1) * datasourceRequest.getPageSize(), datasourceRequest.getPageSize())); + returnSource(connection, datasourceRequest.getDatasource().getId()); list = fetchResult(rs); } catch (SQLException e) { throw new Exception("ERROR:" + e.getMessage(), e); } catch (Exception e) { throw new Exception("ERROR:" + e.getMessage(), e); + }finally { + returnSource(connection, datasourceRequest.getDatasource().getId()); } return list; } @@ -112,23 +123,28 @@ public class JdbcProvider extends DatasourceProvider { public List getTables(DatasourceRequest datasourceRequest) throws Exception { List tables = new ArrayList<>(); String queryStr = getTablesSql(datasourceRequest); - try (Connection con = getConnection(datasourceRequest); Statement ps = con.createStatement()) { + Connection con = null; + try { + con = getConnectionFromPool(datasourceRequest); + Statement ps = con.createStatement(); ResultSet resultSet = ps.executeQuery(queryStr); while (resultSet.next()) { tables.add(resultSet.getString(1)); } + return tables; } catch (Exception e) { throw new Exception("ERROR: " + e.getMessage(), e); + }finally { + returnSource(con, datasourceRequest.getDatasource().getId()); } - return tables; } @Override public List getTableFileds(DatasourceRequest datasourceRequest) throws Exception { List list = new LinkedList<>(); - try ( - Connection connection = getConnection(datasourceRequest); - ) { + Connection connection = null; + try { + connection = getConnectionFromPool(datasourceRequest); DatabaseMetaData databaseMetaData = connection.getMetaData(); ResultSet resultSet = databaseMetaData.getColumns(null, "%", datasourceRequest.getTable().toUpperCase(), "%"); while (resultSet.next()) { @@ -152,6 +168,8 @@ public class JdbcProvider extends DatasourceProvider { throw new Exception("ERROR:" + e.getMessage(), e); } catch (Exception e) { throw new Exception("ERROR:" + e.getMessage(), e); + }finally { + returnSource(connection, datasourceRequest.getDatasource().getId()); } return list; } @@ -161,27 +179,73 @@ public class JdbcProvider extends DatasourceProvider { @Override public void test(DatasourceRequest datasourceRequest) throws Exception { String queryStr = getTablesSql(datasourceRequest); - try (Connection con = getConnection(datasourceRequest); Statement ps = con.createStatement()) { + Connection con = null; + try { + con = getConnection(datasourceRequest); + Statement ps = con.createStatement(); ResultSet resultSet = ps.executeQuery(queryStr); } catch (Exception e) { throw new Exception("ERROR: " + e.getMessage(), e); + }finally { + con.close(); } } public Long count(DatasourceRequest datasourceRequest) throws Exception { - try (Connection con = getConnection(datasourceRequest); Statement ps = con.createStatement()) { + Connection con = null; + try { + con = getConnectionFromPool(datasourceRequest); Statement ps = con.createStatement(); ResultSet resultSet = ps.executeQuery(datasourceRequest.getQuery()); while (resultSet.next()) { return resultSet.getLong(1); } } catch (Exception e) { throw new Exception("ERROR: " + e.getMessage(), e); + }finally { + returnSource(con, datasourceRequest.getDatasource().getId()); } return 0L; } - private Connection getConnection(DatasourceRequest datasourceRequest) throws Exception { + private void returnSource(Connection connection, String dataSourceId) throws Exception{ + if(connection != null && !connection.isClosed()){ + ArrayBlockingQueue connections = jdbcConnection.get(dataSourceId); + connections.put(connection); + } + } + + private Connection getConnectionFromPool(DatasourceRequest datasourceRequest)throws Exception { + ArrayBlockingQueue connections = jdbcConnection.get(datasourceRequest.getDatasource().getId()); + if (connections == null) { + initConnectionPool(datasourceRequest); + } + connections = jdbcConnection.get(datasourceRequest.getDatasource().getId()); + Connection co = connections.take(); + return co; + } + + @Override + public void initConnectionPool(DatasourceRequest datasourceRequest)throws Exception{ + ArrayBlockingQueue connections = jdbcConnection.get(datasourceRequest.getDatasource().getId()); + if (connections == null) { + connections = new ArrayBlockingQueue<>(poolSize); + for (int i = 0; i < poolSize ; i++) { + Connection connection = getConnection(datasourceRequest); + connections.add(connection); + } + jdbcConnection.put(datasourceRequest.getDatasource().getId(), connections); + }else { + for (int i = 0; i < poolSize ; i++) { + Connection connection = connections.take(); + connection.close(); + connection = getConnection(datasourceRequest); + connections.add(connection); + } + } + } + + private static Connection getConnection(DatasourceRequest datasourceRequest) throws Exception { String username = null; String password = null; String driver = null; diff --git a/backend/src/main/java/io/dataease/datasource/service/DatasourceService.java b/backend/src/main/java/io/dataease/datasource/service/DatasourceService.java index 24f6b2a4c0..7fb24d6fae 100644 --- a/backend/src/main/java/io/dataease/datasource/service/DatasourceService.java +++ b/backend/src/main/java/io/dataease/datasource/service/DatasourceService.java @@ -5,6 +5,7 @@ import io.dataease.base.mapper.*; import io.dataease.base.mapper.ext.ExtDataSourceMapper; import io.dataease.base.mapper.ext.query.GridExample; import io.dataease.commons.exception.DEException; +import io.dataease.commons.utils.CommonThreadPool; import io.dataease.controller.sys.base.BaseGridRequest; import io.dataease.datasource.provider.DatasourceProvider; import io.dataease.datasource.provider.ProviderFactory; @@ -24,7 +25,8 @@ public class DatasourceService { @Resource private DatasourceMapper datasourceMapper; - + @Resource + private CommonThreadPool commonThreadPool; @Resource private ExtDataSourceMapper extDataSourceMapper; @@ -39,6 +41,7 @@ public class DatasourceService { datasource.setUpdateTime(currentTimeMillis); datasource.setCreateTime(currentTimeMillis); datasourceMapper.insertSelective(datasource); + initConnectionPool(datasource); return datasource; } @@ -68,6 +71,7 @@ public class DatasourceService { datasource.setCreateTime(null); datasource.setUpdateTime(System.currentTimeMillis()); datasourceMapper.updateByPrimaryKeySelective(datasource); + initConnectionPool(datasource); } public void validate(Datasource datasource) throws Exception { @@ -89,4 +93,30 @@ public class DatasourceService { return datasourceMapper.selectByPrimaryKey(id); } + private void initConnectionPool(Datasource datasource){ + commonThreadPool.addTask(() ->{ + try { + DatasourceProvider datasourceProvider = ProviderFactory.getProvider(datasource.getType()); + DatasourceRequest datasourceRequest = new DatasourceRequest(); + datasourceRequest.setDatasource(datasource); + datasourceProvider.initConnectionPool(datasourceRequest); + }catch (Exception e){} + }); + } + + public void initAllDataSourceConnectionPool(){ + List datasources = datasourceMapper.selectByExampleWithBLOBs(new DatasourceExample()); + datasources.forEach(datasource -> { + commonThreadPool.addTask(() ->{ + try { + DatasourceProvider datasourceProvider = ProviderFactory.getProvider(datasource.getType()); + DatasourceRequest datasourceRequest = new DatasourceRequest(); + datasourceRequest.setDatasource(datasource); + datasourceProvider.initConnectionPool(datasourceRequest); + }catch (Exception e){ + e.printStackTrace(); + } + }); + }); + } } diff --git a/backend/src/main/java/io/dataease/listener/AppStartInitDataSourceListener.java b/backend/src/main/java/io/dataease/listener/AppStartInitDataSourceListener.java new file mode 100644 index 0000000000..632cb2e767 --- /dev/null +++ b/backend/src/main/java/io/dataease/listener/AppStartInitDataSourceListener.java @@ -0,0 +1,31 @@ +package io.dataease.listener; + +import io.dataease.base.domain.DatasetTable; +import io.dataease.base.domain.DatasetTableExample; +import io.dataease.base.domain.DatasetTableField; +import io.dataease.base.mapper.DatasetTableMapper; +import io.dataease.commons.utils.CommonThreadPool; +import io.dataease.datasource.service.DatasourceService; +import io.dataease.service.dataset.DataSetTableFieldsService; +import io.dataease.service.spark.SparkCalc; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; + +@Component +@Order(value = 2) +public class AppStartInitDataSourceListener implements ApplicationListener { + @Resource + private DatasourceService datasourceService; + @Override + public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { + System.out.println("================= Init datasource connection pool ================="); + // 项目启动,从数据集中找到定时抽取的表,从HBase中读取放入缓存 + datasourceService.initAllDataSourceConnectionPool(); + } +} diff --git a/backend/src/main/java/io/dataease/listener/AppStartListener.java b/backend/src/main/java/io/dataease/listener/AppStartListener.java index 6193506241..a2224eaaea 100644 --- a/backend/src/main/java/io/dataease/listener/AppStartListener.java +++ b/backend/src/main/java/io/dataease/listener/AppStartListener.java @@ -1,7 +1,6 @@ package io.dataease.listener; import io.dataease.base.domain.DatasetTableTask; -import io.dataease.job.sechedule.ScheduleManager; import io.dataease.service.ScheduleService; import io.dataease.service.dataset.DataSetTableTaskService; import org.springframework.boot.context.event.ApplicationReadyEvent; diff --git a/backend/src/main/java/io/dataease/listener/AppStartReadHBaseListener.java b/backend/src/main/java/io/dataease/listener/AppStartReadHBaseListener.java index 2fc2f731d7..d8dcc2e3e6 100644 --- a/backend/src/main/java/io/dataease/listener/AppStartReadHBaseListener.java +++ b/backend/src/main/java/io/dataease/listener/AppStartReadHBaseListener.java @@ -3,16 +3,10 @@ package io.dataease.listener; import io.dataease.base.domain.DatasetTable; import io.dataease.base.domain.DatasetTableExample; import io.dataease.base.domain.DatasetTableField; -import io.dataease.base.domain.DatasetTableFieldExample; -import io.dataease.base.mapper.DatasetTableFieldMapper; import io.dataease.base.mapper.DatasetTableMapper; -import io.dataease.commons.utils.CommonBeanFactory; import io.dataease.commons.utils.CommonThreadPool; import io.dataease.service.dataset.DataSetTableFieldsService; import io.dataease.service.spark.SparkCalc; -import org.apache.spark.api.java.JavaSparkContext; -import org.apache.spark.sql.SQLContext; -import org.apache.spark.sql.SparkSession; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationListener; import org.springframework.core.annotation.Order; @@ -45,14 +39,14 @@ public class AppStartReadHBaseListener implements ApplicationListener datasetTables = datasetTableMapper.selectByExampleWithBLOBs(datasetTableExample); for (DatasetTable table : datasetTables) { - commonThreadPool.addTask(() -> { +// commonThreadPool.addTask(() -> { try { List fields = dataSetTableFieldsService.getFieldsByTableId(table.getId()); sparkCalc.getHBaseDataAndCache(table.getId(), fields); } catch (Exception e) { e.printStackTrace(); } - }); +// }); } } } diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index 2100b7ada1..1997b680ff 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -4,9 +4,10 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import io.dataease.base.domain.*; import io.dataease.base.mapper.ChartViewMapper; -import io.dataease.base.mapper.DatasetTableFieldMapper; import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.BeanUtils; +import io.dataease.controller.request.chart.ChartExtFilterRequest; +import io.dataease.controller.request.chart.ChartExtRequest; import io.dataease.controller.request.chart.ChartViewRequest; import io.dataease.datasource.constants.DatasourceTypes; import io.dataease.datasource.provider.DatasourceProvider; @@ -21,6 +22,7 @@ import io.dataease.service.dataset.DataSetTableFieldsService; import io.dataease.service.dataset.DataSetTableService; import io.dataease.service.spark.SparkCalc; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; @@ -88,7 +90,7 @@ public class ChartViewService { chartViewMapper.deleteByExample(chartViewExample); } - public ChartViewDTO getData(String id) throws Exception { + public ChartViewDTO getData(String id, ChartExtRequest requestList) throws Exception { ChartViewWithBLOBs view = chartViewMapper.selectByPrimaryKey(id); List xAxis = new Gson().fromJson(view.getXAxis(), new TypeToken>() { }.getType()); @@ -107,6 +109,24 @@ public class ChartViewService { // List xList = dataSetTableFieldsService.getListByIds(xIds); // List yList = dataSetTableFieldsService.getListByIds(yIds); + // 过滤来自仪表盘的条件 + List extFilterList = new ArrayList<>(); + if (ObjectUtils.isNotEmpty(requestList.getFilter())) { + for (ChartExtFilterRequest request : requestList.getFilter()) { + DatasetTableField datasetTableField = dataSetTableFieldsService.get(request.getFieldId()); + request.setDatasetTableField(datasetTableField); + if (StringUtils.equalsIgnoreCase(datasetTableField.getTableId(), view.getTableId())) { + if (CollectionUtils.isNotEmpty(request.getViewIds())) { + if (request.getViewIds().contains(view.getId())) { + extFilterList.add(request); + } + } else { + extFilterList.add(request); + } + } + } + } + // 获取数据集 DatasetTable table = dataSetTableService.get(view.getTableId()); // 判断连接方式,直连或者定时抽取 table.mode @@ -119,15 +139,15 @@ public class ChartViewService { DataTableInfoDTO dataTableInfoDTO = new Gson().fromJson(table.getInfo(), DataTableInfoDTO.class); if (StringUtils.equalsIgnoreCase(table.getType(), "db")) { datasourceRequest.setTable(dataTableInfoDTO.getTable()); - datasourceRequest.setQuery(getSQL(ds.getType(), dataTableInfoDTO.getTable(), xAxis, yAxis)); + datasourceRequest.setQuery(getSQL(ds.getType(), dataTableInfoDTO.getTable(), xAxis, yAxis, extFilterList)); } else if (StringUtils.equalsIgnoreCase(table.getType(), "sql")) { - datasourceRequest.setQuery(getSQL(ds.getType(), " (" + dataTableInfoDTO.getSql() + ") AS tmp ", xAxis, yAxis)); + datasourceRequest.setQuery(getSQL(ds.getType(), " (" + dataTableInfoDTO.getSql() + ") AS tmp ", xAxis, yAxis, extFilterList)); } data = datasourceProvider.getData(datasourceRequest); } else if (table.getMode() == 1) {// 抽取 // 获取数据集de字段 List fields = dataSetTableFieldsService.getFieldsByTableId(table.getId()); - data = sparkCalc.getData(table.getId(), fields, xAxis, yAxis, "tmp_" + view.getId().split("-")[0]); + data = sparkCalc.getData(table.getId(), fields, xAxis, yAxis, "tmp_" + view.getId().split("-")[0], extFilterList); } // 图表组件可再扩展 @@ -163,18 +183,45 @@ public class ChartViewService { return dto; } - public String getSQL(String type, String table, List xAxis, List yAxis) { + public String transMysqlExtFilter(List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return ""; + } + StringBuilder filter = new StringBuilder(); + for (ChartExtFilterRequest request : requestList) { + List value = request.getValue(); + if (CollectionUtils.isEmpty(value)) { + continue; + } + DatasetTableField field = request.getDatasetTableField(); + filter.append(" AND ") + .append(field.getOriginName()) + .append(" ") + .append(transMysqlFilterTerm(request.getOperator())) + .append(" "); + if (StringUtils.containsIgnoreCase(request.getOperator(), "in")) { + filter.append("('").append(StringUtils.join(value, "','")).append("')"); + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "like")) { + filter.append("'%").append(value.get(0)).append("%'"); + } else { + filter.append("'").append(value.get(0)).append("'"); + } + } + return filter.toString(); + } + + public String getSQL(String type, String table, List xAxis, List yAxis, List extFilterRequestList) { DatasourceTypes datasourceType = DatasourceTypes.valueOf(type); switch (datasourceType) { case mysql: - return transMysqlSQL(table, xAxis, yAxis); + return transMysqlSQL(table, xAxis, yAxis, extFilterRequestList); case sqlServer: default: return ""; } } - public String transMysqlSQL(String table, List xAxis, List yAxis) { + public String transMysqlSQL(String table, List xAxis, List yAxis, List extFilterRequestList) { // 字段汇总 排序等 String[] field = yAxis.stream().map(y -> "CAST(" + y.getSummary() + "(" + y.getOriginName() + ") AS DECIMAL(20,2)) AS _" + y.getSummary() + "_" + y.getOriginName()).toArray(String[]::new); String[] group = xAxis.stream().map(ChartViewFieldDTO::getOriginName).toArray(String[]::new); @@ -185,7 +232,7 @@ public class ChartViewService { StringUtils.join(group, ","), StringUtils.join(field, ","), table, - "", + transMysqlExtFilter(extFilterRequestList),// origin field filter and panel field filter StringUtils.join(group, ","), StringUtils.join(order, ",")); if (sql.endsWith(",")) { @@ -221,6 +268,14 @@ public class ChartViewService { return " > "; case "ge": return " >= "; + case "in": + return " IN "; + case "not in": + return " NOT IN "; + case "like": + return " LIKE "; + case "not like": + return " NOT LIKE "; case "null": return " IS NULL "; case "not_null": @@ -250,4 +305,15 @@ public class ChartViewService { throw new RuntimeException("Name can't repeat in same group."); } } + + public Map getChartDetail(String id) { + Map map = new HashMap<>(); + ChartViewWithBLOBs chartViewWithBLOBs = chartViewMapper.selectByPrimaryKey(id); + map.put("chart", chartViewWithBLOBs); + if (ObjectUtils.isNotEmpty(chartViewWithBLOBs)) { + Map datasetDetail = dataSetTableService.getDatasetDetail(chartViewWithBLOBs.getTableId()); + map.putAll(datasetDetail); + } + return map; + } } diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableFieldsService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableFieldsService.java index 020684bc8e..8d1109780b 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableFieldsService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableFieldsService.java @@ -66,4 +66,8 @@ public class DataSetTableFieldsService { datasetTableFieldExample.createCriteria().andTableIdEqualTo(id); return datasetTableFieldMapper.selectByExample(datasetTableFieldExample); } + + public DatasetTableField get(String id) { + return datasetTableFieldMapper.selectByPrimaryKey(id); + } } diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java index f40e017de8..0ca76754fe 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java @@ -16,6 +16,7 @@ import io.dataease.datasource.provider.ProviderFactory; import io.dataease.datasource.request.DatasourceRequest; import io.dataease.dto.dataset.DataTableInfoDTO; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; @@ -422,4 +423,15 @@ public class DataSetTableService { throw new RuntimeException("Name can't repeat in same group."); } } + + public Map getDatasetDetail(String id) { + Map map = new HashMap<>(); + DatasetTable table = datasetTableMapper.selectByPrimaryKey(id); + map.put("table", table); + if (ObjectUtils.isNotEmpty(table)) { + Datasource datasource = datasourceMapper.selectByPrimaryKey(table.getDataSourceId()); + map.put("datasource", datasource); + } + return map; + } } diff --git a/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java b/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java index d952cbaefe..8c88a6afe2 100644 --- a/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java +++ b/backend/src/main/java/io/dataease/service/dataset/ExtractDataService.java @@ -472,6 +472,8 @@ public class ExtractDataService { hBaseOutputMeta.setTargetMappingName("target_mapping"); hBaseOutputMeta.setNamedCluster(clusterTemplate); hBaseOutputMeta.setCoreConfigURL(hbase_conf_file); + hBaseOutputMeta.setDisableWriteToWAL(true); + hBaseOutputMeta.setWriteBufferSize("31457280"); //30M if (extractType.equalsIgnoreCase("incremental_delete")) { hBaseOutputMeta.setDeleteRowKey(true); } diff --git a/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java b/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java index cbc0521b9f..6a881798a5 100644 --- a/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java +++ b/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java @@ -58,7 +58,7 @@ public class PanelGroupService { return panelGroupDTOList; } - public void getTreeChildren(List parentPanelGroupDTO){ + public void getTreeChildren(List parentPanelGroupDTO) { Optional.ofNullable(parentPanelGroupDTO).ifPresent(parent -> parent.forEach(panelGroupDTO -> { List panelGroupDTOChildren = extPanelGroupMapper.panelGroupList(new PanelGroupRequest(panelGroupDTO.getId())); panelGroupDTO.setChildren(panelGroupDTOChildren); @@ -66,7 +66,7 @@ public class PanelGroupService { })); } - public List getDefaultTree(PanelGroupRequest panelGroupRequest){ + public List getDefaultTree(PanelGroupRequest panelGroupRequest) { return extPanelGroupMapper.panelGroupList(panelGroupRequest); } @@ -86,32 +86,32 @@ public class PanelGroupService { } - public void deleteCircle(String id){ + public void deleteCircle(String id) { Assert.notNull(id, "id cannot be null"); extPanelGroupMapper.deleteCircle(id); } - public PanelGroupWithBLOBs findOne(String panelId){ - return panelGroupMapper.selectByPrimaryKey(panelId); + public PanelGroupWithBLOBs findOne(String panelId) { + return panelGroupMapper.selectByPrimaryKey(panelId); } - public PanelGroupDTO findOneBack(String panelId) throws Exception{ + public PanelGroupDTO findOneBack(String panelId) throws Exception { PanelGroupDTO panelGroupDTO = extPanelGroupMapper.panelGroup(panelId); Assert.notNull(panelGroupDTO, "未查询到仪表盘信息"); PanelDesignExample panelDesignExample = new PanelDesignExample(); panelDesignExample.createCriteria().andPanelIdEqualTo(panelId); - List panelDesignList = panelDesignMapper.selectByExample(panelDesignExample); - if(CollectionUtils.isNotEmpty(panelDesignList)){ + List panelDesignList = panelDesignMapper.selectByExample(panelDesignExample); + if (CollectionUtils.isNotEmpty(panelDesignList)) { List panelDesignDTOList = new ArrayList<>(); //TODO 加载所有视图和组件的数据 - for(PanelDesign panelDesign:panelDesignList){ + for (PanelDesign panelDesign : panelDesignList) { //TODO 获取view 视图数据 - ChartViewDTO chartViewDTO = chartViewService.getData(panelDesign.getComponentId()); + ChartViewDTO chartViewDTO = chartViewService.getData(panelDesign.getComponentId(), null); //TODO 获取systemComponent 系统组件数据(待开发) PanelDesignDTO panelDesignDTO = new PanelDesignDTO(chartViewDTO); - BeanUtils.copyBean(panelDesignDTO,panelDesign); + BeanUtils.copyBean(panelDesignDTO, panelDesign); panelDesignDTO.setKeepFlag(true); panelDesignDTOList.add(panelDesignDTO); } @@ -123,14 +123,14 @@ public class PanelGroupService { } - public List getUsableViews(String panelId) throws Exception{ + public List getUsableViews(String panelId) throws Exception { List chartViewDTOList = new ArrayList<>(); List allChartView = chartViewMapper.selectByExample(null); Optional.ofNullable(allChartView).orElse(new ArrayList<>()).stream().forEach(chartView -> { try { - chartViewDTOList.add(chartViewService.getData(chartView.getId())); - }catch (Exception e){ - LOGGER.error("获取view详情出错:"+chartView.getId(),e); + chartViewDTOList.add(chartViewService.getData(chartView.getId(), null)); + } catch (Exception e) { + LOGGER.error("获取view详情出错:" + chartView.getId(), e); } }); return chartViewDTOList; @@ -150,24 +150,24 @@ public class PanelGroupService { //TODO 更新panelDesign 信息 String panelId = request.getId(); - Assert.notNull(panelId,"panelId should not be null"); + Assert.notNull(panelId, "panelId should not be null"); //清理原有design extPanelDesignMapper.deleteByPanelId(panelId); //保存view 或者component design Optional.ofNullable(request.getPanelDesigns()).orElse(new ArrayList<>()).stream().forEach(panelDesignDTO -> { - if(panelDesignDTO.isKeepFlag()) { - String componentId = ""; - if(StringUtils.equals(PanelConstants.COMPONENT_TYPE_VIEW,panelDesignDTO.getComponentType())){ - componentId = panelDesignDTO.getChartView().getId(); - }else{ - //预留 公共组件id获取 - componentId = ""; - } - panelDesignDTO.setPanelId(panelId); - panelDesignDTO.setComponentId(componentId); - panelDesignDTO.setUpdateTime(System.currentTimeMillis()); - panelDesignMapper.insertSelective(panelDesignDTO); - } + if (panelDesignDTO.isKeepFlag()) { + String componentId = ""; + if (StringUtils.equals(PanelConstants.COMPONENT_TYPE_VIEW, panelDesignDTO.getComponentType())) { + componentId = panelDesignDTO.getChartView().getId(); + } else { + //预留 公共组件id获取 + componentId = ""; + } + panelDesignDTO.setPanelId(panelId); + panelDesignDTO.setComponentId(componentId); + panelDesignDTO.setUpdateTime(System.currentTimeMillis()); + panelDesignMapper.insertSelective(panelDesignDTO); + } }); } } diff --git a/backend/src/main/java/io/dataease/service/spark/SparkCalc.java b/backend/src/main/java/io/dataease/service/spark/SparkCalc.java index 936ddb8d57..0824f2258e 100644 --- a/backend/src/main/java/io/dataease/service/spark/SparkCalc.java +++ b/backend/src/main/java/io/dataease/service/spark/SparkCalc.java @@ -2,11 +2,11 @@ package io.dataease.service.spark; import io.dataease.base.domain.DatasetTableField; import io.dataease.commons.utils.CommonBeanFactory; +import io.dataease.controller.request.chart.ChartExtFilterRequest; import io.dataease.dto.chart.ChartViewFieldDTO; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.io.ImmutableBytesWritable; @@ -22,12 +22,12 @@ import org.apache.spark.sql.*; import org.apache.spark.sql.types.DataTypes; import org.apache.spark.sql.types.StructField; import org.apache.spark.sql.types.StructType; +import org.apache.spark.storage.StorageLevel; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; import scala.Tuple2; import javax.annotation.Resource; -import java.math.BigDecimal; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Base64; @@ -44,13 +44,12 @@ public class SparkCalc { @Resource private Environment env; // 保存了配置文件的信息 - public List getData(String hTable, List fields, List xAxis, List yAxis, String tmpTable) throws Exception { + public List getData(String hTable, List fields, List xAxis, List yAxis, String tmpTable, List requestList) throws Exception { // Spark Context SparkSession spark = CommonBeanFactory.getBean(SparkSession.class); JavaSparkContext sparkContext = new JavaSparkContext(spark.sparkContext()); // Spark SQL Context -// SQLContext sqlContext = CommonBeanFactory.getBean(SQLContext.class); SQLContext sqlContext = new SQLContext(sparkContext); sqlContext.setConf("spark.sql.shuffle.partitions", env.getProperty("spark.sql.shuffle.partitions", "1")); sqlContext.setConf("spark.default.parallelism", env.getProperty("spark.default.parallelism", "1")); @@ -61,7 +60,7 @@ public class SparkCalc { } dataFrame.createOrReplaceTempView(tmpTable); - Dataset sql = sqlContext.sql(getSQL(xAxis, yAxis, tmpTable)); + Dataset sql = sqlContext.sql(getSQL(xAxis, yAxis, tmpTable, requestList)); // transform List data = new ArrayList<>(); List list = sql.collectAsList(); @@ -81,7 +80,6 @@ public class SparkCalc { JavaSparkContext sparkContext = new JavaSparkContext(spark.sparkContext()); // Spark SQL Context -// SQLContext sqlContext = CommonBeanFactory.getBean(SQLContext.class); SQLContext sqlContext = new SQLContext(sparkContext); sqlContext.setConf("spark.sql.shuffle.partitions", env.getProperty("spark.sql.shuffle.partitions", "1")); sqlContext.setConf("spark.default.parallelism", env.getProperty("spark.default.parallelism", "1")); @@ -90,12 +88,14 @@ public class SparkCalc { public Dataset getHBaseDataAndCache(JavaSparkContext sparkContext, SQLContext sqlContext, String hTable, List fields) throws Exception { Scan scan = new Scan(); - scan.addFamily(column_family.getBytes()); + scan.addFamily(Bytes.toBytes(column_family)); + for (DatasetTableField field : fields) { + scan.addColumn(Bytes.toBytes(column_family), Bytes.toBytes(field.getOriginName())); + } ClientProtos.Scan proto = ProtobufUtil.toScan(scan); String scanToString = new String(Base64.getEncoder().encode(proto.toByteArray())); // HBase config -// Configuration conf = CommonBeanFactory.getBean(Configuration.class); org.apache.hadoop.conf.Configuration conf = new org.apache.hadoop.conf.Configuration(); conf.set("hbase.zookeeper.quorum", env.getProperty("hbase.zookeeper.quorum")); conf.set("hbase.zookeeper.property.clientPort", env.getProperty("hbase.zookeeper.property.clientPort")); @@ -144,13 +144,13 @@ public class SparkCalc { }); StructType structType = DataTypes.createStructType(structFields); - Dataset dataFrame = sqlContext.createDataFrame(rdd, structType).persist(); + Dataset dataFrame = sqlContext.createDataFrame(rdd, structType).persist(StorageLevel.MEMORY_AND_DISK_SER()); CacheUtil.getInstance().addCacheData(hTable, dataFrame); dataFrame.count(); return dataFrame; } - public String getSQL(List xAxis, List yAxis, String table) { + public String getSQL(List xAxis, List yAxis, String table, List extFilterRequestList) { // 字段汇总 排序等 String[] field = yAxis.stream().map(y -> "CAST(" + y.getSummary() + "(" + y.getOriginName() + ") AS DECIMAL(20,2)) AS _" + y.getSummary() + "_" + y.getOriginName()).toArray(String[]::new); String[] group = xAxis.stream().map(ChartViewFieldDTO::getOriginName).toArray(String[]::new); @@ -161,7 +161,7 @@ public class SparkCalc { StringUtils.join(group, ","), StringUtils.join(field, ","), table, - "", + transExtFilter(extFilterRequestList),// origin field filter and panel field filter, StringUtils.join(group, ","), StringUtils.join(order, ",")); if (sql.endsWith(",")) { @@ -197,6 +197,14 @@ public class SparkCalc { return " > "; case "ge": return " >= "; + case "in": + return " IN "; + case "not in": + return " NOT IN "; + case "like": + return " LIKE "; + case "not like": + return " NOT LIKE "; case "null": return " IS NULL "; case "not_null": @@ -205,4 +213,31 @@ public class SparkCalc { return ""; } } + + public String transExtFilter(List requestList) { + if (CollectionUtils.isEmpty(requestList)) { + return ""; + } + StringBuilder filter = new StringBuilder(); + for (ChartExtFilterRequest request : requestList) { + List value = request.getValue(); + if (CollectionUtils.isEmpty(value)) { + continue; + } + DatasetTableField field = request.getDatasetTableField(); + filter.append(" AND ") + .append(field.getOriginName()) + .append(" ") + .append(transFilterTerm(request.getOperator())) + .append(" "); + if (StringUtils.containsIgnoreCase(request.getOperator(), "in")) { + filter.append("('").append(StringUtils.join(value, "','")).append("')"); + } else if (StringUtils.containsIgnoreCase(request.getOperator(), "like")) { + filter.append("'%").append(value.get(0)).append("%'"); + } else { + filter.append("'").append(value.get(0)).append("'"); + } + } + return filter.toString(); + } } diff --git a/frontend/src/components/canvas/components/Editor/ContextMenu.vue b/frontend/src/components/canvas/components/Editor/ContextMenu.vue index e22d9b8742..423ac3d5e9 100644 --- a/frontend/src/components/canvas/components/Editor/ContextMenu.vue +++ b/frontend/src/components/canvas/components/Editor/ContextMenu.vue @@ -49,6 +49,9 @@ export default { this.$store.dispatch('chart/setViewId', this.curComponent.propValue.viewId) bus.$emit('PanelSwitchComponent', { name: 'ChartEdit' }) } + if (this.curComponent.type === 'custom') { + bus.$emit('component-dialog-edit') + } // 编辑组件 }, lock() { @@ -65,6 +68,7 @@ export default { }, cut() { + this.deleteCurCondition() this.$store.commit('cut') }, @@ -78,10 +82,17 @@ export default { }, deleteComponent() { + this.deleteCurCondition() this.$store.commit('deleteComponent') this.$store.commit('recordSnapshot') }, + deleteCurCondition() { + if (this.curComponent.type === 'custom') { + bus.$emit('delete-condition', { componentId: this.curComponent.id }) + } + }, + upComponent() { this.$store.commit('upComponent') this.$store.commit('recordSnapshot') diff --git a/frontend/src/components/canvas/components/Editor/MarkLine.vue b/frontend/src/components/canvas/components/Editor/MarkLine.vue index 2ba5233d75..7ad032c413 100644 --- a/frontend/src/components/canvas/components/Editor/MarkLine.vue +++ b/frontend/src/components/canvas/components/Editor/MarkLine.vue @@ -1,14 +1,14 @@ diff --git a/frontend/src/components/canvas/components/Editor/Preview.vue b/frontend/src/components/canvas/components/Editor/Preview.vue index eca610433c..b086c8ef74 100644 --- a/frontend/src/components/canvas/components/Editor/Preview.vue +++ b/frontend/src/components/canvas/components/Editor/Preview.vue @@ -61,13 +61,11 @@ export default { ]) }, mounted() { - debugger const _this = this const erd = elementResizeDetectorMaker() // 监听div变动事件 erd.listenTo(document.getElementById('canvasInfo'), element => { _this.$nextTick(() => { - debugger _this.restore() }) }) diff --git a/frontend/src/components/canvas/components/Editor/PreviewEject.vue b/frontend/src/components/canvas/components/Editor/PreviewEject.vue index 96b6db6fa7..59bb770dcd 100644 --- a/frontend/src/components/canvas/components/Editor/PreviewEject.vue +++ b/frontend/src/components/canvas/components/Editor/PreviewEject.vue @@ -71,7 +71,6 @@ export default { }) }) window.onresize = () => { - debugger this.resize() } // this.resize() @@ -88,7 +87,6 @@ export default { this.handleScaleChange() }, restore() { - debugger this.panelId = this.$route.path.split('/')[2] // 加载视图数据 get('panel/group/findOne/' + this.panelId).then(response => { diff --git a/frontend/src/components/canvas/components/Editor/PreviewFullScreen.vue b/frontend/src/components/canvas/components/Editor/PreviewFullScreen.vue index d14a926e07..a3ba065164 100644 --- a/frontend/src/components/canvas/components/Editor/PreviewFullScreen.vue +++ b/frontend/src/components/canvas/components/Editor/PreviewFullScreen.vue @@ -19,7 +19,6 @@ export default { methods: { toDir() { - debugger this.$router.replace('/panel/index') bus.$emit('PanelSwitchComponent', { name: 'PanelEdit' }) } diff --git a/frontend/src/components/canvas/components/Editor/Shape.vue b/frontend/src/components/canvas/components/Editor/Shape.vue index c2ebc6bc61..9db1a349d0 100644 --- a/frontend/src/components/canvas/components/Editor/Shape.vue +++ b/frontend/src/components/canvas/components/Editor/Shape.vue @@ -3,13 +3,13 @@ - - - - - - - + + + + + + +
{ diff --git a/frontend/src/components/canvas/components/Editor/index.vue b/frontend/src/components/canvas/components/Editor/index.vue index 06efece521..3c6c103ced 100644 --- a/frontend/src/components/canvas/components/Editor/index.vue +++ b/frontend/src/components/canvas/components/Editor/index.vue @@ -25,14 +25,14 @@ :class="{ lock: item.isLock }" > - import { mapState } from 'vuex' import Shape from './Shape' +// eslint-disable-next-line no-unused-vars import { getStyle, getComponentRotatedStyle } from '@/components/canvas/utils/style' import { $ } from '@/components/canvas/utils/utils' import ContextMenu from './ContextMenu' @@ -75,7 +76,8 @@ import Area from './Area' import eventBus from '@/components/canvas/utils/eventBus' import Grid from './Grid' import { changeStyleWithScale } from '@/components/canvas/utils/translate' - +import { Condition } from '@/components/widget/bean/Condition' +import bus from '@/utils/bus' export default { components: { Shape, ContextMenu, MarkLine, Area, Grid }, props: { @@ -94,15 +96,22 @@ export default { }, width: 0, height: 0, - isShowArea: false + isShowArea: false, + conditions: [] } }, - computed: mapState([ - 'componentData', - 'curComponent', - 'canvasStyleData', - 'editor' - ]), + computed: { + panelInfo() { + return this.$store.state.panel.panelInfo + }, + ...mapState([ + 'componentData', + 'curComponent', + 'canvasStyleData', + 'editor' + ]) + }, + mounted() { // 获取编辑器元素 this.$store.commit('getEditor') @@ -110,6 +119,9 @@ export default { eventBus.$on('hideArea', () => { this.hideArea() }) + bus.$on('delete-condition', condition => { + this.deleteCondition(condition) + }) }, methods: { changeStyleWithScale, @@ -275,7 +287,8 @@ export default { }, getComponentStyle(style) { - return getStyle(style, ['top', 'left', 'width', 'height', 'rotate']) + // return getStyle(style, ['top', 'left', 'width', 'height', 'rotate']) + return style }, handleInput(element, value) { @@ -284,6 +297,7 @@ export default { }, getTextareaHeight(element, text) { + // eslint-disable-next-line prefer-const let { lineHeight, fontSize, height } = element.style if (lineHeight === '') { lineHeight = 1.5 @@ -295,6 +309,28 @@ export default { filterValueChange(value) { console.log('emit:' + value) + }, + + setConditionValue(obj) { + const { component, value, operator } = obj + const fieldId = component.options.attrs.fieldId + const condition = new Condition(component.id, fieldId, operator, value, null) + this.addCondition(condition) + }, + addCondition(condition) { + this.conditions.push(condition) + this.executeSearch() + }, + deleteCondition(condition) { + this.conditions = this.conditions.filter(item => { + const componentIdSuitable = !condition.componentId || (item.componentId === condition.componentId) + const fieldIdSuitable = !condition.fieldId || (item.fieldId === condition.fieldId) + return !(componentIdSuitable && fieldIdSuitable) + }) + this.executeSearch() + }, + executeSearch() { + console.log('当前查询条件是: ' + JSON.stringify(this.conditions)) } } } diff --git a/frontend/src/components/canvas/components/Toolbar.vue b/frontend/src/components/canvas/components/Toolbar.vue index a55f26dc89..9342e441e7 100644 --- a/frontend/src/components/canvas/components/Toolbar.vue +++ b/frontend/src/components/canvas/components/Toolbar.vue @@ -228,8 +228,8 @@ export default { float: right; height: 35px; line-height: 35px; - background: #fff; - border-bottom: 1px solid #ddd; + /*background: #fff;*/ + /*border-bottom: 1px solid #ddd;*/ .canvas-config { display: inline-block; diff --git a/frontend/src/components/canvas/store/compose.js b/frontend/src/components/canvas/store/compose.js index 2166b54bdc..c130e800e9 100644 --- a/frontend/src/components/canvas/store/compose.js +++ b/frontend/src/components/canvas/store/compose.js @@ -6,95 +6,95 @@ import { $ } from '@/components/canvas/utils/utils' import { commonStyle, commonAttr } from '@/components/canvas/custom-component/component-list' export default { - state: { - areaData: { // 选中区域包含的组件以及区域位移信息 - style: { - top: 0, - left: 0, - width: 0, - height: 0, - }, - components: [], - }, - editor: null, + state: { + areaData: { // 选中区域包含的组件以及区域位移信息 + style: { + top: 0, + left: 0, + width: 0, + height: 0 + }, + components: [] }, - mutations: { - getEditor(state) { - state.editor = $('#editor') - }, - - setAreaData(state, data) { - state.areaData = data - }, - - compose({ componentData, areaData, editor }) { - const components = [] - areaData.components.forEach(component => { - if (component.component != 'Group') { - components.push(component) - } else { - // 如果要组合的组件中,已经存在组合数据,则需要提前拆分 - const parentStyle = { ...component.style } - const subComponents = component.propValue - const editorRect = editor.getBoundingClientRect() - - store.commit('deleteComponent') - subComponents.forEach(component => { - decomposeComponent(component, editorRect, parentStyle) - store.commit('addComponent', { component }) - }) - - components.push(...component.propValue) - store.commit('batchDeleteComponent', component.propValue) - } - }) - - store.commit('addComponent', { - component: { - id: generateID(), - component: 'Group', - ...commonAttr, - style: { - ...commonStyle, - ...areaData.style, - }, - propValue: components, - }, - }) - - eventBus.$emit('hideArea') - - store.commit('batchDeleteComponent', areaData.components) - store.commit('setCurComponent', { - component: componentData[componentData.length - 1], - index: componentData.length - 1, - }) - - areaData.components = [] - }, - - // 将已经放到 Group 组件数据删除,也就是在 componentData 中删除,因为它们已经放到 Group 组件中了 - batchDeleteComponent({ componentData }, deleteData) { - deleteData.forEach(component => { - for (let i = 0, len = componentData.length; i < len; i++) { - if (component.id == componentData[i].id) { - componentData.splice(i, 1) - break - } - } - }) - }, - - decompose({ curComponent, editor }) { - const parentStyle = { ...curComponent.style } - const components = curComponent.propValue - const editorRect = editor.getBoundingClientRect() - - store.commit('deleteComponent') - components.forEach(component => { - decomposeComponent(component, editorRect, parentStyle) - store.commit('addComponent', { component }) - }) - }, + editor: null + }, + mutations: { + getEditor(state) { + state.editor = $('#editor') }, + + setAreaData(state, data) { + state.areaData = data + }, + + compose({ componentData, areaData, editor }) { + const components = [] + areaData.components.forEach(component => { + if (component.component !== 'Group') { + components.push(component) + } else { + // 如果要组合的组件中,已经存在组合数据,则需要提前拆分 + const parentStyle = { ...component.style } + const subComponents = component.propValue + const editorRect = editor.getBoundingClientRect() + + store.commit('deleteComponent') + subComponents.forEach(component => { + decomposeComponent(component, editorRect, parentStyle) + store.commit('addComponent', { component }) + }) + + components.push(...component.propValue) + store.commit('batchDeleteComponent', component.propValue) + } + }) + + store.commit('addComponent', { + component: { + id: generateID(), + component: 'Group', + ...commonAttr, + style: { + ...commonStyle, + ...areaData.style + }, + propValue: components + } + }) + + eventBus.$emit('hideArea') + + store.commit('batchDeleteComponent', areaData.components) + store.commit('setCurComponent', { + component: componentData[componentData.length - 1], + index: componentData.length - 1 + }) + + areaData.components = [] + }, + + // 将已经放到 Group 组件数据删除,也就是在 componentData 中删除,因为它们已经放到 Group 组件中了 + batchDeleteComponent({ componentData }, deleteData) { + deleteData.forEach(component => { + for (let i = 0, len = componentData.length; i < len; i++) { + if (component.id == componentData[i].id) { + componentData.splice(i, 1) + break + } + } + }) + }, + + decompose({ curComponent, editor }) { + const parentStyle = { ...curComponent.style } + const components = curComponent.propValue + const editorRect = editor.getBoundingClientRect() + + store.commit('deleteComponent') + components.forEach(component => { + decomposeComponent(component, editorRect, parentStyle) + store.commit('addComponent', { component }) + }) + } + } } diff --git a/frontend/src/components/canvas/utils/style.js b/frontend/src/components/canvas/utils/style.js index 3b1fd50f71..f426d07177 100644 --- a/frontend/src/components/canvas/utils/style.js +++ b/frontend/src/components/canvas/utils/style.js @@ -1,55 +1,55 @@ import { sin, cos } from '@/components/canvas/utils/translate' export function getStyle(style, filter = []) { - const needUnit = [ - 'fontSize', - 'width', - 'height', - 'top', - 'left', - 'borderWidth', - 'letterSpacing', - 'borderRadius', - ] + const needUnit = [ + 'fontSize', + 'width', + 'height', + 'top', + 'left', + 'borderWidth', + 'letterSpacing', + 'borderRadius' + ] - const result = {} - Object.keys(style).forEach(key => { - if (!filter.includes(key)) { - if (key != 'rotate') { - result[key] = style[key] + const result = {} + Object.keys(style).forEach(key => { + if (!filter.includes(key)) { + if (key !== 'rotate') { + result[key] = style[key] - if (needUnit.includes(key)) { - result[key] += 'px' - } - } else { - result.transform = key + '(' + style[key] + 'deg)' - } + if (needUnit.includes(key)) { + result[key] += 'px' } - }) + } else { + result.transform = key + '(' + style[key] + 'deg)' + } + } + }) - return result + return result } // 获取一个组件旋转 rotate 后的样式 export function getComponentRotatedStyle(style) { - style = { ...style } - if (style.rotate != 0) { - const newWidth = style.width * cos(style.rotate) + style.height * sin(style.rotate) - const diffX = (style.width - newWidth) / 2 // 旋转后范围变小是正值,变大是负值 - style.left += diffX - style.right = style.left + newWidth + style = { ...style } + if (style.rotate != 0) { + const newWidth = style.width * cos(style.rotate) + style.height * sin(style.rotate) + const diffX = (style.width - newWidth) / 2 // 旋转后范围变小是正值,变大是负值 + style.left += diffX + style.right = style.left + newWidth - const newHeight = style.height * cos(style.rotate) + style.width * sin(style.rotate) - const diffY = (newHeight - style.height) / 2 // 始终是正 - style.top -= diffY - style.bottom = style.top + newHeight + const newHeight = style.height * cos(style.rotate) + style.width * sin(style.rotate) + const diffY = (newHeight - style.height) / 2 // 始终是正 + style.top -= diffY + style.bottom = style.top + newHeight - style.width = newWidth - style.height = newHeight - } else { - style.bottom = style.top + style.height - style.right = style.left + style.width - } + style.width = newWidth + style.height = newHeight + } else { + style.bottom = style.top + style.height + style.right = style.left + style.width + } - return style + return style } diff --git a/frontend/src/components/widget/DeWidget/DeDrawingWidget.vue b/frontend/src/components/widget/DeWidget/DeDrawingWidget.vue index ab37b9d57d..0cebb0cd2d 100644 --- a/frontend/src/components/widget/DeWidget/DeDrawingWidget.vue +++ b/frontend/src/components/widget/DeWidget/DeDrawingWidget.vue @@ -1,20 +1,30 @@ + + diff --git a/frontend/src/views/dataset/data/ViewTable.vue b/frontend/src/views/dataset/data/ViewTable.vue index f737ac8b96..d811a826a8 100644 --- a/frontend/src/views/dataset/data/ViewTable.vue +++ b/frontend/src/views/dataset/data/ViewTable.vue @@ -3,9 +3,18 @@ {{ tableId }} - - {{ table.name }} - + + + + {{ table.name }} + + {{ $t('dataset.edit_sql') }} @@ -81,10 +90,11 @@ import { getTable, getPreviewData, fieldList, batchEdit } from '@/api/dataset/dataset' import TabDataPreview from './TabDataPreview' import UpdateInfo from './UpdateInfo' +import DatasetChartDetail from '../common/DatasetChartDetail' export default { name: 'ViewTable', - components: { UpdateInfo, TabDataPreview }, + components: { DatasetChartDetail, UpdateInfo, TabDataPreview }, data() { return { createViewDialog: false, @@ -98,7 +108,8 @@ export default { tableFields: [], tableViewRowForm: { row: 1000 - } + }, + tabStatus: false } }, computed: { @@ -173,6 +184,13 @@ export default { reSearch(val) { this.tableViewRowForm = val this.initPreviewData() + }, + + showTab() { + this.tabStatus = true + }, + hideTab() { + this.tabStatus = false } } } diff --git a/frontend/src/views/panel/edit/index.vue b/frontend/src/views/panel/edit/index.vue index ec0a689730..55d52cf9d5 100644 --- a/frontend/src/views/panel/edit/index.vue +++ b/frontend/src/views/panel/edit/index.vue @@ -69,19 +69,25 @@ - - + +
@@ -144,7 +147,7 @@ import DeContainer from '@/components/dataease/DeContainer' import DeAsideContainer from '@/components/dataease/DeAsideContainer' import draggable from 'vuedraggable' import DragItem from '@/components/DragItem' -import { ApplicationContext } from '@/utils/ApplicationContext' +// import { ApplicationContext } from '@/utils/ApplicationContext' import { groupTree, loadTable, fieldList, fieldValues } from '@/api/dataset/dataset' export default { name: 'FilterDialog', @@ -156,8 +159,9 @@ export default { DragItem }, props: { - widgetId: { - type: String, + + widgetInfo: { + type: Object, default: null }, componentInfo: { @@ -181,27 +185,34 @@ export default { }, selectField: [], widget: null, - fieldValues: [] + fieldValues: [], + customRange: false } }, + watch: { selectField(values) { if (values && values.length > 0) { const value = values[0] const fieldId = value.id - this.componentInfo && this.componentInfo.setOptionDatas && fieldValues(fieldId).then(res => { - const datas = res.data.map(item => { - return { id: item, text: item } - }) - this.componentInfo.setOptionDatas(datas) - this.$emit('re-fresh-component', this.componentInfo) + const info = this.componentInfo + this.widget && fieldValues(fieldId).then(res => { + info.options.attrs.datas = this.widget.optionDatas(res.data) + info.options.attrs.fieldId = fieldId + info.options.attrs.dragItems = values + this.$emit('re-fresh-component', info) }) } } }, created() { - this.widget = ApplicationContext.getService(this.widgetId) + // this.widget = ApplicationContext.getService(this.widgetId) + this.widget = this.widgetInfo this.loadDataSetTree() + + if (this.componentInfo && this.componentInfo.options.attrs.dragItems) { + this.selectField = this.componentInfo.options.attrs.dragItems + } }, methods: { @@ -322,6 +333,12 @@ export default { closeItem(tag) { const index = tag.index this.selectField.splice(index, 1) + }, + showFilterRange() { + // 如果不是自定义范围 直接返回 + if (!this.customRange) { + return + } } } } @@ -454,5 +471,17 @@ export default { width: 100%; height: 100%; } + .i-filter { + text-align: center; + margin-left: 5px; + margin-top: 1px; + } + .i-filter-inactive { + color: #9ea6b2!important; + cursor: not-allowed!important; + } + .i-filter-active { + cursor: pointer!important; + } diff --git a/frontend/src/views/panel/filter/index.vue b/frontend/src/views/panel/filter/index.vue index 4333644dcb..18c9a9f3f0 100644 --- a/frontend/src/views/panel/filter/index.vue +++ b/frontend/src/views/panel/filter/index.vue @@ -10,8 +10,8 @@
{ const widget = ApplicationContext.getService(widgetName) - return widget + const result = { widgetName: widgetName } + Object.assign(result, widget.getLeftPanel()) + return result }) } },