feat:【系统设置】支持引擎设置

This commit is contained in:
taojinlong 2024-02-28 16:51:46 +08:00
parent 89e67eec38
commit c7b6c274aa
15 changed files with 1502 additions and 150 deletions

View File

@ -22,9 +22,9 @@ import io.dataease.dataset.utils.SqlUtils;
import io.dataease.dataset.utils.TableUtils; import io.dataease.dataset.utils.TableUtils;
import io.dataease.datasource.dao.auto.entity.CoreDatasource; import io.dataease.datasource.dao.auto.entity.CoreDatasource;
import io.dataease.datasource.dao.auto.mapper.CoreDatasourceMapper; import io.dataease.datasource.dao.auto.mapper.CoreDatasourceMapper;
import io.dataease.datasource.manage.EngineManage;
import io.dataease.datasource.provider.CalciteProvider; import io.dataease.datasource.provider.CalciteProvider;
import io.dataease.datasource.request.DatasourceRequest; import io.dataease.datasource.request.DatasourceRequest;
import io.dataease.datasource.server.EngineServer;
import io.dataease.dto.dataset.DatasetTableFieldDTO; import io.dataease.dto.dataset.DatasetTableFieldDTO;
import io.dataease.engine.constant.ExtFieldConstant; import io.dataease.engine.constant.ExtFieldConstant;
import io.dataease.engine.constant.SQLConstants; import io.dataease.engine.constant.SQLConstants;
@ -66,9 +66,7 @@ public class DatasetDataManage {
@Resource @Resource
private DatasetTableFieldManage datasetTableFieldManage; private DatasetTableFieldManage datasetTableFieldManage;
@Resource @Resource
private DatasetTableManage datasetTableManage; private EngineManage engineManage;
@Resource
private EngineServer engineServer;
@Resource @Resource
private DatasetGroupManage datasetGroupManage; private DatasetGroupManage datasetGroupManage;
@Resource @Resource
@ -89,7 +87,7 @@ public class DatasetDataManage {
CoreDatasource coreDatasource = coreDatasourceMapper.selectById(datasetTableDTO.getDatasourceId()); CoreDatasource coreDatasource = coreDatasourceMapper.selectById(datasetTableDTO.getDatasourceId());
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO(); DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();
if (StringUtils.equalsIgnoreCase("excel", coreDatasource.getType()) || StringUtils.equalsIgnoreCase("api", coreDatasource.getType())) { if (StringUtils.equalsIgnoreCase("excel", coreDatasource.getType()) || StringUtils.equalsIgnoreCase("api", coreDatasource.getType())) {
coreDatasource = engineServer.getDeEngine(); coreDatasource = engineManage.getDeEngine();
} }
BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource); BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource);
datasourceSchemaDTO.setSchemaAlias(String.format(SQLConstants.SCHEMA, datasourceSchemaDTO.getId())); datasourceSchemaDTO.setSchemaAlias(String.format(SQLConstants.SCHEMA, datasourceSchemaDTO.getId()));
@ -112,7 +110,7 @@ public class DatasetDataManage {
tableFields = (List<TableField>) calciteProvider.fetchResultField(datasourceRequest).get("fields"); tableFields = (List<TableField>) calciteProvider.fetchResultField(datasourceRequest).get("fields");
} else { } else {
// excel,api // excel,api
CoreDatasource coreDatasource = engineServer.getDeEngine(); CoreDatasource coreDatasource = engineManage.getDeEngine();
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO(); DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();
BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource); BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource);
datasourceSchemaDTO.setSchemaAlias(String.format(SQLConstants.SCHEMA, datasourceSchemaDTO.getId())); datasourceSchemaDTO.setSchemaAlias(String.format(SQLConstants.SCHEMA, datasourceSchemaDTO.getId()));
@ -274,7 +272,7 @@ public class DatasetDataManage {
CoreDatasource coreDatasource = coreDatasourceMapper.selectById(dto.getDatasourceId()); CoreDatasource coreDatasource = coreDatasourceMapper.selectById(dto.getDatasourceId());
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO(); DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();
if (coreDatasource.getType().equalsIgnoreCase("API") || coreDatasource.getType().equalsIgnoreCase("Excel")) { if (coreDatasource.getType().equalsIgnoreCase("API") || coreDatasource.getType().equalsIgnoreCase("Excel")) {
BeanUtils.copyBean(datasourceSchemaDTO, engineServer.getDeEngine()); BeanUtils.copyBean(datasourceSchemaDTO, engineManage.getDeEngine());
} else { } else {
BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource); BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource);
} }

View File

@ -16,7 +16,7 @@ import io.dataease.dataset.utils.SqlUtils;
import io.dataease.dataset.utils.TableUtils; import io.dataease.dataset.utils.TableUtils;
import io.dataease.datasource.dao.auto.entity.CoreDatasource; import io.dataease.datasource.dao.auto.entity.CoreDatasource;
import io.dataease.datasource.dao.auto.mapper.CoreDatasourceMapper; import io.dataease.datasource.dao.auto.mapper.CoreDatasourceMapper;
import io.dataease.datasource.server.EngineServer; import io.dataease.datasource.manage.EngineManage;
import io.dataease.dto.dataset.DatasetTableFieldDTO; import io.dataease.dto.dataset.DatasetTableFieldDTO;
import io.dataease.engine.constant.ExtFieldConstant; import io.dataease.engine.constant.ExtFieldConstant;
import io.dataease.engine.constant.SQLConstants; import io.dataease.engine.constant.SQLConstants;
@ -46,7 +46,7 @@ public class DatasetSQLManage {
@Resource @Resource
private CoreDatasourceMapper coreDatasourceMapper; private CoreDatasourceMapper coreDatasourceMapper;
@Resource @Resource
private EngineServer engineServer; private EngineManage engineManage;
@Resource @Resource
private CorePermissionManage corePermissionManage; private CorePermissionManage corePermissionManage;
@ -340,7 +340,7 @@ public class DatasetSQLManage {
DEException.throwException(Translator.get("i18n_dataset_ds_error") + ",ID:" + ds.getDatasourceId()); DEException.throwException(Translator.get("i18n_dataset_ds_error") + ",ID:" + ds.getDatasourceId());
} }
if (StringUtils.equalsIgnoreCase("excel", coreDatasource.getType()) || StringUtils.equalsIgnoreCase("api", coreDatasource.getType())) { if (StringUtils.equalsIgnoreCase("excel", coreDatasource.getType()) || StringUtils.equalsIgnoreCase("api", coreDatasource.getType())) {
coreDatasource = engineServer.getDeEngine(); coreDatasource = engineManage.getDeEngine();
} }
schemaAlias = String.format(SQLConstants.SCHEMA, coreDatasource.getId()); schemaAlias = String.format(SQLConstants.SCHEMA, coreDatasource.getId());
if (!dsMap.containsKey(coreDatasource.getId())) { if (!dsMap.containsKey(coreDatasource.getId())) {
@ -350,7 +350,7 @@ public class DatasetSQLManage {
dsMap.put(coreDatasource.getId(), datasourceSchemaDTO); dsMap.put(coreDatasource.getId(), datasourceSchemaDTO);
} }
} else { } else {
CoreDatasource coreDatasource = engineServer.getDeEngine(); CoreDatasource coreDatasource = engineManage.getDeEngine();
schemaAlias = String.format(SQLConstants.SCHEMA, coreDatasource.getId()); schemaAlias = String.format(SQLConstants.SCHEMA, coreDatasource.getId());
if (!dsMap.containsKey(coreDatasource.getId())) { if (!dsMap.containsKey(coreDatasource.getId())) {
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO(); DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();

View File

@ -44,7 +44,7 @@ public class DatasourceSyncManage {
@Resource @Resource
private CoreDatasourceMapper datasourceMapper; private CoreDatasourceMapper datasourceMapper;
@Resource @Resource
private EngineServer engineServer; private EngineManage engineManage;
@Resource @Resource
private DatasourceTaskServer datasourceTaskServer; private DatasourceTaskServer datasourceTaskServer;
@Resource @Resource
@ -231,7 +231,7 @@ public class DatasourceSyncManage {
engineTableName = TableUtils.tableName(datasourceRequest.getTable()); engineTableName = TableUtils.tableName(datasourceRequest.getTable());
break; break;
} }
CoreDeEngine engine = engineServer.info(); CoreDeEngine engine = engineManage.info();
EngineRequest engineRequest = new EngineRequest(); EngineRequest engineRequest = new EngineRequest();
engineRequest.setEngine(engine); engineRequest.setEngine(engine);
@ -262,7 +262,7 @@ public class DatasourceSyncManage {
engineTableName = TableUtils.tableName(datasourceRequest.getTable()); engineTableName = TableUtils.tableName(datasourceRequest.getTable());
break; break;
} }
CoreDeEngine engine = engineServer.info(); CoreDeEngine engine = engineManage.info();
EngineRequest engineRequest = new EngineRequest(); EngineRequest engineRequest = new EngineRequest();
engineRequest.setEngine(engine); engineRequest.setEngine(engine);
@ -281,7 +281,7 @@ public class DatasourceSyncManage {
} }
private void replaceTable(String tableName) throws Exception { private void replaceTable(String tableName) throws Exception {
CoreDeEngine engine = engineServer.info(); CoreDeEngine engine = engineManage.info();
EngineRequest engineRequest = new EngineRequest(); EngineRequest engineRequest = new EngineRequest();
engineRequest.setEngine(engine); engineRequest.setEngine(engine);
EngineProvider engineProvider = ProviderUtil.getEngineProvider(engine.getType()); EngineProvider engineProvider = ProviderUtil.getEngineProvider(engine.getType());
@ -295,7 +295,7 @@ public class DatasourceSyncManage {
} }
public void createEngineTable(String tableName, List<TableField> tableFields) throws Exception { public void createEngineTable(String tableName, List<TableField> tableFields) throws Exception {
CoreDeEngine engine = engineServer.info(); CoreDeEngine engine = engineManage.info();
EngineRequest engineRequest = new EngineRequest(); EngineRequest engineRequest = new EngineRequest();
engineRequest.setEngine(engine); engineRequest.setEngine(engine);
EngineProvider engineProvider = ProviderUtil.getEngineProvider(engine.getType()); EngineProvider engineProvider = ProviderUtil.getEngineProvider(engine.getType());
@ -304,7 +304,7 @@ public class DatasourceSyncManage {
} }
public void dropEngineTable(String tableName) throws Exception{ public void dropEngineTable(String tableName) throws Exception{
CoreDeEngine engine = engineServer.info(); CoreDeEngine engine = engineManage.info();
EngineRequest engineRequest = new EngineRequest(); EngineRequest engineRequest = new EngineRequest();
engineRequest.setEngine(engine); engineRequest.setEngine(engine);
EngineProvider engineProvider = ProviderUtil.getEngineProvider(engine.getType()); EngineProvider engineProvider = ProviderUtil.getEngineProvider(engine.getType());

View File

@ -12,8 +12,8 @@ import io.dataease.dataset.utils.FieldUtils;
import io.dataease.datasource.dao.auto.entity.CoreDatasource; import io.dataease.datasource.dao.auto.entity.CoreDatasource;
import io.dataease.datasource.dao.auto.entity.CoreDriver; import io.dataease.datasource.dao.auto.entity.CoreDriver;
import io.dataease.datasource.dao.auto.mapper.CoreDatasourceMapper; import io.dataease.datasource.dao.auto.mapper.CoreDatasourceMapper;
import io.dataease.datasource.manage.EngineManage;
import io.dataease.datasource.request.DatasourceRequest; import io.dataease.datasource.request.DatasourceRequest;
import io.dataease.datasource.server.EngineServer;
import io.dataease.datasource.type.*; import io.dataease.datasource.type.*;
import io.dataease.engine.constant.SQLConstants; import io.dataease.engine.constant.SQLConstants;
import io.dataease.exception.DEException; import io.dataease.exception.DEException;
@ -50,7 +50,7 @@ public class CalciteProvider {
@Resource @Resource
protected CoreDatasourceMapper coreDatasourceMapper; protected CoreDatasourceMapper coreDatasourceMapper;
@Resource @Resource
private EngineServer engineServer; private EngineManage engineManage;
protected ExtendedJdbcClassLoader extendedJdbcClassLoader; protected ExtendedJdbcClassLoader extendedJdbcClassLoader;
private Map<Long, ExtendedJdbcClassLoader> customJdbcClassLoaders = new HashMap<>(); private Map<Long, ExtendedJdbcClassLoader> customJdbcClassLoaders = new HashMap<>();
private final String FILE_PATH = "/opt/dataease2.0/drivers"; private final String FILE_PATH = "/opt/dataease2.0/drivers";
@ -656,7 +656,7 @@ public class CalciteProvider {
LogUtil.info("Begin to init datasource pool..."); LogUtil.info("Begin to init datasource pool...");
QueryWrapper<CoreDatasource> datasourceQueryWrapper = new QueryWrapper(); QueryWrapper<CoreDatasource> datasourceQueryWrapper = new QueryWrapper();
List<CoreDatasource> coreDatasources = coreDatasourceMapper.selectList(datasourceQueryWrapper).stream().filter(coreDatasource -> !Arrays.asList("folder", "API", "Excel").contains(coreDatasource.getType())).collect(Collectors.toList()); List<CoreDatasource> coreDatasources = coreDatasourceMapper.selectList(datasourceQueryWrapper).stream().filter(coreDatasource -> !Arrays.asList("folder", "API", "Excel").contains(coreDatasource.getType())).collect(Collectors.toList());
CoreDatasource engine = engineServer.deEngine(); CoreDatasource engine = engineManage.deEngine();
if (engine != null) { if (engine != null) {
coreDatasources.add(engine); coreDatasources.add(engine);
} }

View File

@ -27,6 +27,7 @@ import io.dataease.datasource.dao.ext.mapper.DataSourceExtMapper;
import io.dataease.datasource.dao.ext.mapper.TaskLogExtMapper; import io.dataease.datasource.dao.ext.mapper.TaskLogExtMapper;
import io.dataease.datasource.manage.DataSourceManage; import io.dataease.datasource.manage.DataSourceManage;
import io.dataease.datasource.manage.DatasourceSyncManage; import io.dataease.datasource.manage.DatasourceSyncManage;
import io.dataease.datasource.manage.EngineManage;
import io.dataease.datasource.provider.ApiUtils; import io.dataease.datasource.provider.ApiUtils;
import io.dataease.datasource.provider.CalciteProvider; import io.dataease.datasource.provider.CalciteProvider;
import io.dataease.datasource.provider.ExcelUtils; import io.dataease.datasource.provider.ExcelUtils;
@ -70,7 +71,7 @@ public class DatasourceServer implements DatasourceApi {
@Resource @Resource
private CoreDatasourceMapper datasourceMapper; private CoreDatasourceMapper datasourceMapper;
@Resource @Resource
private EngineServer engineServer; private EngineManage engineManage;
@Resource @Resource
private DatasourceTaskServer datasourceTaskServer; private DatasourceTaskServer datasourceTaskServer;
@Resource @Resource
@ -737,9 +738,9 @@ public class DatasourceServer implements DatasourceApi {
DatasourceRequest datasourceRequest = new DatasourceRequest(); DatasourceRequest datasourceRequest = new DatasourceRequest();
datasourceRequest.setDatasource(coreDatasource); datasourceRequest.setDatasource(coreDatasource);
if (coreDatasource.getType().equals("API") || coreDatasource.getType().equals("Excel")) { if (coreDatasource.getType().equals("API") || coreDatasource.getType().equals("Excel")) {
datasourceRequest.setDatasource(engineServer.getDeEngine()); datasourceRequest.setDatasource(engineManage.getDeEngine());
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO(); DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();
BeanUtils.copyBean(datasourceSchemaDTO, engineServer.getDeEngine()); BeanUtils.copyBean(datasourceSchemaDTO, engineManage.getDeEngine());
datasourceSchemaDTO.setSchemaAlias(String.format(SQLConstants.SCHEMA, datasourceSchemaDTO.getId())); datasourceSchemaDTO.setSchemaAlias(String.format(SQLConstants.SCHEMA, datasourceSchemaDTO.getId()));
datasourceRequest.setDsList(Map.of(datasourceSchemaDTO.getId(), datasourceSchemaDTO)); datasourceRequest.setDsList(Map.of(datasourceSchemaDTO.getId(), datasourceSchemaDTO));
datasourceRequest.setQuery(TableUtils.tableName2Sql(datasourceSchemaDTO, tableName) + " LIMIT 0 OFFSET 0"); datasourceRequest.setQuery(TableUtils.tableName2Sql(datasourceSchemaDTO, tableName) + " LIMIT 0 OFFSET 0");

View File

@ -1,151 +1,69 @@
package io.dataease.datasource.server; package io.dataease.datasource.server;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import io.dataease.api.ds.vo.DatasourceDTO;
import io.dataease.datasource.dao.auto.entity.CoreDatasource; import io.dataease.api.ds.EngineApi;
import io.dataease.datasource.dao.auto.entity.CoreDeEngine; import io.dataease.datasource.dao.auto.entity.CoreDeEngine;
import io.dataease.datasource.dao.auto.mapper.CoreDeEngineMapper; import io.dataease.datasource.dao.auto.mapper.CoreDeEngineMapper;
import io.dataease.datasource.provider.EngineProvider; import io.dataease.datasource.manage.EngineManage;
import io.dataease.datasource.provider.ProviderUtil;
import io.dataease.datasource.request.DatasourceRequest;
import io.dataease.datasource.type.H2;
import io.dataease.datasource.type.Mysql;
import io.dataease.exception.DEException;
import io.dataease.result.ResultMessage;
import io.dataease.utils.BeanUtils; import io.dataease.utils.BeanUtils;
import io.dataease.utils.JsonUtil; import io.dataease.utils.IDUtils;
import io.dataease.utils.ModelUtils;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*; import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static io.dataease.result.ResultCode.DATA_IS_WRONG; @RestController
@RequestMapping("/engine")
@Service
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public class EngineServer { public class EngineServer implements EngineApi {
@Resource
private Environment env;
@Resource @Resource
private CoreDeEngineMapper deEngineMapper; private CoreDeEngineMapper deEngineMapper;
@Resource
private EngineManage engineManage;
public CoreDeEngine info() throws DEException { @Override
public DatasourceDTO getEngine() {
DatasourceDTO datasourceDTO = new DatasourceDTO();
List<CoreDeEngine> deEngines = deEngineMapper.selectList(null); List<CoreDeEngine> deEngines = deEngineMapper.selectList(null);
if (CollectionUtils.isEmpty(deEngines)) { if (CollectionUtils.isEmpty(deEngines)) {
DEException.throwException("未完整设置数据引擎"); return datasourceDTO;
} }
return deEngines.get(0); return BeanUtils.copyBean(datasourceDTO, deEngines.get(0));
} }
public CoreDatasource getDeEngine(){ @Override
List<CoreDeEngine> deEngines = deEngineMapper.selectList(null); public void save(DatasourceDTO datasourceDTO) {
if(CollectionUtils.isEmpty(deEngines)){ if (StringUtils.isNotEmpty(datasourceDTO.getConfiguration())) {
DEException.throwException("未完整设置数据引擎"); datasourceDTO.setConfiguration(new String(Base64.getDecoder().decode(datasourceDTO.getConfiguration())));
} }
CoreDatasource coreDatasource = new CoreDatasource();
BeanUtils.copyBean(coreDatasource, deEngines.get(0));
return coreDatasource;
}
CoreDeEngine coreDeEngine = new CoreDeEngine();
public CoreDatasource deEngine(){ BeanUtils.copyBean(coreDeEngine, datasourceDTO);
List<CoreDeEngine> deEngines = deEngineMapper.selectList(null); if(coreDeEngine.getId() == null){
CoreDatasource coreDatasource = new CoreDatasource(); coreDeEngine.setId(IDUtils.snowID());
if(CollectionUtils.isEmpty(deEngines)){ deEngineMapper.insert(coreDeEngine);
return null;
}
BeanUtils.copyBean(coreDatasource, deEngines.get(0));
return coreDatasource;
}
public ResultMessage validate(CoreDeEngine engine) throws Exception {
if (StringUtils.isEmpty(engine.getType()) || StringUtils.isEmpty(engine.getConfiguration())) {
throw new Exception("未完整设置数据引擎");
}
try {
EngineProvider provider = ProviderUtil.getEngineProvider(engine.getType());
DatasourceRequest datasourceRequest = new DatasourceRequest();
CoreDatasource datasource = new CoreDatasource();
BeanUtils.copyBean(datasource, engine);
datasourceRequest.setDatasource(datasource);
provider.checkStatus(datasourceRequest);
return ResultMessage.success(datasource);
} catch (Exception e) {
return ResultMessage.failure(DATA_IS_WRONG, "Engine is invalid: " + e.getMessage());
}
}
public ResultMessage save(CoreDeEngine engine) throws Exception {
if (engine.getId() == null) {
deEngineMapper.insert(engine);
} else {
deEngineMapper.updateById(engine);
}
return ResultMessage.success(engine);
}
public void initSimpleEngine() throws Exception{
QueryWrapper<CoreDeEngine> queryWrapper = new QueryWrapper<>();
if(ModelUtils.isDesktop()){
queryWrapper.eq("type", engineType.h2.name());
}else { }else {
queryWrapper.eq("type", engineType.mysql.name()); deEngineMapper.updateById(coreDeEngine);
}
List<CoreDeEngine> deEngines = deEngineMapper.selectList(queryWrapper);
if (!CollectionUtils.isEmpty(deEngines)) {
return;
} }
}
CoreDeEngine engine = new CoreDeEngine(); @Override
if(ModelUtils.isDesktop()){ public void validate(DatasourceDTO datasourceDTO) throws Exception{
engine.setType(engineType.h2.name()); CoreDeEngine coreDeEngine = new CoreDeEngine();
H2 h2 = new H2(); BeanUtils.copyBean(coreDeEngine, datasourceDTO);
h2.setJdbc("jdbc:h2:/opt/dataease2.0/desktop_data;AUTO_SERVER=TRUE;AUTO_RECONNECT=TRUE;MODE=MySQL"); coreDeEngine.setConfiguration(new String(Base64.getDecoder().decode(coreDeEngine.getConfiguration())));
h2.setDataBase("PUBLIC"); engineManage.validate(coreDeEngine);
h2.setUsername(env.getProperty("spring.datasource.username")); }
h2.setPassword(env.getProperty("spring.datasource.password"));
engine.setConfiguration(JsonUtil.toJSONString(h2).toString()); @Override
}else { public void validateById(Long id) throws Exception {
engine.setType(engineType.mysql.name()); engineManage.validate(deEngineMapper.selectById(id));
Mysql mysqlConfiguration = new Mysql();
Pattern WITH_SQL_FRAGMENT = Pattern.compile("jdbc:mysql://(.*):(\\d+)/(.*)");
Matcher matcher = WITH_SQL_FRAGMENT.matcher(env.getProperty("spring.datasource.url"));
if (!matcher.find()) {
return;
}
mysqlConfiguration.setHost(matcher.group(1));
mysqlConfiguration.setPort(Integer.valueOf(matcher.group(2)));
String[] databasePrams = matcher.group(3).split("\\?");
mysqlConfiguration.setDataBase(databasePrams[0]);
if(databasePrams.length == 2){
mysqlConfiguration.setExtraParams(databasePrams[1]);
}
mysqlConfiguration.setUsername(env.getProperty("spring.datasource.username"));
mysqlConfiguration.setPassword(env.getProperty("spring.datasource.password"));
engine.setConfiguration(JsonUtil.toJSONString(mysqlConfiguration).toString());
}
deEngineMapper.insert(engine);
} }
public enum engineType {
mysql("Mysql"),
h2("h2");
private String alias;
private engineType(String alias) {
this.alias = alias;
}
public String getAlias() {
return alias;
}
}
} }

View File

@ -2,10 +2,10 @@ package io.dataease.listener;
import io.dataease.datasource.dao.auto.entity.CoreDatasourceTask; import io.dataease.datasource.dao.auto.entity.CoreDatasourceTask;
import io.dataease.datasource.manage.DatasourceSyncManage; import io.dataease.datasource.manage.DatasourceSyncManage;
import io.dataease.datasource.manage.EngineManage;
import io.dataease.datasource.provider.CalciteProvider; import io.dataease.datasource.provider.CalciteProvider;
import io.dataease.datasource.server.DatasourceServer; import io.dataease.datasource.server.DatasourceServer;
import io.dataease.datasource.server.DatasourceTaskServer; import io.dataease.datasource.server.DatasourceTaskServer;
import io.dataease.datasource.server.EngineServer;
import io.dataease.system.dao.auto.entity.CoreSysSetting; import io.dataease.system.dao.auto.entity.CoreSysSetting;
import io.dataease.system.manage.SysParameterManage; import io.dataease.system.manage.SysParameterManage;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -30,14 +30,14 @@ public class DataSourceInitStartListener implements ApplicationListener<Applicat
@Resource @Resource
private CalciteProvider calciteProvider; private CalciteProvider calciteProvider;
@Resource @Resource
private EngineServer engineServer; private EngineManage engineManage;
@Resource @Resource
private SysParameterManage sysParameterManage; private SysParameterManage sysParameterManage;
@Override @Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
try { try {
engineServer.initSimpleEngine(); engineManage.initSimpleEngine();
}catch (Exception e){ }catch (Exception e){
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -161,3 +161,5 @@ export const uploadFile = async (data): Promise<IResponse> => {
export const listSyncRecord = (page: number, limit: number, dsId: number | string) => export const listSyncRecord = (page: number, limit: number, dsId: number | string) =>
request.post({ url: '/datasource/listSyncRecord/' + dsId + '/' + page + '/' + limit }) request.post({ url: '/datasource/listSyncRecord/' + dsId + '/' + page + '/' + limit })
export const getDeEngine = () => request.get({ url: '/engine/getEngine' })

View File

@ -292,6 +292,7 @@ export default {
modify: '编辑数据源', modify: '编辑数据源',
copy: '复制数据源', copy: '复制数据源',
validate_success: '校验成功', validate_success: '校验成功',
validate_failed: '校验失败',
validate: '校验', validate: '校验',
search_by_name: '根据名称搜索', search_by_name: '根据名称搜索',
delete_warning: '确定要删除吗?', delete_warning: '确定要删除吗?',

View File

@ -66,11 +66,11 @@ declare interface ChartBasicStyle {
/** /**
* 字段ID * 字段ID
*/ */
fieldId: string, fieldId: string
/** /**
* 字段名称 * 字段名称
*/ */
name: string, name: string
/** /**
* 字段宽度占比 * 字段宽度占比
*/ */

View File

@ -0,0 +1,406 @@
<script lang="ts" setup>
import { ref, reactive } from 'vue'
import { ElMessage, ElLoading } from 'element-plus-secondary'
import { useI18n } from '@/hooks/web/useI18n'
import request from '@/config/axios'
import { dsTypes, Node } from '@/views/visualized/data/datasource/form/option'
import { cloneDeep } from 'lodash-es'
import { CustomPassword } from '@/components/custom-password'
import { Base64 } from 'js-base64'
const { t } = useI18n()
const dialogVisible = ref(false)
const loadingInstance = ref(null)
const defaultRule = {
name: [
{
required: true,
message: t('datasource.input_name'),
trigger: 'blur'
},
{
min: 2,
max: 64,
message: t('datasource.input_limit_2_25', [2, 64]),
trigger: 'blur'
}
]
}
const configRules = {
'configuration.dataBase': [
{
required: true,
message: t('datasource.please_input_data_base'),
trigger: 'blur'
}
],
'configuration.username': [
{
required: true,
message: t('datasource.please_input_user_name'),
trigger: 'blur'
}
],
'configuration.password': [
{
required: true,
message: t('datasource.please_input_password'),
trigger: 'blur'
}
],
'configuration.host': [
{
required: true,
message: t('datasource._ip_address'),
trigger: 'blur'
}
],
'configuration.extraParams': [
{
required: false,
message: t('datasource.please_input_url'),
trigger: 'blur'
}
],
'configuration.port': [
{
required: true,
message: t('datasource.please_input_port'),
trigger: 'blur'
}
],
'configuration.initialPoolSize': [
{
required: true,
message: t('common.inputText') + t('datasource.initial_pool_size'),
trigger: 'blur'
}
],
'configuration.minPoolSize': [
{
required: true,
message: t('common.inputText') + t('datasource.min_pool_size'),
trigger: 'blur'
}
],
'configuration.maxPoolSize': [
{
required: true,
message: t('common.inputText') + t('datasource.max_pool_size'),
trigger: 'blur'
}
],
'configuration.queryTimeout': [
{
required: true,
message: t('common.inputText') + t('datasource.query_timeout'),
trigger: 'blur'
}
]
}
const rule = { ...cloneDeep(configRules), ...cloneDeep(defaultRule) }
const emits = defineEmits(['saved'])
const resetForm = () => {
dialogVisible.value = false
Object.assign(nodeInfo, cloneDeep(defaultInfo))
}
const reset = () => {
resetForm()
}
const showLoading = () => {
loadingInstance.value = ElLoading.service({ target: '.basic-param-drawer' })
}
const closeLoading = () => {
loadingInstance.value?.close()
}
const showPriority = ref(false)
const defaultInfo = {
name: '',
createBy: '',
creator: '',
createTime: '',
description: '',
id: 0,
size: 0,
nodeType: '',
type: '',
fileName: '',
configuration: {},
syncSetting: null,
apiConfiguration: [],
weight: 0
}
const nodeInfo = reactive<Node>(cloneDeep(defaultInfo))
const edit = info => {
Object.assign(nodeInfo, cloneDeep(info))
dialogVisible.value = true
}
const basicForm = ref()
const submitForm = async () => {
let data = JSON.parse(JSON.stringify(nodeInfo)) as unknown as Omit<
Node,
'configuration' | 'apiConfiguration'
> & {
configuration: string
apiConfiguration: string
}
data.configuration = Base64.encode(JSON.stringify(data.configuration))
basicForm.value.validate(result => {
if (result) {
showLoading()
request
.post({ url: '/engine/save', data: data })
.then(res => {
if (res !== undefined) {
console.log(res)
ElMessage.success(t('common.save_success'))
emits('saved')
reset()
}
closeLoading()
})
.catch(() => {
closeLoading()
})
}
})
}
const validate = async () => {
let data = JSON.parse(JSON.stringify(nodeInfo)) as unknown as Omit<
Node,
'configuration' | 'apiConfiguration'
> & {
configuration: string
apiConfiguration: string
}
data.configuration = Base64.encode(JSON.stringify(data.configuration))
basicForm.value.validate(result => {
if (result) {
showLoading()
request
.post({ url: '/engine/validate', data: data })
.then(res => {
if (res !== undefined) {
ElMessage.success(t('datasource.validate_success'))
}
closeLoading()
})
.catch(() => {
closeLoading()
})
}
})
}
defineExpose({
edit
})
</script>
<template>
<el-drawer
title="引擎设置"
v-model="dialogVisible"
custom-class="basic-param-drawer"
size="600px"
direction="rtl"
>
<el-form
ref="basicForm"
require-asterisk-position="right"
:model="nodeInfo"
:rules="rule"
label-width="80px"
label-position="top"
>
<el-form-item :label="t('datasource.type')">
<el-select v-model="nodeInfo.type" class="de-select" disabled>
<el-option
v-for="item in dsTypes"
:key="item.type"
:label="item.name"
:value="item.type"
/>
</el-select>
</el-form-item>
<el-form-item :label="t('datasource.host')" prop="configuration.host">
<el-input
v-model="nodeInfo.configuration.host"
:placeholder="t('datasource._ip_address')"
autocomplete="off"
/>
</el-form-item>
<el-form-item :label="t('datasource.port')" prop="configuration.port">
<el-input-number
v-model="nodeInfo.configuration.port"
autocomplete="off"
step-strictly
class="text-left"
:min="0"
:placeholder="t('common.inputText') + t('datasource.port')"
controls-position="right"
type="number"
/>
</el-form-item>
<el-form-item :label="t('datasource.data_base')" prop="configuration.dataBase">
<el-input
v-model="nodeInfo.configuration.dataBase"
:placeholder="t('datasource.please_input_data_base')"
autocomplete="off"
/>
</el-form-item>
<el-form-item :label="t('datasource.user_name')">
<el-input
:placeholder="t('common.inputText') + t('datasource.user_name')"
v-model="nodeInfo.configuration.username"
autocomplete="off"
/>
</el-form-item>
<el-form-item :label="t('datasource.password')">
<CustomPassword
:placeholder="t('common.inputText') + t('datasource.password')"
show-password
type="password"
v-model="nodeInfo.configuration.password"
/>
</el-form-item>
<el-form-item :label="t('datasource.extra_params')">
<el-input
:placeholder="t('common.inputText') + t('datasource.extra_params')"
v-model="nodeInfo.configuration.extraParams"
autocomplete="off"
/>
</el-form-item>
<span class="de-expand" @click="showPriority = !showPriority"
>{{ t('datasource.priority') }}
<el-icon>
<Icon :name="showPriority ? 'icon_down_outlined' : 'icon_down_outlined-1'"></Icon>
</el-icon>
</span>
<template v-if="showPriority">
<el-row :gutter="24" class="mb16">
<el-col :span="12">
<el-form-item
:label="t('datasource.initial_pool_size')"
prop="configuration.initialPoolSize"
>
<el-input-number
v-model="nodeInfo.configuration.initialPoolSize"
controls-position="right"
autocomplete="off"
:placeholder="t('common.inputText') + t('datasource.initial_pool_size')"
type="number"
:min="0"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item :label="t('datasource.min_pool_size')" prop="configuration.minPoolSize">
<el-input-number
v-model="nodeInfo.configuration.minPoolSize"
controls-position="right"
autocomplete="off"
:placeholder="t('common.inputText') + t('datasource.min_pool_size')"
type="number"
:min="0"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<el-form-item :label="t('datasource.max_pool_size')" prop="configuration.maxPoolSize">
<el-input-number
v-model="nodeInfo.configuration.maxPoolSize"
controls-position="right"
autocomplete="off"
:placeholder="t('common.inputText') + t('datasource.max_pool_size')"
type="number"
:min="0"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
:label="`${t('datasource.query_timeout')}(${t('common.second')})`"
prop="configuration.queryTimeout"
>
<el-input-number
v-model="nodeInfo.configuration.queryTimeout"
controls-position="right"
autocomplete="off"
:placeholder="t('common.inputText') + t('datasource.query_timeout')"
type="number"
:min="0"
/>
</el-form-item>
</el-col>
</el-row>
</template>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button secondary @click="resetForm()">{{ t('common.cancel') }}</el-button>
<el-button secondary @click="validate()">{{ t('datasource.validate') }}</el-button>
<el-button type="primary" @click="submitForm()">
{{ t('commons.save') }}
</el-button>
</span>
</template>
</el-drawer>
</template>
<style lang="less">
.basic-param-drawer {
.ed-drawer__footer {
height: 64px !important;
padding: 16px 24px !important;
.dialog-footer {
height: 32px;
line-height: 32px;
}
}
.ed-form-item__label {
line-height: 22px !important;
height: 22px !important;
}
}
</style>
<style scoped lang="less">
.basic-param-drawer {
.ed-form-item {
margin-bottom: 16px;
}
.is-error {
margin-bottom: 40px !important;
}
.edit-all-line {
width: 552px !important;
}
}
.setting-hidden-item {
display: none !important;
}
.ds-task-form-inline {
width: 100%;
display: flex;
.ed-input-number {
width: 140px;
margin: 0 6px;
}
.ed-select {
width: 240px;
:deep(.ed-input) {
width: 100% !important;
}
}
span.ds-span {
margin-left: 6px;
}
}
</style>

View File

@ -0,0 +1,482 @@
<template>
<EngineInfoTemplate
ref="engineInfoTemplate"
setting-key="engine"
setting-title="基础设置"
:nodeInfo="nodeInfo"
@edit="edit"
/>
<engine-edit ref="editor" @saved="refresh" />
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { reactive } from 'vue'
import { cloneDeep } from 'lodash-es'
import { useI18n } from '@/hooks/web/useI18n'
import { Node } from '@/views/visualized/data/datasource/form/option'
import { getDeEngine } from '@/api/datasource'
import EngineInfoTemplate from '@/views/system/parameter/engine/EngineInfoTemplate.vue'
import EngineEdit from '@/views/system/parameter/engine/EngineEdit.vue'
const editor = ref()
const engineInfoTemplate = ref()
const defaultInfo = {
name: 'aaaaa',
createBy: '',
creator: '',
createTime: '',
description: '',
id: 0,
size: 0,
nodeType: '',
type: '',
fileName: '',
configuration: {},
syncSetting: null,
apiConfiguration: [],
weight: 0
}
const nodeInfo = reactive<Node>(cloneDeep(defaultInfo))
const { t } = useI18n()
const edit = () => {
editor?.value.edit(cloneDeep(nodeInfo))
}
const getEngine = () => {
return getDeEngine().then(res => {
let {
name,
createBy,
id,
createTime,
creator,
type,
pid,
configuration,
syncSetting,
fileName,
size,
description,
lastSyncTime
} = res.data
if (configuration) {
configuration = JSON.parse(configuration)
}
Object.assign(nodeInfo, {
name,
pid,
description,
fileName,
size,
createTime,
creator,
createBy,
id,
type,
configuration,
syncSetting,
lastSyncTime
})
console.log(nodeInfo)
})
}
getEngine()
const refresh = () => {
getEngine()
}
refresh()
</script>
<style lang="less" scoped>
@import '@/style/mixin.less';
.datasource-manage {
display: flex;
width: 100%;
height: 100%;
background: #fff;
position: relative;
.resource-area {
position: relative;
height: 100%;
width: 279px;
padding: 0;
border-right: 1px solid #d7d7d7;
overflow: visible;
&.retract {
display: none;
}
.resource-tree {
padding: 16px 0 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.tree-header {
padding: 0 16px;
}
.icon-methods {
display: flex;
align-items: center;
justify-content: flex-end;
font-size: 20px;
font-weight: 500;
color: var(--TextPrimary, #1f2329);
padding-bottom: 16px;
.title {
margin-right: auto;
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: 24px;
}
.custom-icon {
&.btn {
color: #3370ff;
}
&:hover {
cursor: pointer;
}
}
}
.search-bar {
padding-bottom: 10px;
}
}
}
.update-records {
position: absolute;
top: 19px;
right: 12px;
}
.update-info {
display: inline-flex;
height: 24px;
padding: 1px 6px;
align-items: center;
border-radius: 2px;
&.to-be-updated {
background: rgba(31, 35, 41, 0.1);
color: #646a73;
}
&.updating {
color: #2b5fd9;
background: rgba(51, 112, 255, 0.2);
}
&.pause {
background: rgba(31, 35, 41, 0.1);
color: #646a73;
}
&.updated {
color: #2ca91f;
background: rgba(52, 199, 36, 0.2);
}
}
.icon-border {
font-size: 18px;
}
.excel-table {
margin-top: 16px;
.sheet-table-content {
height: 400px;
}
}
.api-card-content {
display: flex;
flex-wrap: wrap;
margin-top: 16px;
margin-left: -16px;
}
.api-card {
width: calc(50% - 16px);
height: 140px;
border-radius: 4px;
border: 1px solid var(--deCardStrokeColor, #dee0e3);
border-radius: 4px;
margin: 0 0 16px 16px;
padding: 16px;
font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
.name {
font-size: 16px;
font-weight: 500;
margin-right: 8px;
max-width: 80%;
}
.req-title,
.req-value {
display: flex;
font-size: 14px;
font-weight: 400;
:nth-child(1) {
width: 100px;
}
:nth-child(2) {
margin-left: 24px;
max-width: calc(100% - 124px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.req-title {
color: var(--deTextSecondary, #646a73);
margin: 16px 0 4px 0;
}
.req-value {
color: var(--deTextPrimary, #1f2329);
}
.de-copy-icon {
cursor: pointer;
margin-right: 20px;
color: var(--deTextSecondary, #646a73);
}
.de-delete-icon:not(.not-allow) {
cursor: pointer;
&:hover {
color: var(--deDanger, #f54a45);
}
}
.de-tag {
display: inline-flex;
justify-content: center;
align-items: center;
border-radius: 2px;
padding: 1px 6px;
height: 24px;
}
.error-color {
color: #646a73;
background-color: rgba(31, 35, 41, 10%);
}
.success-color {
color: green;
background-color: rgba(52, 199, 36, 20%);
}
}
.de-expand {
font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px;
font-weight: 400;
line-height: 22px;
color: #3370ff;
cursor: pointer;
margin-top: 16px;
display: inline-flex;
align-items: center;
.ed-icon {
margin-left: 4px;
}
}
.datasource-height,
.datasource-content {
height: calc(100vh - 56px);
overflow: auto;
position: relative;
&.h100 {
.datasource-table {
height: calc(100% - 140px);
}
}
}
.datasource-list {
width: 279px;
padding: 16px 8px;
}
.datasource-content {
background: #f5f6f7;
overflow-y: auto;
}
.m24 {
margin: 24px 0;
}
.w100 {
width: 100%;
}
.datasource-content {
flex: 1;
position: relative;
.datasource-info {
background: #fff;
padding: 0 24px;
padding-top: 12px;
height: 90px;
position: sticky;
top: 0;
z-index: 6;
.info-method {
width: 100%;
display: flex;
align-items: center;
font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 16px;
font-weight: 500;
.ed-icon {
font-size: 24px;
}
.name {
margin-left: 8px;
max-width: 200px;
}
.create-user {
font-size: 14px;
font-weight: 400;
line-height: 22px;
color: #646a73;
margin-right: 4px;
}
.mr8 {
margin-left: 8px;
}
.right-btn {
margin-left: auto;
.replace-excel {
margin: 0 12px;
}
}
}
.tab-border {
.border-bottom-tab(24px);
:deep(.ed-tabs__item) {
font-size: 14px;
}
:deep(.ed-tabs__nav-wrap::after) {
border-color: rgba(31, 35, 41, 0.15);
}
margin-left: 0;
}
}
.datasource-table {
padding: 24px;
margin: 24px;
background: #fff;
height: calc(100vh - 190px);
.search-operate {
width: 280px;
margin-bottom: 16px;
}
}
.info-table {
height: calc(100% - 49px);
}
}
}
.custom-tree {
height: calc(100vh - 148px);
padding: 0 8px;
}
.custom-tree-node {
width: calc(100% - 30px);
display: flex;
align-items: center;
box-sizing: content-box;
padding-right: 4px;
.label-tooltip {
width: 100%;
margin-left: 8.75px;
}
.icon-more {
margin-left: auto;
display: none;
}
&:hover {
.label-tooltip {
width: calc(100% - 78px);
&.excel {
width: calc(100% - 54px);
}
}
.icon-more {
display: inline-flex;
}
}
}
</style>
<style lang="less">
.record-drawer {
.ed-drawer__body {
padding: 24px;
}
.flex-align-center {
.ed-icon {
margin: 0 4px;
}
.error-info {
cursor: pointer;
}
}
}
.ds-table-drawer {
max-height: calc(100% - 120px);
display: flex;
flex-direction: column;
.ed-dialog__body {
overflow-y: auto;
}
.table-value,
.table-name {
font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px;
font-weight: 400;
margin: 0;
}
.table-name {
color: var(--deTextSecondary, #646a73);
}
.table-value {
margin: 4px 0 24px 0;
color: var(--deTextPrimary, #1f2329);
}
}
</style>

View File

@ -0,0 +1,515 @@
<template>
<div>
<el-button type="primary" @click="edit">{{ t('commons.edit') }}</el-button>
<el-button type="primary" @click="validateById">{{ t('commons.validate') }}</el-button>
</div>
<BaseInfoContent v-slot="slotProps" :name="t('datasource.base_info')">
<template v-if="slotProps.active">
<el-row :gutter="24">
<el-col :span="12">
<BaseInfoItem :label="t('datasource.type')">{{ typeMap[nodeInfo.type] }}</BaseInfoItem>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<BaseInfoItem :label="t('datasource.host')">{{
nodeInfo.configuration.host
}}</BaseInfoItem>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<BaseInfoItem :label="t('datasource.port')">{{
nodeInfo.configuration.port
}}</BaseInfoItem>
</el-col>
<el-col :span="12">
<BaseInfoItem :label="t('datasource.data_base')">{{
nodeInfo.configuration.dataBase
}}</BaseInfoItem>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<BaseInfoItem :label="t('datasource.user_name')">{{
nodeInfo.configuration.username
}}</BaseInfoItem>
</el-col>
<el-col :span="12">
<BaseInfoItem :label="t('datasource.extra_params')">{{
nodeInfo.configuration.extraParams
}}</BaseInfoItem>
</el-col>
</el-row>
<span class="de-expand" @click="showPriority = !showPriority">
{{ t('datasource.priority') }}
<el-icon>
<Icon :name="showPriority ? 'icon_down_outlined' : 'icon_down_outlined-1'"></Icon>
</el-icon>
</span>
<template v-if="showPriority">
<el-row :gutter="24">
<el-col :span="12">
<BaseInfoItem :label="t('datasource.initial_pool_size')">{{
nodeInfo.configuration.initialPoolSize || 5
}}</BaseInfoItem>
</el-col>
<el-col :span="12">
<BaseInfoItem :label="t('datasource.min_pool_size')">{{
nodeInfo.configuration.minPoolSize || 5
}}</BaseInfoItem>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<BaseInfoItem :label="t('datasource.max_pool_size')">{{
nodeInfo.configuration.maxPoolSize || 5
}}</BaseInfoItem>
</el-col>
<el-col :span="12">
<BaseInfoItem
:value="nodeInfo.configuration.queryTimeout"
:label="t('datasource.query_timeout')"
>{{ nodeInfo.configuration.queryTimeout || '30'
}}{{ t('common.second') }}</BaseInfoItem
>
</el-col>
</el-row>
</template>
</template>
</BaseInfoContent>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { SettingRecord } from '@/views/system/common/SettingTemplate'
import { reactive } from 'vue'
import BaseInfoItem from '@/views/visualized/data/datasource/BaseInfoItem.vue'
import BaseInfoContent from '@/views/visualized/data/datasource/BaseInfoContent.vue'
import { ElIcon, ElMessage } from 'element-plus-secondary'
import { Icon } from '@/components/icon-custom'
import { useI18n } from '@/hooks/web/useI18n'
import { dsTypes } from '@/views/visualized/data/datasource/form/option'
import { defineProps } from 'vue/dist/vue'
import request from '@/config/axios'
const editor = ref()
const state = reactive({
templateList: [] as SettingRecord[]
})
const { t } = useI18n()
const typeMap = dsTypes.reduce((pre, next) => {
pre[next.type] = next.name
return pre
}, {})
const showPriority = ref(true)
const props = defineProps({
nodeInfo: {
type: Node,
default: {}
}
})
const emits = defineEmits(['edit'])
const edit = () => {
emits('edit')
}
const validateById = async () => {
request.post({ url: '/engine/validate/' + props.nodeInfo.id }).then(res => {
if (res !== undefined) {
ElMessage.success(t('datasource.validate_success'))
}
})
}
</script>
<style lang="less" scoped>
@import '@/style/mixin.less';
.datasource-manage {
display: flex;
width: 100%;
height: 100%;
background: #fff;
position: relative;
.resource-area {
position: relative;
height: 100%;
width: 279px;
padding: 0;
border-right: 1px solid #d7d7d7;
overflow: visible;
&.retract {
display: none;
}
.resource-tree {
padding: 16px 0 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.tree-header {
padding: 0 16px;
}
.icon-methods {
display: flex;
align-items: center;
justify-content: flex-end;
font-size: 20px;
font-weight: 500;
color: var(--TextPrimary, #1f2329);
padding-bottom: 16px;
.title {
margin-right: auto;
font-size: 16px;
font-style: normal;
font-weight: 500;
line-height: 24px;
}
.custom-icon {
&.btn {
color: #3370ff;
}
&:hover {
cursor: pointer;
}
}
}
.search-bar {
padding-bottom: 10px;
}
}
}
.update-records {
position: absolute;
top: 19px;
right: 12px;
}
.update-info {
display: inline-flex;
height: 24px;
padding: 1px 6px;
align-items: center;
border-radius: 2px;
&.to-be-updated {
background: rgba(31, 35, 41, 0.1);
color: #646a73;
}
&.updating {
color: #2b5fd9;
background: rgba(51, 112, 255, 0.2);
}
&.pause {
background: rgba(31, 35, 41, 0.1);
color: #646a73;
}
&.updated {
color: #2ca91f;
background: rgba(52, 199, 36, 0.2);
}
}
.icon-border {
font-size: 18px;
}
.excel-table {
margin-top: 16px;
.sheet-table-content {
height: 400px;
}
}
.api-card-content {
display: flex;
flex-wrap: wrap;
margin-top: 16px;
margin-left: -16px;
}
.api-card {
width: calc(50% - 16px);
height: 140px;
border-radius: 4px;
border: 1px solid var(--deCardStrokeColor, #dee0e3);
border-radius: 4px;
margin: 0 0 16px 16px;
padding: 16px;
font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
.name {
font-size: 16px;
font-weight: 500;
margin-right: 8px;
max-width: 80%;
}
.req-title,
.req-value {
display: flex;
font-size: 14px;
font-weight: 400;
:nth-child(1) {
width: 100px;
}
:nth-child(2) {
margin-left: 24px;
max-width: calc(100% - 124px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.req-title {
color: var(--deTextSecondary, #646a73);
margin: 16px 0 4px 0;
}
.req-value {
color: var(--deTextPrimary, #1f2329);
}
.de-copy-icon {
cursor: pointer;
margin-right: 20px;
color: var(--deTextSecondary, #646a73);
}
.de-delete-icon:not(.not-allow) {
cursor: pointer;
&:hover {
color: var(--deDanger, #f54a45);
}
}
.de-tag {
display: inline-flex;
justify-content: center;
align-items: center;
border-radius: 2px;
padding: 1px 6px;
height: 24px;
}
.error-color {
color: #646a73;
background-color: rgba(31, 35, 41, 10%);
}
.success-color {
color: green;
background-color: rgba(52, 199, 36, 20%);
}
}
.de-expand {
font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px;
font-weight: 400;
line-height: 22px;
color: #3370ff;
cursor: pointer;
margin-top: 16px;
display: inline-flex;
align-items: center;
.ed-icon {
margin-left: 4px;
}
}
.datasource-height,
.datasource-content {
height: calc(100vh - 56px);
overflow: auto;
position: relative;
&.h100 {
.datasource-table {
height: calc(100% - 140px);
}
}
}
.datasource-list {
width: 279px;
padding: 16px 8px;
}
.datasource-content {
background: #f5f6f7;
overflow-y: auto;
}
.m24 {
margin: 24px 0;
}
.w100 {
width: 100%;
}
.datasource-content {
flex: 1;
position: relative;
.datasource-info {
background: #fff;
padding: 0 24px;
padding-top: 12px;
height: 90px;
position: sticky;
top: 0;
z-index: 6;
.info-method {
width: 100%;
display: flex;
align-items: center;
font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 16px;
font-weight: 500;
.ed-icon {
font-size: 24px;
}
.name {
margin-left: 8px;
max-width: 200px;
}
.create-user {
font-size: 14px;
font-weight: 400;
line-height: 22px;
color: #646a73;
margin-right: 4px;
}
.mr8 {
margin-left: 8px;
}
.right-btn {
margin-left: auto;
.replace-excel {
margin: 0 12px;
}
}
}
.tab-border {
.border-bottom-tab(24px);
:deep(.ed-tabs__item) {
font-size: 14px;
}
:deep(.ed-tabs__nav-wrap::after) {
border-color: rgba(31, 35, 41, 0.15);
}
margin-left: 0;
}
}
.datasource-table {
padding: 24px;
margin: 24px;
background: #fff;
height: calc(100vh - 190px);
.search-operate {
width: 280px;
margin-bottom: 16px;
}
}
.info-table {
height: calc(100% - 49px);
}
}
}
.custom-tree {
height: calc(100vh - 148px);
padding: 0 8px;
}
.custom-tree-node {
width: calc(100% - 30px);
display: flex;
align-items: center;
box-sizing: content-box;
padding-right: 4px;
.label-tooltip {
width: 100%;
margin-left: 8.75px;
}
.icon-more {
margin-left: auto;
display: none;
}
&:hover {
.label-tooltip {
width: calc(100% - 78px);
&.excel {
width: calc(100% - 54px);
}
}
.icon-more {
display: inline-flex;
}
}
}
</style>
<style lang="less">
.record-drawer {
.ed-drawer__body {
padding: 24px;
}
.flex-align-center {
.ed-icon {
margin: 0 4px;
}
.error-info {
cursor: pointer;
}
}
}
.ds-table-drawer {
max-height: calc(100% - 120px);
display: flex;
flex-direction: column;
.ed-dialog__body {
overflow-y: auto;
}
.table-value,
.table-name {
font-family: '阿里巴巴普惠体 3.0 55 Regular L3';
font-size: 14px;
font-weight: 400;
margin: 0;
}
.table-name {
color: var(--deTextSecondary, #646a73);
}
.table-value {
margin: 4px 0 24px 0;
color: var(--deTextPrimary, #1f2329);
}
}
</style>

View File

@ -7,6 +7,7 @@
<div class="container-sys-param"> <div class="container-sys-param">
<map-setting v-if="activeName === 'map'" /> <map-setting v-if="activeName === 'map'" />
<basic-info v-if="activeName === 'basic'" /> <basic-info v-if="activeName === 'basic'" />
<engine-info v-if="activeName === 'engine'" />
</div> </div>
</div> </div>
</template> </template>
@ -16,14 +17,15 @@ import { ref } from 'vue'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import MapSetting from './map/MapSetting.vue' import MapSetting from './map/MapSetting.vue'
import BasicInfo from './basic/BasicInfo.vue' import BasicInfo from './basic/BasicInfo.vue'
import EngineInfo from '@/views/system/parameter/engine/EngineInfo.vue'
/* import EmailInfo from './email/EmailInfo.vue' */ /* import EmailInfo from './email/EmailInfo.vue' */
const { t } = useI18n() const { t } = useI18n()
const tabArray = [ const tabArray = [
{ label: '基础设置', name: 'basic' }, { label: '基础设置', name: 'basic' },
/* { label: '邮件设置', name: 'email' }, */ /* { label: '邮件设置', name: 'email' }, */
{ label: '地图设置', name: 'map' } { label: '地图设置', name: 'map' },
/* {label: '引擎设置', name: 'engine'}, */ { label: '引擎设置', name: 'engine' }
] ]
const activeName = ref('basic') const activeName = ref('basic')
</script> </script>

View File

@ -0,0 +1,27 @@
package io.dataease.api.ds;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.api.ds.vo.DatasourceDTO;
import io.dataease.auth.DeApiPath;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import static io.dataease.constant.AuthResourceEnum.DATASOURCE;
@Tag(name = "引擎管理:基础")
@ApiSupport(order = 970)
@DeApiPath(value = "/engine", rt = DATASOURCE)
public interface EngineApi {
@GetMapping("/getEngine")
DatasourceDTO getEngine();
@PostMapping("/save")
void save(@RequestBody DatasourceDTO datasourceDTO);
@PostMapping("/validate")
void validate(@RequestBody DatasourceDTO datasourceDTO) throws Exception;
@PostMapping("/validate/{id}")
void validateById(@PathVariable Long id) throws Exception;
}