提交 b57e71ce authored 作者: taojinlong's avatar taojinlong

Merge branch 'dev' into pr@dev@oracle

...@@ -355,7 +355,7 @@ ...@@ -355,7 +355,7 @@
https://github.com/dataease/dataease-plugins--> https://github.com/dataease/dataease-plugins-->
<dependency> <dependency>
<groupId>io.dataease</groupId> <groupId>io.dataease</groupId>
<artifactId>dataease-plugin-xpack</artifactId> <artifactId>dataease-plugin-interface</artifactId>
<version>1.0</version> <version>1.0</version>
</dependency> </dependency>
......
...@@ -2,9 +2,18 @@ package io.dataease.base.mapper.ext; ...@@ -2,9 +2,18 @@ package io.dataease.base.mapper.ext;
import io.dataease.controller.request.chart.ChartViewRequest; import io.dataease.controller.request.chart.ChartViewRequest;
import io.dataease.dto.chart.ChartViewDTO; import io.dataease.dto.chart.ChartViewDTO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List; import java.util.List;
@Mapper
public interface ExtChartViewMapper { public interface ExtChartViewMapper {
List<ChartViewDTO> search(ChartViewRequest request); List<ChartViewDTO> search(ChartViewRequest request);
void chartCopy(@Param("newChartId")String newChartId,@Param("oldChartId")String oldChartId);
@Select("select id from chart_view where table_id = #{tableId}")
List<String> allViewIds(@Param("tableId") String tableId);
} }
...@@ -27,4 +27,45 @@ ...@@ -27,4 +27,45 @@
</select> </select>
<insert id="chartCopy">
INSERT INTO chart_view (
`id`,
`name`,
`scene_id`,
`table_id`,
`type`,
`title`,
`x_axis`,
`y_axis`,
`custom_attr`,
`custom_style`,
`custom_filter`,
`create_by`,
`create_time`,
`update_time`,
`snapshot`,
`style_priority`
) SELECT
#{newChartId},
GET_CHART_VIEW_COPY_NAME ( #{oldChartId} ),
`scene_id`,
`table_id`,
`type`,
`title`,
`x_axis`,
`y_axis`,
`custom_attr`,
`custom_style`,
`custom_filter`,
`create_by`,
`create_time`,
`update_time`,
`snapshot`,
`style_priority`
FROM
chart_view
WHERE
id = #{oldChartId}
</insert>
</mapper> </mapper>
package io.dataease.commons.constants;
public class JdbcConstants {
public final static String VIEW_CACHE_KEY = "view_cache";
}
...@@ -55,4 +55,9 @@ public class ChartViewController { ...@@ -55,4 +55,9 @@ public class ChartViewController {
public Map<String, Object> chartDetail(@PathVariable String id) { public Map<String, Object> chartDetail(@PathVariable String id) {
return chartViewService.getChartDetail(id); return chartViewService.getChartDetail(id);
} }
@PostMapping("chartCopy/{id}")
public String chartCopy(@PathVariable String id) {
return chartViewService.chartCopy(id);
}
} }
...@@ -11,7 +11,6 @@ import io.dataease.datasource.request.DatasourceRequest; ...@@ -11,7 +11,6 @@ import io.dataease.datasource.request.DatasourceRequest;
import io.dataease.exception.DataEaseException; import io.dataease.exception.DataEaseException;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.beans.PropertyVetoException; import java.beans.PropertyVetoException;
import java.sql.*; import java.sql.*;
import java.util.*; import java.util.*;
...@@ -23,14 +22,29 @@ public class JdbcProvider extends DatasourceProvider { ...@@ -23,14 +22,29 @@ public class JdbcProvider extends DatasourceProvider {
private static int initPoolSize = 1; private static int initPoolSize = 1;
private static int maxConnections = 1; private static int maxConnections = 1;
/**
* 增加缓存机制 key 由 'provider_sql_' dsr.datasource.id dsr.table dsr.query共4部分组成,命中则使用缓存直接返回不再执行sql逻辑
* @param dsr
* @return
* @throws Exception
*/
/**
* 这里使用声明式缓存不是很妥当
* 改为chartViewService中使用编程式缓存
@Cacheable(
value = JdbcConstants.JDBC_PROVIDER_KEY,
key = "'provider_sql_' + #dsr.datasource.id + '_' + #dsr.table + '_' + #dsr.query",
condition = "#dsr.pageSize == null || #dsr.pageSize == 0L"
)
*/
@Override @Override
public List<String[]> getData(DatasourceRequest datasourceRequest) throws Exception { public List<String[]> getData(DatasourceRequest dsr) throws Exception {
List<String[]> list = new LinkedList<>(); List<String[]> list = new LinkedList<>();
Connection connection = null; Connection connection = null;
try { try {
connection = getConnectionFromPool(datasourceRequest); connection = getConnectionFromPool(dsr);
Statement stat = connection.createStatement(); Statement stat = connection.createStatement();
ResultSet rs = stat.executeQuery(datasourceRequest.getQuery()); ResultSet rs = stat.executeQuery(dsr.getQuery());
list = fetchResult(rs); list = fetchResult(rs);
} catch (SQLException e) { } catch (SQLException e) {
DataEaseException.throwException(e); DataEaseException.throwException(e);
......
...@@ -24,18 +24,19 @@ public class CacheUtils { ...@@ -24,18 +24,19 @@ public class CacheUtils {
return element.getObjectValue(); return element.getObjectValue();
} }
private static void put(String cacheName, Object key, Object value, Integer ttl, Integer tti) { public static void put(String cacheName, Object key, Object value, Integer ttl, Integer tti) {
Element e = new Element(key, value); Element e = new Element(key, value);
//不设置则使用xml配置 //不设置则使用xml配置
if (ttl != null) if (ttl != null) {
e.setEternal(false); e.setEternal(false);
e.setTimeToLive(ttl); e.setTimeToLive(ttl);
}
if (tti != null) if (tti != null)
e.setTimeToIdle(tti); e.setTimeToIdle(tti);
cache(cacheName).put(e); cache(cacheName).put(e);
} }
private static boolean remove(String cacheName, Object key) { public static boolean remove(String cacheName, Object key) {
return cache(cacheName).remove(key); return cache(cacheName).remove(key);
} }
......
...@@ -237,7 +237,7 @@ public class DorisQueryProvider extends QueryProvider { ...@@ -237,7 +237,7 @@ public class DorisQueryProvider extends QueryProvider {
String filterSql = MessageFormat.format("SELECT * FROM {0} WHERE 1=1 {1} ORDER BY {2}", String filterSql = MessageFormat.format("SELECT * FROM {0} WHERE 1=1 {1} ORDER BY {2}",
"(" + sql + ") AS tmp", "(" + sql + ") AS tmp",
StringUtils.join(resultFilter, " "), StringUtils.join(resultFilter, " "),
StringUtils.join(yOrder, ",")); ObjectUtils.isNotEmpty(yOrder) ? StringUtils.join(yOrder, ",") : "null");
return filterSql; return filterSql;
} }
} }
...@@ -318,7 +318,7 @@ public class DorisQueryProvider extends QueryProvider { ...@@ -318,7 +318,7 @@ public class DorisQueryProvider extends QueryProvider {
String filterSql = MessageFormat.format("SELECT * FROM {0} WHERE 1=1 {1} ORDER BY {2}", String filterSql = MessageFormat.format("SELECT * FROM {0} WHERE 1=1 {1} ORDER BY {2}",
"(" + sql + ") AS tmp", "(" + sql + ") AS tmp",
StringUtils.join(resultFilter, " "), StringUtils.join(resultFilter, " "),
StringUtils.join(order, ",")); ObjectUtils.isNotEmpty(order) ? StringUtils.join(order, ",") : "null");
return filterSql; return filterSql;
} }
} }
......
...@@ -245,7 +245,7 @@ public class MysqlQueryProvider extends QueryProvider { ...@@ -245,7 +245,7 @@ public class MysqlQueryProvider extends QueryProvider {
String filterSql = MessageFormat.format("SELECT * FROM {0} WHERE 1=1 {1} ORDER BY {2}", String filterSql = MessageFormat.format("SELECT * FROM {0} WHERE 1=1 {1} ORDER BY {2}",
"(" + sql + ") AS tmp", "(" + sql + ") AS tmp",
StringUtils.join(resultFilter, " "), StringUtils.join(resultFilter, " "),
StringUtils.join(yOrder, ",")); ObjectUtils.isNotEmpty(yOrder) ? StringUtils.join(yOrder, ",") : "null");
return filterSql; return filterSql;
} }
} }
...@@ -326,7 +326,7 @@ public class MysqlQueryProvider extends QueryProvider { ...@@ -326,7 +326,7 @@ public class MysqlQueryProvider extends QueryProvider {
String filterSql = MessageFormat.format("SELECT * FROM {0} WHERE 1=1 {1} ORDER BY {2}", String filterSql = MessageFormat.format("SELECT * FROM {0} WHERE 1=1 {1} ORDER BY {2}",
"(" + sql + ") AS tmp", "(" + sql + ") AS tmp",
StringUtils.join(resultFilter, " "), StringUtils.join(resultFilter, " "),
StringUtils.join(order, ",")); ObjectUtils.isNotEmpty(order) ? StringUtils.join(order, ",") : "null");
return filterSql; return filterSql;
} }
} }
......
...@@ -6,6 +6,7 @@ import io.dataease.base.domain.*; ...@@ -6,6 +6,7 @@ import io.dataease.base.domain.*;
import io.dataease.base.mapper.ChartViewMapper; import io.dataease.base.mapper.ChartViewMapper;
import io.dataease.base.mapper.ext.ExtChartGroupMapper; import io.dataease.base.mapper.ext.ExtChartGroupMapper;
import io.dataease.base.mapper.ext.ExtChartViewMapper; import io.dataease.base.mapper.ext.ExtChartViewMapper;
import io.dataease.commons.constants.JdbcConstants;
import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.BeanUtils; import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.CommonBeanFactory; import io.dataease.commons.utils.CommonBeanFactory;
...@@ -20,6 +21,7 @@ import io.dataease.datasource.service.DatasourceService; ...@@ -20,6 +21,7 @@ import io.dataease.datasource.service.DatasourceService;
import io.dataease.dto.chart.*; import io.dataease.dto.chart.*;
import io.dataease.dto.dataset.DataTableInfoDTO; import io.dataease.dto.dataset.DataTableInfoDTO;
import io.dataease.i18n.Translator; import io.dataease.i18n.Translator;
import io.dataease.listener.util.CacheUtils;
import io.dataease.provider.QueryProvider; import io.dataease.provider.QueryProvider;
import io.dataease.service.dataset.DataSetTableFieldsService; import io.dataease.service.dataset.DataSetTableFieldsService;
import io.dataease.service.dataset.DataSetTableService; import io.dataease.service.dataset.DataSetTableService;
...@@ -32,6 +34,7 @@ import javax.annotation.Resource; ...@@ -32,6 +34,7 @@ import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.*; import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -53,6 +56,9 @@ public class ChartViewService { ...@@ -53,6 +56,9 @@ public class ChartViewService {
@Resource @Resource
private ExtChartGroupMapper extChartGroupMapper; private ExtChartGroupMapper extChartGroupMapper;
//默认使用非公平
private ReentrantLock lock = new ReentrantLock();
public ChartViewWithBLOBs save(ChartViewWithBLOBs chartView) { public ChartViewWithBLOBs save(ChartViewWithBLOBs chartView) {
checkName(chartView); checkName(chartView);
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
...@@ -65,6 +71,10 @@ public class ChartViewService { ...@@ -65,6 +71,10 @@ public class ChartViewService {
chartView.setUpdateTime(timestamp); chartView.setUpdateTime(timestamp);
chartViewMapper.insertSelective(chartView); chartViewMapper.insertSelective(chartView);
} }
Optional.ofNullable(chartView.getId()).ifPresent(id -> {
CacheUtils.remove(JdbcConstants.VIEW_CACHE_KEY, id);
});
return chartView; return chartView;
} }
...@@ -188,6 +198,17 @@ public class ChartViewService { ...@@ -188,6 +198,17 @@ public class ChartViewService {
} }
} }
data = datasourceProvider.getData(datasourceRequest); data = datasourceProvider.getData(datasourceRequest);
/**
* 直连不实用缓存
String key = "provider_sql_"+datasourceRequest.getDatasource().getId() + "_" + datasourceRequest.getTable() + "_" +datasourceRequest.getQuery();
Object cache;
if ((cache = CacheUtils.get(JdbcConstants.JDBC_PROVIDER_KEY, key)) == null) {
data = datasourceProvider.getData(datasourceRequest);
CacheUtils.put(JdbcConstants.JDBC_PROVIDER_KEY,key ,data, null, null);
}else {
data = (List<String[]>) cache;
}
*/
} else if (table.getMode() == 1) {// 抽取 } else if (table.getMode() == 1) {// 抽取
// 连接doris,构建doris数据源查询 // 连接doris,构建doris数据源查询
Datasource ds = (Datasource) CommonBeanFactory.getBean("DorisDatasource"); Datasource ds = (Datasource) CommonBeanFactory.getBean("DorisDatasource");
...@@ -202,7 +223,23 @@ public class ChartViewService { ...@@ -202,7 +223,23 @@ public class ChartViewService {
} else { } else {
datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, customFilter, extFilterList)); datasourceRequest.setQuery(qp.getSQL(tableName, xAxis, yAxis, customFilter, extFilterList));
} }
/*// 定时抽取使用缓存
Object cache;
// 仪表板有参数不实用缓存
if (CollectionUtils.isNotEmpty(requestList.getFilter())) {
data = datasourceProvider.getData(datasourceRequest);
}
// 仪表板无参数 且 未缓存过该视图 则查询后缓存
else if ((cache = CacheUtils.get(JdbcConstants.VIEW_CACHE_KEY, id)) == null) {
lock.lock();
data = datasourceProvider.getData(datasourceRequest); data = datasourceProvider.getData(datasourceRequest);
CacheUtils.put(JdbcConstants.VIEW_CACHE_KEY, id, data, null, null);
}
// 仪表板有缓存 使用缓存
else {
data = (List<String[]>) cache;
}*/
data = cacheViewData(datasourceProvider, datasourceRequest, id);
} }
if (StringUtils.containsIgnoreCase(view.getType(), "pie") && data.size() > 1000) { if (StringUtils.containsIgnoreCase(view.getType(), "pie") && data.size() > 1000) {
data = data.subList(0, 1000); data = data.subList(0, 1000);
...@@ -269,6 +306,35 @@ public class ChartViewService { ...@@ -269,6 +306,35 @@ public class ChartViewService {
return dto; return dto;
} }
/**
* 避免缓存击穿
* 虽然流量不一定能够达到击穿的水平
* @param datasourceProvider
* @param datasourceRequest
* @param viewId
* @return
* @throws Exception
*/
public List<String[]> cacheViewData(DatasourceProvider datasourceProvider, DatasourceRequest datasourceRequest, String viewId) throws Exception{
List<String[]> result ;
Object cache = CacheUtils.get(JdbcConstants.VIEW_CACHE_KEY, viewId);
if (cache == null) {
if (lock.tryLock()) {// 获取锁成功
result = datasourceProvider.getData(datasourceRequest);
if (result != null) {
CacheUtils.put(JdbcConstants.VIEW_CACHE_KEY, viewId, result, null, null);
}
lock.unlock();
}else {//获取锁失败
Thread.sleep(100);//避免CAS自旋频率过大 占用cpu资源过高
result = cacheViewData(datasourceProvider, datasourceRequest, viewId);
}
}else {
result = (List<String[]>)cache;
}
return result;
}
private void checkName(ChartViewWithBLOBs chartView) { private void checkName(ChartViewWithBLOBs chartView) {
// if (StringUtils.isEmpty(chartView.getId())) { // if (StringUtils.isEmpty(chartView.getId())) {
// return; // return;
...@@ -310,4 +376,10 @@ public class ChartViewService { ...@@ -310,4 +376,10 @@ public class ChartViewService {
public ChartViewWithBLOBs findOne(String id) { public ChartViewWithBLOBs findOne(String id) {
return chartViewMapper.selectByPrimaryKey(id); return chartViewMapper.selectByPrimaryKey(id);
} }
public String chartCopy(String id) {
String newChartId = UUID.randomUUID().toString();
extChartViewMapper.chartCopy(newChartId,id);
return newChartId;
}
} }
...@@ -5,11 +5,14 @@ import io.dataease.base.domain.*; ...@@ -5,11 +5,14 @@ import io.dataease.base.domain.*;
import io.dataease.base.mapper.DatasetTableMapper; import io.dataease.base.mapper.DatasetTableMapper;
import io.dataease.base.mapper.DatasetTableTaskMapper; import io.dataease.base.mapper.DatasetTableTaskMapper;
import io.dataease.base.mapper.DatasourceMapper; import io.dataease.base.mapper.DatasourceMapper;
import io.dataease.base.mapper.ext.ExtChartViewMapper;
import io.dataease.commons.constants.JdbcConstants;
import io.dataease.commons.constants.JobStatus; import io.dataease.commons.constants.JobStatus;
import io.dataease.commons.constants.ScheduleType; import io.dataease.commons.constants.ScheduleType;
import io.dataease.commons.constants.UpdateType; import io.dataease.commons.constants.UpdateType;
import io.dataease.commons.utils.CommonBeanFactory; import io.dataease.commons.utils.CommonBeanFactory;
import io.dataease.commons.utils.DorisTableUtils; import io.dataease.commons.utils.DorisTableUtils;
import io.dataease.commons.utils.HttpClientUtil;
import io.dataease.commons.utils.LogUtil; import io.dataease.commons.utils.LogUtil;
import io.dataease.datasource.constants.DatasourceTypes; import io.dataease.datasource.constants.DatasourceTypes;
import io.dataease.datasource.dto.*; import io.dataease.datasource.dto.*;
...@@ -19,6 +22,7 @@ import io.dataease.datasource.provider.ProviderFactory; ...@@ -19,6 +22,7 @@ import io.dataease.datasource.provider.ProviderFactory;
import io.dataease.datasource.request.DatasourceRequest; import io.dataease.datasource.request.DatasourceRequest;
import io.dataease.dto.dataset.DataTableInfoDTO; import io.dataease.dto.dataset.DataTableInfoDTO;
import io.dataease.exception.DataEaseException; import io.dataease.exception.DataEaseException;
import io.dataease.listener.util.CacheUtils;
import io.dataease.provider.QueryProvider; import io.dataease.provider.QueryProvider;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
...@@ -27,6 +31,7 @@ import org.apache.commons.lang3.exception.ExceptionUtils; ...@@ -27,6 +31,7 @@ import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFSheet;
...@@ -59,6 +64,7 @@ import org.pentaho.di.trans.steps.userdefinedjavaclass.UserDefinedJavaClassDef; ...@@ -59,6 +64,7 @@ import org.pentaho.di.trans.steps.userdefinedjavaclass.UserDefinedJavaClassDef;
import org.pentaho.di.trans.steps.userdefinedjavaclass.UserDefinedJavaClassMeta; import org.pentaho.di.trans.steps.userdefinedjavaclass.UserDefinedJavaClassMeta;
import org.pentaho.di.www.SlaveServerJobStatus; import org.pentaho.di.www.SlaveServerJobStatus;
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionContext;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -93,6 +99,9 @@ public class ExtractDataService { ...@@ -93,6 +99,9 @@ public class ExtractDataService {
@Resource @Resource
private DatasetTableTaskMapper datasetTableTaskMapper; private DatasetTableTaskMapper datasetTableTaskMapper;
@Resource
private ExtChartViewMapper extChartViewMapper;
private static String lastUpdateTime = "${__last_update_time__}"; private static String lastUpdateTime = "${__last_update_time__}";
private static String currentUpdateTime = "${__current_update_time__}"; private static String currentUpdateTime = "${__current_update_time__}";
private static String separator = "|DE|"; private static String separator = "|DE|";
...@@ -275,6 +284,14 @@ public class ExtractDataService { ...@@ -275,6 +284,14 @@ public class ExtractDataService {
} }
break; break;
} }
//侵入式清除下属视图缓存
List<String> viewIds = extChartViewMapper.allViewIds(datasetTableId);
if (CollectionUtils.isNotEmpty(viewIds)){
viewIds.forEach(viewId -> {
CacheUtils.remove(JdbcConstants.VIEW_CACHE_KEY, viewId);
});
}
} }
private void updateTableStatus(String datasetTableId, DatasetTable datasetTable, JobStatus completed, Long execTime) { private void updateTableStatus(String datasetTableId, DatasetTable datasetTable, JobStatus completed, Long execTime) {
...@@ -844,12 +861,15 @@ public class ExtractDataService { ...@@ -844,12 +861,15 @@ public class ExtractDataService {
if (!InetAddress.getByName(carte).isReachable(1000)) { if (!InetAddress.getByName(carte).isReachable(1000)) {
return false; return false;
} }
HttpClient httpClient; }catch (Exception e){
return false;
}
HttpGet getMethod = new HttpGet("http://" + carte + ":" + port); HttpGet getMethod = new HttpGet("http://" + carte + ":" + port);
HttpClientManager.HttpClientBuilderFacade clientBuilder = HttpClientManager.getInstance().createBuilder(); HttpClientManager.HttpClientBuilderFacade clientBuilder = HttpClientManager.getInstance().createBuilder();
clientBuilder.setConnectionTimeout(1); clientBuilder.setConnectionTimeout(1);
clientBuilder.setCredentials(user, passwd); clientBuilder.setCredentials(user, passwd);
httpClient = clientBuilder.build(); CloseableHttpClient httpClient = clientBuilder.build();
try {
HttpResponse httpResponse = httpClient.execute(getMethod); HttpResponse httpResponse = httpClient.execute(getMethod);
int statusCode = httpResponse.getStatusLine().getStatusCode(); int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode != -1 && statusCode < 400) { if (statusCode != -1 && statusCode < 400) {
...@@ -859,6 +879,12 @@ public class ExtractDataService { ...@@ -859,6 +879,12 @@ public class ExtractDataService {
} }
} catch (Exception e) { } catch (Exception e) {
return false; return false;
}finally {
try {
httpClient.close();
} catch (Exception e) {
LoggerFactory.getLogger(HttpClientUtil.class).error("HttpClient关闭连接失败", e);
}
} }
} }
......
DROP FUNCTION IF EXISTS `GET_CHART_VIEW_COPY_NAME`;
delimiter ;;
CREATE DEFINER=`root`@`%` FUNCTION `GET_CHART_VIEW_COPY_NAME`(chartId varchar(255)) RETURNS varchar(255) CHARSET utf8
READS SQL DATA
BEGIN
DECLARE chartName varchar(255);
DECLARE pid varchar(255);
DECLARE regexpInfo varchar(255);
DECLARE chartNameCount INTEGER;
select `name` ,`scene_id` into chartName, pid from chart_view where id =chartId;
set regexpInfo = concat('^',chartName,'-copy','\\(([0-9])+\\)$');
select (count(1)+1) into chartNameCount from chart_view where name REGEXP regexpInfo;
RETURN concat(chartName,'-copy(',chartNameCount,')');
END
;;
delimiter ;
...@@ -82,5 +82,17 @@ ...@@ -82,5 +82,17 @@
<cacheEventListenerFactory class="io.dataease.listener.LicCacheEventListener" /> <cacheEventListenerFactory class="io.dataease.listener.LicCacheEventListener" />
</cache> </cache>
<cache
name="jdbc_provider_cache"
eternal="false"
maxElementsInMemory="100"
maxElementsOnDisk="10000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="28800"
timeToLiveSeconds="86400"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache> </ehcache>
\ No newline at end of file
...@@ -27,3 +27,11 @@ export function getChartTree(data) { ...@@ -27,3 +27,11 @@ export function getChartTree(data) {
data data
}) })
} }
export function chartCopy(id) {
return request({
url: '/chart/view/chartCopy/' + id,
method: 'post',
loading: true
})
}
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<template v-if="curComponent"> <template v-if="curComponent">
<template v-if="!curComponent.isLock"> <template v-if="!curComponent.isLock">
<li v-if="editFilter.includes(curComponent.type)" @click="edit"> {{ $t('panel.edit') }}</li> <li v-if="editFilter.includes(curComponent.type)" @click="edit"> {{ $t('panel.edit') }}</li>
<!-- <li @click="copy"> {{ $t('panel.copy') }}</li>--> <li @click="copy"> {{ $t('panel.copy') }}</li>
<li @click="paste"> {{ $t('panel.paste') }}</li> <li @click="paste"> {{ $t('panel.paste') }}</li>
<li @click="cut"> {{ $t('panel.cut') }}</li> <li @click="cut"> {{ $t('panel.cut') }}</li>
<li @click="deleteComponent"> {{ $t('panel.delete') }}</li> <li @click="deleteComponent"> {{ $t('panel.delete') }}</li>
......
...@@ -2,6 +2,7 @@ import store from '@/store/index' ...@@ -2,6 +2,7 @@ import store from '@/store/index'
import toast from '@/components/canvas/utils/toast' import toast from '@/components/canvas/utils/toast'
import generateID from '@/components/canvas/utils/generateID' import generateID from '@/components/canvas/utils/generateID'
import { deepCopy } from '@/components/canvas/utils/utils' import { deepCopy } from '@/components/canvas/utils/utils'
import { chartCopy } from '@/api/chart/chart'
export default { export default {
state: { state: {
...@@ -36,7 +37,18 @@ export default { ...@@ -36,7 +37,18 @@ export default {
} }
data.id = generateID() data.id = generateID()
// 如果是用户视图 测先进行底层复制
debugger
if (data.type === 'view') {
chartCopy(data.propValue.viewId).then(res => {
const newView = deepCopy(data)
newView.propValue.viewId = res.data
store.commit('addComponent', { component: newView })
})
} else {
store.commit('addComponent', { component: deepCopy(data) }) store.commit('addComponent', { component: deepCopy(data) })
}
if (state.isCut) { if (state.isCut) {
state.copyData = null state.copyData = null
} }
......
...@@ -720,7 +720,21 @@ export default { ...@@ -720,7 +720,21 @@ export default {
chart_error_tips: 'Please contact admin ', chart_error_tips: 'Please contact admin ',
title_cannot_empty: 'Title can not be empty', title_cannot_empty: 'Title can not be empty',
table_title_height: 'Table header height', table_title_height: 'Table header height',
table_item_height: 'Table row height' table_item_height: 'Table row height',
axis_show: 'Axis Show',
axis_color: 'Axis Color',
axis_width: 'Axis Width',
axis_type: 'Axis Type',
axis_type_solid: 'Solid',
axis_type_dashed: 'Dashed',
axis_type_dotted: 'Dotted',
axis_label_show: 'Label Show',
axis_label_color: 'Label Color',
axis_label_fontsize: 'Label Fontsize',
text_style: 'Font Style',
bolder: 'Bolder',
change_ds: 'Change Dataset',
change_ds_tip: 'Tips:Change Dataset will change fields,you need rebuild chart'
}, },
dataset: { dataset: {
sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default', sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default',
......
...@@ -762,7 +762,21 @@ export default { ...@@ -762,7 +762,21 @@ export default {
chart_error_tips: '如有疑問請聯系管理員', chart_error_tips: '如有疑問請聯系管理員',
title_cannot_empty: '標題不能為空', title_cannot_empty: '標題不能為空',
table_title_height: '表頭行高', table_title_height: '表頭行高',
table_item_height: '表格行高' table_item_height: '表格行高',
axis_show: '軸線顯示',
axis_color: '軸線顏色',
axis_width: '軸線寬度',
axis_type: '軸線類型',
axis_type_solid: '實線',
axis_type_dashed: '虛線',
axis_type_dotted: '點',
axis_label_show: '標簽顯示',
axis_label_color: '標簽顏色',
axis_label_fontsize: '標簽大小',
text_style: '字體樣式',
bolder: '加粗',
change_ds: '更換數據集',
change_ds_tip: '提示:更換數據集將導致字段發生變化,需重新製作視圖'
}, },
dataset: { dataset: {
sheet_warn: '有多個sheet頁面,默認抽取第一個', sheet_warn: '有多個sheet頁面,默認抽取第一個',
......
...@@ -720,7 +720,21 @@ export default { ...@@ -720,7 +720,21 @@ export default {
chart_error_tips: '如有疑问请联系管理员', chart_error_tips: '如有疑问请联系管理员',
title_cannot_empty: '标题不能为空', title_cannot_empty: '标题不能为空',
table_title_height: '表头行高', table_title_height: '表头行高',
table_item_height: '表格行高' table_item_height: '表格行高',
axis_show: '轴线显示',
axis_color: '轴线颜色',
axis_width: '轴线宽度',
axis_type: '轴线类型',
axis_type_solid: '实线',
axis_type_dashed: '虚线',
axis_type_dotted: '点',
axis_label_show: '标签显示',
axis_label_color: '标签颜色',
axis_label_fontsize: '标签大小',
text_style: '字体样式',
bolder: '加粗',
change_ds: '更换数据集',
change_ds_tip: '提示:更换数据集将导致字段发生变化,需重新制作视图'
}, },
dataset: { dataset: {
sheet_warn: '有多个 Sheet 页,默认抽取第一个', sheet_warn: '有多个 Sheet 页,默认抽取第一个',
......
...@@ -16,7 +16,7 @@ const LinkTokenKey = Config.LinkTokenKey ...@@ -16,7 +16,7 @@ const LinkTokenKey = Config.LinkTokenKey
const service = axios.create({ const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests // withCredentials: true, // send cookies when cross-domain requests
timeout: 10000 // request timeout timeout: 0 // request timeout
}) })
// request interceptor // request interceptor
......
...@@ -63,7 +63,8 @@ export const DEFAULT_TITLE_STYLE = { ...@@ -63,7 +63,8 @@ export const DEFAULT_TITLE_STYLE = {
color: '#303133', color: '#303133',
hPosition: 'center', hPosition: 'center',
vPosition: 'top', vPosition: 'top',
isItalic: false isItalic: false,
isBolder: false
} }
export const DEFAULT_LEGEND_STYLE = { export const DEFAULT_LEGEND_STYLE = {
show: true, show: true,
...@@ -81,8 +82,19 @@ export const DEFAULT_XAXIS_STYLE = { ...@@ -81,8 +82,19 @@ export const DEFAULT_XAXIS_STYLE = {
position: 'bottom', position: 'bottom',
name: '', name: '',
axisLabel: { axisLabel: {
show: true,
color: '#333333',
fontSize: '12',
rotate: 0, rotate: 0,
formatter: '{value}' formatter: '{value}'
},
splitLine: {
show: false,
lineStyle: {
color: '#cccccc',
width: 1,
style: 'solid'
}
} }
} }
export const DEFAULT_YAXIS_STYLE = { export const DEFAULT_YAXIS_STYLE = {
...@@ -90,8 +102,19 @@ export const DEFAULT_YAXIS_STYLE = { ...@@ -90,8 +102,19 @@ export const DEFAULT_YAXIS_STYLE = {
position: 'left', position: 'left',
name: '', name: '',
axisLabel: { axisLabel: {
show: true,
color: '#333333',
fontSize: '12',
rotate: 0, rotate: 0,
formatter: '{value}' formatter: '{value}'
},
splitLine: {
show: true,
lineStyle: {
color: '#cccccc',
width: 1,
style: 'solid'
}
} }
} }
export const DEFAULT_BACKGROUND_COLOR = { export const DEFAULT_BACKGROUND_COLOR = {
......
...@@ -11,6 +11,7 @@ export function componentStyle(chart_option, chart) { ...@@ -11,6 +11,7 @@ export function componentStyle(chart_option, chart) {
style.fontSize = customStyle.text.fontSize style.fontSize = customStyle.text.fontSize
style.color = customStyle.text.color style.color = customStyle.text.color
customStyle.text.isItalic ? style.fontStyle = 'italic' : style.fontStyle = 'normal' customStyle.text.isItalic ? style.fontStyle = 'italic' : style.fontStyle = 'normal'
customStyle.text.isBolder ? style.fontWeight = 'bold' : style.fontWeight = 'normal'
chart_option.title.textStyle = style chart_option.title.textStyle = style
} }
if (customStyle.legend) { if (customStyle.legend) {
...@@ -26,12 +27,14 @@ export function componentStyle(chart_option, chart) { ...@@ -26,12 +27,14 @@ export function componentStyle(chart_option, chart) {
chart_option.xAxis.position = customStyle.xAxis.position chart_option.xAxis.position = customStyle.xAxis.position
chart_option.xAxis.name = customStyle.xAxis.name chart_option.xAxis.name = customStyle.xAxis.name
chart_option.xAxis.axisLabel = customStyle.xAxis.axisLabel chart_option.xAxis.axisLabel = customStyle.xAxis.axisLabel
chart_option.xAxis.splitLine = customStyle.xAxis.splitLine
} }
if (customStyle.yAxis && (chart.type.includes('bar') || chart.type.includes('line'))) { if (customStyle.yAxis && (chart.type.includes('bar') || chart.type.includes('line'))) {
chart_option.yAxis.show = customStyle.yAxis.show chart_option.yAxis.show = customStyle.yAxis.show
chart_option.yAxis.position = customStyle.yAxis.position chart_option.yAxis.position = customStyle.yAxis.position
chart_option.yAxis.name = customStyle.yAxis.name chart_option.yAxis.name = customStyle.yAxis.name
chart_option.yAxis.axisLabel = customStyle.yAxis.axisLabel chart_option.yAxis.axisLabel = customStyle.yAxis.axisLabel
chart_option.yAxis.splitLine = customStyle.yAxis.splitLine
} }
if (customStyle.background) { if (customStyle.background) {
chart_option.backgroundColor = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha) chart_option.backgroundColor = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha)
......
...@@ -44,8 +44,9 @@ ...@@ -44,8 +44,9 @@
<el-radio-button label="bottom">{{ $t('chart.text_pos_bottom') }}</el-radio-button> <el-radio-button label="bottom">{{ $t('chart.text_pos_bottom') }}</el-radio-button>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item :label="$t('chart.text_italic')" class="form-item"> <el-form-item :label="$t('chart.text_style')" class="form-item">
<el-checkbox v-model="titleForm.isItalic" @change="changeTitleStyle">{{ $t('chart.italic') }}</el-checkbox> <el-checkbox v-model="titleForm.isItalic" @change="changeTitleStyle">{{ $t('chart.italic') }}</el-checkbox>
<el-checkbox v-model="titleForm.isBolder" @change="changeTitleStyle">{{ $t('chart.bolder') }}</el-checkbox>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-col> </el-col>
......
...@@ -24,6 +24,40 @@ ...@@ -24,6 +24,40 @@
<el-form-item :label="$t('chart.rotate')" class="form-item form-item-slider"> <el-form-item :label="$t('chart.rotate')" class="form-item form-item-slider">
<el-slider v-model="axisForm.axisLabel.rotate" show-input :show-input-controls="false" :min="-90" :max="90" input-size="mini" @change="changeXAxisStyle" /> <el-slider v-model="axisForm.axisLabel.rotate" show-input :show-input-controls="false" :min="-90" :max="90" input-size="mini" @change="changeXAxisStyle" />
</el-form-item> </el-form-item>
<el-divider />
<el-form-item :label="$t('chart.axis_show')" class="form-item">
<el-checkbox v-model="axisForm.splitLine.show" @change="changeXAxisStyle">{{ $t('chart.axis_show') }}</el-checkbox>
</el-form-item>
<span v-show="axisForm.splitLine.show">
<el-form-item :label="$t('chart.axis_color')" class="form-item">
<colorPicker v-model="axisForm.splitLine.lineStyle.color" style="margin-top: 6px;cursor: pointer;z-index: 1004;border: solid 1px black" @change="changeXAxisStyle" />
</el-form-item>
<el-form-item :label="$t('chart.axis_width')" class="form-item form-item-slider">
<el-slider v-model="axisForm.splitLine.lineStyle.width" :min="1" :max="10" show-input :show-input-controls="false" input-size="mini" @change="changeXAxisStyle" />
</el-form-item>
<el-form-item :label="$t('chart.axis_type')" class="form-item">
<el-radio-group v-model="axisForm.splitLine.lineStyle.type" size="mini" @change="changeXAxisStyle">
<el-radio-button label="solid">{{ $t('chart.axis_type_solid') }}</el-radio-button>
<el-radio-button label="dashed">{{ $t('chart.axis_type_dashed') }}</el-radio-button>
<el-radio-button label="dotted">{{ $t('chart.axis_type_dotted') }}</el-radio-button>
</el-radio-group>
</el-form-item>
</span>
<el-divider />
<el-form-item :label="$t('chart.axis_label_show')" class="form-item">
<el-checkbox v-model="axisForm.axisLabel.show" @change="changeXAxisStyle">{{ $t('chart.axis_label_show') }}</el-checkbox>
</el-form-item>
<span v-show="axisForm.axisLabel.show">
<el-form-item :label="$t('chart.axis_label_color')" class="form-item">
<colorPicker v-model="axisForm.axisLabel.color" style="margin-top: 6px;cursor: pointer;z-index: 1004;border: solid 1px black" @change="changeXAxisStyle" />
</el-form-item>
<el-form-item :label="$t('chart.axis_label_fontsize')" class="form-item form-item-slider">
<el-select v-model="axisForm.axisLabel.fontSize" :placeholder="$t('chart.axis_label_fontsize')" @change="changeXAxisStyle">
<el-option v-for="option in fontSize" :key="option.value" :label="option.name" :value="option.value" />
</el-select>
</el-form-item>
</span>
<el-divider />
<el-form-item :label="$t('chart.content_formatter')" class="form-item"> <el-form-item :label="$t('chart.content_formatter')" class="form-item">
<el-input v-model="axisForm.axisLabel.formatter" type="textarea" :autosize="{ minRows: 4, maxRows: 4}" @blur="changeXAxisStyle" /> <el-input v-model="axisForm.axisLabel.formatter" type="textarea" :autosize="{ minRows: 4, maxRows: 4}" @blur="changeXAxisStyle" />
</el-form-item> </el-form-item>
...@@ -58,7 +92,8 @@ export default { ...@@ -58,7 +92,8 @@ export default {
data() { data() {
return { return {
axisForm: JSON.parse(JSON.stringify(DEFAULT_XAXIS_STYLE)), axisForm: JSON.parse(JSON.stringify(DEFAULT_XAXIS_STYLE)),
isSetting: false isSetting: false,
fontSize: []
} }
}, },
watch: { watch: {
...@@ -74,14 +109,28 @@ export default { ...@@ -74,14 +109,28 @@ export default {
} }
if (customStyle.xAxis) { if (customStyle.xAxis) {
this.axisForm = customStyle.xAxis this.axisForm = customStyle.xAxis
if (!this.axisForm.splitLine) {
this.axisForm.splitLine = JSON.parse(JSON.stringify(DEFAULT_XAXIS_STYLE.splitLine))
}
} }
} }
} }
} }
}, },
mounted() { mounted() {
this.init()
}, },
methods: { methods: {
init() {
const arr = []
for (let i = 10; i <= 40; i = i + 2) {
arr.push({
name: i + '',
value: i + ''
})
}
this.fontSize = arr
},
changeXAxisStyle() { changeXAxisStyle() {
if (!this.axisForm.show) { if (!this.axisForm.show) {
this.isSetting = false this.isSetting = false
...@@ -93,6 +142,9 @@ export default { ...@@ -93,6 +142,9 @@ export default {
</script> </script>
<style scoped> <style scoped>
.el-divider--horizontal {
margin: 10px 0
}
.shape-item{ .shape-item{
padding: 6px; padding: 6px;
border: none; border: none;
......
...@@ -24,6 +24,40 @@ ...@@ -24,6 +24,40 @@
<el-form-item :label="$t('chart.rotate')" class="form-item form-item-slider"> <el-form-item :label="$t('chart.rotate')" class="form-item form-item-slider">
<el-slider v-model="axisForm.axisLabel.rotate" show-input :show-input-controls="false" :min="-90" :max="90" input-size="mini" @change="changeYAxisStyle" /> <el-slider v-model="axisForm.axisLabel.rotate" show-input :show-input-controls="false" :min="-90" :max="90" input-size="mini" @change="changeYAxisStyle" />
</el-form-item> </el-form-item>
<el-divider />
<el-form-item :label="$t('chart.axis_show')" class="form-item">
<el-checkbox v-model="axisForm.splitLine.show" @change="changeYAxisStyle">{{ $t('chart.axis_show') }}</el-checkbox>
</el-form-item>
<span v-show="axisForm.splitLine.show">
<el-form-item :label="$t('chart.axis_color')" class="form-item">
<colorPicker v-model="axisForm.splitLine.lineStyle.color" style="margin-top: 6px;cursor: pointer;z-index: 1004;border: solid 1px black" @change="changeYAxisStyle" />
</el-form-item>
<el-form-item :label="$t('chart.axis_width')" class="form-item form-item-slider">
<el-slider v-model="axisForm.splitLine.lineStyle.width" :min="1" :max="10" show-input :show-input-controls="false" input-size="mini" @change="changeYAxisStyle" />
</el-form-item>
<el-form-item :label="$t('chart.axis_type')" class="form-item">
<el-radio-group v-model="axisForm.splitLine.lineStyle.type" size="mini" @change="changeYAxisStyle">
<el-radio-button label="solid">{{ $t('chart.axis_type_solid') }}</el-radio-button>
<el-radio-button label="dashed">{{ $t('chart.axis_type_dashed') }}</el-radio-button>
<el-radio-button label="dotted">{{ $t('chart.axis_type_dotted') }}</el-radio-button>
</el-radio-group>
</el-form-item>
</span>
<el-divider />
<el-form-item :label="$t('chart.axis_label_show')" class="form-item">
<el-checkbox v-model="axisForm.axisLabel.show" @change="changeYAxisStyle">{{ $t('chart.axis_label_show') }}</el-checkbox>
</el-form-item>
<span v-show="axisForm.axisLabel.show">
<el-form-item :label="$t('chart.axis_label_color')" class="form-item">
<colorPicker v-model="axisForm.axisLabel.color" style="margin-top: 6px;cursor: pointer;z-index: 1004;border: solid 1px black" @change="changeYAxisStyle" />
</el-form-item>
<el-form-item :label="$t('chart.axis_label_fontsize')" class="form-item form-item-slider">
<el-select v-model="axisForm.axisLabel.fontSize" :placeholder="$t('chart.axis_label_fontsize')" @change="changeYAxisStyle">
<el-option v-for="option in fontSize" :key="option.value" :label="option.name" :value="option.value" />
</el-select>
</el-form-item>
</span>
<el-divider />
<el-form-item :label="$t('chart.content_formatter')" class="form-item"> <el-form-item :label="$t('chart.content_formatter')" class="form-item">
<el-input v-model="axisForm.axisLabel.formatter" type="textarea" :autosize="{ minRows: 4, maxRows: 4}" @blur="changeYAxisStyle" /> <el-input v-model="axisForm.axisLabel.formatter" type="textarea" :autosize="{ minRows: 4, maxRows: 4}" @blur="changeYAxisStyle" />
</el-form-item> </el-form-item>
...@@ -58,7 +92,8 @@ export default { ...@@ -58,7 +92,8 @@ export default {
data() { data() {
return { return {
axisForm: JSON.parse(JSON.stringify(DEFAULT_YAXIS_STYLE)), axisForm: JSON.parse(JSON.stringify(DEFAULT_YAXIS_STYLE)),
isSetting: false isSetting: false,
fontSize: []
} }
}, },
watch: { watch: {
...@@ -74,14 +109,28 @@ export default { ...@@ -74,14 +109,28 @@ export default {
} }
if (customStyle.yAxis) { if (customStyle.yAxis) {
this.axisForm = customStyle.yAxis this.axisForm = customStyle.yAxis
if (!this.axisForm.splitLine) {
this.axisForm.splitLine = JSON.parse(JSON.stringify(DEFAULT_YAXIS_STYLE.splitLine))
}
} }
} }
} }
} }
}, },
mounted() { mounted() {
this.init()
}, },
methods: { methods: {
init() {
const arr = []
for (let i = 10; i <= 40; i = i + 2) {
arr.push({
name: i + '',
value: i + ''
})
}
this.fontSize = arr
},
changeYAxisStyle() { changeYAxisStyle() {
if (!this.axisForm.show) { if (!this.axisForm.show) {
this.isSetting = false this.isSetting = false
...@@ -93,6 +142,9 @@ export default { ...@@ -93,6 +142,9 @@ export default {
</script> </script>
<style scoped> <style scoped>
.el-divider--horizontal {
margin: 10px 0
}
.shape-item{ .shape-item{
padding: 6px; padding: 6px;
border: none; border: none;
......
...@@ -50,7 +50,8 @@ export default { ...@@ -50,7 +50,8 @@ export default {
fontSize: '18px', fontSize: '18px',
color: '#303133', color: '#303133',
textAlign: 'left', textAlign: 'left',
fontStyle: 'normal' fontStyle: 'normal',
fontWeight: 'normal'
}, },
content_class: { content_class: {
display: 'flex', display: 'flex',
...@@ -136,6 +137,7 @@ export default { ...@@ -136,6 +137,7 @@ export default {
this.title_class.color = customStyle.text.color this.title_class.color = customStyle.text.color
this.title_class.textAlign = customStyle.text.hPosition this.title_class.textAlign = customStyle.text.hPosition
this.title_class.fontStyle = customStyle.text.isItalic ? 'italic' : 'normal' this.title_class.fontStyle = customStyle.text.isItalic ? 'italic' : 'normal'
this.title_class.fontWeight = customStyle.text.isBolder ? 'bold' : 'normal'
} }
if (customStyle.background) { if (customStyle.background) {
this.bg_class.background = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha) this.bg_class.background = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha)
......
...@@ -60,7 +60,8 @@ export default { ...@@ -60,7 +60,8 @@ export default {
fontSize: '18px', fontSize: '18px',
color: '#303133', color: '#303133',
textAlign: 'left', textAlign: 'left',
fontStyle: 'normal' fontStyle: 'normal',
fontWeight: 'normal'
}, },
bg_class: { bg_class: {
background: hexColorToRGBA('#ffffff', 0) background: hexColorToRGBA('#ffffff', 0)
...@@ -175,6 +176,7 @@ export default { ...@@ -175,6 +176,7 @@ export default {
this.title_class.color = customStyle.text.color this.title_class.color = customStyle.text.color
this.title_class.textAlign = customStyle.text.hPosition this.title_class.textAlign = customStyle.text.hPosition
this.title_class.fontStyle = customStyle.text.isItalic ? 'italic' : 'normal' this.title_class.fontStyle = customStyle.text.isItalic ? 'italic' : 'normal'
this.title_class.fontWeight = customStyle.text.isBolder ? 'bold' : 'normal'
} }
if (customStyle.background) { if (customStyle.background) {
this.bg_class.background = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha) this.bg_class.background = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha)
......
...@@ -129,9 +129,9 @@ ...@@ -129,9 +129,9 @@
/> />
</span> </span>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<!-- <el-dropdown-item icon="el-icon-edit-outline" :command="beforeClickMore('renameChart',data,node)">--> <el-dropdown-item icon="el-icon-edit-outline" :command="beforeClickMore('renameChart',data,node)">
<!-- {{ $t('chart.rename') }}--> {{ $t('chart.rename') }}
<!-- </el-dropdown-item>--> </el-dropdown-item>
<el-dropdown-item icon="el-icon-right" :command="beforeClickMore('moveDs',data,node)"> <el-dropdown-item icon="el-icon-right" :command="beforeClickMore('moveDs',data,node)">
{{ $t('dataset.move_to') }} {{ $t('dataset.move_to') }}
</el-dropdown-item> </el-dropdown-item>
...@@ -544,6 +544,7 @@ export default { ...@@ -544,6 +544,7 @@ export default {
saveTable(view) { saveTable(view) {
this.$refs['tableForm'].validate((valid) => { this.$refs['tableForm'].validate((valid) => {
if (valid) { if (valid) {
view.title = view.name
post('/chart/view/save', view).then(response => { post('/chart/view/save', view).then(response => {
this.closeTable() this.closeTable()
this.$message({ this.$message({
......
...@@ -13,6 +13,9 @@ ...@@ -13,6 +13,9 @@
<span slot="reference" style="line-height: 40px;cursor: pointer;">{{ view.name }}</span> <span slot="reference" style="line-height: 40px;cursor: pointer;">{{ view.name }}</span>
</el-popover> </el-popover>
<span style="float: right;line-height: 40px;"> <span style="float: right;line-height: 40px;">
<el-button size="mini" @click="changeDs">
{{ $t('chart.change_ds') }}
</el-button>
<el-button size="mini" @click="closeEdit"> <el-button size="mini" @click="closeEdit">
{{ $t('commons.save') }} {{ $t('commons.save') }}
</el-button> </el-button>
...@@ -208,10 +211,10 @@ ...@@ -208,10 +211,10 @@
<tooltip-selector v-show="!view.type.includes('table') && !view.type.includes('text')" class="attr-selector" :chart="chart" @onTooltipChange="onTooltipChange" /> <tooltip-selector v-show="!view.type.includes('table') && !view.type.includes('text')" class="attr-selector" :chart="chart" @onTooltipChange="onTooltipChange" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('chart.module_style')" class="padding-lr"> <el-tab-pane :label="$t('chart.module_style')" class="padding-lr">
<title-selector class="attr-selector" :chart="chart" @onTextChange="onTextChange" />
<legend-selector v-show="!view.type.includes('table') && !view.type.includes('text')" class="attr-selector" :chart="chart" @onLegendChange="onLegendChange" />
<x-axis-selector v-show="view.type.includes('bar') || view.type.includes('line')" class="attr-selector" :chart="chart" @onChangeXAxisForm="onChangeXAxisForm" /> <x-axis-selector v-show="view.type.includes('bar') || view.type.includes('line')" class="attr-selector" :chart="chart" @onChangeXAxisForm="onChangeXAxisForm" />
<y-axis-selector v-show="view.type.includes('bar') || view.type.includes('line')" class="attr-selector" :chart="chart" @onChangeYAxisForm="onChangeYAxisForm" /> <y-axis-selector v-show="view.type.includes('bar') || view.type.includes('line')" class="attr-selector" :chart="chart" @onChangeYAxisForm="onChangeYAxisForm" />
<title-selector class="attr-selector" :chart="chart" @onTextChange="onTextChange" />
<legend-selector v-show="!view.type.includes('table') && !view.type.includes('text')" class="attr-selector" :chart="chart" @onLegendChange="onLegendChange" />
<background-color-selector class="attr-selector" :chart="chart" @onChangeBackgroundForm="onChangeBackgroundForm" /> <background-color-selector class="attr-selector" :chart="chart" @onChangeBackgroundForm="onChangeBackgroundForm" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
...@@ -330,6 +333,24 @@ ...@@ -330,6 +333,24 @@
<el-button type="primary" size="mini" @click="saveResultFilter">{{ $t('chart.confirm') }}</el-button> <el-button type="primary" size="mini" @click="saveResultFilter">{{ $t('chart.confirm') }}</el-button>
</div> </div>
</el-dialog> </el-dialog>
<!--视图更换数据集-->
<el-dialog
v-dialogDrag
:title="$t('chart.change_ds')+'['+table.name+']'"
:visible="selectTableFlag"
:show-close="false"
width="70%"
class="dialog-css"
:destroy-on-close="true"
>
<table-selector @getTable="getTable" />
<span>{{ $t('chart.change_ds_tip') }}</span>
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="closeChangeChart">{{ $t('chart.cancel') }}</el-button>
<el-button type="primary" size="mini" :disabled="!table.id" @click="changeChart">{{ $t('chart.confirm') }}</el-button>
</div>
</el-dialog>
</el-row> </el-row>
</template> </template>
...@@ -368,10 +389,11 @@ import DimensionFilterEditor from '../components/filter/DimensionFilterEditor' ...@@ -368,10 +389,11 @@ import DimensionFilterEditor from '../components/filter/DimensionFilterEditor'
import TableNormal from '../components/table/TableNormal' import TableNormal from '../components/table/TableNormal'
import LabelNormal from '../components/normal/LabelNormal' import LabelNormal from '../components/normal/LabelNormal'
import html2canvas from 'html2canvas' import html2canvas from 'html2canvas'
import TableSelector from './TableSelector'
export default { export default {
name: 'ChartEdit', name: 'ChartEdit',
components: { ResultFilterEditor, LabelNormal, DimensionFilterEditor, TableNormal, DatasetChartDetail, QuotaFilterEditor, BackgroundColorSelector, XAxisSelector, YAxisSelector, TooltipSelector, LabelSelector, LegendSelector, TitleSelector, SizeSelector, ColorSelector, ChartComponent, QuotaItem, DimensionItem, draggable }, components: { TableSelector, ResultFilterEditor, LabelNormal, DimensionFilterEditor, TableNormal, DatasetChartDetail, QuotaFilterEditor, BackgroundColorSelector, XAxisSelector, YAxisSelector, TooltipSelector, LabelSelector, LegendSelector, TitleSelector, SizeSelector, ColorSelector, ChartComponent, QuotaItem, DimensionItem, draggable },
props: { props: {
param: { param: {
type: Object, type: Object,
...@@ -430,7 +452,9 @@ export default { ...@@ -430,7 +452,9 @@ export default {
httpRequest: { httpRequest: {
status: true, status: true,
msg: '' msg: ''
} },
selectTableFlag: false,
changeTable: {}
} }
}, },
computed: { computed: {
...@@ -556,6 +580,7 @@ export default { ...@@ -556,6 +580,7 @@ export default {
if (needRefreshGroup) { if (needRefreshGroup) {
this.refreshGroup(view) this.refreshGroup(view)
} }
this.closeChangeChart()
}) })
}, },
...@@ -628,6 +653,7 @@ export default { ...@@ -628,6 +653,7 @@ export default {
// 从仪表板入口关闭 // 从仪表板入口关闭
bus.$emit('PanelSwitchComponent', { name: 'PanelEdit' }) bus.$emit('PanelSwitchComponent', { name: 'PanelEdit' })
// this.$emit('switchComponent', { name: '' }) // this.$emit('switchComponent', { name: '' })
this.$success(this.$t('commons.save_success'))
}, },
getData(id) { getData(id) {
if (id) { if (id) {
...@@ -930,6 +956,26 @@ export default { ...@@ -930,6 +956,26 @@ export default {
refreshGroup(view) { refreshGroup(view) {
this.$emit('saveSuccess', view) this.$emit('saveSuccess', view)
},
getTable(table) {
this.changeTable = JSON.parse(JSON.stringify(table))
},
changeDs() {
this.selectTableFlag = true
},
closeChangeChart() {
this.selectTableFlag = false
},
changeChart() {
this.view.tableId = this.changeTable.id
this.view.xaxis = []
this.view.yaxis = []
this.view.customFilter = []
this.save(true, 'chart', false)
} }
} }
} }
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
<el-form-item class="form-item"> <el-form-item class="form-item">
<el-input v-model="name" size="mini" :placeholder="$t('commons.name')" /> <el-input v-model="name" size="mini" :placeholder="$t('commons.name')" />
</el-form-item> </el-form-item>
<el-form-item class="form-item"> <el-form-item v-if="!param.tableId" class="form-item">
<el-select v-model="mode" filterable :placeholder="$t('dataset.connect_mode')" size="mini"> <el-select v-model="mode" filterable :placeholder="$t('dataset.connect_mode')" size="mini">
<el-option :label="$t('dataset.direct_connect')" value="0" /> <el-option :label="$t('dataset.direct_connect')" value="0" />
<el-option :label="$t('dataset.sync_data')" value="1" :disabled="!kettleRunning" /> <el-option :label="$t('dataset.sync_data')" value="1" :disabled="!kettleRunning" />
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论