forked from github/dataease
Merge remote-tracking branch 'origin/main' into main
# Conflicts: # frontend/src/views/panel/list/PanelViewShow.vue
This commit is contained in:
commit
f4f43a47aa
@ -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;
|
||||
}
|
||||
|
@ -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<String, Object> chartDetail(@PathVariable String id) {
|
||||
return chartViewService.getChartDetail(id);
|
||||
}
|
||||
}
|
||||
|
@ -82,4 +82,8 @@ public class DataSetTableController {
|
||||
dataSetTableService.saveIncrementalConfig(datasetTableIncrementalConfig);
|
||||
}
|
||||
|
||||
@PostMapping("datasetDetail/{id}")
|
||||
public Map<String, Object> datasetDetail(@PathVariable String id) {
|
||||
return dataSetTableService.getDatasetDetail(id);
|
||||
}
|
||||
}
|
||||
|
@ -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<String> value;
|
||||
private List<String> viewIds;
|
||||
private DatasetTableField datasetTableField;
|
||||
}
|
@ -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<ChartExtFilterRequest> filter;
|
||||
}
|
@ -19,7 +19,7 @@ public abstract class DatasourceProvider {
|
||||
|
||||
abstract public List<String> getTables(DatasourceRequest datasourceRequest) throws Exception;
|
||||
|
||||
public List<TableFiled> getTableFileds(DatasourceRequest datasourceRequest) throws Exception{
|
||||
public List<TableFiled> 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<String[]> getPageData(DatasourceRequest datasourceRequest) throws Exception;
|
||||
|
||||
@ -35,4 +35,5 @@ public abstract class DatasourceProvider {
|
||||
|
||||
abstract public List<TableFiled> fetchResultField(ResultSet rs) throws Exception;
|
||||
|
||||
abstract public void initConnectionPool(DatasourceRequest datasourceRequest) throws Exception;
|
||||
}
|
||||
|
@ -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<String, ArrayBlockingQueue<Connection>> jdbcConnection = new HashMap<>();
|
||||
private static int poolSize = 20;
|
||||
@Override
|
||||
public List<String[]> getData(DatasourceRequest datasourceRequest) throws Exception {
|
||||
List<String[]> 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<String[]> getPageData(DatasourceRequest datasourceRequest) throws Exception {
|
||||
List<String[]> 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<String> getTables(DatasourceRequest datasourceRequest) throws Exception {
|
||||
List<String> 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<TableFiled> getTableFileds(DatasourceRequest datasourceRequest) throws Exception {
|
||||
List<TableFiled> 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<Connection> connections = jdbcConnection.get(dataSourceId);
|
||||
connections.put(connection);
|
||||
}
|
||||
}
|
||||
|
||||
private Connection getConnectionFromPool(DatasourceRequest datasourceRequest)throws Exception {
|
||||
ArrayBlockingQueue<Connection> 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<Connection> 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;
|
||||
|
@ -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<Datasource> 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();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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<ApplicationReadyEvent> {
|
||||
@Resource
|
||||
private DatasourceService datasourceService;
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
|
||||
System.out.println("================= Init datasource connection pool =================");
|
||||
// 项目启动,从数据集中找到定时抽取的表,从HBase中读取放入缓存
|
||||
datasourceService.initAllDataSourceConnectionPool();
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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<Applicatio
|
||||
datasetTableExample.createCriteria().andModeEqualTo(1);
|
||||
List<DatasetTable> datasetTables = datasetTableMapper.selectByExampleWithBLOBs(datasetTableExample);
|
||||
for (DatasetTable table : datasetTables) {
|
||||
commonThreadPool.addTask(() -> {
|
||||
// commonThreadPool.addTask(() -> {
|
||||
try {
|
||||
List<DatasetTableField> fields = dataSetTableFieldsService.getFieldsByTableId(table.getId());
|
||||
sparkCalc.getHBaseDataAndCache(table.getId(), fields);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
// });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<ChartViewFieldDTO> xAxis = new Gson().fromJson(view.getXAxis(), new TypeToken<List<ChartViewFieldDTO>>() {
|
||||
}.getType());
|
||||
@ -107,6 +109,24 @@ public class ChartViewService {
|
||||
// List<DatasetTableField> xList = dataSetTableFieldsService.getListByIds(xIds);
|
||||
// List<DatasetTableField> yList = dataSetTableFieldsService.getListByIds(yIds);
|
||||
|
||||
// 过滤来自仪表盘的条件
|
||||
List<ChartExtFilterRequest> 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<DatasetTableField> 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<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis) {
|
||||
public String transMysqlExtFilter(List<ChartExtFilterRequest> requestList) {
|
||||
if (CollectionUtils.isEmpty(requestList)) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder filter = new StringBuilder();
|
||||
for (ChartExtFilterRequest request : requestList) {
|
||||
List<String> 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<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartExtFilterRequest> 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<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis) {
|
||||
public String transMysqlSQL(String table, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<ChartExtFilterRequest> 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<String, Object> getChartDetail(String id) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
ChartViewWithBLOBs chartViewWithBLOBs = chartViewMapper.selectByPrimaryKey(id);
|
||||
map.put("chart", chartViewWithBLOBs);
|
||||
if (ObjectUtils.isNotEmpty(chartViewWithBLOBs)) {
|
||||
Map<String, Object> datasetDetail = dataSetTableService.getDatasetDetail(chartViewWithBLOBs.getTableId());
|
||||
map.putAll(datasetDetail);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
@ -66,4 +66,8 @@ public class DataSetTableFieldsService {
|
||||
datasetTableFieldExample.createCriteria().andTableIdEqualTo(id);
|
||||
return datasetTableFieldMapper.selectByExample(datasetTableFieldExample);
|
||||
}
|
||||
|
||||
public DatasetTableField get(String id) {
|
||||
return datasetTableFieldMapper.selectByPrimaryKey(id);
|
||||
}
|
||||
}
|
||||
|
@ -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<String, Object> getDatasetDetail(String id) {
|
||||
Map<String, Object> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class PanelGroupService {
|
||||
return panelGroupDTOList;
|
||||
}
|
||||
|
||||
public void getTreeChildren(List<PanelGroupDTO> parentPanelGroupDTO){
|
||||
public void getTreeChildren(List<PanelGroupDTO> parentPanelGroupDTO) {
|
||||
Optional.ofNullable(parentPanelGroupDTO).ifPresent(parent -> parent.forEach(panelGroupDTO -> {
|
||||
List<PanelGroupDTO> panelGroupDTOChildren = extPanelGroupMapper.panelGroupList(new PanelGroupRequest(panelGroupDTO.getId()));
|
||||
panelGroupDTO.setChildren(panelGroupDTOChildren);
|
||||
@ -66,7 +66,7 @@ public class PanelGroupService {
|
||||
}));
|
||||
}
|
||||
|
||||
public List<PanelGroupDTO> getDefaultTree(PanelGroupRequest panelGroupRequest){
|
||||
public List<PanelGroupDTO> 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<PanelDesign> panelDesignList = panelDesignMapper.selectByExample(panelDesignExample);
|
||||
if(CollectionUtils.isNotEmpty(panelDesignList)){
|
||||
List<PanelDesign> panelDesignList = panelDesignMapper.selectByExample(panelDesignExample);
|
||||
if (CollectionUtils.isNotEmpty(panelDesignList)) {
|
||||
List<PanelDesignDTO> 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<ChartViewDTO> getUsableViews(String panelId) throws Exception{
|
||||
public List<ChartViewDTO> getUsableViews(String panelId) throws Exception {
|
||||
List<ChartViewDTO> chartViewDTOList = new ArrayList<>();
|
||||
List<ChartView> 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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<String[]> getData(String hTable, List<DatasetTableField> fields, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, String tmpTable) throws Exception {
|
||||
public List<String[]> getData(String hTable, List<DatasetTableField> fields, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, String tmpTable, List<ChartExtFilterRequest> 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<Row> sql = sqlContext.sql(getSQL(xAxis, yAxis, tmpTable));
|
||||
Dataset<Row> sql = sqlContext.sql(getSQL(xAxis, yAxis, tmpTable, requestList));
|
||||
// transform
|
||||
List<String[]> data = new ArrayList<>();
|
||||
List<Row> 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<Row> getHBaseDataAndCache(JavaSparkContext sparkContext, SQLContext sqlContext, String hTable, List<DatasetTableField> 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<Row> dataFrame = sqlContext.createDataFrame(rdd, structType).persist();
|
||||
Dataset<Row> dataFrame = sqlContext.createDataFrame(rdd, structType).persist(StorageLevel.MEMORY_AND_DISK_SER());
|
||||
CacheUtil.getInstance().addCacheData(hTable, dataFrame);
|
||||
dataFrame.count();
|
||||
return dataFrame;
|
||||
}
|
||||
|
||||
public String getSQL(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, String table) {
|
||||
public String getSQL(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, String table, List<ChartExtFilterRequest> 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<ChartExtFilterRequest> requestList) {
|
||||
if (CollectionUtils.isEmpty(requestList)) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder filter = new StringBuilder();
|
||||
for (ChartExtFilterRequest request : requestList) {
|
||||
List<String> 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();
|
||||
}
|
||||
}
|
||||
|
@ -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')
|
||||
|
@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<div class="mark-line">
|
||||
<div
|
||||
v-for="line in lines"
|
||||
:key="line"
|
||||
class="line"
|
||||
:class="line.includes('x')? 'xline' : 'yline'"
|
||||
:ref="line"
|
||||
v-show="lineStatus[line] || false"
|
||||
></div>
|
||||
</div>
|
||||
<div class="mark-line">
|
||||
<div
|
||||
v-for="line in lines"
|
||||
v-show="lineStatus[line] || false"
|
||||
:key="line"
|
||||
:ref="line"
|
||||
class="line"
|
||||
:class="line.includes('x')? 'xline' : 'yline'"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -17,215 +17,215 @@ import { mapState } from 'vuex'
|
||||
import { getComponentRotatedStyle } from '@/components/canvas/utils/style'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lines: ['xt', 'xc', 'xb', 'yl', 'yc', 'yr'], // 分别对应三条横线和三条竖线
|
||||
diff: 3, // 相距 dff 像素将自动吸附
|
||||
lineStatus: {
|
||||
xt: false,
|
||||
xc: false,
|
||||
xb: false,
|
||||
yl: false,
|
||||
yc: false,
|
||||
yr: false,
|
||||
data() {
|
||||
return {
|
||||
lines: ['xt', 'xc', 'xb', 'yl', 'yc', 'yr'], // 分别对应三条横线和三条竖线
|
||||
diff: 3, // 相距 dff 像素将自动吸附
|
||||
lineStatus: {
|
||||
xt: false,
|
||||
xc: false,
|
||||
xb: false,
|
||||
yl: false,
|
||||
yc: false,
|
||||
yr: false
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: mapState([
|
||||
'curComponent',
|
||||
'componentData'
|
||||
]),
|
||||
mounted() {
|
||||
// 监听元素移动和不移动的事件
|
||||
eventBus.$on('move', (isDownward, isRightward) => {
|
||||
this.showLine(isDownward, isRightward)
|
||||
})
|
||||
|
||||
eventBus.$on('unmove', () => {
|
||||
this.hideLine()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
hideLine() {
|
||||
Object.keys(this.lineStatus).forEach(line => {
|
||||
this.lineStatus[line] = false
|
||||
})
|
||||
},
|
||||
|
||||
showLine(isDownward, isRightward) {
|
||||
const lines = this.$refs
|
||||
const components = this.componentData
|
||||
const curComponentStyle = getComponentRotatedStyle(this.curComponent.style)
|
||||
const curComponentHalfwidth = curComponentStyle.width / 2
|
||||
const curComponentHalfHeight = curComponentStyle.height / 2
|
||||
|
||||
this.hideLine()
|
||||
components.forEach(component => {
|
||||
if (component === this.curComponent) return
|
||||
const componentStyle = getComponentRotatedStyle(component.style)
|
||||
const { top, left, bottom, right } = componentStyle
|
||||
const componentHalfwidth = componentStyle.width / 2
|
||||
const componentHalfHeight = componentStyle.height / 2
|
||||
|
||||
const conditions = {
|
||||
top: [
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.top, top),
|
||||
lineNode: lines.xt[0], // xt
|
||||
line: 'xt',
|
||||
dragShift: top,
|
||||
lineShift: top
|
||||
},
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.bottom, top),
|
||||
lineNode: lines.xt[0], // xt
|
||||
line: 'xt',
|
||||
dragShift: top - curComponentStyle.height,
|
||||
lineShift: top
|
||||
},
|
||||
{
|
||||
// 组件与拖拽节点的中间是否对齐
|
||||
isNearly: this.isNearly(curComponentStyle.top + curComponentHalfHeight, top + componentHalfHeight),
|
||||
lineNode: lines.xc[0], // xc
|
||||
line: 'xc',
|
||||
dragShift: top + componentHalfHeight - curComponentHalfHeight,
|
||||
lineShift: top + componentHalfHeight
|
||||
},
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.top, bottom),
|
||||
lineNode: lines.xb[0], // xb
|
||||
line: 'xb',
|
||||
dragShift: bottom,
|
||||
lineShift: bottom
|
||||
},
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.bottom, bottom),
|
||||
lineNode: lines.xb[0], // xb
|
||||
line: 'xb',
|
||||
dragShift: bottom - curComponentStyle.height,
|
||||
lineShift: bottom
|
||||
}
|
||||
],
|
||||
left: [
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.left, left),
|
||||
lineNode: lines.yl[0], // yl
|
||||
line: 'yl',
|
||||
dragShift: left,
|
||||
lineShift: left
|
||||
},
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.right, left),
|
||||
lineNode: lines.yl[0], // yl
|
||||
line: 'yl',
|
||||
dragShift: left - curComponentStyle.width,
|
||||
lineShift: left
|
||||
},
|
||||
{
|
||||
// 组件与拖拽节点的中间是否对齐
|
||||
isNearly: this.isNearly(curComponentStyle.left + curComponentHalfwidth, left + componentHalfwidth),
|
||||
lineNode: lines.yc[0], // yc
|
||||
line: 'yc',
|
||||
dragShift: left + componentHalfwidth - curComponentHalfwidth,
|
||||
lineShift: left + componentHalfwidth
|
||||
},
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.left, right),
|
||||
lineNode: lines.yr[0], // yr
|
||||
line: 'yr',
|
||||
dragShift: right,
|
||||
lineShift: right
|
||||
},
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.right, right),
|
||||
lineNode: lines.yr[0], // yr
|
||||
line: 'yr',
|
||||
dragShift: right - curComponentStyle.width,
|
||||
lineShift: right
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: mapState([
|
||||
'curComponent',
|
||||
'componentData',
|
||||
]),
|
||||
mounted() {
|
||||
// 监听元素移动和不移动的事件
|
||||
eventBus.$on('move', (isDownward, isRightward) => {
|
||||
this.showLine(isDownward, isRightward)
|
||||
|
||||
const needToShow = []
|
||||
const { rotate } = this.curComponent.style
|
||||
Object.keys(conditions).forEach(key => {
|
||||
// 遍历符合的条件并处理
|
||||
conditions[key].forEach((condition) => {
|
||||
if (!condition.isNearly) return
|
||||
// 修改当前组件位移
|
||||
this.$store.commit('setShapeSingleStyle', {
|
||||
key,
|
||||
value: rotate !== 0 ? this.translatecurComponentShift(key, condition, curComponentStyle) : condition.dragShift
|
||||
})
|
||||
|
||||
condition.lineNode && (condition.lineNode.style[key] = `${condition.lineShift}px`)
|
||||
needToShow.push(condition.line)
|
||||
})
|
||||
})
|
||||
|
||||
eventBus.$on('unmove', () => {
|
||||
this.hideLine()
|
||||
})
|
||||
// 同一方向上同时显示三条线可能不太美观,因此才有了这个解决方案
|
||||
// 同一方向上的线只显示一条,例如多条横条只显示一条横线
|
||||
if (needToShow.length) {
|
||||
this.chooseTheTureLine(needToShow, isDownward, isRightward)
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
hideLine() {
|
||||
Object.keys(this.lineStatus).forEach(line => {
|
||||
this.lineStatus[line] = false
|
||||
})
|
||||
},
|
||||
|
||||
showLine(isDownward, isRightward) {
|
||||
const lines = this.$refs
|
||||
const components = this.componentData
|
||||
const curComponentStyle = getComponentRotatedStyle(this.curComponent.style)
|
||||
const curComponentHalfwidth = curComponentStyle.width / 2
|
||||
const curComponentHalfHeight = curComponentStyle.height / 2
|
||||
translatecurComponentShift(key, condition, curComponentStyle) {
|
||||
const { width, height } = this.curComponent.style
|
||||
if (key === 'top') {
|
||||
return Math.round(condition.dragShift - (height - curComponentStyle.height) / 2)
|
||||
}
|
||||
|
||||
this.hideLine()
|
||||
components.forEach(component => {
|
||||
if (component == this.curComponent) return
|
||||
const componentStyle = getComponentRotatedStyle(component.style)
|
||||
const { top, left, bottom, right } = componentStyle
|
||||
const componentHalfwidth = componentStyle.width / 2
|
||||
const componentHalfHeight = componentStyle.height / 2
|
||||
|
||||
const conditions = {
|
||||
top: [
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.top, top),
|
||||
lineNode: lines.xt[0], // xt
|
||||
line: 'xt',
|
||||
dragShift: top,
|
||||
lineShift: top,
|
||||
},
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.bottom, top),
|
||||
lineNode: lines.xt[0], // xt
|
||||
line: 'xt',
|
||||
dragShift: top - curComponentStyle.height,
|
||||
lineShift: top,
|
||||
},
|
||||
{
|
||||
// 组件与拖拽节点的中间是否对齐
|
||||
isNearly: this.isNearly(curComponentStyle.top + curComponentHalfHeight, top + componentHalfHeight),
|
||||
lineNode: lines.xc[0], // xc
|
||||
line: 'xc',
|
||||
dragShift: top + componentHalfHeight - curComponentHalfHeight,
|
||||
lineShift: top + componentHalfHeight,
|
||||
},
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.top, bottom),
|
||||
lineNode: lines.xb[0], // xb
|
||||
line: 'xb',
|
||||
dragShift: bottom,
|
||||
lineShift: bottom,
|
||||
},
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.bottom, bottom),
|
||||
lineNode: lines.xb[0], // xb
|
||||
line: 'xb',
|
||||
dragShift: bottom - curComponentStyle.height,
|
||||
lineShift: bottom,
|
||||
},
|
||||
],
|
||||
left: [
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.left, left),
|
||||
lineNode: lines.yl[0], // yl
|
||||
line: 'yl',
|
||||
dragShift: left,
|
||||
lineShift: left,
|
||||
},
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.right, left),
|
||||
lineNode: lines.yl[0], // yl
|
||||
line: 'yl',
|
||||
dragShift: left - curComponentStyle.width,
|
||||
lineShift: left,
|
||||
},
|
||||
{
|
||||
// 组件与拖拽节点的中间是否对齐
|
||||
isNearly: this.isNearly(curComponentStyle.left + curComponentHalfwidth, left + componentHalfwidth),
|
||||
lineNode: lines.yc[0], // yc
|
||||
line: 'yc',
|
||||
dragShift: left + componentHalfwidth - curComponentHalfwidth,
|
||||
lineShift: left + componentHalfwidth,
|
||||
},
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.left, right),
|
||||
lineNode: lines.yr[0], // yr
|
||||
line: 'yr',
|
||||
dragShift: right,
|
||||
lineShift: right,
|
||||
},
|
||||
{
|
||||
isNearly: this.isNearly(curComponentStyle.right, right),
|
||||
lineNode: lines.yr[0], // yr
|
||||
line: 'yr',
|
||||
dragShift: right - curComponentStyle.width,
|
||||
lineShift: right,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const needToShow = []
|
||||
const { rotate } = this.curComponent.style
|
||||
Object.keys(conditions).forEach(key => {
|
||||
// 遍历符合的条件并处理
|
||||
conditions[key].forEach((condition) => {
|
||||
if (!condition.isNearly) return
|
||||
// 修改当前组件位移
|
||||
this.$store.commit('setShapeSingleStyle', {
|
||||
key,
|
||||
value: rotate !== 0? this.translatecurComponentShift(key, condition, curComponentStyle) : condition.dragShift,
|
||||
})
|
||||
|
||||
condition.lineNode.style[key] = `${condition.lineShift}px`
|
||||
needToShow.push(condition.line)
|
||||
})
|
||||
})
|
||||
|
||||
// 同一方向上同时显示三条线可能不太美观,因此才有了这个解决方案
|
||||
// 同一方向上的线只显示一条,例如多条横条只显示一条横线
|
||||
if (needToShow.length) {
|
||||
this.chooseTheTureLine(needToShow, isDownward, isRightward)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
translatecurComponentShift(key, condition, curComponentStyle) {
|
||||
const { width, height } = this.curComponent.style
|
||||
if (key === 'top') {
|
||||
return Math.round(condition.dragShift - (height - curComponentStyle.height) / 2)
|
||||
}
|
||||
|
||||
return Math.round(condition.dragShift - (width - curComponentStyle.width) / 2)
|
||||
},
|
||||
|
||||
chooseTheTureLine(needToShow, isDownward, isRightward) {
|
||||
// 如果鼠标向右移动 则按从右到左的顺序显示竖线 否则按相反顺序显示
|
||||
// 如果鼠标向下移动 则按从下到上的顺序显示横线 否则按相反顺序显示
|
||||
if (isRightward) {
|
||||
if (needToShow.includes('yr')) {
|
||||
this.lineStatus.yr = true
|
||||
} else if (needToShow.includes('yc')) {
|
||||
this.lineStatus.yc = true
|
||||
} else if (needToShow.includes('yl')) {
|
||||
this.lineStatus.yl = true
|
||||
}
|
||||
} else {
|
||||
// eslint-disable-next-line no-lonely-if
|
||||
if (needToShow.includes('yl')) {
|
||||
this.lineStatus.yl = true
|
||||
} else if (needToShow.includes('yc')) {
|
||||
this.lineStatus.yc = true
|
||||
} else if (needToShow.includes('yr')) {
|
||||
this.lineStatus.yr = true
|
||||
}
|
||||
}
|
||||
|
||||
if (isDownward) {
|
||||
if (needToShow.includes('xb')) {
|
||||
this.lineStatus.xb = true
|
||||
} else if (needToShow.includes('xc')) {
|
||||
this.lineStatus.xc = true
|
||||
} else if (needToShow.includes('xt')) {
|
||||
this.lineStatus.xt = true
|
||||
}
|
||||
} else {
|
||||
// eslint-disable-next-line no-lonely-if
|
||||
if (needToShow.includes('xt')) {
|
||||
this.lineStatus.xt = true
|
||||
} else if (needToShow.includes('xc')) {
|
||||
this.lineStatus.xc = true
|
||||
} else if (needToShow.includes('xb')) {
|
||||
this.lineStatus.xb = true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
isNearly(dragValue, targetValue) {
|
||||
return Math.abs(dragValue - targetValue) <= this.diff
|
||||
},
|
||||
return Math.round(condition.dragShift - (width - curComponentStyle.width) / 2)
|
||||
},
|
||||
|
||||
chooseTheTureLine(needToShow, isDownward, isRightward) {
|
||||
// 如果鼠标向右移动 则按从右到左的顺序显示竖线 否则按相反顺序显示
|
||||
// 如果鼠标向下移动 则按从下到上的顺序显示横线 否则按相反顺序显示
|
||||
if (isRightward) {
|
||||
if (needToShow.includes('yr')) {
|
||||
this.lineStatus.yr = true
|
||||
} else if (needToShow.includes('yc')) {
|
||||
this.lineStatus.yc = true
|
||||
} else if (needToShow.includes('yl')) {
|
||||
this.lineStatus.yl = true
|
||||
}
|
||||
} else {
|
||||
// eslint-disable-next-line no-lonely-if
|
||||
if (needToShow.includes('yl')) {
|
||||
this.lineStatus.yl = true
|
||||
} else if (needToShow.includes('yc')) {
|
||||
this.lineStatus.yc = true
|
||||
} else if (needToShow.includes('yr')) {
|
||||
this.lineStatus.yr = true
|
||||
}
|
||||
}
|
||||
|
||||
if (isDownward) {
|
||||
if (needToShow.includes('xb')) {
|
||||
this.lineStatus.xb = true
|
||||
} else if (needToShow.includes('xc')) {
|
||||
this.lineStatus.xc = true
|
||||
} else if (needToShow.includes('xt')) {
|
||||
this.lineStatus.xt = true
|
||||
}
|
||||
} else {
|
||||
// eslint-disable-next-line no-lonely-if
|
||||
if (needToShow.includes('xt')) {
|
||||
this.lineStatus.xt = true
|
||||
} else if (needToShow.includes('xc')) {
|
||||
this.lineStatus.xc = true
|
||||
} else if (needToShow.includes('xb')) {
|
||||
this.lineStatus.xb = true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
isNearly(dragValue, targetValue) {
|
||||
return Math.abs(dragValue - targetValue) <= this.diff
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -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()
|
||||
})
|
||||
})
|
||||
|
@ -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 => {
|
||||
|
@ -19,7 +19,6 @@ export default {
|
||||
|
||||
methods: {
|
||||
toDir() {
|
||||
debugger
|
||||
this.$router.replace('/panel/index')
|
||||
bus.$emit('PanelSwitchComponent', { name: 'PanelEdit' })
|
||||
}
|
||||
|
@ -3,13 +3,13 @@
|
||||
<span v-show="isActive()" class="iconfont icon-xiangyouxuanzhuan" @mousedown="handleRotate" />
|
||||
<span v-show="element.isLock" class="iconfont icon-suo" />
|
||||
|
||||
<!-- <span v-show="isActive()" class="iconfont icon-more">-->
|
||||
<!-- <el-button-->
|
||||
<!-- icon="el-icon-more"-->
|
||||
<!-- type="text"-->
|
||||
<!-- size="small"-->
|
||||
<!-- />-->
|
||||
<!-- </span>-->
|
||||
<!-- <span v-show="isActive()" class="iconfont icon-more">-->
|
||||
<!-- <el-button-->
|
||||
<!-- icon="el-icon-more"-->
|
||||
<!-- type="text"-->
|
||||
<!-- size="small"-->
|
||||
<!-- />-->
|
||||
<!-- </span>-->
|
||||
<div
|
||||
v-for="item in (isActive()? pointList : [])"
|
||||
:key="item"
|
||||
@ -335,9 +335,9 @@ export default {
|
||||
symmetricPoint
|
||||
})
|
||||
|
||||
console.log('this is test:' + JSON.stringify(this.element.propValue.viewId))
|
||||
// console.log('this is test:' + JSON.stringify(this.element.propValue.viewId))
|
||||
this.$store.commit('setShapeStyle', style)
|
||||
eventBus.$emit('resizing', this.element.propValue.viewId)
|
||||
this.element.propValue && this.element.propValue.viewId && eventBus.$emit('resizing', this.element.propValue.viewId)
|
||||
}
|
||||
|
||||
const up = () => {
|
||||
|
@ -25,14 +25,14 @@
|
||||
:class="{ lock: item.isLock }"
|
||||
>
|
||||
|
||||
<de-drawing-widget
|
||||
<component
|
||||
:is="item.component"
|
||||
v-if="item.type==='custom'"
|
||||
:id="'component' + item.id"
|
||||
class="component"
|
||||
:style="getComponentStyle(item.style)"
|
||||
:style="item.style"
|
||||
:element="item"
|
||||
:item="item"
|
||||
@filter-value-change="filterValueChange"
|
||||
@set-condition-value="setConditionValue"
|
||||
/>
|
||||
|
||||
<component
|
||||
@ -67,6 +67,7 @@
|
||||
<script>
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -1,20 +1,30 @@
|
||||
<script>
|
||||
import { ApplicationContext } from '@/utils/ApplicationContext'
|
||||
import store from '@/store'
|
||||
export default {
|
||||
name: 'DeDrawingWidget',
|
||||
functional: true,
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
serviceName: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
|
||||
render(createElement, context) {
|
||||
const item = context.props.item
|
||||
return createElement(item.component, {
|
||||
const widgetInfo = ApplicationContext.getService(context.props.serviceName)
|
||||
// const widgetInfo = context.props.widgetInfo
|
||||
const dialogInfo = widgetInfo.getDialogPanel && widgetInfo.getDialogPanel() || null
|
||||
const drawInfo = widgetInfo.getDrawPanel && widgetInfo.getDrawPanel() || null
|
||||
const curComponent = store.state.curComponent
|
||||
if (!dialogInfo) {
|
||||
throw new Error('系统错误')
|
||||
}
|
||||
return createElement(dialogInfo.component, {
|
||||
props: {
|
||||
element: item
|
||||
element: curComponent || drawInfo || dialogInfo
|
||||
},
|
||||
style: context.data.style,
|
||||
on: {
|
||||
'value-change': value => {
|
||||
context.listeners['filter-value-change'] && context.listeners['filter-value-change'](value)
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
|
||||
<el-select v-if="options!== null && options.attrs!==null" v-model="options.value" :placeholder="options.attrs.placeholder" @change="changeValue">
|
||||
<el-select v-if="options!== null && options.attrs!==null" v-model="options.value" :style="element.style" :placeholder="options.attrs.placeholder" @change="changeValue">
|
||||
<el-option
|
||||
v-for="item in options.attrs.datas"
|
||||
:key="item[options.attrs.key]"
|
||||
@ -12,19 +12,31 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
|
||||
props: {
|
||||
element: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
inDraw: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options: null
|
||||
options: null,
|
||||
operator: 'eq'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'element.style': function(value) {
|
||||
// console.log(value)
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.options = this.element.options
|
||||
},
|
||||
@ -35,7 +47,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
changeValue(value) {
|
||||
this.$emit('value-change', value)
|
||||
this.inDraw && this.$emit('set-condition-value', { component: this.element, value: [value], operator: this.operator })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
frontend/src/components/widget/bean/Condition.js
Normal file
15
frontend/src/components/widget/bean/Condition.js
Normal file
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* fieldId 字段ID
|
||||
* value 字段值
|
||||
* operator 操作[eq, ne, gt, ge, lt, le, in, not in, like, not like]
|
||||
* viewIds 过滤视图范围
|
||||
*/
|
||||
export class Condition {
|
||||
constructor(componentId, fieldId, operator, value, viewIds) {
|
||||
this.componentId = componentId
|
||||
this.fieldId = fieldId
|
||||
this.operator = operator || 'eq'
|
||||
this.value = value
|
||||
this.viewIds = viewIds
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
export class Widget {
|
||||
constructor(options = {}) {
|
||||
this.type = options.type
|
||||
this.default_style = options.default_style
|
||||
this.icon = options.icon
|
||||
this.lable = options.label
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
|
||||
import { DrawWidgetService } from '../service/DrawWidgetService'
|
||||
|
||||
const leftPanel = {
|
||||
// name: 'text-select',
|
||||
icon: 'iconfont icon-xialakuang',
|
||||
label: '文本下拉',
|
||||
defaultClass: 'text-filter'
|
||||
}
|
||||
|
||||
const dialogPanel = {
|
||||
options: {
|
||||
refId: '1234567890',
|
||||
attrs: {
|
||||
multiple: false,
|
||||
placeholder: '请选择',
|
||||
datas: [],
|
||||
key: 'id',
|
||||
label: 'text',
|
||||
value: 'id'
|
||||
},
|
||||
value: ''
|
||||
},
|
||||
defaultClass: 'text-filter',
|
||||
component: 'de-select'
|
||||
}
|
||||
const drawPanel = {
|
||||
type: 'custom',
|
||||
style: {
|
||||
width: 200,
|
||||
height: 22,
|
||||
fontSize: 14,
|
||||
fontWeight: 500,
|
||||
lineHeight: '',
|
||||
letterSpacing: 0,
|
||||
textAlign: '',
|
||||
color: ''
|
||||
},
|
||||
component: 'de-select'
|
||||
}
|
||||
|
||||
class MySelectImpl extends DrawWidgetService {
|
||||
constructor(options = {}) {
|
||||
Object.assign(options, { name: 'mySelectWidget' })
|
||||
super(options)
|
||||
this.filterDialog = true
|
||||
this.showSwitch = true
|
||||
}
|
||||
|
||||
initLeftPanel() {
|
||||
const value = JSON.parse(JSON.stringify(leftPanel))
|
||||
return value
|
||||
// console.log('this is first initWidget')
|
||||
}
|
||||
|
||||
initFilterDialog() {
|
||||
const value = JSON.parse(JSON.stringify(dialogPanel))
|
||||
return value
|
||||
}
|
||||
|
||||
initDrawPanel() {
|
||||
const value = JSON.parse(JSON.stringify(drawPanel))
|
||||
return value
|
||||
}
|
||||
|
||||
filterFieldMethod(fields) {
|
||||
return fields.filter(field => {
|
||||
return field['deType'] === 0
|
||||
})
|
||||
}
|
||||
|
||||
optionDatas(datas) {
|
||||
if (!datas) return null
|
||||
return datas.map(item => {
|
||||
return {
|
||||
id: item,
|
||||
text: item
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
const mySelectImpl = new MySelectImpl()
|
||||
export default mySelectImpl
|
@ -31,7 +31,8 @@ requireComponent.keys().forEach(fileName => {
|
||||
)
|
||||
})
|
||||
|
||||
const req = require.context('./serviceImpl', false, /\.js$/)
|
||||
// const req = require.context('./serviceImpl', false, /\.js$/)
|
||||
const req = require.context('./drawServiceImpl', false, /\.js$/)
|
||||
const requireAll = requireContext => requireContext.keys()
|
||||
|
||||
const widgets = {}
|
||||
|
@ -0,0 +1,53 @@
|
||||
import store from '@/store'
|
||||
export const commonStyle = {
|
||||
rotate: 0,
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
export const commonAttr = {
|
||||
animations: [],
|
||||
events: {},
|
||||
groupStyle: {}, // 当一个组件成为 Group 的子组件时使用
|
||||
isLock: false // 是否锁定组件
|
||||
}
|
||||
export class DrawWidgetService {
|
||||
constructor(options) {
|
||||
this.options = options
|
||||
this.name = options.name
|
||||
// this.leftPanelPath = 'application/addLeftWidget'
|
||||
// this.dialogPanelPath = 'application/addDialogWidget'
|
||||
// this.drawPanelPath = 'application/addDrawWidget'
|
||||
this.storeWidget()
|
||||
}
|
||||
/**
|
||||
* 存储数据到本地
|
||||
* @param {本地存储路径} path
|
||||
* @param {要存储的数据} data
|
||||
*/
|
||||
store(path, data) {
|
||||
store.dispatch(path, data)
|
||||
}
|
||||
|
||||
getLeftPanel() {
|
||||
return this.initLeftPanel()
|
||||
}
|
||||
|
||||
getDialogPanel() {
|
||||
return this.initFilterDialog()
|
||||
}
|
||||
|
||||
getDrawPanel() {
|
||||
let drawPanel = this.initDrawPanel()
|
||||
drawPanel.serviceName = this.options.name
|
||||
drawPanel.style = Object.assign(drawPanel.style, commonStyle)
|
||||
drawPanel = Object.assign(drawPanel, commonAttr)
|
||||
if (this.filterDialog) {
|
||||
const dialogOptions = this.getDialogPanel()
|
||||
drawPanel = Object.assign(drawPanel, dialogOptions)
|
||||
}
|
||||
return drawPanel
|
||||
}
|
||||
storeWidget() {
|
||||
this.store('application/loadBean', { key: this.name, value: this })
|
||||
}
|
||||
}
|
@ -697,7 +697,9 @@ export default {
|
||||
rose_type: '玫瑰图模式',
|
||||
radius_mode: '半径',
|
||||
area_mode: '面积',
|
||||
rose_radius: '圆角'
|
||||
rose_radius: '圆角',
|
||||
view_name: '视图名称',
|
||||
name_can_not_empty: '名称不能为空'
|
||||
},
|
||||
dataset: {
|
||||
datalist: '数据集',
|
||||
@ -777,9 +779,14 @@ export default {
|
||||
showRow: '显示行',
|
||||
add_excel_table: '添加Excel数据集',
|
||||
add_custom_table: '添加自助数据集',
|
||||
upload_file: '上传文件'
|
||||
upload_file: '上传文件',
|
||||
detail: '详情',
|
||||
type: '类型',
|
||||
create_by: '创建者',
|
||||
create_time: '创建时间'
|
||||
},
|
||||
datasource: {
|
||||
datasource: '数据源',
|
||||
create: '新建数据连接',
|
||||
type: '类型',
|
||||
please_choose_type: '请选择数据源类型',
|
||||
|
@ -18,6 +18,9 @@ const getters = {
|
||||
loadingMap: state => state.request.loadingMap,
|
||||
currentPath: state => state.permission.currentPath,
|
||||
permissions: state => state.user.permissions,
|
||||
beanMap: state => state.application.beanMap
|
||||
beanMap: state => state.application.beanMap,
|
||||
leftWidgetMap: state => state.application.leftWidgetMap,
|
||||
dialogWidgetMap: state => state.application.dialogWidgetMap,
|
||||
drawWidgetMap: state => state.application.drawWidgetMap
|
||||
}
|
||||
export default getters
|
||||
|
@ -97,6 +97,26 @@ const data = {
|
||||
}
|
||||
},
|
||||
|
||||
setComponentWithId(state, component) {
|
||||
for (let index = 0; index < state.componentData.length; index++) {
|
||||
const element = state.componentData[index]
|
||||
if (element.id && element.id === component.id) {
|
||||
state.componentData[index] = component
|
||||
return
|
||||
}
|
||||
}
|
||||
state.componentData.push(component)
|
||||
},
|
||||
deleteComponentWithId(state, id) {
|
||||
for (let index = 0; index < state.componentData.length; index++) {
|
||||
const element = state.componentData[index]
|
||||
if (element.id && element.id === id) {
|
||||
state.componentData.splice(index, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
deleteComponent(state, index) {
|
||||
if (index === undefined) {
|
||||
index = state.curComponentIndex
|
||||
|
@ -1,11 +1,26 @@
|
||||
const state = {
|
||||
beanMap: {}
|
||||
beanMap: {},
|
||||
leftWidgetMap: {},
|
||||
dialogWidgetMap: {},
|
||||
drawWidgetMap: {}
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
|
||||
ADD_BEAN: (state, { key, value }) => {
|
||||
state.beanMap[key] = value
|
||||
},
|
||||
|
||||
ADD_LEFT_WIDGET: (state, { uuid, leftPanel }) => {
|
||||
state.leftWidgetMap[uuid] = leftPanel
|
||||
},
|
||||
|
||||
ADD_DIALOG_WIDGET: (state, { uuid, dialogPanel }) => {
|
||||
state.dialogWidgetMap[uuid] = dialogPanel
|
||||
},
|
||||
|
||||
ADD_DRAW_WIDGET: (state, { uuid, drawPanel }) => {
|
||||
state.drawWidgetMap[uuid] = drawPanel
|
||||
}
|
||||
|
||||
}
|
||||
@ -13,7 +28,20 @@ const mutations = {
|
||||
const actions = {
|
||||
loadBean({ commit }, data) {
|
||||
commit('ADD_BEAN', data)
|
||||
},
|
||||
|
||||
addLeftWidget({ commit }, data) {
|
||||
commit('ADD_LEFT_WIDGET', data)
|
||||
},
|
||||
|
||||
addDialogWidget({ commit }, data) {
|
||||
commit('ADD_DIALOG_WIDGET', data)
|
||||
},
|
||||
|
||||
addDrawWidget({ commit }, data) {
|
||||
commit('ADD_DRAW_WIDGET', data)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default {
|
||||
|
@ -199,10 +199,17 @@
|
||||
width="70%"
|
||||
class="dialog-css"
|
||||
>
|
||||
<el-row style="width: 400px;">
|
||||
<el-form ref="form" :model="table" label-width="80px" size="mini" class="form-item">
|
||||
<el-form-item :label="$t('chart.view_name')">
|
||||
<el-input v-model="table.name" size="mini" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<table-selector @getTable="getTable" />
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button size="mini" @click="selectTableFlag = false">{{ $t('chart.cancel') }}</el-button>
|
||||
<el-button type="primary" size="mini" @click="createChart">{{ $t('chart.confirm') }}</el-button>
|
||||
<el-button size="mini" @click="closeCreateChart">{{ $t('chart.cancel') }}</el-button>
|
||||
<el-button type="primary" size="mini" :disabled="!table.id" @click="createChart">{{ $t('chart.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
@ -518,10 +525,24 @@ export default {
|
||||
this.selectTableFlag = true
|
||||
},
|
||||
|
||||
closeCreateChart() {
|
||||
this.selectTableFlag = false
|
||||
this.table = {}
|
||||
},
|
||||
|
||||
createChart() {
|
||||
console.log(this.table)
|
||||
if (!this.table.name) {
|
||||
this.$message({
|
||||
message: this.$t('chart.name_can_not_empty'),
|
||||
type: 'error',
|
||||
showClose: true
|
||||
})
|
||||
return
|
||||
}
|
||||
const view = {}
|
||||
view.name = this.table.name
|
||||
view.title = this.table.name
|
||||
view.sceneId = this.currGroup.id
|
||||
view.tableId = this.table.id
|
||||
view.type = 'bar'
|
||||
@ -540,7 +561,7 @@ export default {
|
||||
})
|
||||
view.customFilter = JSON.stringify([])
|
||||
post('/chart/view/save', view).then(response => {
|
||||
this.selectTableFlag = false
|
||||
this.closeCreateChart()
|
||||
this.$store.dispatch('chart/setTableId', null)
|
||||
this.$store.dispatch('chart/setTableId', this.table.id)
|
||||
// this.$router.push('/chart/chart-edit')
|
||||
@ -551,7 +572,7 @@ export default {
|
||||
},
|
||||
|
||||
getTable(table) {
|
||||
this.table = table
|
||||
this.table = JSON.parse(JSON.stringify(table))
|
||||
},
|
||||
|
||||
refresh() {
|
||||
@ -630,4 +651,8 @@ export default {
|
||||
.dialog-css >>> .el-dialog__body {
|
||||
padding: 10px 20px 20px;
|
||||
}
|
||||
|
||||
.form-item>>>.el-form-item__label{
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
|
@ -2,7 +2,16 @@
|
||||
<el-row style="height: 100%;overflow-y: hidden;width: 100%;">
|
||||
<span v-show="false">{{ vId }}</span>
|
||||
<el-row style="height: 40px;background-color: white" class="padding-lr">
|
||||
<span style="line-height: 40px;">{{ view.name }}</span>
|
||||
<el-popover
|
||||
placement="right-start"
|
||||
width="400"
|
||||
trigger="click"
|
||||
@show="showTab"
|
||||
@hide="hideTab"
|
||||
>
|
||||
<dataset-chart-detail type="chart" :data="view" :tab-status="tabStatus" />
|
||||
<span slot="reference" style="line-height: 40px;cursor: pointer;">{{ view.name }}</span>
|
||||
</el-popover>
|
||||
<span style="float: right;line-height: 40px;">
|
||||
<el-button size="mini" @click="closeEdit">
|
||||
{{ $t('chart.close') }}
|
||||
@ -132,7 +141,7 @@
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div style="overflow:auto;border-top: 1px solid #e6e6e6" class="padding-lr filter-class">
|
||||
<div v-if="false" style="overflow:auto;border-top: 1px solid #e6e6e6" class="padding-lr filter-class">
|
||||
<span>{{ $t('chart.result_filter') }}</span>
|
||||
<div style="margin: 8px" class="filter-inner-class">
|
||||
<draggable
|
||||
@ -229,6 +238,7 @@ import QuotaItem from '../components/drag-item/QuotaItem'
|
||||
import FilterItem from '../components/drag-item/FilterItem'
|
||||
import ChartComponent from '../components/ChartComponent'
|
||||
import bus from '@/utils/bus'
|
||||
import DatasetChartDetail from '../../dataset/common/DatasetChartDetail'
|
||||
|
||||
// shape attr,component style
|
||||
import {
|
||||
@ -255,7 +265,7 @@ import QuotaFilterEditor from '../components/filter/QuotaFilterEditor'
|
||||
|
||||
export default {
|
||||
name: 'ChartEdit',
|
||||
components: { QuotaFilterEditor, BackgroundColorSelector, FilterItem, XAxisSelector, YAxisSelector, TooltipSelector, LabelSelector, LegendSelector, TitleSelector, SizeSelector, ColorSelector, ChartComponent, QuotaItem, DimensionItem, draggable },
|
||||
components: { DatasetChartDetail, QuotaFilterEditor, BackgroundColorSelector, FilterItem, XAxisSelector, YAxisSelector, TooltipSelector, LabelSelector, LegendSelector, TitleSelector, SizeSelector, ColorSelector, ChartComponent, QuotaItem, DimensionItem, draggable },
|
||||
data() {
|
||||
return {
|
||||
table: {},
|
||||
@ -296,7 +306,8 @@ export default {
|
||||
name: [
|
||||
{ required: true, message: this.$t('commons.input_content'), trigger: 'change' }
|
||||
]
|
||||
}
|
||||
},
|
||||
tabStatus: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -380,7 +391,9 @@ export default {
|
||||
},
|
||||
getData(id) {
|
||||
if (id) {
|
||||
post('/chart/view/getData/' + id, null).then(response => {
|
||||
post('/chart/view/getData/' + id, {
|
||||
filter: []
|
||||
}).then(response => {
|
||||
this.initTableData(response.data.tableId)
|
||||
this.view = JSON.parse(JSON.stringify(response.data))
|
||||
this.view.xaxis = this.view.xaxis ? JSON.parse(this.view.xaxis) : []
|
||||
@ -577,6 +590,13 @@ export default {
|
||||
},
|
||||
resetRename() {
|
||||
// this.itemForm = {}
|
||||
},
|
||||
|
||||
showTab() {
|
||||
this.tabStatus = true
|
||||
},
|
||||
hideTab() {
|
||||
this.tabStatus = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,10 +24,11 @@
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-upload
|
||||
action="https://jsonplaceholder.typicode.com/posts/"
|
||||
action="/posts/"
|
||||
:multiple="false"
|
||||
:show-file-list="false"
|
||||
accept=".xls,.xlsx,.csv"
|
||||
:on-success="uploadSuccess"
|
||||
>
|
||||
<el-button size="mini" type="primary">{{ $t('dataset.upload_file') }}</el-button>
|
||||
</el-upload>
|
||||
@ -117,6 +118,9 @@ export default {
|
||||
// this.options = response.data
|
||||
// })
|
||||
// },
|
||||
uploadSuccess(response, file, fileList) {
|
||||
console.log(response)
|
||||
},
|
||||
|
||||
save() {
|
||||
// console.log(this.checkTableList);
|
||||
|
165
frontend/src/views/dataset/common/DatasetChartDetail.vue
Normal file
165
frontend/src/views/dataset/common/DatasetChartDetail.vue
Normal file
@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<el-col>
|
||||
<el-row>
|
||||
<span style="font-weight: 500;">{{ $t('dataset.detail') }}</span>
|
||||
</el-row>
|
||||
<el-col>
|
||||
<el-tabs v-if="tabStatus" v-model="tabActive" class="info-tab">
|
||||
<el-tab-pane v-if="type === 'chart'" :label="$t('chart.datalist')" name="chart">
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('commons.name') }}</p>
|
||||
<p class="info-content">{{ detail.chart.name }}</p>
|
||||
</el-col>
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('chart.chart_type') }}</p>
|
||||
<svg-icon v-if="detail.chart.type" :icon-class="detail.chart.type" />
|
||||
</el-col>
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('chart.title') }}</p>
|
||||
<p class="info-content">{{ detail.chart.title || 'N/A' }}</p>
|
||||
</el-col>
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('dataset.create_by') }}</p>
|
||||
<p class="info-content">{{ detail.chart.createBy }}</p>
|
||||
</el-col>
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('dataset.create_time') }}</p>
|
||||
<p class="info-content">{{ detail.chart.createTime | timestampFormatDate }}</p>
|
||||
</el-col>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane :label="$t('dataset.datalist')" name="table">
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('commons.name') }}</p>
|
||||
<p class="info-content">{{ detail.table.name }}</p>
|
||||
</el-col>
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('dataset.type') }}</p>
|
||||
<p v-if="detail.table.type === 'db'" class="info-content">{{ $t('dataset.db_data') }}</p>
|
||||
<p v-if="detail.table.type === 'sql'" class="info-content">{{ $t('dataset.sql_data') }}</p>
|
||||
<p v-if="detail.table.type === 'excel'" class="info-content">{{ $t('dataset.excel_data') }}</p>
|
||||
<p v-if="detail.table.type === 'custom'" class="info-content">{{ $t('dataset.custom_data') }}</p>
|
||||
</el-col>
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('dataset.mode') }}</p>
|
||||
<p v-if="detail.table.mode === 0" class="info-content">{{ $t('dataset.direct_connect') }}</p>
|
||||
<p v-if="detail.table.mode === 1" class="info-content">{{ $t('dataset.sync_data') }}</p>
|
||||
</el-col>
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('dataset.create_by') }}</p>
|
||||
<p class="info-content">{{ detail.table.createBy }}</p>
|
||||
</el-col>
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('dataset.create_time') }}</p>
|
||||
<p class="info-content">{{ detail.table.createTime | timestampFormatDate }}</p>
|
||||
</el-col>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane :label="$t('datasource.datasource')" name="datasource">
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('commons.name') }}</p>
|
||||
<p class="info-content">{{ detail.datasource.name }}</p>
|
||||
</el-col>
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('commons.description') }}</p>
|
||||
<p class="info-content">{{ detail.datasource.desc || 'N/A' }}</p>
|
||||
</el-col>
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('datasource.type') }}</p>
|
||||
<p class="info-content">{{ detail.datasource.type }}</p>
|
||||
</el-col>
|
||||
<el-col class="info-item">
|
||||
<p class="info-title">{{ $t('dataset.create_time') }}</p>
|
||||
<p class="info-content">{{ detail.datasource.createTime | timestampFormatDate }}</p>
|
||||
</el-col>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-col>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { post } from '@/api/dataset/dataset'
|
||||
export default {
|
||||
name: 'DatasetChartDetail',
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
tabStatus: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabActive: 'chart',
|
||||
detail: {
|
||||
chart: {},
|
||||
table: {},
|
||||
datasource: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'data': function() {
|
||||
this.init()
|
||||
},
|
||||
'type': function() {
|
||||
this.typeChange()
|
||||
},
|
||||
'tabStatus': function() {
|
||||
this.typeChange()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
if (this.data.id) {
|
||||
if (this.type === 'dataset') {
|
||||
post('/dataset/table/datasetDetail/' + this.data.id, null).then(res => {
|
||||
this.detail = res.data
|
||||
})
|
||||
} else if (this.type === 'chart') {
|
||||
post('/chart/view/chartDetail/' + this.data.id, null).then(res => {
|
||||
this.detail = res.data
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
typeChange() {
|
||||
if (this.type === 'dataset') {
|
||||
this.tabActive = 'table'
|
||||
} else if (this.type === 'chart') {
|
||||
this.tabActive = 'chart'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.info-tab>>>.el-tabs__item{
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
}
|
||||
.info-item{
|
||||
margin: 6px 0;
|
||||
}
|
||||
.info-title{
|
||||
margin: 0!important;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
}
|
||||
.info-content{
|
||||
margin: 0!important;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
@ -3,9 +3,18 @@
|
||||
<el-row>
|
||||
<el-row style="height: 26px;">
|
||||
<span v-show="false">{{ tableId }}</span>
|
||||
<span style="line-height: 26px;">
|
||||
{{ table.name }}
|
||||
</span>
|
||||
<el-popover
|
||||
placement="right-start"
|
||||
width="400"
|
||||
trigger="click"
|
||||
@show="showTab"
|
||||
@hide="hideTab"
|
||||
>
|
||||
<dataset-chart-detail type="dataset" :data="table" :tab-status="tabStatus" />
|
||||
<span slot="reference" style="line-height: 26px;cursor: pointer;">
|
||||
{{ table.name }}
|
||||
</span>
|
||||
</el-popover>
|
||||
<el-row style="float: right">
|
||||
<el-button v-if="table.type ==='sql'" size="mini" @click="editSql">
|
||||
{{ $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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,19 +69,25 @@
|
||||
</de-container>
|
||||
|
||||
<el-dialog
|
||||
v-if="filterVisible"
|
||||
v-if="filterVisible && panelInfo.id"
|
||||
title="过滤组件"
|
||||
:visible.sync="filterVisible"
|
||||
custom-class="de-filter-dialog"
|
||||
>
|
||||
<filter-dialog v-if="filterVisible" :component-info="currentComponent" :widget-id="currentWidgetId" @re-fresh-component="reFreshComponent">
|
||||
<de-drawing-widget
|
||||
v-if="filterVisible && currentComponent"
|
||||
:id="'component' + currentComponent.id"
|
||||
<filter-dialog v-if="filterVisible && currentWidget" :widget-info="currentWidget" :component-info="currentFilterCom" @re-fresh-component="reFreshComponent">
|
||||
<!-- <de-drawing-widget
|
||||
v-if="filterVisible"
|
||||
style="width: 100% !important;"
|
||||
class="component"
|
||||
:element="currentComponent"
|
||||
:item="currentComponent"
|
||||
:service-name="currentWidget.name"
|
||||
/> -->
|
||||
<component
|
||||
:is="currentFilterCom.component"
|
||||
:id="'component' + currentFilterCom.id"
|
||||
class="component"
|
||||
:style="currentFilterCom.style"
|
||||
:element="currentFilterCom"
|
||||
:in-draw="false"
|
||||
/>
|
||||
</filter-dialog>
|
||||
<!-- <div slot="footer" class="dialog-footer">
|
||||
@ -144,9 +150,8 @@ export default {
|
||||
activeName: 'attr',
|
||||
reSelectAnimateIndex: undefined,
|
||||
filterVisible: false,
|
||||
currentWidgetId: null,
|
||||
currentWidget: null,
|
||||
currentComponent: null
|
||||
currentFilterCom: null
|
||||
}
|
||||
},
|
||||
|
||||
@ -158,7 +163,8 @@ export default {
|
||||
'componentData',
|
||||
'curComponent',
|
||||
'isClickComponent',
|
||||
'canvasStyleData'
|
||||
'canvasStyleData',
|
||||
'curComponentIndex'
|
||||
])
|
||||
},
|
||||
|
||||
@ -174,7 +180,6 @@ export default {
|
||||
}
|
||||
},
|
||||
panelInfo(newVal, oldVal) {
|
||||
debugger
|
||||
this.init(newVal.id)
|
||||
}
|
||||
},
|
||||
@ -189,6 +194,10 @@ export default {
|
||||
bus.$on('component-on-drag', () => {
|
||||
this.show = false
|
||||
})
|
||||
|
||||
bus.$on('component-dialog-edit', () => {
|
||||
this.eidtDialog()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
const elx = this.$refs.rightPanel
|
||||
@ -196,7 +205,6 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
init(panelId) {
|
||||
debugger
|
||||
// 如果临时画布有数据 则使用临时画布数据(视图编辑的时候 会保存临时画布数据)
|
||||
const componentDataTemp = this.$store.state.panel.componentDataTemp
|
||||
const canvasStyleDataTemp = this.$store.state.panel.canvasStyleDataTemp
|
||||
@ -252,6 +260,7 @@ export default {
|
||||
e.stopPropagation()
|
||||
let component
|
||||
const newComponentId = uuid.v1()
|
||||
|
||||
const componentInfo = JSON.parse(e.dataTransfer.getData('componentInfo'))
|
||||
|
||||
// 用户视图设置 复制一个模板
|
||||
@ -268,16 +277,17 @@ export default {
|
||||
})
|
||||
} else {
|
||||
this.currentWidget = ApplicationContext.getService(componentInfo.id)
|
||||
|
||||
this.currentFilterCom = this.currentWidget.getDrawPanel()
|
||||
this.currentFilterCom.style.top = e.offsetY
|
||||
this.currentFilterCom.style.left = e.offsetX
|
||||
this.currentFilterCom.id = newComponentId
|
||||
if (this.currentWidget.filterDialog) {
|
||||
this.show = false
|
||||
this.currentComponent = deepCopy(this.currentWidget)
|
||||
this.currentComponent.style.top = e.offsetY
|
||||
this.currentComponent.style.left = e.offsetX
|
||||
this.currentComponent.id = newComponentId
|
||||
this.openFilterDiolog()
|
||||
return
|
||||
}
|
||||
component = deepCopy(this.currentWidget)
|
||||
component = deepCopy(this.currentFilterCom)
|
||||
}
|
||||
|
||||
component.style.top = e.offsetY
|
||||
@ -285,6 +295,11 @@ export default {
|
||||
component.id = newComponentId
|
||||
this.$store.commit('addComponent', { component })
|
||||
this.$store.commit('recordSnapshot')
|
||||
this.clearCurrentInfo()
|
||||
},
|
||||
clearCurrentInfo() {
|
||||
this.currentWidget = null
|
||||
this.currentFilterCom = null
|
||||
},
|
||||
|
||||
handleDragOver(e) {
|
||||
@ -311,23 +326,28 @@ export default {
|
||||
}
|
||||
},
|
||||
openFilterDiolog() {
|
||||
this.currentWidgetId = this.currentComponent.name
|
||||
this.filterVisible = true
|
||||
},
|
||||
cancelFilter() {
|
||||
this.filterVisible = false
|
||||
this.currentWidgetId = null
|
||||
this.currentWidget = null
|
||||
this.currentComponent = null
|
||||
this.clearCurrentInfo()
|
||||
},
|
||||
sureFilter() {
|
||||
const component = deepCopy(this.currentComponent)
|
||||
this.$store.commit('addComponent', { component })
|
||||
const component = deepCopy(this.currentFilterCom)
|
||||
// this.$store.commit('addComponent', { component })
|
||||
this.$store.commit('setComponentWithId', component)
|
||||
this.$store.commit('recordSnapshot')
|
||||
this.cancelFilter()
|
||||
},
|
||||
reFreshComponent(component) {
|
||||
this.currentComponent = component
|
||||
this.currentFilterCom = component
|
||||
},
|
||||
eidtDialog() {
|
||||
const serviceName = this.curComponent.serviceName
|
||||
this.currentWidget = ApplicationContext.getService(serviceName)
|
||||
this.currentFilterCom = this.curComponent
|
||||
this.openFilterDiolog()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,14 +106,17 @@
|
||||
<el-col :span="8">
|
||||
<div class="filter-options-left">
|
||||
<el-switch
|
||||
active-text="单选"
|
||||
inactive-text="多选"
|
||||
v-if="widget.showSwitch"
|
||||
v-model="componentInfo.options.attrs.multiple"
|
||||
active-text="多选"
|
||||
inactive-text="单选"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="16"><div class="filter-options-right">
|
||||
<el-checkbox disabled>备选项1</el-checkbox>
|
||||
<el-checkbox disabled>备选项</el-checkbox>
|
||||
<el-checkbox v-model="customRange"><span> 自定义控制范围 </span> </el-checkbox>
|
||||
<i :class="{'i-filter-active': customRange, 'i-filter-inactive': !customRange}" class="el-icon-setting i-filter" @click="showFilterRange" />
|
||||
<!-- <el-checkbox disabled>备选项</el-checkbox> -->
|
||||
</div>
|
||||
|
||||
</el-col>
|
||||
@ -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;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -10,8 +10,8 @@
|
||||
<div class="filter-widget-content">
|
||||
<div
|
||||
v-for="(widget, index) in item"
|
||||
:key="widget.name+index"
|
||||
:data-id="widget.name"
|
||||
:key="widget.widgetName+index"
|
||||
:data-id="widget.widgetName"
|
||||
draggable
|
||||
:data-index="index"
|
||||
:class="'filter-widget '+ (widget.defaultClass || '')"
|
||||
@ -35,23 +35,29 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
componentList,
|
||||
panelInfo: this.$store.state.panel.panelInfo,
|
||||
widgetSubjects: {
|
||||
'时间过滤组件': [
|
||||
'timeYearWidget',
|
||||
'timeMonthWidget',
|
||||
'timeQuarterWidget',
|
||||
'timeDateWidget',
|
||||
'timeDateRangeWidget'
|
||||
|
||||
],
|
||||
'文本过滤组件': [
|
||||
'textSelectWidget',
|
||||
'textInputWidget'
|
||||
],
|
||||
'按钮': [
|
||||
'buttonSureWidget'
|
||||
'mySelectWidget'
|
||||
]
|
||||
}
|
||||
// widgetSubjects: {
|
||||
// '时间过滤组件': [
|
||||
// 'timeYearWidget',
|
||||
// 'timeMonthWidget',
|
||||
// 'timeQuarterWidget',
|
||||
// 'timeDateWidget',
|
||||
// 'timeDateRangeWidget'
|
||||
|
||||
// ],
|
||||
// '文本过滤组件': [
|
||||
// 'textSelectWidget',
|
||||
// 'textInputWidget'
|
||||
// ],
|
||||
// '按钮': [
|
||||
// 'buttonSureWidget'
|
||||
// ]
|
||||
// }
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@ -59,7 +65,9 @@ export default {
|
||||
const widgetNames = this.widgetSubjects[key]
|
||||
this.widgetSubjects[key] = widgetNames.map(widgetName => {
|
||||
const widget = ApplicationContext.getService(widgetName)
|
||||
return widget
|
||||
const result = { widgetName: widgetName }
|
||||
Object.assign(result, widget.getLeftPanel())
|
||||
return result
|
||||
})
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user