Compare commits
37 Commits
pr@dev-v2@
...
dev-v2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23d9b5f879 | ||
|
|
0feea4cc2c | ||
|
|
05827ca172 | ||
|
|
5184f8b5e0 | ||
|
|
f7f0b1bdad | ||
|
|
1687b52419 | ||
|
|
5f9f520236 | ||
|
|
e1c9fb5b55 | ||
|
|
506f2ca552 | ||
|
|
e439bcafcb | ||
|
|
8438ba0aba | ||
|
|
e7993d7a0a | ||
|
|
d80221033c | ||
|
|
98f737e781 | ||
|
|
bcb9c9b263 | ||
|
|
204797ce24 | ||
|
|
f04aed6745 | ||
|
|
306c6711f7 | ||
|
|
a8738bca9b | ||
|
|
1e771beeb5 | ||
|
|
9104e3789c | ||
|
|
8bf0778b3e | ||
|
|
b3ae2c9d8d | ||
|
|
d99bb92e1a | ||
|
|
8918516508 | ||
|
|
e16b4b7234 | ||
|
|
c429eccd71 | ||
|
|
2e6a9e4f9c | ||
|
|
693061d2ec | ||
|
|
b5dda58118 | ||
|
|
9b9cb8ff92 | ||
|
|
5205972eb7 | ||
|
|
2c724a9624 | ||
|
|
87d31f6907 | ||
|
|
d655a77ece | ||
|
|
46c66b2395 | ||
|
|
3b95c6a945 |
@ -97,7 +97,6 @@ public class TableInfoHandler extends DefaultChartHandler {
|
|||||||
fieldDTO = allField;
|
fieldDTO = allField;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert fieldDTO != null;
|
|
||||||
if (fieldDTO != null && fieldDTO.isAgg()) {
|
if (fieldDTO != null && fieldDTO.isAgg()) {
|
||||||
sqlMeta.getXFields().get(i).setFieldName("'-'");
|
sqlMeta.getXFields().get(i).setFieldName("'-'");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package io.dataease.config;
|
|||||||
|
|
||||||
|
|
||||||
import io.dataease.commons.utils.MybatisInterceptorConfig;
|
import io.dataease.commons.utils.MybatisInterceptorConfig;
|
||||||
|
import io.dataease.datasource.dao.auto.entity.CoreDatasource;
|
||||||
import io.dataease.datasource.dao.auto.entity.CoreDeEngine;
|
import io.dataease.datasource.dao.auto.entity.CoreDeEngine;
|
||||||
import io.dataease.interceptor.MybatisInterceptor;
|
import io.dataease.interceptor.MybatisInterceptor;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
@ -22,6 +23,7 @@ public class MybatisConfig {
|
|||||||
MybatisInterceptor interceptor = new MybatisInterceptor();
|
MybatisInterceptor interceptor = new MybatisInterceptor();
|
||||||
List<MybatisInterceptorConfig> configList = new ArrayList<>();
|
List<MybatisInterceptorConfig> configList = new ArrayList<>();
|
||||||
configList.add(new MybatisInterceptorConfig(CoreDeEngine.class, "configuration"));
|
configList.add(new MybatisInterceptorConfig(CoreDeEngine.class, "configuration"));
|
||||||
|
configList.add(new MybatisInterceptorConfig(CoreDatasource.class, "configuration"));
|
||||||
interceptor.setInterceptorConfigList(configList);
|
interceptor.setInterceptorConfigList(configList);
|
||||||
return interceptor;
|
return interceptor;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -156,6 +156,13 @@ public class DataSourceManage {
|
|||||||
coreOptRecentManage.saveOpt(sourceData.getId(), OptConstants.OPT_RESOURCE_TYPE.DATASOURCE, OptConstants.OPT_TYPE.UPDATE);
|
coreOptRecentManage.saveOpt(sourceData.getId(), OptConstants.OPT_RESOURCE_TYPE.DATASOURCE, OptConstants.OPT_TYPE.UPDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void encryptDsConfig(){
|
||||||
|
coreDatasourceMapper.selectList(null).forEach(dataSource -> {
|
||||||
|
coreDatasourceMapper.updateById(dataSource);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public DatasourceDTO getDs(Long id) {
|
public DatasourceDTO getDs(Long id) {
|
||||||
CoreDatasource coreDatasource = coreDatasourceMapper.selectById(id);
|
CoreDatasource coreDatasource = coreDatasourceMapper.selectById(id);
|
||||||
DatasourceDTO dto = new DatasourceDTO();
|
DatasourceDTO dto = new DatasourceDTO();
|
||||||
|
|||||||
@ -703,7 +703,7 @@ public class DatasourceServer implements DatasourceApi {
|
|||||||
String datasourceId = req.get("datasourceId");
|
String datasourceId = req.get("datasourceId");
|
||||||
DatasetTableDTO datasetTableDTO = new DatasetTableDTO();
|
DatasetTableDTO datasetTableDTO = new DatasetTableDTO();
|
||||||
datasetTableDTO.setDatasourceId(Long.valueOf(datasourceId));
|
datasetTableDTO.setDatasourceId(Long.valueOf(datasourceId));
|
||||||
if (!getTables(datasetTableDTO).stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList()).contains("tableName")) {
|
if (!getTables(datasetTableDTO).stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList()).contains(tableName)) {
|
||||||
DEException.throwException("无效的表名!");
|
DEException.throwException("无效的表名!");
|
||||||
}
|
}
|
||||||
CoreDatasource coreDatasource = datasourceMapper.selectById(datasourceId);
|
CoreDatasource coreDatasource = datasourceMapper.selectById(datasourceId);
|
||||||
@ -817,7 +817,7 @@ public class DatasourceServer implements DatasourceApi {
|
|||||||
sheet.setDeTableName(datasetTableDTO.getTableName());
|
sheet.setDeTableName(datasetTableDTO.getTableName());
|
||||||
datasourceRequest.setTable(datasetTableDTO.getTableName());
|
datasourceRequest.setTable(datasetTableDTO.getTableName());
|
||||||
List<TableField> oldTableFields = ExcelUtils.getTableFields(datasourceRequest);
|
List<TableField> oldTableFields = ExcelUtils.getTableFields(datasourceRequest);
|
||||||
mergeFields(sheet.getFields(), oldTableFields);
|
mergeFields(oldTableFields, sheet.getFields());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!find) {
|
if (!find) {
|
||||||
@ -843,6 +843,10 @@ public class DatasourceServer implements DatasourceApi {
|
|||||||
if (CollectionUtils.isEmpty(newTableFields) || CollectionUtils.isEmpty(oldTableFields)) {
|
if (CollectionUtils.isEmpty(newTableFields) || CollectionUtils.isEmpty(oldTableFields)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
boolean isHistory = oldTableFields.stream().filter(tableField -> !tableField.isChecked()).collect(Collectors.toList()).size() == oldTableFields.size();
|
||||||
|
if (isHistory) {
|
||||||
|
oldTableFields.forEach(tableField -> tableField.setChecked(true));
|
||||||
|
}
|
||||||
newTableFields.forEach(tableField -> tableField.setChecked(false));
|
newTableFields.forEach(tableField -> tableField.setChecked(false));
|
||||||
for (TableField oldField : oldTableFields) {
|
for (TableField oldField : oldTableFields) {
|
||||||
if (!oldField.isChecked()) {
|
if (!oldField.isChecked()) {
|
||||||
@ -866,7 +870,11 @@ public class DatasourceServer implements DatasourceApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void mergeFields(List<TableField> oldFields, List<TableField> newFields) {
|
private void mergeFields(List<TableField> oldFields, List<TableField> newFields) {
|
||||||
oldFields.forEach(tableField -> tableField.setChecked(false));
|
newFields.forEach(tableField -> tableField.setChecked(false));
|
||||||
|
boolean isHistory = oldFields.stream().filter(tableField -> !tableField.isChecked()).collect(Collectors.toList()).size() == oldFields.size();
|
||||||
|
if (isHistory) {
|
||||||
|
oldFields.forEach(tableField -> tableField.setChecked(true));
|
||||||
|
}
|
||||||
for (TableField newField : newFields) {
|
for (TableField newField : newFields) {
|
||||||
for (TableField oldField : oldFields) {
|
for (TableField oldField : oldFields) {
|
||||||
if (oldField.getName().equals(newField.getName())) {
|
if (oldField.getName().equals(newField.getName())) {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package io.dataease.listener;
|
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.DataSourceManage;
|
||||||
import io.dataease.datasource.manage.DatasourceSyncManage;
|
import io.dataease.datasource.manage.DatasourceSyncManage;
|
||||||
import io.dataease.datasource.manage.EngineManage;
|
import io.dataease.datasource.manage.EngineManage;
|
||||||
import io.dataease.datasource.provider.CalciteProvider;
|
import io.dataease.datasource.provider.CalciteProvider;
|
||||||
@ -26,6 +27,8 @@ public class DataSourceInitStartListener implements ApplicationListener<Applicat
|
|||||||
@Resource
|
@Resource
|
||||||
private DatasourceServer datasourceServer;
|
private DatasourceServer datasourceServer;
|
||||||
@Resource
|
@Resource
|
||||||
|
private DataSourceManage dataSourceManage;
|
||||||
|
@Resource
|
||||||
private DatasourceTaskServer datasourceTaskServer;
|
private DatasourceTaskServer datasourceTaskServer;
|
||||||
@Resource
|
@Resource
|
||||||
private CalciteProvider calciteProvider;
|
private CalciteProvider calciteProvider;
|
||||||
@ -71,7 +74,7 @@ public class DataSourceInitStartListener implements ApplicationListener<Applicat
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
dataSourceManage.encryptDsConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
package io.dataease.rmonitor.bo;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class PerMonitorCheckBO implements Serializable {
|
|
||||||
|
|
||||||
private boolean valid;
|
|
||||||
|
|
||||||
private boolean emptyPermission;
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package io.dataease.rmonitor.bo;
|
|
||||||
|
|
||||||
import io.dataease.model.TreeBaseModel;
|
|
||||||
import io.dataease.model.TreeResultModel;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class PerMonitorNodeBO implements TreeBaseModel<PerMonitorNodeBO>, TreeResultModel<PerMonitorNodeBO>, Serializable {
|
|
||||||
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
private Long pid;
|
|
||||||
|
|
||||||
private boolean leaf;
|
|
||||||
|
|
||||||
private int extraFlag;
|
|
||||||
|
|
||||||
private List<PerMonitorNodeBO> children;
|
|
||||||
}
|
|
||||||
@ -1,120 +0,0 @@
|
|||||||
package io.dataease.rmonitor.manage;
|
|
||||||
|
|
||||||
import io.dataease.constant.DataSourceType;
|
|
||||||
import io.dataease.exception.DEException;
|
|
||||||
import io.dataease.rmonitor.bo.PerMonitorCheckBO;
|
|
||||||
import io.dataease.rmonitor.bo.PerMonitorNodeBO;
|
|
||||||
import io.dataease.rmonitor.mapper.ResourceMonitorMapper;
|
|
||||||
import io.dataease.rmonitor.mapper.entity.DatasetFreeResource;
|
|
||||||
import io.dataease.rmonitor.mapper.entity.DsFreeResource;
|
|
||||||
import io.dataease.rmonitor.mapper.entity.VisualFreeResource;
|
|
||||||
import io.dataease.utils.BeanUtils;
|
|
||||||
import io.dataease.utils.TreeUtils;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
|
||||||
import org.apache.commons.collections4.MapUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Component("resourceMonitorManage")
|
|
||||||
public class ResourceMonitorManage {
|
|
||||||
|
|
||||||
|
|
||||||
@Resource(name = "resourceMonitorSyncManage")
|
|
||||||
private ResourceMonitorSyncManage resourceMonitorSyncManage;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ResourceMonitorMapper resourceMonitorMapper;
|
|
||||||
|
|
||||||
|
|
||||||
private boolean existFreeResource() {
|
|
||||||
int rCount = resourceMonitorMapper.dsCount() + resourceMonitorMapper.datasetCount() + resourceMonitorMapper.vCount();
|
|
||||||
return rCount > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, List<PerMonitorNodeBO>> freeResource() {
|
|
||||||
Map<String, List<PerMonitorNodeBO>> result = new HashMap<>();
|
|
||||||
|
|
||||||
List<DsFreeResource> dsFreeResources = resourceMonitorMapper.queryFreeDs();
|
|
||||||
if (CollectionUtils.isNotEmpty(dsFreeResources)) {
|
|
||||||
List<PerMonitorNodeBO> dsBos = dsFreeResources.stream().map(node -> {
|
|
||||||
PerMonitorNodeBO bo = BeanUtils.copyBean(new PerMonitorNodeBO(), node);
|
|
||||||
bo.setLeaf(!StringUtils.equals("folder", node.getType()));
|
|
||||||
bo.setExtraFlag(DataSourceType.valueOf(node.getType()).getFlag());
|
|
||||||
return bo;
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
List<PerMonitorNodeBO> dsTree = TreeUtils.mergeTree(dsBos, PerMonitorNodeBO.class, false);
|
|
||||||
result.put("datasource", dsTree);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<DatasetFreeResource> datasetFreeResources = resourceMonitorMapper.queryFreeDataset();
|
|
||||||
if (CollectionUtils.isNotEmpty(datasetFreeResources)) {
|
|
||||||
List<PerMonitorNodeBO> datasetBos = datasetFreeResources.stream().map(node -> {
|
|
||||||
PerMonitorNodeBO bo = BeanUtils.copyBean(new PerMonitorNodeBO(), node);
|
|
||||||
bo.setLeaf(!StringUtils.equals("folder", node.getNodeType()));
|
|
||||||
return bo;
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
List<PerMonitorNodeBO> datasetTree = TreeUtils.mergeTree(datasetBos, PerMonitorNodeBO.class, false);
|
|
||||||
result.put("dataset", datasetTree);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<VisualFreeResource> visualFreeResources = resourceMonitorMapper.queryFreeVusial();
|
|
||||||
if (CollectionUtils.isNotEmpty(visualFreeResources)) {
|
|
||||||
Map<String, List<VisualFreeResource>> baseMap = visualFreeResources.stream().collect(Collectors.groupingBy(VisualFreeResource::getType));
|
|
||||||
for (Map.Entry<String, List<VisualFreeResource>> entry : baseMap.entrySet()) {
|
|
||||||
List<VisualFreeResource> freeResource = entry.getValue();
|
|
||||||
List<PerMonitorNodeBO> visualBos = freeResource.stream().map(node -> {
|
|
||||||
PerMonitorNodeBO bo = BeanUtils.copyBean(new PerMonitorNodeBO(), node);
|
|
||||||
bo.setLeaf(!StringUtils.equals("folder", node.getNodeType()));
|
|
||||||
return bo;
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
result.put(convertBusiFlag(entry.getKey()), TreeUtils.mergeTree(visualBos, PerMonitorNodeBO.class, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String convertBusiFlag(String key) {
|
|
||||||
if (StringUtils.equals("dashboard", key)) {
|
|
||||||
return "panel";
|
|
||||||
} else if (StringUtils.equals("dataV", key)) {
|
|
||||||
return "screen";
|
|
||||||
} else return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean check() {
|
|
||||||
PerMonitorCheckBO checkBO = resourceMonitorSyncManage.checkXpackResource();
|
|
||||||
return checkBO.isValid() && checkBO.isEmptyPermission() && existFreeResource();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public void delete() {
|
|
||||||
boolean existFree = existFreeResource();
|
|
||||||
if (!existFree) DEException.throwException("无未同步资源!");
|
|
||||||
resourceMonitorMapper.delFreeDs();
|
|
||||||
resourceMonitorMapper.delFreeDataset();
|
|
||||||
resourceMonitorMapper.delFreeVisual();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sync() {
|
|
||||||
//1、从xpack获取资源 如果xpack不存在 或者资源不为空 则直接返回 并且抛出异常“仅支持首次导入lic同步”
|
|
||||||
//2、从core获取资源
|
|
||||||
//3、根据类型分组 并组织成树形结构
|
|
||||||
//4、分别遍历每一棵树 从上到下 同步到权限体系 给默认组织
|
|
||||||
PerMonitorCheckBO checkBO = resourceMonitorSyncManage.checkXpackResource();
|
|
||||||
if (!checkBO.isValid()) DEException.throwException("缺少许可证");
|
|
||||||
if (!checkBO.isEmptyPermission()) DEException.throwException("仅支持license首次导入同步");
|
|
||||||
Map<String, List<PerMonitorNodeBO>> freeResourceMap = freeResource();
|
|
||||||
if (MapUtils.isEmpty(freeResourceMap)) DEException.throwException("无未同步资源!");
|
|
||||||
for (Map.Entry<String, List<PerMonitorNodeBO>> entry : freeResourceMap.entrySet()) {
|
|
||||||
resourceMonitorSyncManage.sync(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
package io.dataease.rmonitor.manage;
|
|
||||||
|
|
||||||
import io.dataease.exception.DEException;
|
|
||||||
import io.dataease.license.config.XpackInteract;
|
|
||||||
import io.dataease.rmonitor.bo.PerMonitorCheckBO;
|
|
||||||
import io.dataease.rmonitor.bo.PerMonitorNodeBO;
|
|
||||||
import io.dataease.rmonitor.mapper.ResourceMonitorMapper;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Component("resourceMonitorSyncManage")
|
|
||||||
public class ResourceMonitorSyncManage {
|
|
||||||
|
|
||||||
@Resource(name = "resourceMonitorMapper")
|
|
||||||
private ResourceMonitorMapper resourceMonitorMapper;
|
|
||||||
|
|
||||||
@XpackInteract(value = "resourceMonitorSyncManage", replace = true)
|
|
||||||
public void sync(String flag, List<PerMonitorNodeBO> treeNodes) {
|
|
||||||
DEException.throwException("缺失许可证");
|
|
||||||
}
|
|
||||||
|
|
||||||
@XpackInteract(value = "resourceMonitorSyncManage", replace = true)
|
|
||||||
public PerMonitorCheckBO checkXpackResource() {
|
|
||||||
return new PerMonitorCheckBO();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package io.dataease.rmonitor.mapper;
|
|
||||||
|
|
||||||
import io.dataease.rmonitor.mapper.entity.DatasetFreeResource;
|
|
||||||
import io.dataease.rmonitor.mapper.entity.DsFreeResource;
|
|
||||||
import io.dataease.rmonitor.mapper.entity.VisualFreeResource;
|
|
||||||
import org.apache.ibatis.annotations.Delete;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
import org.apache.ibatis.annotations.Select;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Mapper
|
|
||||||
public interface ResourceMonitorMapper {
|
|
||||||
|
|
||||||
@Select("select count(id) from core_datasource")
|
|
||||||
int dsCount();
|
|
||||||
|
|
||||||
@Select("select count(id) from core_dataset_group")
|
|
||||||
int datasetCount();
|
|
||||||
|
|
||||||
@Select("select count(id) from data_visualization_info where delete_flag = 0 and pid != -1")
|
|
||||||
int vCount();
|
|
||||||
|
|
||||||
@Select("select id, name, pid, type, status from core_datasource")
|
|
||||||
List<DsFreeResource> queryFreeDs();
|
|
||||||
|
|
||||||
@Select("select id, name, pid, node_type from core_dataset_group")
|
|
||||||
List<DatasetFreeResource> queryFreeDataset();
|
|
||||||
|
|
||||||
@Select("select id, name, pid, node_type, type from data_visualization_info where delete_flag = 0 and pid != -1")
|
|
||||||
List<VisualFreeResource> queryFreeVusial();
|
|
||||||
|
|
||||||
@Delete("delete from core_datasource")
|
|
||||||
void delFreeDs();
|
|
||||||
|
|
||||||
@Delete("delete from core_dataset_group")
|
|
||||||
void delFreeDataset();
|
|
||||||
@Delete("delete from data_visualization_info")
|
|
||||||
void delFreeVisual();
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
package io.dataease.rmonitor.mapper.entity;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class BaseFreeResource implements Serializable {
|
|
||||||
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
private Long pid;
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package io.dataease.rmonitor.mapper.entity;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
|
||||||
public class DatasetFreeResource extends BaseFreeResource implements Serializable {
|
|
||||||
|
|
||||||
private String nodeType;
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
package io.dataease.rmonitor.mapper.entity;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
|
||||||
public class DsFreeResource extends BaseFreeResource implements Serializable {
|
|
||||||
|
|
||||||
private String type;
|
|
||||||
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
package io.dataease.rmonitor.mapper.entity;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Data
|
|
||||||
public class VisualFreeResource extends BaseFreeResource implements Serializable {
|
|
||||||
|
|
||||||
private String nodeType;
|
|
||||||
|
|
||||||
private String type;
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
package io.dataease.rmonitor.server;
|
|
||||||
|
|
||||||
import io.dataease.api.rmonitor.ResourceMonitorApi;
|
|
||||||
import io.dataease.rmonitor.manage.ResourceMonitorManage;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/rmonitor")
|
|
||||||
public class ResourceMonitorServer implements ResourceMonitorApi {
|
|
||||||
|
|
||||||
@Resource(name = "resourceMonitorManage")
|
|
||||||
private ResourceMonitorManage resourceMonitorManage;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean existFree() {
|
|
||||||
return resourceMonitorManage.check();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete() {
|
|
||||||
resourceMonitorManage.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sync() {
|
|
||||||
resourceMonitorManage.sync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -52,3 +52,6 @@ create table core_custom_geo_sub_area
|
|||||||
)
|
)
|
||||||
comment '自定义地理区域分区详情';
|
comment '自定义地理区域分区详情';
|
||||||
|
|
||||||
|
|
||||||
|
UPDATE `core_sys_setting` SET `sort` = 11 WHERE `pkey` = 'basic.dsIntervalTime';
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,3 @@ import request from '@/config/axios'
|
|||||||
export const validateApi = data => request.post({ url: '/license/validate', data })
|
export const validateApi = data => request.post({ url: '/license/validate', data })
|
||||||
export const buildVersionApi = () => request.get({ url: '/license/version' })
|
export const buildVersionApi = () => request.get({ url: '/license/version' })
|
||||||
export const updateInfoApi = data => request.post({ url: '/license/update', data })
|
export const updateInfoApi = data => request.post({ url: '/license/update', data })
|
||||||
|
|
||||||
export const checkFreeApi = () => request.get({ url: '/rmonitor/existFree' })
|
|
||||||
export const syncFreeApi = () => request.post({ url: '/rmonitor/sync' })
|
|
||||||
export const delFreeApi = () => request.post({ url: '/rmonitor/delete' })
|
|
||||||
|
|||||||
@ -139,8 +139,7 @@ const previewOuter = () => {
|
|||||||
}
|
}
|
||||||
canvasSave(() => {
|
canvasSave(() => {
|
||||||
const url = '#/preview?dvId=' + dvInfo.value.id + '&ignoreParams=true'
|
const url = '#/preview?dvId=' + dvInfo.value.id + '&ignoreParams=true'
|
||||||
const openType = wsCache.get('open-backend') === '1' ? '_self' : '_blank'
|
const newWindow = window.open(url, '_blank')
|
||||||
const newWindow = window.open(url, openType)
|
|
||||||
initOpenHandler(newWindow)
|
initOpenHandler(newWindow)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import noLic from './nolic.vue'
|
|||||||
import { ref, useAttrs, onMounted } from 'vue'
|
import { ref, useAttrs, onMounted } from 'vue'
|
||||||
import { execute, randomKey, formatArray } from './convert'
|
import { execute, randomKey, formatArray } from './convert'
|
||||||
import { load, loadDistributed, xpackModelApi } from '@/api/plugin'
|
import { load, loadDistributed, xpackModelApi } from '@/api/plugin'
|
||||||
|
import configGlobal from '@/components/config-global/src/ConfigGlobal.vue'
|
||||||
import { useCache } from '@/hooks/web/useCache'
|
import { useCache } from '@/hooks/web/useCache'
|
||||||
import { i18n } from '@/plugins/vue-i18n'
|
import { i18n } from '@/plugins/vue-i18n'
|
||||||
import * as Vue from 'vue'
|
import * as Vue from 'vue'
|
||||||
@ -152,6 +153,7 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<configGlobal>
|
||||||
<component
|
<component
|
||||||
:key="attrs.jsname"
|
:key="attrs.jsname"
|
||||||
ref="pluginProxy"
|
ref="pluginProxy"
|
||||||
@ -159,6 +161,5 @@ onMounted(async () => {
|
|||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
v-bind="attrs"
|
v-bind="attrs"
|
||||||
></component>
|
></component>
|
||||||
|
</configGlobal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
|
||||||
|
|||||||
@ -453,7 +453,7 @@ const exportAsExcel = () => {
|
|||||||
const viewDataInfo = dvMainStore.getViewDataDetails(element.value.id)
|
const viewDataInfo = dvMainStore.getViewDataDetails(element.value.id)
|
||||||
const chartExtRequest = dvMainStore.getLastViewRequestInfo(element.value.id)
|
const chartExtRequest = dvMainStore.getLastViewRequestInfo(element.value.id)
|
||||||
const viewInfo = dvMainStore.getViewDetails(element.value.id)
|
const viewInfo = dvMainStore.getViewDetails(element.value.id)
|
||||||
const chart = { ...viewInfo, chartExtRequest, data: viewDataInfo }
|
const chart = { ...viewInfo, chartExtRequest, data: viewDataInfo, busiFlag: dvInfo.value.type }
|
||||||
exportExcelDownload(chart, () => {
|
exportExcelDownload(chart, () => {
|
||||||
openMessageLoading(callbackExport)
|
openMessageLoading(callbackExport)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -14,7 +14,12 @@ const { curComponent } = storeToRefs(dvMainStore)
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-collapse-item :effect="themes" :title="t('visualization.position')" name="position" v-if="!dashboardActive">
|
<el-collapse-item
|
||||||
|
:effect="themes"
|
||||||
|
:title="t('visualization.position')"
|
||||||
|
name="position"
|
||||||
|
v-if="!dashboardActive"
|
||||||
|
>
|
||||||
<component-position :themes="themes" />
|
<component-position :themes="themes" />
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -225,7 +225,7 @@ const init = ref({
|
|||||||
// 显示原始手柄并移除克隆手柄
|
// 显示原始手柄并移除克隆手柄
|
||||||
originalHandle.style.display = ''
|
originalHandle.style.display = ''
|
||||||
if (cloneHandle) {
|
if (cloneHandle) {
|
||||||
cloneHandle.parentNode.removeChild(cloneHandle) // 获取原手柄的父元素
|
cloneHandle.parentNode?.removeChild(cloneHandle) // 获取原手柄的父元素
|
||||||
}
|
}
|
||||||
cloneHandle = null
|
cloneHandle = null
|
||||||
originalHandle = null
|
originalHandle = null
|
||||||
@ -539,6 +539,9 @@ const calcData = (view: Chart, callback) => {
|
|||||||
updateEmptyValue(view)
|
updateEmptyValue(view)
|
||||||
if (view.tableId || view['dataFrom'] === 'template') {
|
if (view.tableId || view['dataFrom'] === 'template') {
|
||||||
const v = JSON.parse(JSON.stringify(view))
|
const v = JSON.parse(JSON.stringify(view))
|
||||||
|
v.type = 'table-info'
|
||||||
|
v.render = 'antv'
|
||||||
|
v.resultCount = 1
|
||||||
getData(v)
|
getData(v)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.code && res.code !== 0) {
|
if (res.code && res.code !== 0) {
|
||||||
@ -546,6 +549,8 @@ const calcData = (view: Chart, callback) => {
|
|||||||
errMsg.value = res.msg
|
errMsg.value = res.msg
|
||||||
} else {
|
} else {
|
||||||
state.data = res?.data
|
state.data = res?.data
|
||||||
|
res.type = 'rich-text'
|
||||||
|
res.render = 'custom'
|
||||||
state.viewDataInfo = res
|
state.viewDataInfo = res
|
||||||
state.totalItems = res?.totalItems
|
state.totalItems = res?.totalItems
|
||||||
const curViewInfo = canvasViewInfo.value[element.value.id]
|
const curViewInfo = canvasViewInfo.value[element.value.id]
|
||||||
|
|||||||
@ -187,16 +187,16 @@ function move(keyCode) {
|
|||||||
const scale = dvMainStore.canvasStyleData.scale / 100
|
const scale = dvMainStore.canvasStyleData.scale / 100
|
||||||
if (keyCode === leftKey) {
|
if (keyCode === leftKey) {
|
||||||
curComponent.value.style.left = curComponent.value.style.left - scale
|
curComponent.value.style.left = curComponent.value.style.left - scale
|
||||||
groupAreaAdaptor(-1, 0)
|
groupAreaAdaptor(-scale, 0)
|
||||||
} else if (keyCode === rightKey) {
|
} else if (keyCode === rightKey) {
|
||||||
curComponent.value.style.left = curComponent.value.style.left + scale
|
curComponent.value.style.left = curComponent.value.style.left + scale
|
||||||
groupAreaAdaptor(1, 0)
|
groupAreaAdaptor(scale, 0)
|
||||||
} else if (keyCode === upKey) {
|
} else if (keyCode === upKey) {
|
||||||
curComponent.value.style.top = curComponent.value.style.top - scale
|
curComponent.value.style.top = curComponent.value.style.top - scale
|
||||||
groupAreaAdaptor(0, -1)
|
groupAreaAdaptor(0, -scale)
|
||||||
} else if (keyCode === downKey) {
|
} else if (keyCode === downKey) {
|
||||||
curComponent.value.style.top = curComponent.value.style.top + scale
|
curComponent.value.style.top = curComponent.value.style.top + scale
|
||||||
groupAreaAdaptor(0, 1)
|
groupAreaAdaptor(0, scale)
|
||||||
}
|
}
|
||||||
snapshotStore.recordSnapshotCache('key-move')
|
snapshotStore.recordSnapshotCache('key-move')
|
||||||
}
|
}
|
||||||
@ -212,6 +212,11 @@ function groupAreaAdaptor(leftOffset = 0, topOffset = 0) {
|
|||||||
width: parentNode.offsetWidth,
|
width: parentNode.offsetWidth,
|
||||||
height: parentNode.offsetHeight
|
height: parentNode.offsetHeight
|
||||||
})
|
})
|
||||||
|
} else if (curComponent.value.component === 'GroupArea' && areaData.value.components.length > 0) {
|
||||||
|
areaData.value.components.forEach(component => {
|
||||||
|
component.style.top = component.style.top + topOffset
|
||||||
|
component.style.left = component.style.left + leftOffset
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,11 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import logo from '@/assets/svg/logo.svg'
|
import logo from '@/assets/svg/logo.svg'
|
||||||
import aboutBg from '@/assets/img/about-bg.png'
|
import aboutBg from '@/assets/img/about-bg.png'
|
||||||
import { ref, reactive, onMounted, h } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import { useUserStoreWithOut } from '@/store/modules/user'
|
import { useUserStoreWithOut } from '@/store/modules/user'
|
||||||
import { F2CLicense } from './index'
|
import { F2CLicense } from './index'
|
||||||
import {
|
import { validateApi, buildVersionApi, updateInfoApi } from '@/api/about'
|
||||||
validateApi,
|
import { ElMessage } from 'element-plus-secondary'
|
||||||
buildVersionApi,
|
|
||||||
updateInfoApi,
|
|
||||||
checkFreeApi,
|
|
||||||
syncFreeApi,
|
|
||||||
delFreeApi
|
|
||||||
} from '@/api/about'
|
|
||||||
import { ElMessage, ElMessageBox, Action } from 'element-plus-secondary'
|
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||||
import { useCache } from '@/hooks/web/useCache'
|
import { useCache } from '@/hooks/web/useCache'
|
||||||
@ -129,65 +122,11 @@ const update = (licKey: string) => {
|
|||||||
ElMessage.success(t('about.update_success'))
|
ElMessage.success(t('about.update_success'))
|
||||||
const info = getLicense(response.data)
|
const info = getLicense(response.data)
|
||||||
setLicense(info)
|
setLicense(info)
|
||||||
checkFree()
|
|
||||||
} else {
|
} else {
|
||||||
ElMessage.warning(response.data.message)
|
ElMessage.warning(response.data.message)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const autoSync = ref(true)
|
|
||||||
const checkFree = () => {
|
|
||||||
checkFreeApi().then(res => {
|
|
||||||
if (res.data) {
|
|
||||||
if (autoSync.value) {
|
|
||||||
syncFree()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// do something
|
|
||||||
const title = '存在未同步的资源数据,请谨慎操作!'
|
|
||||||
const childrenDomList = [h('strong', null, title)]
|
|
||||||
ElMessageBox.confirm('', {
|
|
||||||
confirmButtonType: 'primary',
|
|
||||||
type: 'warning',
|
|
||||||
autofocus: false,
|
|
||||||
dangerouslyUseHTMLString: true,
|
|
||||||
message: h('div', { class: 'free-sync-tip-box' }, childrenDomList),
|
|
||||||
showClose: false,
|
|
||||||
cancelButtonText: '删除',
|
|
||||||
cancelButtonClass: 'free-cancel-bt',
|
|
||||||
showCancelButton: false,
|
|
||||||
preButtonType: 'danger',
|
|
||||||
preButtonText: '删除',
|
|
||||||
showPreButton: true,
|
|
||||||
confirmButtonText: '同步',
|
|
||||||
callback: (action: Action) => {
|
|
||||||
if (action === 'confirm') {
|
|
||||||
syncFree()
|
|
||||||
} else {
|
|
||||||
delFree
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const delFree = () => {
|
|
||||||
delFreeApi().then(res => {
|
|
||||||
if (!res.code && !res.msg) {
|
|
||||||
ElMessage.success(t('common.delete_success'))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const syncFree = () => {
|
|
||||||
syncFreeApi().then(res => {
|
|
||||||
if (!res.code && !res.msg) {
|
|
||||||
ElMessage.success('同步成功')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@ -282,8 +282,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
:deep(.ed-tabs__content) {
|
:deep(.ed-tabs__content) {
|
||||||
height: calc(100% - 35px);
|
height: calc(100% - 35px);
|
||||||
overflow-y: auto;
|
overflow: hidden;
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding-tab {
|
.padding-tab {
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import {
|
|||||||
S2Event,
|
S2Event,
|
||||||
S2Options,
|
S2Options,
|
||||||
S2Theme,
|
S2Theme,
|
||||||
|
ScrollbarPositionType,
|
||||||
TableColCell,
|
TableColCell,
|
||||||
TableSheet,
|
TableSheet,
|
||||||
ViewMeta
|
ViewMeta
|
||||||
@ -22,7 +23,8 @@ import {
|
|||||||
calculateHeaderHeight,
|
calculateHeaderHeight,
|
||||||
SortTooltip,
|
SortTooltip,
|
||||||
configSummaryRow,
|
configSummaryRow,
|
||||||
summaryRowStyle
|
summaryRowStyle,
|
||||||
|
configEmptyDataStyle
|
||||||
} from '@/views/chart/components/js/panel/common/common_table'
|
} from '@/views/chart/components/js/panel/common/common_table'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
@ -167,7 +169,10 @@ export class TableInfo extends S2ChartView<TableSheet> {
|
|||||||
renderTooltip: sheet => new SortTooltip(sheet)
|
renderTooltip: sheet => new SortTooltip(sheet)
|
||||||
},
|
},
|
||||||
interaction: {
|
interaction: {
|
||||||
hoverHighlight: !(basicStyle.showHoverStyle === false)
|
hoverHighlight: !(basicStyle.showHoverStyle === false),
|
||||||
|
scrollbarPosition: newData.length
|
||||||
|
? ScrollbarPositionType.CONTENT
|
||||||
|
: ScrollbarPositionType.CANVAS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s2Options.style = this.configStyle(chart, s2DataConfig)
|
s2Options.style = this.configStyle(chart, s2DataConfig)
|
||||||
@ -335,6 +340,8 @@ export class TableInfo extends S2ChartView<TableSheet> {
|
|||||||
ev.colsHierarchy.width = containerWidth
|
ev.colsHierarchy.width = containerWidth
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 空数据时表格样式
|
||||||
|
configEmptyDataStyle(newChart, basicStyle, newData, container)
|
||||||
// click
|
// click
|
||||||
newChart.on(S2Event.DATA_CELL_CLICK, ev => {
|
newChart.on(S2Event.DATA_CELL_CLICK, ev => {
|
||||||
const cell = newChart.getCell(ev.target)
|
const cell = newChart.getCell(ev.target)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { formatterItem, valueFormatter } from '@/views/chart/components/js/formatter'
|
import { formatterItem, valueFormatter } from '@/views/chart/components/js/formatter'
|
||||||
import {
|
import {
|
||||||
|
configEmptyDataStyle,
|
||||||
configSummaryRow,
|
configSummaryRow,
|
||||||
copyContent,
|
copyContent,
|
||||||
SortTooltip,
|
SortTooltip,
|
||||||
@ -13,6 +14,7 @@ import {
|
|||||||
S2DataConfig,
|
S2DataConfig,
|
||||||
S2Event,
|
S2Event,
|
||||||
S2Options,
|
S2Options,
|
||||||
|
ScrollbarPositionType,
|
||||||
TableColCell,
|
TableColCell,
|
||||||
TableSheet,
|
TableSheet,
|
||||||
ViewMeta
|
ViewMeta
|
||||||
@ -145,7 +147,10 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
|||||||
renderTooltip: sheet => new SortTooltip(sheet)
|
renderTooltip: sheet => new SortTooltip(sheet)
|
||||||
},
|
},
|
||||||
interaction: {
|
interaction: {
|
||||||
hoverHighlight: !(basicStyle.showHoverStyle === false)
|
hoverHighlight: !(basicStyle.showHoverStyle === false),
|
||||||
|
scrollbarPosition: newData.length
|
||||||
|
? ScrollbarPositionType.CONTENT
|
||||||
|
: ScrollbarPositionType.CANVAS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 列宽设置
|
// 列宽设置
|
||||||
@ -242,6 +247,7 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
|||||||
ev.colsHierarchy.width = containerWidth
|
ev.colsHierarchy.width = containerWidth
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
configEmptyDataStyle(newChart, basicStyle, newData, container)
|
||||||
// click
|
// click
|
||||||
newChart.on(S2Event.DATA_CELL_CLICK, ev => {
|
newChart.on(S2Event.DATA_CELL_CLICK, ev => {
|
||||||
const cell = newChart.getCell(ev.target)
|
const cell = newChart.getCell(ev.target)
|
||||||
|
|||||||
@ -1671,6 +1671,7 @@ const drawTextShape = (cell, isHeader) => {
|
|||||||
* @param layoutResult
|
* @param layoutResult
|
||||||
*/
|
*/
|
||||||
export const calculateHeaderHeight = (info, newChart, tableHeader, basicStyle, layoutResult) => {
|
export const calculateHeaderHeight = (info, newChart, tableHeader, basicStyle, layoutResult) => {
|
||||||
|
if (tableHeader.showTableHeader === false ) return
|
||||||
const ev = layoutResult || newChart.facet.layoutResult
|
const ev = layoutResult || newChart.facet.layoutResult
|
||||||
const maxLines = basicStyle.maxLines ?? 1
|
const maxLines = basicStyle.maxLines ?? 1
|
||||||
const textStyle = { ...newChart.theme.cornerCell.text }
|
const textStyle = { ...newChart.theme.cornerCell.text }
|
||||||
@ -1763,7 +1764,7 @@ const getWrapTextHeight = (wrapText, textStyle, spreadsheet, maxLines) => {
|
|||||||
* @param showSummary
|
* @param showSummary
|
||||||
*/
|
*/
|
||||||
export const configSummaryRow = (chart, s2Options, newData, tableHeader, basicStyle, showSummary) =>{
|
export const configSummaryRow = (chart, s2Options, newData, tableHeader, basicStyle, showSummary) =>{
|
||||||
if (!showSummary) return
|
if (!showSummary || !newData.length) return
|
||||||
// 设置汇总行高度和表头一致
|
// 设置汇总行高度和表头一致
|
||||||
const heightByField = {}
|
const heightByField = {}
|
||||||
heightByField[newData.length] = tableHeader.tableTitleHeight
|
heightByField[newData.length] = tableHeader.tableTitleHeight
|
||||||
@ -1821,10 +1822,13 @@ export const configSummaryRow = (chart, s2Options, newData, tableHeader, basicSt
|
|||||||
* @param showSummary
|
* @param showSummary
|
||||||
*/
|
*/
|
||||||
export const summaryRowStyle = (newChart, newData, tableCell, tableHeader, showSummary) => {
|
export const summaryRowStyle = (newChart, newData, tableCell, tableHeader, showSummary) => {
|
||||||
if (!showSummary) return
|
if (!showSummary || !newData.length) return
|
||||||
newChart.on(S2Event.LAYOUT_BEFORE_RENDER, () => {
|
newChart.on(S2Event.LAYOUT_BEFORE_RENDER, () => {
|
||||||
|
const showHeader = tableHeader.showTableHeader === true
|
||||||
|
// 不显示表头时,减少一个表头的高度
|
||||||
|
const headerAndSummaryHeight = showHeader ? 2 : 1
|
||||||
const totalHeight =
|
const totalHeight =
|
||||||
tableHeader.tableTitleHeight * 2 + tableCell.tableItemHeight * (newData.length - 1)
|
tableHeader.tableTitleHeight * headerAndSummaryHeight + tableCell.tableItemHeight * (newData.length - 1)
|
||||||
if (totalHeight < newChart.options.height) {
|
if (totalHeight < newChart.options.height) {
|
||||||
// 6 是阴影高度
|
// 6 是阴影高度
|
||||||
newChart.options.height =
|
newChart.options.height =
|
||||||
@ -1844,3 +1848,41 @@ export class SummaryCell extends CustomDataCell {
|
|||||||
return { backgroundColor, backgroundColorOpacity }
|
return { backgroundColor, backgroundColorOpacity }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置空数据样式
|
||||||
|
* @param newChart
|
||||||
|
* @param basicStyle
|
||||||
|
* @param newData
|
||||||
|
* @param container
|
||||||
|
*/
|
||||||
|
export const configEmptyDataStyle = (newChart, basicStyle, newData, container) => {
|
||||||
|
/**
|
||||||
|
* 辅助函数:移除空数据dom
|
||||||
|
*/
|
||||||
|
const removeEmptyDom = () => {
|
||||||
|
const emptyElement = document.getElementById(container + '_empty')
|
||||||
|
if (emptyElement) {
|
||||||
|
emptyElement.parentElement.removeChild(emptyElement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeEmptyDom()
|
||||||
|
if (newData.length) return
|
||||||
|
newChart.on(S2Event.LAYOUT_AFTER_HEADER_LAYOUT, (ev) => {
|
||||||
|
removeEmptyDom()
|
||||||
|
if (!newData.length) {
|
||||||
|
const emptyDom = document.createElement('div')
|
||||||
|
const left = Math.min(newChart.options.width, ev.colsHierarchy.width) / 2 - 32
|
||||||
|
emptyDom.id = container + '_empty'
|
||||||
|
emptyDom.textContent = t('data_set.no_data')
|
||||||
|
emptyDom.setAttribute(
|
||||||
|
'style',
|
||||||
|
`position: absolute;
|
||||||
|
left: ${left}px;
|
||||||
|
top: 50%;`
|
||||||
|
)
|
||||||
|
const parent = document.getElementById(container)
|
||||||
|
parent.insertBefore(emptyDom, parent.firstChild)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ const favorited = ref(false)
|
|||||||
const preview = () => {
|
const preview = () => {
|
||||||
const baseUrl = isDataEaseBi.value ? embeddedStore.baseUrl : ''
|
const baseUrl = isDataEaseBi.value ? embeddedStore.baseUrl : ''
|
||||||
const url = baseUrl + '#/preview?dvId=' + dvInfo.value.id + '&ignoreParams=true'
|
const url = baseUrl + '#/preview?dvId=' + dvInfo.value.id + '&ignoreParams=true'
|
||||||
const newWindow = window.open(url, openType)
|
const newWindow = window.open(url, '_blank')
|
||||||
initOpenHandler(newWindow)
|
initOpenHandler(newWindow)
|
||||||
}
|
}
|
||||||
const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
|
const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
|
||||||
|
|||||||
@ -1,10 +1,19 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive, PropType } from 'vue'
|
||||||
import { ElMessage, ElLoading } from 'element-plus-secondary'
|
import { ElMessage, ElLoading } from 'element-plus-secondary'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import type { FormInstance, FormRules } from 'element-plus-secondary'
|
import type { FormInstance, FormRules } from 'element-plus-secondary'
|
||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
import dvInfo from '@/assets/svg/dv-info.svg'
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
labelTooltips: {
|
||||||
|
type: Array as PropType<any[]>,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const loadingInstance = ref(null)
|
const loadingInstance = ref(null)
|
||||||
const basicForm = ref<FormInstance>()
|
const basicForm = ref<FormInstance>()
|
||||||
@ -48,6 +57,14 @@ const state = reactive({
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const tooltipItem = ref({})
|
||||||
|
const formatLabel = () => {
|
||||||
|
props.labelTooltips?.length &&
|
||||||
|
props.labelTooltips.forEach(tooltip => {
|
||||||
|
tooltipItem.value[tooltip.key] = tooltip.val
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const rule = reactive<FormRules>({
|
const rule = reactive<FormRules>({
|
||||||
dsIntervalTime: [
|
dsIntervalTime: [
|
||||||
{
|
{
|
||||||
@ -229,6 +246,7 @@ const oidChange = () => {
|
|||||||
state.form['platformRid'] = []
|
state.form['platformRid'] = []
|
||||||
loadRoleOptions()
|
loadRoleOptions()
|
||||||
}
|
}
|
||||||
|
formatLabel()
|
||||||
defineExpose({
|
defineExpose({
|
||||||
edit
|
edit
|
||||||
})
|
})
|
||||||
@ -255,8 +273,22 @@ defineExpose({
|
|||||||
:key="item.pkey"
|
:key="item.pkey"
|
||||||
:prop="item.pkey"
|
:prop="item.pkey"
|
||||||
:class="{ 'setting-hidden-item': item.pkey === 'dsExecuteTime' }"
|
:class="{ 'setting-hidden-item': item.pkey === 'dsExecuteTime' }"
|
||||||
:label="t(item.label)"
|
|
||||||
>
|
>
|
||||||
|
<template v-slot:label>
|
||||||
|
<div class="basic-form-info-tips">
|
||||||
|
<span class="custom-form-item__label">{{ t(item.label) }}</span>
|
||||||
|
<el-tooltip
|
||||||
|
v-if="tooltipItem[`setting_basic.${item.pkey}`]"
|
||||||
|
effect="dark"
|
||||||
|
:content="tooltipItem[`setting_basic.${item.pkey}`]"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<el-icon
|
||||||
|
><Icon name="dv-info"><dvInfo class="svg-icon" /></Icon
|
||||||
|
></el-icon>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<el-switch
|
<el-switch
|
||||||
class="de-basic-switch"
|
class="de-basic-switch"
|
||||||
v-if="
|
v-if="
|
||||||
@ -419,6 +451,32 @@ defineExpose({
|
|||||||
.ed-form-item__label {
|
.ed-form-item__label {
|
||||||
line-height: 22px !important;
|
line-height: 22px !important;
|
||||||
height: 22px !important;
|
height: 22px !important;
|
||||||
|
|
||||||
|
.basic-form-info-tips {
|
||||||
|
width: fit-content;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ed-form-item {
|
||||||
|
&.is-required.asterisk-right {
|
||||||
|
.ed-form-item__label:after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.basic-form-info-tips {
|
||||||
|
.custom-form-item__label:after {
|
||||||
|
content: '*';
|
||||||
|
color: var(--ed-color-danger);
|
||||||
|
margin-left: 2px;
|
||||||
|
font-family: var(--de-custom_font, 'PingFang');
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.ed-radio__label {
|
.ed-radio__label {
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<InfoTemplate
|
<InfoTemplate
|
||||||
|
v-if="loginInoSettings?.length"
|
||||||
ref="loginTemplate"
|
ref="loginTemplate"
|
||||||
class="login-setting-template"
|
class="login-setting-template"
|
||||||
:label-tooltips="tooltips"
|
:label-tooltips="tooltips"
|
||||||
@ -28,6 +29,7 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<InfoTemplate
|
<InfoTemplate
|
||||||
|
v-if="thirdInfoSettings?.length"
|
||||||
ref="thirdTemplate"
|
ref="thirdTemplate"
|
||||||
class="login-setting-template"
|
class="login-setting-template"
|
||||||
:label-tooltips="tooltips"
|
:label-tooltips="tooltips"
|
||||||
@ -41,7 +43,7 @@
|
|||||||
)
|
)
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<basic-edit ref="editor" @saved="refresh" />
|
<basic-edit ref="editor" :label-tooltips="tooltips" @saved="refresh" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@ -249,9 +251,9 @@ const search = cb => {
|
|||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
search(() => {
|
search(() => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
infoTemplate?.value.init()
|
infoTemplate?.value?.init()
|
||||||
loginTemplate?.value.init()
|
loginTemplate?.value?.init()
|
||||||
thirdTemplate?.value.init()
|
thirdTemplate?.value?.init()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -215,6 +215,13 @@ const saveExcelDs = (params, successCb, finallyCb) => {
|
|||||||
if (selectNode[i].changeFiled) {
|
if (selectNode[i].changeFiled) {
|
||||||
changeFiled = true
|
changeFiled = true
|
||||||
}
|
}
|
||||||
|
if (selectNode[i].fields.filter(field => field.checked).length == 0) {
|
||||||
|
ElMessage({
|
||||||
|
message: selectNode[i].excelLabel + t('datasource.api_field_not_empty'),
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
for (let j = 0; j < selectNode[i].fields.length; j++) {
|
for (let j = 0; j < selectNode[i].fields.length; j++) {
|
||||||
if (
|
if (
|
||||||
selectNode[i].fields[j].checked &&
|
selectNode[i].fields[j].checked &&
|
||||||
@ -653,14 +660,6 @@ defineExpose({
|
|||||||
{{ t('data_set.field_selection') }}
|
{{ t('data_set.field_selection') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-button @click="refreshData" secondary>
|
|
||||||
<template #icon>
|
|
||||||
<el-icon>
|
|
||||||
<Icon><icon_refresh_outlined class="svg-icon" /></Icon>
|
|
||||||
</el-icon>
|
|
||||||
</template>
|
|
||||||
{{ t('data_set.refresh_data') }}
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="info-table" v-if="isResize">
|
<div class="info-table" v-if="isResize">
|
||||||
<el-auto-resizer v-if="currentMode === 'preview'">
|
<el-auto-resizer v-if="currentMode === 'preview'">
|
||||||
|
|||||||
2
de-xpack
2
de-xpack
@ -1 +1 @@
|
|||||||
Subproject commit d0056943de6199f78d70b52b66174786e4d56519
|
Subproject commit 13ecdfab148086cf6e66fed2bcb41d88fdd5efab
|
||||||
@ -371,6 +371,7 @@ function restore() {
|
|||||||
mkdir -p $DE_RUNNING_BASE
|
mkdir -p $DE_RUNNING_BASE
|
||||||
fi
|
fi
|
||||||
echo "恢复备份 $target"
|
echo "恢复备份 $target"
|
||||||
|
rm -rf $DE_RUNNING_BASE/data/mysql/*
|
||||||
tar -zxf $target --directory=$DE_RUNNING_BASE
|
tar -zxf $target --directory=$DE_RUNNING_BASE
|
||||||
service dataease start
|
service dataease start
|
||||||
else
|
else
|
||||||
|
|||||||
@ -1,16 +0,0 @@
|
|||||||
package io.dataease.api.rmonitor;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
|
|
||||||
public interface ResourceMonitorApi {
|
|
||||||
|
|
||||||
@GetMapping("/existFree")
|
|
||||||
boolean existFree();
|
|
||||||
|
|
||||||
@PostMapping("/delete")
|
|
||||||
void delete();
|
|
||||||
|
|
||||||
@PostMapping("/sync")
|
|
||||||
void sync();
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user