mirror of
https://github.com/dataease/dataease.git
synced 2025-02-24 11:32:57 +08:00
Merge branch 'dev-v2' into pr@dev-v2@fixds
This commit is contained in:
commit
52a52dd581
@ -21,11 +21,11 @@ public class MybatisPlusGenerator {
|
||||
/**
|
||||
* 业务模块例如datasource,dataset,panel等
|
||||
*/
|
||||
private static final String busi = "chart";
|
||||
private static final String busi = "visualization";
|
||||
/**
|
||||
* 这是要生成代码的表名称
|
||||
*/
|
||||
private static final String TABLE_NAME = "core_chart_view";
|
||||
private static final String TABLE_NAME = "visualization_link_jump_target_view_info";
|
||||
|
||||
/**
|
||||
* 下面两个配置基本上不用动
|
||||
|
@ -120,7 +120,7 @@ public class YoyChartHandler extends DefaultChartHandler {
|
||||
expandedResult.setQuerySql(originSql);
|
||||
}
|
||||
// 同环比数据排序
|
||||
expandedResult.setOriginData(sortData(view, expandedResult.getOriginData(),formatResult));
|
||||
expandedResult.setOriginData(sortData(view, expandedResult.getOriginData(), formatResult));
|
||||
return expandedResult;
|
||||
}
|
||||
|
||||
@ -128,7 +128,14 @@ public class YoyChartHandler extends DefaultChartHandler {
|
||||
// 维度排序
|
||||
List<ChartViewFieldDTO> xAxisSortList = view.getXAxis().stream().filter(x -> !StringUtils.equalsIgnoreCase("none", x.getSort())).toList();
|
||||
// 指标排序
|
||||
List<ChartViewFieldDTO> yAxisSortList = view.getYAxis().stream().filter(y -> !StringUtils.equalsIgnoreCase("none", y.getSort())).toList();
|
||||
List<ChartViewFieldDTO> yAxisSortList = view.getYAxis().stream().filter(y -> {
|
||||
//需要针对区间条形图的时间类型判断一下
|
||||
if (StringUtils.equalsIgnoreCase("bar-range", view.getType()) && StringUtils.equalsIgnoreCase(y.getGroupType(), "d") && y.getDeType() == 1) {
|
||||
return false;
|
||||
} else {
|
||||
return !StringUtils.equalsIgnoreCase("none", y.getSort());
|
||||
}
|
||||
}).toList();
|
||||
// 不包含维度排序时,指标排序生效
|
||||
if (!data.isEmpty() && CollectionUtils.isEmpty(xAxisSortList) && CollectionUtils.isNotEmpty(yAxisSortList)) {
|
||||
// 指标排序仅第一个生效
|
||||
|
@ -30,6 +30,7 @@ import io.dataease.license.config.XpackInteract;
|
||||
import io.dataease.utils.BeanUtils;
|
||||
import io.dataease.utils.IDUtils;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import io.dataease.utils.LogUtil;
|
||||
import io.dataease.visualization.dao.auto.entity.DataVisualizationInfo;
|
||||
import io.dataease.visualization.dao.auto.mapper.DataVisualizationInfoMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
@ -41,6 +42,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -127,11 +129,53 @@ public class ChartViewManege {
|
||||
QueryWrapper<CoreChartView> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("scene_id", sceneId);
|
||||
List<ChartViewDTO> chartViewDTOS = transChart(coreChartViewMapper.selectList(wrapper));
|
||||
for (ChartViewDTO dto : chartViewDTOS) {
|
||||
QueryWrapper<CoreDatasetTableField> wp = new QueryWrapper<>();
|
||||
wp.eq("dataset_group_id", dto.getTableId());
|
||||
List<CoreDatasetTableField> coreDatasetTableFields = coreDatasetTableFieldMapper.selectList(wp);
|
||||
dto.setCalParams(Utils.getParams(datasetTableFieldManage.transDTO(coreDatasetTableFields)));
|
||||
if (!CollectionUtils.isEmpty(chartViewDTOS)) {
|
||||
List<Long> tableIds = chartViewDTOS.stream()
|
||||
.map(ChartViewDTO::getTableId).distinct()
|
||||
.toList();
|
||||
if (!CollectionUtils.isEmpty(tableIds)) {
|
||||
QueryWrapper<CoreDatasetTableField> wp = new QueryWrapper<>();
|
||||
wp.in("dataset_group_id", tableIds);
|
||||
List<CoreDatasetTableField> coreDatasetTableFields = coreDatasetTableFieldMapper.selectList(wp);
|
||||
Map<Long, List<CoreDatasetTableField>> groupedByTableId = coreDatasetTableFields.stream()
|
||||
.collect(Collectors.groupingBy(CoreDatasetTableField::getDatasetGroupId));
|
||||
if(chartViewDTOS.size()<10){
|
||||
chartViewDTOS.forEach(dto -> {
|
||||
if (dto.getTableId() != null) {
|
||||
dto.setCalParams(Utils.getParams(datasetTableFieldManage.transDTO(groupedByTableId.get(dto.getTableId()))));
|
||||
}
|
||||
});
|
||||
}else{
|
||||
ExecutorService executor = Executors.newFixedThreadPool(10);
|
||||
try {
|
||||
// 超过10个图表要处理启用多线程处理
|
||||
CountDownLatch latch = new CountDownLatch(chartViewDTOS.size());
|
||||
chartViewDTOS.forEach(dto -> {
|
||||
executor.submit(() -> {
|
||||
try {
|
||||
if (dto.getTableId() != null) {
|
||||
dto.setCalParams(Utils.getParams(datasetTableFieldManage.transDTO(groupedByTableId.get(dto.getTableId()))));
|
||||
}
|
||||
} finally {
|
||||
latch.countDown(); // 减少计数器
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 等待所有线程完成
|
||||
boolean completedInTime = latch.await(200, TimeUnit.SECONDS);
|
||||
if (!completedInTime) {
|
||||
throw new InterruptedException("Tasks did not complete within 200 seconds");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
LogUtil.error(e);
|
||||
} finally {
|
||||
executor.shutdown(); // 确保线程池关闭
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return chartViewDTOS;
|
||||
}
|
||||
|
@ -606,7 +606,11 @@ public class SqlparserUtils {
|
||||
&& sqlVariableDetails.getDeType() == 0) {
|
||||
return "N'" + String.join("', N'", sqlVariableDetails.getValue()) + "'";
|
||||
} else {
|
||||
return "'" + String.join("','", sqlVariableDetails.getValue()) + "'";
|
||||
if (sqlVariableDetails.getDeType() == 2 || sqlVariableDetails.getDeType() == 3) {
|
||||
return String.join(",", sqlVariableDetails.getValue());
|
||||
} else {
|
||||
return "'" + String.join("','", sqlVariableDetails.getValue()) + "'";
|
||||
}
|
||||
}
|
||||
} else if (sqlVariableDetails.getOperator().equals("between")) {
|
||||
if (sqlVariableDetails.getDeType() == 1) {
|
||||
|
@ -113,8 +113,9 @@ public class DatasetDataManage {
|
||||
sql = provider.transSqlDialect(sql, datasourceRequest.getDsList());
|
||||
} else {
|
||||
// parser sql params and replace default value
|
||||
String originSql = provider.replaceComment(new String(Base64.getDecoder().decode(tableInfoDTO.getSql())));
|
||||
originSql = SqlparserUtils.handleVariableDefaultValue(originSql, datasetTableDTO.getSqlVariableDetails(), false, false, null, false, datasourceRequest.getDsList(), pluginManage);
|
||||
String s = new String(Base64.getDecoder().decode(tableInfoDTO.getSql()));
|
||||
String originSql = SqlparserUtils.handleVariableDefaultValue(s, datasetTableDTO.getSqlVariableDetails(), false, false, null, false, datasourceRequest.getDsList(), pluginManage);
|
||||
originSql = provider.replaceComment(originSql);
|
||||
// add sql table schema
|
||||
|
||||
sql = SQLUtils.buildOriginPreviewSql(SqlPlaceholderConstants.TABLE_PLACEHOLDER, 0, 0);
|
||||
@ -403,8 +404,9 @@ public class DatasetDataManage {
|
||||
|
||||
// parser sql params and replace default value
|
||||
|
||||
String originSql = provider.replaceComment(new String(Base64.getDecoder().decode(dto.getSql())));
|
||||
originSql = SqlparserUtils.handleVariableDefaultValue(datasetSQLManage.subPrefixSuffixChar(originSql), dto.getSqlVariableDetails(), true, true, null, false, dsMap, pluginManage);
|
||||
String s = new String(Base64.getDecoder().decode(dto.getSql()));
|
||||
String originSql = SqlparserUtils.handleVariableDefaultValue(datasetSQLManage.subPrefixSuffixChar(s), dto.getSqlVariableDetails(), true, true, null, false, dsMap, pluginManage);
|
||||
originSql = provider.replaceComment(originSql);
|
||||
|
||||
// sql 作为临时表,外层加上limit
|
||||
String sql;
|
||||
|
@ -222,14 +222,17 @@ public class DatasetGroupManage {
|
||||
}
|
||||
|
||||
|
||||
@XpackInteract(value = "authResourceTree", replace = true)
|
||||
@XpackInteract(value = "authResourceTree", replace = true, invalid = true)
|
||||
public List<BusiNodeVO> tree(BusiNodeRequest request) {
|
||||
|
||||
QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
|
||||
if (ObjectUtils.isNotEmpty(request.getLeaf())) {
|
||||
queryWrapper.eq("node_type", request.getLeaf() ? "dataset" : "folder");
|
||||
}
|
||||
|
||||
String info = CommunityUtils.getInfo();
|
||||
if (StringUtils.isNotBlank(info)) {
|
||||
queryWrapper.notExists(String.format(info, "core_dataset_group.id"));
|
||||
}
|
||||
queryWrapper.orderByDesc("create_time");
|
||||
List<DataSetNodePO> pos = coreDataSetExtMapper.query(queryWrapper);
|
||||
List<DataSetNodeBO> nodes = new ArrayList<>();
|
||||
|
@ -451,8 +451,9 @@ public class DatasetSQLManage {
|
||||
} else if (StringUtils.equalsIgnoreCase(currentDs.getType(), DatasetTableTypeConstants.DATASET_TABLE_SQL)) {
|
||||
Provider provider = ProviderFactory.getProvider(dsMap.entrySet().iterator().next().getValue().getType());
|
||||
// parser sql params and replace default value
|
||||
String sql = provider.replaceComment(new String(Base64.getDecoder().decode(infoDTO.getSql())));
|
||||
sql = SqlparserUtils.handleVariableDefaultValue(sql, currentDs.getSqlVariableDetails(), false, isFromDataSet, parameters, isCross, dsMap, pluginManage);
|
||||
String s = new String(Base64.getDecoder().decode(infoDTO.getSql()));
|
||||
String sql = SqlparserUtils.handleVariableDefaultValue(s, currentDs.getSqlVariableDetails(), false, isFromDataSet, parameters, isCross, dsMap, pluginManage);
|
||||
sql = provider.replaceComment(sql);
|
||||
// add table schema
|
||||
if (isCross) {
|
||||
sql = SqlUtils.addSchema(sql, tableSchema);
|
||||
|
@ -279,18 +279,23 @@ public class DatasetTableFieldManage {
|
||||
}
|
||||
|
||||
public List<DatasetTableFieldDTO> transDTO(List<CoreDatasetTableField> list) {
|
||||
return list.stream().map(ele -> {
|
||||
DatasetTableFieldDTO dto = new DatasetTableFieldDTO();
|
||||
if (ele == null) return null;
|
||||
BeanUtils.copyBean(dto, ele);
|
||||
if (StringUtils.isNotEmpty(ele.getParams())) {
|
||||
TypeReference<List<CalParam>> tokenType = new TypeReference<>() {
|
||||
};
|
||||
List<CalParam> calParams = JsonUtil.parseList(ele.getParams(), tokenType);
|
||||
dto.setParams(calParams);
|
||||
}
|
||||
return dto;
|
||||
}).collect(Collectors.toList());
|
||||
if(!CollectionUtils.isEmpty(list)){
|
||||
return list.stream().map(ele -> {
|
||||
DatasetTableFieldDTO dto = new DatasetTableFieldDTO();
|
||||
if (ele == null) return null;
|
||||
BeanUtils.copyBean(dto, ele);
|
||||
if (StringUtils.isNotEmpty(ele.getParams())) {
|
||||
TypeReference<List<CalParam>> tokenType = new TypeReference<>() {
|
||||
};
|
||||
List<CalParam> calParams = JsonUtil.parseList(ele.getParams(), tokenType);
|
||||
dto.setParams(calParams);
|
||||
}
|
||||
return dto;
|
||||
}).collect(Collectors.toList());
|
||||
}else{
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private CoreDatasetTableField transDTO2Record(DatasetTableFieldDTO dto) {
|
||||
|
@ -19,6 +19,7 @@ import io.dataease.model.BusiNodeVO;
|
||||
import io.dataease.operation.manage.CoreOptRecentManage;
|
||||
import io.dataease.utils.AuthUtils;
|
||||
import io.dataease.utils.BeanUtils;
|
||||
import io.dataease.utils.CommunityUtils;
|
||||
import io.dataease.utils.TreeUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
@ -56,13 +57,17 @@ public class DataSourceManage {
|
||||
return new DatasourceNodeBO(po.getId(), po.getName(), !StringUtils.equals(po.getType(), "folder"), 7, po.getPid(), extraFlag, dataSourceType.name());
|
||||
}
|
||||
|
||||
@XpackInteract(value = "datasourceResourceTree", replace = true)
|
||||
@XpackInteract(value = "datasourceResourceTree", replace = true, invalid = true)
|
||||
public List<BusiNodeVO> tree(BusiNodeRequest request) {
|
||||
|
||||
QueryWrapper<DataSourceNodePO> queryWrapper = new QueryWrapper<>();
|
||||
if (ObjectUtils.isNotEmpty(request.getLeaf()) && !request.getLeaf()) {
|
||||
queryWrapper.eq("type", "folder");
|
||||
}
|
||||
String info = CommunityUtils.getInfo();
|
||||
if (StringUtils.isNotBlank(info)) {
|
||||
queryWrapper.notExists(String.format(info, "core_datasource.id"));
|
||||
}
|
||||
queryWrapper.orderByDesc("create_time");
|
||||
List<DatasourceNodeBO> nodes = new ArrayList<>();
|
||||
List<DataSourceNodePO> pos = dataSourceExtMapper.selectList(queryWrapper);
|
||||
|
@ -22,6 +22,7 @@ import io.dataease.extensions.datasource.provider.Provider;
|
||||
import io.dataease.job.schedule.ExtractDataJob;
|
||||
import io.dataease.job.schedule.ScheduleManager;
|
||||
import io.dataease.utils.BeanUtils;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import io.dataease.utils.LogUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -30,6 +31,7 @@ import org.quartz.JobKey;
|
||||
import org.quartz.TriggerKey;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -245,17 +247,7 @@ public class DatasourceSyncManage {
|
||||
private void extractExcelData(DatasourceRequest datasourceRequest, DatasourceServer.UpdateType extractType, List<TableField> tableFields) throws Exception {
|
||||
ExcelUtils excelUtils = new ExcelUtils();
|
||||
List<String[]> dataList = excelUtils.fetchDataList(datasourceRequest);
|
||||
String engineTableName;
|
||||
switch (extractType) {
|
||||
case all_scope:
|
||||
engineTableName = TableUtils.tmpName(TableUtils.tableName(datasourceRequest.getTable()));
|
||||
break;
|
||||
default:
|
||||
engineTableName = TableUtils.tableName(datasourceRequest.getTable());
|
||||
break;
|
||||
}
|
||||
CoreDeEngine engine = engineManage.info();
|
||||
|
||||
EngineRequest engineRequest = new EngineRequest();
|
||||
engineRequest.setEngine(engine);
|
||||
EngineProvider engineProvider = ProviderUtil.getEngineProvider(engine.getType());
|
||||
@ -267,7 +259,7 @@ public class DatasourceSyncManage {
|
||||
totalPage = dataList.size() / pageNumber;
|
||||
}
|
||||
for (int page = 1; page <= totalPage; page++) {
|
||||
engineRequest.setQuery(engineProvider.insertSql(engineTableName, extractType, dataList, page, pageNumber, tableFields));
|
||||
engineRequest.setQuery(engineProvider.insertSql(datasourceRequest.getTable(), extractType, dataList, page, pageNumber, tableFields));
|
||||
calciteProvider.exec(engineRequest);
|
||||
}
|
||||
}
|
||||
|
@ -437,6 +437,7 @@ public class ExcelUtils {
|
||||
tableFiled.setFieldType(null);
|
||||
tableFiled.setName(s);
|
||||
tableFiled.setOriginName(s);
|
||||
tableFiled.setChecked(true);
|
||||
fields.add(tableFiled);
|
||||
}
|
||||
List<String[]> data = new ArrayList<>(noModelDataListener.getData());
|
||||
|
@ -40,12 +40,16 @@ public class H2EngineProvider extends EngineProvider {
|
||||
|
||||
Integer realSize = page * pageNumber < dataList.size() ? page * pageNumber : dataList.size();
|
||||
for (String[] strings : dataList.subList((page - 1) * pageNumber, realSize)) {
|
||||
String[] strings1 = new String[strings.length];
|
||||
int length = 0;
|
||||
String[] strings1 = new String[tableFields.stream().filter(TableField::isChecked).toList().size()];
|
||||
for (int i = 0; i < strings.length; i++) {
|
||||
if (StringUtils.isEmpty(strings[i])) {
|
||||
strings1[i] = null;
|
||||
} else {
|
||||
strings1[i] = strings[i].replace("'", "\\'");
|
||||
if (tableFields.get(i).isChecked()) {
|
||||
if (StringUtils.isEmpty(strings[i])) {
|
||||
strings1[length] = null;
|
||||
} else {
|
||||
strings1[length] = strings[i].replace("\\", "\\\\").replace("'", "\\'");
|
||||
}
|
||||
length++;
|
||||
}
|
||||
}
|
||||
values.append("('").append(String.join("','", Arrays.asList(strings1)))
|
||||
@ -81,6 +85,9 @@ public class H2EngineProvider extends EngineProvider {
|
||||
StringBuilder columnFields = new StringBuilder("`");
|
||||
StringBuilder key = new StringBuilder();
|
||||
for (TableField tableField : tableFields) {
|
||||
if (!tableField.isChecked()) {
|
||||
continue;
|
||||
}
|
||||
if (tableField.isPrimaryKey()) {
|
||||
key.append("`").append(tableField.getName()).append("`, ");
|
||||
}
|
||||
|
@ -47,19 +47,23 @@ public class MysqlEngineProvider extends EngineProvider {
|
||||
|
||||
Integer realSize = page * pageNumber < dataList.size() ? page * pageNumber : dataList.size();
|
||||
for (String[] strings : dataList.subList((page - 1) * pageNumber, realSize)) {
|
||||
String[] strings1 = new String[strings.length];
|
||||
int length = 0;
|
||||
String[] strings1 = new String[tableFields.stream().filter(TableField::isChecked).toList().size()];
|
||||
for (int i = 0; i < strings.length; i++) {
|
||||
if (StringUtils.isEmpty(strings[i])) {
|
||||
strings1[i] = null;
|
||||
} else {
|
||||
strings1[i] = strings[i].replace("\\", "\\\\").replace("'", "\\'");
|
||||
if (tableFields.get(i).isChecked()) {
|
||||
if (StringUtils.isEmpty(strings[i])) {
|
||||
strings1[length] = null;
|
||||
} else {
|
||||
strings1[length] = strings[i].replace("\\", "\\\\").replace("'", "\\'");
|
||||
}
|
||||
length++;
|
||||
}
|
||||
}
|
||||
values.append("('").append(String.join("','", Arrays.asList(strings1)))
|
||||
.append("'),");
|
||||
}
|
||||
List<TableField> keys = tableFields.stream().filter(TableField::isPrimaryKey).toList();
|
||||
List<TableField> notKeys = tableFields.stream().filter(tableField -> !tableField.isPrimaryKey()).toList();
|
||||
List<TableField> keys = tableFields.stream().filter(tableField -> tableField.isPrimaryKey() && tableField.isChecked()).toList();
|
||||
List<TableField> notKeys = tableFields.stream().filter(tableField -> tableField.isChecked() && !tableField.isPrimaryKey()).toList();
|
||||
String insetSql = (insertSql + values.substring(0, values.length() - 1)).replaceAll("'null'", "null");
|
||||
if (CollectionUtils.isNotEmpty(keys) && extractType.equals(DatasourceServer.UpdateType.add_scope)) {
|
||||
insetSql = insetSql + " ON DUPLICATE KEY UPDATE ";
|
||||
@ -101,6 +105,9 @@ public class MysqlEngineProvider extends EngineProvider {
|
||||
StringBuilder columnFields = new StringBuilder("`");
|
||||
StringBuilder key = new StringBuilder();
|
||||
for (TableField tableField : tableFields) {
|
||||
if (!tableField.isChecked()) {
|
||||
continue;
|
||||
}
|
||||
if (tableField.isPrimaryKey()) {
|
||||
key.append("`").append(tableField.getName()).append("`, ");
|
||||
}
|
||||
|
@ -107,6 +107,8 @@ public class DatasourceServer implements DatasourceApi {
|
||||
private PluginManageApi pluginManage;
|
||||
@Autowired(required = false)
|
||||
private RelationApi relationManage;
|
||||
@Autowired
|
||||
private CoreDatasourceMapper coreDatasourceMapper;
|
||||
|
||||
public enum UpdateType {
|
||||
all_scope, add_scope
|
||||
@ -406,14 +408,13 @@ public class DatasourceServer implements DatasourceApi {
|
||||
requestDatasource.setEnableDataFill(null);
|
||||
List<String> sourceTables = ExcelUtils.getTables(sourceTableRequest).stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList());
|
||||
List<String> tables = ExcelUtils.getTables(datasourceRequest).stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList());
|
||||
if (dataSourceDTO.getEditType() == 0) {
|
||||
if (Objects.equals(dataSourceDTO.getEditType(), replace)) {
|
||||
toCreateTables = tables;
|
||||
toDeleteTables = sourceTables.stream().filter(s -> tables.contains(s)).collect(Collectors.toList());
|
||||
for (String deleteTable : toDeleteTables) {
|
||||
try {
|
||||
datasourceSyncManage.dropEngineTable(deleteTable);
|
||||
} catch (Exception e) {
|
||||
DEException.throwException("Failed to drop table " + deleteTable + ", " + e.getMessage());
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
for (String toCreateTable : toCreateTables) {
|
||||
@ -424,12 +425,16 @@ public class DatasourceServer implements DatasourceApi {
|
||||
DEException.throwException("Failed to create table " + toCreateTable + ", " + e.getMessage());
|
||||
}
|
||||
}
|
||||
datasourceSyncManage.extractExcelData(requestDatasource, "all_scope");
|
||||
commonThreadPool.addTask(() -> {
|
||||
datasourceSyncManage.extractExcelData(requestDatasource, "all_scope");
|
||||
});
|
||||
dataSourceManage.checkName(dataSourceDTO);
|
||||
ExcelUtils.mergeSheets(requestDatasource, sourceData);
|
||||
dataSourceManage.innerEdit(requestDatasource);
|
||||
} else {
|
||||
datasourceSyncManage.extractExcelData(requestDatasource, "add_scope");
|
||||
commonThreadPool.addTask(() -> {
|
||||
datasourceSyncManage.extractExcelData(requestDatasource, "add_scope");
|
||||
});
|
||||
dataSourceManage.checkName(dataSourceDTO);
|
||||
dataSourceManage.innerEdit(requestDatasource);
|
||||
}
|
||||
@ -765,6 +770,7 @@ public class DatasourceServer implements DatasourceApi {
|
||||
|
||||
ExcelUtils excelUtils = new ExcelUtils();
|
||||
ExcelFileData excelFileData = excelUtils.excelSaveAndParse(file);
|
||||
|
||||
if (Objects.equals(editType, append)) { //按照excel sheet 名称匹配,替换:0;追加:1
|
||||
if (coreDatasource != null) {
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
@ -774,15 +780,9 @@ public class DatasourceServer implements DatasourceApi {
|
||||
for (ExcelSheetData sheet : excelFileData.getSheets()) {
|
||||
for (DatasetTableDTO datasetTableDTO : datasetTableDTOS) {
|
||||
if (excelDataTableName(datasetTableDTO.getTableName()).equals(sheet.getTableName()) || isCsv(file.getOriginalFilename())) {
|
||||
List<TableField> newTableFields = deepCopy(sheet.getFields());
|
||||
newTableFields.sort((o1, o2) -> {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
});
|
||||
List<TableField> newTableFields = sheet.getFields();
|
||||
datasourceRequest.setTable(datasetTableDTO.getTableName());
|
||||
List<TableField> oldTableFields = ExcelUtils.getTableFields(datasourceRequest);
|
||||
oldTableFields.sort((o1, o2) -> {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
});
|
||||
if (isEqual(newTableFields, oldTableFields)) {
|
||||
sheet.setDeTableName(datasetTableDTO.getTableName());
|
||||
excelSheetDataList.add(sheet);
|
||||
@ -796,20 +796,29 @@ public class DatasourceServer implements DatasourceApi {
|
||||
excelFileData.setSheets(excelSheetDataList);
|
||||
}
|
||||
} else {
|
||||
// 替换
|
||||
if (coreDatasource != null) {
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setDatasource(transDTO(coreDatasource));
|
||||
List<DatasetTableDTO> datasetTableDTOS = ExcelUtils.getTables(datasourceRequest);
|
||||
for (ExcelSheetData sheet : excelFileData.getSheets()) {
|
||||
boolean find = false;
|
||||
for (DatasetTableDTO datasetTableDTO : datasetTableDTOS) {
|
||||
if (excelDataTableName(datasetTableDTO.getTableName()).equals(sheet.getTableName()) || isCsv(file.getOriginalFilename())) {
|
||||
find = true;
|
||||
sheet.setDeTableName(datasetTableDTO.getTableName());
|
||||
datasourceRequest.setTable(datasetTableDTO.getTableName());
|
||||
List<TableField> oldTableFields = ExcelUtils.getTableFields(datasourceRequest);
|
||||
mergeFields(sheet.getFields(), oldTableFields);
|
||||
}
|
||||
}
|
||||
if (!find) {
|
||||
sheet.setNewSheet(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (ExcelSheetData sheet : excelFileData.getSheets()) {
|
||||
for (int i = 0; i < sheet.getFields().size() - 1; i++) {
|
||||
for (int j = i + 1; j < sheet.getFields().size(); j++) {
|
||||
@ -823,31 +832,42 @@ public class DatasourceServer implements DatasourceApi {
|
||||
}
|
||||
|
||||
private boolean isEqual(List<TableField> newTableFields, List<TableField> oldTableFields) {
|
||||
boolean isEqual = true;
|
||||
if (CollectionUtils.isEmpty(newTableFields) || CollectionUtils.isEmpty(oldTableFields)) {
|
||||
isEqual = false;
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < newTableFields.size(); i++) {
|
||||
if (!newTableFields.get(i).getName().equals(oldTableFields.get(i).getName())) {
|
||||
isEqual = false;
|
||||
break;
|
||||
newTableFields.forEach(tableField -> tableField.setChecked(false));
|
||||
for (TableField oldField : oldTableFields) {
|
||||
if (!oldField.isChecked()) {
|
||||
continue;
|
||||
}
|
||||
if (!newTableFields.get(i).getFieldType().equals(oldTableFields.get(i).getFieldType())) {
|
||||
if (oldTableFields.get(i).getFieldType().equals("TEXT")) {
|
||||
continue;
|
||||
boolean find = false;
|
||||
for (TableField newField : newTableFields) {
|
||||
if (oldField.getName().equals(newField.getName())) {
|
||||
find = true;
|
||||
newField.setChecked(oldField.isChecked());
|
||||
newField.setPrimaryKey(oldField.isPrimaryKey());
|
||||
newField.setLength(oldField.getLength());
|
||||
break;
|
||||
}
|
||||
if (oldTableFields.get(i).getFieldType().equals("DOUBLE")) {
|
||||
if (newTableFields.get(i).getFieldType().equals("LONG")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
isEqual = false;
|
||||
break;
|
||||
}
|
||||
if (!find) {
|
||||
return find;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return isEqual;
|
||||
|
||||
private void mergeFields(List<TableField> oldFields, List<TableField> newFields) {
|
||||
oldFields.forEach(tableField -> tableField.setChecked(false));
|
||||
for (TableField newField : newFields) {
|
||||
for (TableField oldField : oldFields) {
|
||||
if (oldField.getName().equals(newField.getName())) {
|
||||
newField.setChecked(oldField.isChecked());
|
||||
newField.setPrimaryKey(oldField.isPrimaryKey());
|
||||
newField.setLength(oldField.getLength());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCsv(String fileName) {
|
||||
@ -1209,4 +1229,25 @@ public class DatasourceServer implements DatasourceApi {
|
||||
return datasourceDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DsSimpleVO simple(Long id) {
|
||||
if (ObjectUtils.isEmpty(id)) DEException.throwException("id is null");
|
||||
CoreDatasource coreDatasource = coreDatasourceMapper.selectById(id);
|
||||
if (ObjectUtils.isEmpty(coreDatasource)) return null;
|
||||
DsSimpleVO vo = new DsSimpleVO();
|
||||
vo.setName(coreDatasource.getName());
|
||||
vo.setType(coreDatasource.getType());
|
||||
vo.setDescription(coreDatasource.getDescription());
|
||||
String configuration = coreDatasource.getConfiguration();
|
||||
DatasourceConfiguration config = null;
|
||||
String host = null;
|
||||
if (StringUtils.isBlank(configuration)
|
||||
|| StringUtils.equalsIgnoreCase("[]", configuration)
|
||||
|| ObjectUtils.isEmpty(config = JsonUtil.parseObject(configuration, DatasourceConfiguration.class))
|
||||
|| StringUtils.isBlank(host = config.getHost())) {
|
||||
return vo;
|
||||
}
|
||||
vo.setHost(host);
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +168,11 @@ public class ExtWhere2Str {
|
||||
|| StringUtils.containsIgnoreCase(request.getDatasetTableField().getType(), "NCHAR")) {
|
||||
whereValue = "(" + value.stream().map(str -> "'" + SQLConstants.MSSQL_N_PREFIX + str + "'").collect(Collectors.joining(",")) + ")";
|
||||
} else {
|
||||
whereValue = "('" + StringUtils.join(value, "','") + "')";
|
||||
if (request.getDatasetTableField().getDeType() == 2 || request.getDatasetTableField().getDeType() == 3) {
|
||||
whereValue = "(" + StringUtils.join(value, ",") + ")";
|
||||
} else {
|
||||
whereValue = "('" + StringUtils.join(value, "','") + "')";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,6 +105,7 @@ public class MenuManage {
|
||||
|| coreMenu.getId().equals(50L)
|
||||
|| coreMenu.getId().equals(60L)
|
||||
|| coreMenu.getId().equals(61L)
|
||||
|| coreMenu.getId().equals(80L)
|
||||
|| coreMenu.getPid().equals(70L);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
package io.dataease.msgCenter;
|
||||
|
||||
import io.dataease.api.msgCenter.MsgCenterApi;
|
||||
import io.dataease.license.config.XpackInteract;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/msg-center")
|
||||
public class MsgCenterServer implements MsgCenterApi {
|
||||
@Override
|
||||
@XpackInteract(value = "msgCenterServer", replace = true)
|
||||
public long count() {
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -166,6 +166,10 @@ public class XpackShareManage {
|
||||
if (StringUtils.isNotBlank(request.getKeyword())) {
|
||||
queryWrapper.like("v.name", request.getKeyword());
|
||||
}
|
||||
String info = CommunityUtils.getInfo();
|
||||
if (StringUtils.isNotBlank(info)) {
|
||||
queryWrapper.notExists(String.format(info, "s.resource_id"));
|
||||
}
|
||||
queryWrapper.orderBy(true, request.isAsc(), "s.time");
|
||||
Page<XpackSharePO> page = new Page<>(goPage, pageSize);
|
||||
return xpackShareExtMapper.query(page, queryWrapper);
|
||||
@ -179,7 +183,7 @@ public class XpackShareManage {
|
||||
};
|
||||
}
|
||||
|
||||
@XpackInteract(value = "perFilterShareManage", recursion = true)
|
||||
@XpackInteract(value = "perFilterShareManage", recursion = true, invalid = true)
|
||||
public IPage<XpackShareGridVO> query(int pageNum, int pageSize, VisualizationWorkbranchQueryRequest request) {
|
||||
IPage<XpackSharePO> poiPage = proxy().querySharePage(pageNum, pageSize, request);
|
||||
List<XpackShareGridVO> vos = proxy().formatResult(poiPage.getRecords());
|
||||
|
@ -5,11 +5,11 @@ import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* 可视化大屏信息表
|
||||
* </p>
|
||||
*
|
||||
* @author fit2cloud
|
||||
* @since 2024-04-11
|
||||
* @since 2024-11-22
|
||||
*/
|
||||
@TableName("data_visualization_info")
|
||||
public class DataVisualizationInfo implements Serializable {
|
||||
@ -59,7 +59,7 @@ public class DataVisualizationInfo implements Serializable {
|
||||
private String componentData;
|
||||
|
||||
/**
|
||||
* 移动端布局
|
||||
* 移动端布局0-关闭 1-开启
|
||||
*/
|
||||
private Boolean mobileLayout;
|
||||
|
||||
@ -128,11 +128,15 @@ public class DataVisualizationInfo implements Serializable {
|
||||
*/
|
||||
private Integer version;
|
||||
|
||||
/**
|
||||
* 内容标识
|
||||
*/
|
||||
private String contentId;
|
||||
|
||||
public String getContentId() {
|
||||
return contentId;
|
||||
}
|
||||
/**
|
||||
* 内容检查标识
|
||||
*/
|
||||
private String checkVersion;
|
||||
|
||||
public void setContentId(String contentId) {
|
||||
this.contentId = contentId;
|
||||
@ -322,6 +326,18 @@ public class DataVisualizationInfo implements Serializable {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getContentId() {
|
||||
return contentId;
|
||||
}
|
||||
|
||||
public String getCheckVersion() {
|
||||
return checkVersion;
|
||||
}
|
||||
|
||||
public void setCheckVersion(String checkVersion) {
|
||||
this.checkVersion = checkVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DataVisualizationInfo{" +
|
||||
@ -348,6 +364,8 @@ public class DataVisualizationInfo implements Serializable {
|
||||
", deleteTime = " + deleteTime +
|
||||
", deleteBy = " + deleteBy +
|
||||
", version = " + version +
|
||||
", contentId = " + contentId +
|
||||
", checkVersion = " + checkVersion +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
package io.dataease.visualization.dao.auto.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* 跳转目标仪表板图表字段配置表
|
||||
* </p>
|
||||
*
|
||||
* @author fit2cloud
|
||||
* @since 2023-09-22
|
||||
* @since 2024-11-20
|
||||
*/
|
||||
@TableName("visualization_link_jump_target_view_info")
|
||||
public class VisualizationLinkJumpTargetViewInfo implements Serializable {
|
||||
@ -18,6 +19,9 @@ public class VisualizationLinkJumpTargetViewInfo implements Serializable {
|
||||
|
||||
private Long targetId;
|
||||
|
||||
/**
|
||||
* visualization_link_jump_info 表的 ID
|
||||
*/
|
||||
private Long linkJumpInfoId;
|
||||
|
||||
/**
|
||||
@ -25,14 +29,31 @@ public class VisualizationLinkJumpTargetViewInfo implements Serializable {
|
||||
*/
|
||||
private Long sourceFieldActiveId;
|
||||
|
||||
private Long targetViewId;
|
||||
/**
|
||||
* 目标图表ID
|
||||
*/
|
||||
private String targetViewId;
|
||||
|
||||
private Long targetFieldId;
|
||||
/**
|
||||
* 目标字段ID
|
||||
*/
|
||||
private String targetFieldId;
|
||||
|
||||
/**
|
||||
* 复制来源
|
||||
*/
|
||||
private Long copyFrom;
|
||||
|
||||
/**
|
||||
* 复制来源ID
|
||||
*/
|
||||
private Long copyId;
|
||||
|
||||
/**
|
||||
* 联动目标类型 view 图表 filter 过滤组件 outParams 外部参数
|
||||
*/
|
||||
private String targetType;
|
||||
|
||||
public Long getTargetId() {
|
||||
return targetId;
|
||||
}
|
||||
@ -57,19 +78,19 @@ public class VisualizationLinkJumpTargetViewInfo implements Serializable {
|
||||
this.sourceFieldActiveId = sourceFieldActiveId;
|
||||
}
|
||||
|
||||
public Long getTargetViewId() {
|
||||
public String getTargetViewId() {
|
||||
return targetViewId;
|
||||
}
|
||||
|
||||
public void setTargetViewId(Long targetViewId) {
|
||||
public void setTargetViewId(String targetViewId) {
|
||||
this.targetViewId = targetViewId;
|
||||
}
|
||||
|
||||
public Long getTargetFieldId() {
|
||||
public String getTargetFieldId() {
|
||||
return targetFieldId;
|
||||
}
|
||||
|
||||
public void setTargetFieldId(Long targetFieldId) {
|
||||
public void setTargetFieldId(String targetFieldId) {
|
||||
this.targetFieldId = targetFieldId;
|
||||
}
|
||||
|
||||
@ -89,6 +110,14 @@ public class VisualizationLinkJumpTargetViewInfo implements Serializable {
|
||||
this.copyId = copyId;
|
||||
}
|
||||
|
||||
public String getTargetType() {
|
||||
return targetType;
|
||||
}
|
||||
|
||||
public void setTargetType(String targetType) {
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VisualizationLinkJumpTargetViewInfo{" +
|
||||
@ -99,6 +128,7 @@ public class VisualizationLinkJumpTargetViewInfo implements Serializable {
|
||||
", targetFieldId = " + targetFieldId +
|
||||
", copyFrom = " + copyFrom +
|
||||
", copyId = " + copyId +
|
||||
", targetType = " + targetType +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import org.apache.ibatis.annotations.Mapper;
|
||||
* </p>
|
||||
*
|
||||
* @author fit2cloud
|
||||
* @since 2024-11-18
|
||||
* @since 2024-11-22
|
||||
*/
|
||||
@Mapper
|
||||
public interface DataVisualizationInfoMapper extends BaseMapper<DataVisualizationInfo> {
|
||||
|
@ -6,11 +6,11 @@ import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* 跳转目标仪表板图表字段配置表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author fit2cloud
|
||||
* @since 2023-09-22
|
||||
* @since 2024-11-20
|
||||
*/
|
||||
@Mapper
|
||||
public interface VisualizationLinkJumpTargetViewInfoMapper extends BaseMapper<VisualizationLinkJumpTargetViewInfo> {
|
||||
|
@ -4,6 +4,7 @@ import io.dataease.api.visualization.dto.VisualizationLinkJumpDTO;
|
||||
import io.dataease.api.visualization.request.VisualizationLinkJumpBaseRequest;
|
||||
import io.dataease.api.visualization.vo.VisualizationLinkJumpInfoVO;
|
||||
import io.dataease.api.visualization.vo.VisualizationLinkJumpVO;
|
||||
import io.dataease.api.visualization.vo.VisualizationOutParamsJumpVO;
|
||||
import io.dataease.api.visualization.vo.VisualizationViewTableVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
@ -36,6 +37,10 @@ public interface ExtVisualizationLinkJumpMapper {
|
||||
void copyLinkJumpTarget(@Param("copyId")Long copyId);
|
||||
|
||||
List<VisualizationLinkJumpVO> findLinkJumpWithDvId(@Param("dvId")Long dvId);
|
||||
|
||||
List<VisualizationLinkJumpInfoVO> findLinkJumpInfoWithDvId(@Param("dvId")Long dvId);
|
||||
|
||||
List<VisualizationViewTableVO> getViewTableDetails(@Param("dvId")Long dvId);
|
||||
|
||||
List<VisualizationOutParamsJumpVO> queryOutParamsTargetWithDvId(@Param("dvId")Long dvId);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ package io.dataease.visualization.dao.ext.mapper;
|
||||
import io.dataease.api.dataset.vo.CoreDatasetGroupVO;
|
||||
import io.dataease.api.visualization.dto.VisualizationOuterParamsDTO;
|
||||
import io.dataease.api.visualization.dto.VisualizationOuterParamsInfoDTO;
|
||||
import io.dataease.visualization.dao.auto.entity.VisualizationOuterParamsInfo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@ -22,5 +23,7 @@ public interface ExtVisualizationOuterParamsMapper {
|
||||
|
||||
List<VisualizationOuterParamsInfoDTO> getVisualizationOuterParamsInfo(@Param("visualizationId") String visualizationId);
|
||||
|
||||
List<VisualizationOuterParamsInfo> getVisualizationOuterParamsInfoBase(@Param("visualizationId") String visualizationId);
|
||||
|
||||
List<CoreDatasetGroupVO> queryDsWithVisualizationId(@Param("visualizationId") String visualizationId);
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public class CoreVisualizationManage {
|
||||
@Resource
|
||||
private CoreOptRecentManage coreOptRecentManage;
|
||||
|
||||
@XpackInteract(value = "visualizationResourceTree", replace = true)
|
||||
@XpackInteract(value = "visualizationResourceTree", replace = true, invalid = true)
|
||||
public List<BusiNodeVO> tree(BusiNodeRequest request) {
|
||||
List<VisualizationNodeBO> nodes = new ArrayList<>();
|
||||
if (ObjectUtils.isEmpty(request.getLeaf()) || !request.getLeaf()) {
|
||||
@ -59,6 +59,10 @@ public class CoreVisualizationManage {
|
||||
queryWrapper.ne("pid", -1);
|
||||
queryWrapper.eq(ObjectUtils.isNotEmpty(request.getLeaf()), "node_type", ObjectUtils.isNotEmpty(request.getLeaf()) && request.getLeaf() ? "leaf" : "folder");
|
||||
queryWrapper.eq("type", request.getBusiFlag());
|
||||
String info = CommunityUtils.getInfo();
|
||||
if (StringUtils.isNotBlank(info)) {
|
||||
queryWrapper.notExists(String.format(info, "data_visualization_info.id"));
|
||||
}
|
||||
queryWrapper.orderByDesc("create_time");
|
||||
List<VisualizationNodePO> pos = extMapper.queryNodes(queryWrapper);
|
||||
if (CollectionUtils.isNotEmpty(pos)) {
|
||||
@ -158,7 +162,7 @@ public class CoreVisualizationManage {
|
||||
return CommonBeanFactory.getBean(this.getClass());
|
||||
}
|
||||
|
||||
@XpackInteract(value = "perFilterManage", recursion = true)
|
||||
@XpackInteract(value = "perFilterManage", recursion = true, invalid = true)
|
||||
public IPage<VisualizationResourceVO> query(int pageNum, int pageSize, VisualizationWorkbranchQueryRequest request) {
|
||||
IPage<VisualizationResourcePO> visualizationResourcePOPageIPage = proxy().queryVisualizationPage(pageNum, pageSize, request);
|
||||
if (ObjectUtils.isEmpty(visualizationResourcePOPageIPage)) {
|
||||
@ -182,7 +186,7 @@ public class CoreVisualizationManage {
|
||||
new VisualizationResourceVO(
|
||||
po.getId(), po.getResourceId(), po.getName(),
|
||||
po.getType(), String.valueOf(po.getCreator()), String.valueOf(po.getLastEditor()), po.getLastEditTime(),
|
||||
po.getFavorite(), 9,po.getExtFlag())).toList();
|
||||
po.getFavorite(), 9, po.getExtFlag())).toList();
|
||||
}
|
||||
|
||||
public IPage<VisualizationResourcePO> queryVisualizationPage(int goPage, int pageSize, VisualizationWorkbranchQueryRequest request) {
|
||||
@ -198,6 +202,10 @@ public class CoreVisualizationManage {
|
||||
if (StringUtils.isNotBlank(request.getKeyword())) {
|
||||
queryWrapper.like("dvResource.name", request.getKeyword());
|
||||
}
|
||||
String info = CommunityUtils.getInfo();
|
||||
if (StringUtils.isNotBlank(info)) {
|
||||
queryWrapper.notExists(String.format(info, "core_opt_recent.resource_id"));
|
||||
}
|
||||
queryWrapper.orderBy(true, request.isAsc(), "core_opt_recent.time");
|
||||
Page<VisualizationResourcePO> page = new Page<>(goPage, pageSize);
|
||||
return extDataVisualizationMapper.findRecent(page, uid, queryWrapper);
|
||||
|
@ -11,6 +11,7 @@ import io.dataease.exception.DEException;
|
||||
import io.dataease.license.config.XpackInteract;
|
||||
import io.dataease.utils.AuthUtils;
|
||||
import io.dataease.utils.CommonBeanFactory;
|
||||
import io.dataease.utils.CommunityUtils;
|
||||
import io.dataease.utils.IDUtils;
|
||||
import io.dataease.visualization.dao.auto.entity.CoreStore;
|
||||
import io.dataease.visualization.dao.auto.mapper.CoreStoreMapper;
|
||||
@ -65,7 +66,7 @@ public class VisualizationStoreManage {
|
||||
return coreStoreMapper.exists(queryWrapper);
|
||||
}
|
||||
|
||||
@XpackInteract(value = "perFilterManage", recursion = true)
|
||||
@XpackInteract(value = "perFilterManage", recursion = true, invalid = true)
|
||||
public IPage<VisualizationStoreVO> query(int pageNum, int pageSize, VisualizationWorkbranchQueryRequest request) {
|
||||
IPage<StorePO> storePOIPage = proxy().queryStorePage(pageNum, pageSize, request);
|
||||
if (ObjectUtils.isEmpty(storePOIPage)) return null;
|
||||
@ -89,7 +90,7 @@ public class VisualizationStoreManage {
|
||||
new VisualizationStoreVO(
|
||||
po.getStoreId(), po.getResourceId(), po.getName(),
|
||||
po.getType(), String.valueOf(po.getCreator()), ObjectUtils.isEmpty(po.getEditor()) ? null : String.valueOf(po.getEditor()),
|
||||
po.getEditTime(), 9,po.getExtFlag())).toList();
|
||||
po.getEditTime(), 9, po.getExtFlag())).toList();
|
||||
}
|
||||
|
||||
public IPage<StorePO> queryStorePage(int goPage, int pageSize, VisualizationWorkbranchQueryRequest request) {
|
||||
@ -106,6 +107,10 @@ public class VisualizationStoreManage {
|
||||
if (StringUtils.isNotBlank(request.getKeyword())) {
|
||||
queryWrapper.like("v.name", request.getKeyword());
|
||||
}
|
||||
String info = CommunityUtils.getInfo();
|
||||
if (StringUtils.isNotBlank(info)) {
|
||||
queryWrapper.notExists(String.format(info, "s.resource_id"));
|
||||
}
|
||||
queryWrapper.orderBy(true, request.isAsc(), "v.update_time");
|
||||
Page<StorePO> page = new Page<>(goPage, pageSize);
|
||||
return coreStoreExtMapper.query(page, queryWrapper);
|
||||
|
@ -36,6 +36,7 @@ import io.dataease.exception.DEException;
|
||||
import io.dataease.extensions.datasource.vo.DatasourceConfiguration;
|
||||
import io.dataease.extensions.view.dto.ChartViewDTO;
|
||||
import io.dataease.license.config.XpackInteract;
|
||||
import io.dataease.license.manage.CoreLicManage;
|
||||
import io.dataease.log.DeLog;
|
||||
import io.dataease.model.BusiNodeRequest;
|
||||
import io.dataease.model.BusiNodeVO;
|
||||
@ -133,6 +134,9 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
@Resource
|
||||
private CoreBusiManage coreBusiManage;
|
||||
|
||||
@Resource
|
||||
private CoreLicManage coreLicManage;
|
||||
|
||||
@Override
|
||||
public DataVisualizationVO findCopyResource(Long dvId, String busiFlag) {
|
||||
DataVisualizationVO result = Objects.requireNonNull(CommonBeanFactory.proxy(this.getClass())).findById(new DataVisualizationBaseRequest(dvId, busiFlag));
|
||||
@ -572,6 +576,15 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
return extDataVisualizationMapper.findDvType(dvId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String updateCheckVersion(Long dvId) {
|
||||
DataVisualizationInfo updateInfo = new DataVisualizationInfo();
|
||||
updateInfo.setId(dvId);
|
||||
updateInfo.setCheckVersion(coreLicManage.getVersion());
|
||||
visualizationInfoMapper.updateById(updateInfo);
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataVisualizationVO decompression(DataVisualizationBaseRequest request) throws Exception {
|
||||
try {
|
||||
|
@ -6,6 +6,7 @@ import io.dataease.api.visualization.dto.VisualizationLinkJumpDTO;
|
||||
import io.dataease.api.visualization.dto.VisualizationLinkJumpInfoDTO;
|
||||
import io.dataease.api.visualization.request.VisualizationLinkJumpBaseRequest;
|
||||
import io.dataease.api.visualization.response.VisualizationLinkJumpBaseResponse;
|
||||
import io.dataease.api.visualization.vo.VisualizationOutParamsJumpVO;
|
||||
import io.dataease.api.visualization.vo.VisualizationViewTableVO;
|
||||
import io.dataease.auth.DeLinkPermit;
|
||||
import io.dataease.chart.dao.auto.entity.CoreChartView;
|
||||
@ -148,15 +149,18 @@ public class VisualizationLinkJumpService implements VisualizationLinkJumpApi {
|
||||
public VisualizationComponentDTO viewTableDetailList(Long dvId) {
|
||||
DataVisualizationInfo dvInfo = dataVisualizationInfoMapper.selectById(dvId);
|
||||
List<VisualizationViewTableVO> result;
|
||||
List<VisualizationOutParamsJumpVO> outParamsJumpInfo;
|
||||
String componentData;
|
||||
if (dvInfo != null) {
|
||||
result = extVisualizationLinkJumpMapper.getViewTableDetails(dvId).stream().filter(viewTableInfo -> dvInfo.getComponentData().indexOf(viewTableInfo.getId().toString()) > -1).collect(Collectors.toList());
|
||||
componentData = dvInfo.getComponentData();
|
||||
outParamsJumpInfo = extVisualizationLinkJumpMapper.queryOutParamsTargetWithDvId(dvId);
|
||||
} else {
|
||||
result = new ArrayList<>();
|
||||
outParamsJumpInfo = new ArrayList<>();
|
||||
componentData = "[]";
|
||||
}
|
||||
return new VisualizationComponentDTO(componentData,result);
|
||||
return new VisualizationComponentDTO(componentData,result,outParamsJumpInfo);
|
||||
|
||||
}
|
||||
|
||||
|
@ -29,10 +29,7 @@ import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -72,6 +69,12 @@ public class VisualizationOuterParamsService implements VisualizationOuterParams
|
||||
public void updateOuterParamsSet(VisualizationOuterParamsDTO outerParamsDTO) {
|
||||
String visualizationId = outerParamsDTO.getVisualizationId();
|
||||
Assert.notNull(visualizationId, "visualizationId cannot be null");
|
||||
Map<String,String> paramsInfoNameIdMap = new HashMap<>();
|
||||
List<VisualizationOuterParamsInfo> paramsInfoNameIdList = extOuterParamsMapper.getVisualizationOuterParamsInfoBase(visualizationId);
|
||||
if(!CollectionUtils.isEmpty(paramsInfoNameIdList)){
|
||||
paramsInfoNameIdMap = paramsInfoNameIdList.stream()
|
||||
.collect(Collectors.toMap(VisualizationOuterParamsInfo::getParamName, VisualizationOuterParamsInfo::getParamsInfoId));
|
||||
}
|
||||
//清理原有数据
|
||||
extOuterParamsMapper.deleteOuterParamsTargetWithVisualizationId(visualizationId);
|
||||
extOuterParamsMapper.deleteOuterParamsInfoWithVisualizationId(visualizationId);
|
||||
@ -82,17 +85,22 @@ public class VisualizationOuterParamsService implements VisualizationOuterParams
|
||||
VisualizationOuterParams newOuterParams = new VisualizationOuterParams();
|
||||
BeanUtils.copyBean(newOuterParams, outerParamsDTO);
|
||||
outerParamsMapper.insert(newOuterParams);
|
||||
Map<String, String> finalParamsInfoNameIdMap = paramsInfoNameIdMap;
|
||||
Optional.ofNullable(outerParamsDTO.getOuterParamsInfoArray()).orElse(new ArrayList<>()).forEach(outerParamsInfo -> {
|
||||
String paramsInfoId = UUID.randomUUID().toString();
|
||||
String paramsInfoId = finalParamsInfoNameIdMap.get(outerParamsInfo.getParamName());
|
||||
if(StringUtils.isEmpty(paramsInfoId)){
|
||||
paramsInfoId = UUID.randomUUID().toString();
|
||||
}
|
||||
outerParamsInfo.setParamsInfoId(paramsInfoId);
|
||||
outerParamsInfo.setParamsId(paramsId);
|
||||
VisualizationOuterParamsInfo newOuterParamsInfo = new VisualizationOuterParamsInfo();
|
||||
BeanUtils.copyBean(newOuterParamsInfo, outerParamsInfo);
|
||||
outerParamsInfoMapper.insert(newOuterParamsInfo);
|
||||
String finalParamsInfoId = paramsInfoId;
|
||||
Optional.ofNullable(outerParamsInfo.getTargetViewInfoList()).orElse(new ArrayList<>()).forEach(targetViewInfo -> {
|
||||
String targetViewInfoId = UUID.randomUUID().toString();
|
||||
targetViewInfo.setTargetId(targetViewInfoId);
|
||||
targetViewInfo.setParamsInfoId(paramsInfoId);
|
||||
targetViewInfo.setParamsInfoId(finalParamsInfoId);
|
||||
VisualizationOuterParamsTargetViewInfo newOuterParamsTargetViewInfo = new VisualizationOuterParamsTargetViewInfo();
|
||||
BeanUtils.copyBean(newOuterParamsTargetViewInfo, targetViewInfo);
|
||||
outerParamsTargetViewInfoMapper.insert(newOuterParamsTargetViewInfo);
|
||||
|
@ -2,7 +2,20 @@ INSERT INTO `core_sys_setting`(`id`, `pkey`, `pval`, `type`, `sort`)
|
||||
VALUES (1048232869488627719, 'basic.defaultSort', '1', 'text', 13);
|
||||
|
||||
INSERT INTO `core_sys_setting`(`id`, `pkey`, `pval`, `type`, `sort`)
|
||||
VALUES (1048232869488627719, 'basic.defaultOpen', '1', 'text', 14);
|
||||
VALUES (1048232869488627720, 'basic.defaultOpen', '1', 'text', 14);
|
||||
|
||||
ALTER TABLE `data_visualization_info`
|
||||
ADD COLUMN `content_id` varchar(50) NULL DEFAULT '0' COMMENT '内容标识';
|
||||
ADD COLUMN `content_id` varchar(50) NULL DEFAULT '0' COMMENT '内容标识';
|
||||
|
||||
ALTER TABLE `visualization_link_jump_target_view_info`
|
||||
ADD COLUMN `target_type` varchar(50) NULL COMMENT '联动目标类型 view 图表 filter 过滤组件 outParams 外部参数';
|
||||
|
||||
ALTER TABLE `visualization_link_jump_target_view_info`
|
||||
MODIFY COLUMN `target_view_id` varchar(50) NULL DEFAULT NULL COMMENT '目标图表ID';
|
||||
ALTER TABLE `visualization_link_jump_target_view_info`
|
||||
MODIFY COLUMN `target_field_id` varchar(50) NULL DEFAULT NULL COMMENT '目标字段ID';
|
||||
|
||||
update visualization_link_jump_target_view_info set target_type = 'view';
|
||||
ALTER TABLE `data_visualization_info`
|
||||
ADD COLUMN `check_version` varchar(50) NULL DEFAULT '1' COMMENT '内容检查标识';
|
||||
update data_visualization_info set check_version = '1';
|
@ -2,7 +2,7 @@ INSERT INTO `core_sys_setting`(`id`, `pkey`, `pval`, `type`, `sort`)
|
||||
VALUES (1048232869488627719, 'basic.defaultSort', '1', 'text', 13);
|
||||
|
||||
INSERT INTO `core_sys_setting`(`id`, `pkey`, `pval`, `type`, `sort`)
|
||||
VALUES (1048232869488627719, 'basic.defaultOpen', '0', 'text', 14);
|
||||
VALUES (1048232869488627720, 'basic.defaultOpen', '0', 'text', 14);
|
||||
|
||||
INSERT INTO `core_menu` VALUES (70, 0, 1, 'msg', NULL, 200, NULL, '/msg', 1, 1, 0);
|
||||
|
||||
@ -10,3 +10,15 @@ UPDATE `xpack_setting_authentication` set `synced` = 0 where `name` = 'oidc' or
|
||||
|
||||
ALTER TABLE `data_visualization_info`
|
||||
ADD COLUMN `content_id` varchar(50) NULL DEFAULT '0' COMMENT '内容标识';
|
||||
|
||||
ALTER TABLE `visualization_link_jump_target_view_info`
|
||||
ADD COLUMN `target_type` varchar(50) NULL DEFAULT 'view' COMMENT '联动目标类型 view 图表 filter 过滤组件 outParams 外部参数';
|
||||
|
||||
ALTER TABLE `visualization_link_jump_target_view_info`
|
||||
MODIFY COLUMN `target_view_id` varchar(50) NULL DEFAULT NULL COMMENT '目标图表ID' AFTER `source_field_active_id`,
|
||||
MODIFY COLUMN `target_field_id` varchar(50) NULL DEFAULT NULL COMMENT '目标字段ID' AFTER `target_view_id`;
|
||||
|
||||
update visualization_link_jump_target_view_info set target_type = 'view';
|
||||
ALTER TABLE `data_visualization_info`
|
||||
ADD COLUMN `check_version` varchar(50) NULL DEFAULT '1' COMMENT '内容检查标识';
|
||||
update data_visualization_info set check_version = '1';
|
@ -103,6 +103,10 @@ i18n_df_decimal=decimal
|
||||
i18n_df_multiple_value_split=use ';' to split multiple value
|
||||
i18n_df_email_type=email type
|
||||
i18n_df_phone_type=phone type
|
||||
i18n_df_lt_check=need less than %s: %s
|
||||
i18n_df_gt_check=need greater than %s: %s
|
||||
i18n_df_le_check=need less than or equal to %s: %s
|
||||
i18n_df_ge_check=need greater than or equal to %s: %s
|
||||
|
||||
|
||||
|
||||
|
@ -123,6 +123,10 @@ i18n_df_decimal=\u5C0F\u6570\u6570\u5B57
|
||||
i18n_df_multiple_value_split=\u591A\u4E2A\u503C\u4F7F\u7528\u5206\u53F7";"\u5206\u5272
|
||||
i18n_df_email_type=\u90AE\u7BB1\u683C\u5F0F
|
||||
i18n_df_phone_type=\u624B\u673A\u53F7\u683C\u5F0F
|
||||
i18n_df_lt_check=\u503C\u9700\u8981\u5C0F\u4E8E %s: %s
|
||||
i18n_df_gt_check=\u503C\u9700\u8981\u5927\u4E8E %s: %s
|
||||
i18n_df_le_check=\u503C\u9700\u8981\u5C0F\u4E8E\u7B49\u4E8E %s: %s
|
||||
i18n_df_ge_check=\u503C\u9700\u8981\u5927\u4E8E\u7B49\u4E8E %s: %s
|
||||
|
||||
|
||||
|
||||
|
@ -123,6 +123,10 @@ i18n_df_decimal=\u5C0F\u6578\u6578\u5B57
|
||||
i18n_df_multiple_value_split=\u591A\u500B\u503C\u4F7F\u7528\u5206\u865F";"\u5206\u5272
|
||||
i18n_df_email_type=\u90F5\u7BB1\u683C\u5F0F
|
||||
i18n_df_phone_type=\u624B\u6A5F\u865F\u683C\u5F0F
|
||||
i18n_df_lt_check=\u503C\u9700\u8981\u5C0F\u4E8E %s: %s
|
||||
i18n_df_gt_check=\u503C\u9700\u8981\u5927\u4E8E %s: %s
|
||||
i18n_df_le_check=\u503C\u9700\u8981\u5C0F\u4E8E\u7B49\u4E8E %s: %s
|
||||
i18n_df_ge_check=\u503C\u9700\u8981\u5927\u4E8E\u7B49\u4E8E %s: %s
|
||||
|
||||
|
||||
|
||||
|
@ -167,7 +167,8 @@
|
||||
`delete_time`,
|
||||
`delete_by`,
|
||||
`version`,
|
||||
`content_id`
|
||||
`content_id`,
|
||||
`check_version`
|
||||
FROM data_visualization_info
|
||||
where data_visualization_info.delete_flag = 0
|
||||
and data_visualization_info.id = #{dvId}
|
||||
|
@ -43,9 +43,12 @@
|
||||
<result column="publicJumpId" jdbcType="VARCHAR" property="publicJumpId"/>
|
||||
<collection property="targetViewInfoList"
|
||||
ofType="io.dataease.api.visualization.vo.VisualizationLinkJumpTargetViewInfoVO">
|
||||
<result column="target_id" jdbcType="BIGINT" property="targetId"/>
|
||||
<result column="target_view_id" jdbcType="BIGINT" property="targetViewId"/>
|
||||
<result column="target_field_id" jdbcType="BIGINT" property="targetFieldId"/>
|
||||
<result column="source_field_active_id" jdbcType="VARCHAR" property="sourceFieldActiveId"/>
|
||||
<result column="target_type" jdbcType="VARCHAR" property="targetType"/>
|
||||
<result column="outer_params_name" jdbcType="VARCHAR" property="outerParamsName"/>
|
||||
</collection>
|
||||
</resultMap>
|
||||
<resultMap id="ViewTableFieldDetailsMap" type="io.dataease.api.visualization.vo.VisualizationViewTableVO">
|
||||
@ -85,9 +88,12 @@
|
||||
xpack_share.uuid AS publicJumpId,
|
||||
ifnull( visualization_link_jump_info.checked, 0 ) AS checked,
|
||||
ifnull( visualization_link_jump_info.attach_params, 0 ) AS attach_params,
|
||||
visualization_link_jump_target_view_info.target_id,
|
||||
visualization_link_jump_target_view_info.target_view_id,
|
||||
visualization_link_jump_target_view_info.target_field_id,
|
||||
visualization_link_jump_target_view_info.source_field_active_id
|
||||
visualization_link_jump_target_view_info.target_type,
|
||||
visualization_link_jump_target_view_info.source_field_active_id,
|
||||
visualization_outer_params_info.param_name as outer_params_name
|
||||
FROM
|
||||
core_chart_view
|
||||
LEFT JOIN core_dataset_table_field ON core_chart_view.table_id = core_dataset_table_field.dataset_group_id
|
||||
@ -98,6 +104,7 @@
|
||||
LEFT JOIN visualization_link_jump_target_view_info ON visualization_link_jump_info.id = visualization_link_jump_target_view_info.link_jump_info_id
|
||||
LEFT JOIN xpack_share ON xpack_share.creator = #{uid}
|
||||
AND visualization_link_jump_info.target_dv_id = xpack_share.resource_id
|
||||
left join visualization_outer_params_info on visualization_outer_params_info.params_info_id = visualization_link_jump_target_view_info.target_view_id
|
||||
WHERE
|
||||
core_chart_view.id = #{source_view_id}
|
||||
AND core_chart_view.type != 'VQuery'
|
||||
@ -155,6 +162,19 @@
|
||||
WHERE core_chart_view.id = #{viewId}
|
||||
</select>
|
||||
|
||||
<select id="queryOutParamsTargetWithDvId" resultType="io.dataease.api.visualization.vo.VisualizationOutParamsJumpVO">
|
||||
SELECT
|
||||
vopi.params_info_id as id,
|
||||
vopi.param_name as name,
|
||||
vopi.param_name as title,
|
||||
'outerParams' as type
|
||||
FROM
|
||||
visualization_outer_params_info vopi
|
||||
LEFT JOIN visualization_outer_params vop ON vopi.params_id = vop.params_id
|
||||
WHERE
|
||||
vop.visualization_id = #{dvId}
|
||||
</select>
|
||||
|
||||
<delete id="deleteJumpTargetViewInfo">
|
||||
DELETE
|
||||
ljtv
|
||||
|
@ -139,6 +139,17 @@
|
||||
and popi.checked=1
|
||||
</select>
|
||||
|
||||
<select id="getVisualizationOuterParamsInfoBase" resultType="io.dataease.visualization.dao.auto.entity.VisualizationOuterParamsInfo">
|
||||
SELECT
|
||||
vopi.param_name,
|
||||
vopi.params_info_id
|
||||
FROM
|
||||
visualization_outer_params_info vopi
|
||||
INNER JOIN visualization_outer_params vop ON vop.params_id = vopi.params_id
|
||||
WHERE
|
||||
vop.visualization_id = #{visualizationId}
|
||||
</select>
|
||||
|
||||
<select id="queryDsWithVisualizationId" resultMap="BaseDsResultMapDTO">
|
||||
SELECT DISTINCT
|
||||
cdg.*,#{visualizationId} as visualizationId
|
||||
|
3
core/core-frontend/src/api/msg.ts
Normal file
3
core/core-frontend/src/api/msg.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
export const msgCountApi = () => request.post({ url: '/msg-center/count', data: {} })
|
@ -35,6 +35,9 @@ export const findById = async (
|
||||
return request.post({ url: '/dataVisualization/findById', data })
|
||||
}
|
||||
|
||||
export const updateCheckVersion = dvId =>
|
||||
request.get({ url: `/dataVisualization/updateCheckVersion/${dvId}` })
|
||||
|
||||
export const queryTreeApi = async (data: BusiTreeRequest): Promise<IResponse> => {
|
||||
return request.post({ url: '/dataVisualization/tree', data }).then(res => {
|
||||
return res?.data
|
||||
|
12
core/core-frontend/src/assets/svg/dv-style-blur.svg
Normal file
12
core/core-frontend/src/assets/svg/dv-style-blur.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="44px" height="44px" viewBox="0 0 44 44" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>模糊修复</title>
|
||||
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="模糊修复" fill="#BBBFC3" fill-rule="nonzero">
|
||||
<path d="M4.94539535,3.06976745 C3.90986044,3.06976745 3.06976745,3.90883718 3.06976745,4.94539535 L3.06976745,39.0546046 C3.06976745,40.0901396 3.90883718,40.9302326 4.94539535,40.9302326 L39.0546046,40.9302326 C40.0901396,40.9302326 40.9302326,40.0911628 40.9302326,39.0546046 L40.9302326,4.94539535 C40.9302326,3.90986044 40.0911628,3.06976745 39.0546046,3.06976745 L4.94539535,3.06976745 Z M0,4.94539535 C0,2.21412892 2.21412892,0 4.94539535,0 L39.0546046,0 C41.7858711,0 44,2.21412892 44,4.94539535 L44,39.0546046 C44,41.7858711 41.7858711,44 39.0546046,44 L4.94539535,44 C2.21412892,44 0,41.7858711 0,39.0546046 L0,4.94539535 L0,4.94539535 Z" id="形状"></path>
|
||||
<path d="M10,11.4868562 C10,10.6656882 10.6656354,10 11.4867383,10 L33.5132617,10 C34.3343646,10 35,10.6656882 35,11.4868562 L35,33.5131438 C35,34.3343118 34.3343646,35 33.5132617,35 L11.4867383,35 C10.6656354,35 10,34.3343118 10,33.5131438 L10,11.4868562 L10,11.4868562 Z M12.9734765,12.9737123 L12.9734765,32.0262877 L32.0265234,32.0262877 L32.0265234,12.9737123 L12.9734765,12.9737123 Z" id="形状"></path>
|
||||
<path d="M34.5646998,20.3474464 C35.1451,20.9280211 35.1451,21.8691328 34.5646998,22.4497075 L22.4506634,34.5647187 C22.074953,34.9402515 21.5274377,35.0868193 21.0143611,34.9492114 C20.5012846,34.8116035 20.1005953,34.4107259 19.9632291,33.8975852 C19.8258629,33.3844446 19.972689,32.8369991 20.3483993,32.4614663 L32.4624357,20.3474464 C33.0430113,19.7670469 33.9841243,19.7670469 34.5646998,20.3474464 L34.5646998,20.3474464 Z M24.6540264,10.4357952 C25.2344267,11.01637 25.2344267,11.9574817 24.6540264,12.5380565 L12.5380077,24.6530676 C11.9572098,25.233591 11.0157722,25.2333691 10.435248,24.652572 C9.85472385,24.0717749 9.85494572,23.1303387 10.4357436,22.5498153 L22.54978,10.4357952 C22.828627,10.1567699 23.206932,10 23.6014076,10 C23.9958833,10 24.3741883,10.1567699 24.6530352,10.4357952 L24.6540264,10.4357952 Z M34.5646998,10.4357952 C35.1451001,11.01637 35.1451001,11.9574817 34.5646998,12.5380565 L12.5389988,34.5647187 C11.9582009,35.1452421 11.0167634,35.1450202 10.4362392,34.5642231 C9.85571504,33.983426 9.8559369,33.0419897 10.4367348,32.4614663 L32.4624357,10.4357952 C33.0430113,9.85539577 33.9841243,9.85539577 34.5646998,10.4357952 Z" id="形状"></path>
|
||||
<path d="M11.4859238,18.8111098 C11.8802783,18.8111098 12.258481,18.9677602 12.5373316,19.2465999 C12.8161823,19.5254395 12.972839,19.9036272 12.972839,20.297966 L12.972839,32.0262877 L24.7036082,32.0262877 C25.2348319,32.0262876 25.7257028,32.3096808 25.9913146,32.7697157 C26.2569264,33.2297506 26.2569264,33.796537 25.9913146,34.2565719 C25.7257028,34.7166069 25.2348319,35 24.7036082,35 L11.4869151,35 C10.6657146,35 10,34.3343118 10,33.5131438 L10,20.297966 C10,19.9036272 10.1566567,19.5254395 10.4355073,19.2465999 C10.714358,18.9677602 11.0925607,18.8111098 11.4869151,18.8111098 L11.4859238,18.8111098 Z M18.8084853,11.4868562 C18.8084853,11.0925174 18.965142,10.7143297 19.2439927,10.4354901 C19.5228434,10.1566504 19.9010461,10 20.2954005,10 L33.5130849,10 C34.3342854,10 35,10.6656882 35,11.4868562 L35,24.7030253 C35,25.5241932 34.3342854,26.1898814 33.5130849,26.1898814 C32.6918843,26.1898814 32.0261697,25.5241932 32.0261697,24.7030253 L32.0261697,12.9737123 L20.2954005,12.9737123 C19.9010461,12.9737124 19.5228434,12.8170619 19.2439927,12.5382223 C18.965142,12.2593826 18.8084853,11.881195 18.8084853,11.4868562 L18.8084853,11.4868562 Z" id="形状"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
4
core/core-frontend/src/assets/svg/icon_free.svg
Normal file
4
core/core-frontend/src/assets/svg/icon_free.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.833344 3.75C0.833344 2.82952 1.57954 2.08333 2.50001 2.08333H7.91668C8.16399 2.08333 8.39853 2.19319 8.55686 2.38318L10.3903 4.58333H15.625C16.5455 4.58333 17.2917 5.32951 17.2917 6.25V8.75C17.2917 9.21024 16.9186 9.58333 16.4583 9.58333H4.40066L2.47513 17.2854C2.37305 17.6937 1.98257 17.9618 1.56486 17.9104C1.14715 17.859 0.833344 17.5042 0.833344 17.0833V3.75ZM7.52636 3.75H2.50001V10.3141L2.94156 8.54789C3.0343 8.17691 3.36762 7.91667 3.75001 7.91667H15.625V6.25H10C9.75269 6.25 9.51815 6.14015 9.35983 5.95015L7.52636 3.75Z" fill=""/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.86165 8.55504C2.95176 8.18059 3.28672 7.91667 3.67186 7.91667H18.3333C18.583 7.91667 18.8195 8.0286 18.9778 8.22168C19.1361 8.41475 19.1994 8.66862 19.1505 8.91343L17.4838 17.2468C17.4059 17.6363 17.0639 17.9167 16.6667 17.9167H1.66665C1.41133 17.9167 1.1701 17.7996 1.01209 17.5991C0.854075 17.3985 0.796715 17.1366 0.856446 16.8884L2.86165 8.55504ZM4.32846 9.58333L2.72429 16.25H15.9835L17.3168 9.58333H4.32846Z" fill=""/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
3
core/core-frontend/src/assets/svg/icon_sync_free.svg
Normal file
3
core/core-frontend/src/assets/svg/icon_sync_free.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.666577 4.60903C0.666577 4.69744 0.701696 4.78222 0.764208 4.84474C0.82672 4.90725 0.911505 4.94237 0.999911 4.94237H13.1666C13.7692 4.94237 14.0626 4.20637 13.6249 3.7917L10.2166 0.5627C10.1848 0.532575 10.1474 0.509006 10.1065 0.493338C10.0656 0.47767 10.0221 0.470212 9.97829 0.471388C9.93452 0.472564 9.89141 0.482352 9.85142 0.500193C9.81143 0.518034 9.77536 0.543579 9.74524 0.575367L9.28391 1.06237C9.2236 1.12601 9.1908 1.21086 9.19261 1.29852C9.19442 1.38618 9.23069 1.4696 9.29358 1.5307L11.4936 3.66837H0.999911C0.956137 3.66837 0.912791 3.67699 0.872349 3.69374C0.831908 3.71049 0.795161 3.73504 0.764208 3.766C0.733255 3.79695 0.708702 3.8337 0.691951 3.87414C0.675199 3.91458 0.666577 3.95793 0.666577 4.0017V4.60903ZM0.833244 9.00003C0.230577 9.00003 -0.0627561 9.73603 0.374911 10.1507L3.78324 13.38C3.81504 13.4101 3.85246 13.4337 3.89336 13.4493C3.93425 13.465 3.97783 13.4724 4.0216 13.4712C4.06537 13.47 4.10848 13.4602 4.14845 13.4423C4.18843 13.4244 4.22449 13.3988 4.25458 13.367L4.71324 12.8834C4.74335 12.8516 4.76689 12.8142 4.78253 12.7733C4.79817 12.7324 4.8056 12.6888 4.80439 12.645C4.80318 12.6012 4.79337 12.5581 4.7755 12.5182C4.75763 12.4782 4.73205 12.4421 4.70024 12.412L2.50658 10.3334H12.9999C13.0883 10.3334 13.1731 10.2982 13.2356 10.2357C13.2981 10.1732 13.3332 10.0884 13.3332 10V9.33337C13.3332 9.24496 13.2981 9.16018 13.2356 9.09766C13.1731 9.03515 13.0883 9.00003 12.9999 9.00003H0.833244Z" fill=""/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
@ -224,7 +224,15 @@ const saveResource = () => {
|
||||
ElMessage.success(t('common.save_success'))
|
||||
let url = window.location.href
|
||||
url = url.replace(/\?opt=create/, `?resourceId=${dvInfo.value.id}`)
|
||||
window.history.replaceState(null, '', url)
|
||||
if (!embeddedStore.baseUrl) {
|
||||
window.history.replaceState(
|
||||
{
|
||||
path: url
|
||||
},
|
||||
'',
|
||||
url
|
||||
)
|
||||
}
|
||||
|
||||
if (appData.value) {
|
||||
initCanvasData(dvInfo.value.id, 'dashboard', () => {
|
||||
@ -286,7 +294,12 @@ const backHandler = (url: string) => {
|
||||
return
|
||||
}
|
||||
wsCache.delete('DE-DV-CATCH-' + dvInfo.value.id)
|
||||
window.open(url, '_self')
|
||||
wsCache.set('db-info-id', dvInfo.value.id)
|
||||
if (!!history.state.back) {
|
||||
history.back()
|
||||
} else {
|
||||
window.open(url, '_self')
|
||||
}
|
||||
}
|
||||
|
||||
const multiplexingCanvasOpen = () => {
|
||||
|
@ -23,6 +23,21 @@
|
||||
</color-button>
|
||||
</el-space>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="dvInfo.type === 'dashboard'"
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
label="仪表板字体选择"
|
||||
>
|
||||
<el-select :effect="themes" v-model="canvasStyleData.fontFamily" @change="fontFamilyChange()">
|
||||
<el-option
|
||||
v-for="option in fontFamily"
|
||||
:key="option.value"
|
||||
:label="option.name"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="dvInfo.type === 'dashboard'"
|
||||
class="form-item"
|
||||
@ -221,10 +236,12 @@ const dvMainStore = dvMainStoreWithOut()
|
||||
const { canvasStyleData, dvInfo } = storeToRefs(dvMainStore)
|
||||
import {
|
||||
adaptCurThemeCommonStyleAll,
|
||||
adaptTitleFontFamilyAll,
|
||||
DARK_THEME_DASHBOARD_BACKGROUND,
|
||||
LIGHT_THEME_DASHBOARD_BACKGROUND
|
||||
} from '@/utils/canvasStyle'
|
||||
import {
|
||||
CHART_FONT_FAMILY,
|
||||
DEFAULT_COLOR_CASE_DARK,
|
||||
DEFAULT_COLOR_CASE_LIGHT,
|
||||
DEFAULT_TAB_COLOR_CASE_DARK,
|
||||
@ -245,8 +262,11 @@ import {
|
||||
COMMON_COMPONENT_BACKGROUND_DARK,
|
||||
COMMON_COMPONENT_BACKGROUND_LIGHT
|
||||
} from '@/custom-component/component-list'
|
||||
import { ElFormItem, ElIcon, ElMessage, ElSpace } from 'element-plus-secondary'
|
||||
import { ElFormItem, ElIcon, ElSpace } from 'element-plus-secondary'
|
||||
import Icon from '@/components/icon-custom/src/Icon.vue'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const props = defineProps({
|
||||
themes: {
|
||||
@ -254,6 +274,13 @@ const props = defineProps({
|
||||
default: 'light'
|
||||
}
|
||||
})
|
||||
const fontFamily = CHART_FONT_FAMILY.concat(
|
||||
appearanceStore.fontList.map(ele => ({
|
||||
name: ele.name,
|
||||
value: ele.name
|
||||
}))
|
||||
)
|
||||
|
||||
const toolTip = computed(() => {
|
||||
return props.themes === 'dark' ? 'ndark' : 'dark'
|
||||
})
|
||||
@ -271,6 +298,15 @@ const onRefreshChange = val => {
|
||||
}
|
||||
themeChange()
|
||||
}
|
||||
const fontFamilyChange = () => {
|
||||
appearanceStore.setCurrentFont(canvasStyleData.value.fontFamily)
|
||||
document.documentElement.style.setProperty(
|
||||
'--de-canvas_custom_font',
|
||||
`${canvasStyleData.value.fontFamily}`
|
||||
)
|
||||
adaptTitleFontFamilyAll(canvasStyleData.value.fontFamily)
|
||||
snapshotStore.recordSnapshotCache('renderChart')
|
||||
}
|
||||
|
||||
const themeChange = (modifyName?) => {
|
||||
if (modifyName === 'themeColor') {
|
||||
|
@ -24,7 +24,8 @@ const canvasAttrActiveNames = ref(['size', 'baseSetting', 'background', 'color']
|
||||
const screenAdaptorList = [
|
||||
{ label: '宽度优先', value: 'widthFirst' },
|
||||
{ label: '高度优先', value: 'heightFirst' },
|
||||
{ label: '铺满全屏', value: 'full' }
|
||||
{ label: '铺满全屏', value: 'full' },
|
||||
{ label: '不缩放', value: 'keep' }
|
||||
]
|
||||
const init = () => {
|
||||
nextTick(() => {
|
||||
|
@ -166,7 +166,15 @@ const saveResource = () => {
|
||||
ElMessage.success('保存成功')
|
||||
let url = window.location.href
|
||||
url = url.replace(/\?opt=create/, `?dvId=${dvInfo.value.id}`)
|
||||
window.history.replaceState(null, '', url)
|
||||
if (!embeddedStore.baseUrl) {
|
||||
window.history.replaceState(
|
||||
{
|
||||
path: url
|
||||
},
|
||||
'',
|
||||
url
|
||||
)
|
||||
}
|
||||
if (appData.value) {
|
||||
initCanvasData(dvInfo.value.id, 'dataV', () => {
|
||||
useEmitt().emitter.emit('refresh-dataset-selector')
|
||||
@ -235,7 +243,12 @@ const backHandler = (url: string) => {
|
||||
}
|
||||
dvMainStore.canvasStateChange({ key: 'curPointArea', value: 'base' })
|
||||
wsCache.delete('DE-DV-CATCH-' + dvInfo.value.id)
|
||||
window.open(url, '_self')
|
||||
wsCache.set('dv-info-id', dvInfo.value.id)
|
||||
if (!!history.state.back) {
|
||||
history.back()
|
||||
} else {
|
||||
window.open(url, '_self')
|
||||
}
|
||||
}
|
||||
const openHandler = ref(null)
|
||||
|
||||
|
@ -172,6 +172,11 @@ const props = defineProps({
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
fontFamily: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'inherit'
|
||||
}
|
||||
})
|
||||
|
||||
@ -1628,6 +1633,7 @@ defineExpose({
|
||||
:dv-info="dvInfo"
|
||||
:canvas-active="canvasActive"
|
||||
:show-position="'canvas'"
|
||||
:font-family="fontFamily"
|
||||
/>
|
||||
<component
|
||||
v-else-if="item.component.includes('Svg')"
|
||||
@ -1646,6 +1652,7 @@ defineExpose({
|
||||
:active="item.id === curComponentId"
|
||||
:canvas-active="canvasActive"
|
||||
:show-position="'edit'"
|
||||
:font-family="fontFamily"
|
||||
/>
|
||||
<component
|
||||
v-else
|
||||
@ -1664,6 +1671,7 @@ defineExpose({
|
||||
:active="item.id === curComponentId"
|
||||
:canvas-active="canvasActive"
|
||||
:show-position="'edit'"
|
||||
:font-family="fontFamily"
|
||||
/>
|
||||
</Shape>
|
||||
<!-- 右击菜单 -->
|
||||
|
@ -107,6 +107,12 @@ const props = defineProps({
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'common'
|
||||
},
|
||||
// 字体
|
||||
fontFamily: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'inherit'
|
||||
}
|
||||
})
|
||||
const {
|
||||
@ -196,6 +202,8 @@ const onMouseEnter = () => {
|
||||
const componentBackgroundStyle = computed(() => {
|
||||
if (config.value.commonBackground) {
|
||||
const {
|
||||
backdropFilterEnable,
|
||||
backdropFilter,
|
||||
backgroundColorSelect,
|
||||
backgroundColor,
|
||||
backgroundImageEnable,
|
||||
@ -243,6 +251,9 @@ const componentBackgroundStyle = computed(() => {
|
||||
if (config.value.component !== 'UserView') {
|
||||
style['overflow'] = 'hidden'
|
||||
}
|
||||
if (backdropFilterEnable) {
|
||||
style['backdrop-filter'] = 'blur(' + backdropFilter + 'px)'
|
||||
}
|
||||
return style
|
||||
}
|
||||
return {}
|
||||
@ -419,6 +430,7 @@ const showActive = computed(() => props.popActive || (dvMainStore.mobileInPc &&
|
||||
:disabled="true"
|
||||
:is-edit="false"
|
||||
:suffix-id="suffixId"
|
||||
:font-family="fontFamily"
|
||||
@onPointClick="onPointClick"
|
||||
/>
|
||||
</div>
|
||||
|
@ -141,9 +141,12 @@ const canvasStyle = computed(() => {
|
||||
style['overflowY'] = 'hidden !important'
|
||||
}
|
||||
if (canvasStyleData.value && canvasStyleData.value.width && isMainCanvas(canvasId.value)) {
|
||||
style = {
|
||||
...getCanvasStyle(canvasStyleData.value),
|
||||
height: dashboardActive.value
|
||||
style = getCanvasStyle(canvasStyleData.value)
|
||||
if (canvasStyleData.value?.screenAdaptor === 'keep') {
|
||||
style['height'] = canvasStyleData.value?.height + 'px'
|
||||
style['width'] = canvasStyleData.value?.width + 'px'
|
||||
} else {
|
||||
style['height'] = dashboardActive.value
|
||||
? downloadStatus.value
|
||||
? getDownloadStatusMainHeight()
|
||||
: '100%'
|
||||
@ -151,11 +154,11 @@ const canvasStyle = computed(() => {
|
||||
canvasStyleData.value?.screenAdaptor === 'widthFirst'
|
||||
? changeStyleWithScale(canvasStyleData.value?.height, scaleMin.value) + 'px'
|
||||
: '100%'
|
||||
style['width'] =
|
||||
!dashboardActive.value && canvasStyleData.value?.screenAdaptor === 'heightFirst'
|
||||
? changeStyleWithScale(canvasStyleData.value?.width, scaleHeightPoint.value) + 'px'
|
||||
: '100%'
|
||||
}
|
||||
style['width'] =
|
||||
!dashboardActive.value && canvasStyleData.value?.screenAdaptor === 'heightFirst'
|
||||
? changeStyleWithScale(canvasStyleData.value?.width, scaleHeightPoint.value) + 'px'
|
||||
: '100%'
|
||||
}
|
||||
return style
|
||||
})
|
||||
|
@ -131,7 +131,12 @@ import Icon from '@/components/icon-custom/src/Icon.vue'
|
||||
import ComponentEditBar from '@/components/visualization/ComponentEditBar.vue'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import ComposeShow from '@/components/data-visualization/canvas/ComposeShow.vue'
|
||||
import { groupSizeStyleAdaptor, groupStyleRevert, groupStyleRevertBatch } from '@/utils/style'
|
||||
import {
|
||||
groupSizeStyleAdaptor,
|
||||
groupStyleRevert,
|
||||
groupStyleRevertBatch,
|
||||
tabInnerStyleRevert
|
||||
} from '@/utils/style'
|
||||
import { isDashboard, isGroupCanvas, isMainCanvas, isTabCanvas } from '@/utils/canvasUtils'
|
||||
import Board from '@/components/de-board/Board.vue'
|
||||
import { activeWatermarkCheckUser, removeActiveWatermark } from '@/components/watermark/watermark'
|
||||
@ -789,6 +794,12 @@ const handleMouseDownOnPoint = (point, e) => {
|
||||
}
|
||||
|
||||
const up = () => {
|
||||
// 如果内部组件保持尺寸时,这里在鼠标抬起时,重新计算一下内部组件占比
|
||||
if (['DeTabs'].includes(element.value.component) && element.value.resizeInnerKeep) {
|
||||
console.log('===test3==')
|
||||
tabInnerStyleRevert(element.value)
|
||||
}
|
||||
|
||||
dashboardActive.value && emit('onMouseUp')
|
||||
element.value['resizing'] = false
|
||||
document.removeEventListener('mousemove', move)
|
||||
@ -881,6 +892,8 @@ const padding3D = computed(() => {
|
||||
const componentBackgroundStyle = computed(() => {
|
||||
if (element.value.commonBackground && element.value.component !== 'GroupArea') {
|
||||
const {
|
||||
backdropFilterEnable,
|
||||
backdropFilter,
|
||||
backgroundColorSelect,
|
||||
backgroundColor,
|
||||
backgroundImageEnable,
|
||||
@ -931,6 +944,9 @@ const componentBackgroundStyle = computed(() => {
|
||||
if (element.value.component !== 'UserView') {
|
||||
style['overflow'] = 'hidden'
|
||||
}
|
||||
if (backdropFilterEnable) {
|
||||
style['backdrop-filter'] = 'blur(' + backdropFilter + 'px)'
|
||||
}
|
||||
return style
|
||||
}
|
||||
return {}
|
||||
@ -977,6 +993,7 @@ const tabMoveInCheck = async () => {
|
||||
for (const item of nodes) {
|
||||
if (
|
||||
item.className !== undefined &&
|
||||
typeof item.className === 'string' &&
|
||||
item.className.split(' ').includes('shape') &&
|
||||
item.getAttribute('component-id') !== domId.value && // 去掉当前
|
||||
item.getAttribute('tab-is-check') !== null &&
|
||||
|
@ -43,6 +43,8 @@ import waterfall from '@/assets/svg/waterfall.svg'
|
||||
import wordCloud from '@/assets/svg/word-cloud.svg'
|
||||
import tHeatmap from '@/assets/svg/t-heatmap.svg'
|
||||
import pictureGroup from '@/assets/svg/picture-group.svg'
|
||||
import filter from '@/assets/svg/filter.svg'
|
||||
import outerParams from '@/assets/svg/icon_params_setting.svg'
|
||||
|
||||
const iconChartMap = {
|
||||
'area-stack': areaStack,
|
||||
@ -89,7 +91,9 @@ const iconChartMap = {
|
||||
waterfall: waterfall,
|
||||
'word-cloud': wordCloud,
|
||||
't-heatmap': tHeatmap,
|
||||
'picture-group': pictureGroup
|
||||
'picture-group': pictureGroup,
|
||||
filter: filter,
|
||||
outerParams: outerParams
|
||||
}
|
||||
|
||||
export { iconChartMap }
|
||||
|
@ -8,7 +8,7 @@ import { i18n } from '@/plugins/vue-i18n'
|
||||
import * as Vue from 'vue'
|
||||
import axios from 'axios'
|
||||
import * as Pinia from 'pinia'
|
||||
import * as vueRouter from 'vue-router'
|
||||
import router from '@/router'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import request from '@/config/axios'
|
||||
const { wsCache } = useCache()
|
||||
@ -122,12 +122,12 @@ onMounted(async () => {
|
||||
const xpack = await window[moduleName].mapping[attrs.jsname]
|
||||
plugin.value = xpack.default
|
||||
} else {
|
||||
window['Vue'] = Vue
|
||||
window['Axios'] = axios
|
||||
window['Pinia'] = Pinia
|
||||
window['vueRouter'] = vueRouter
|
||||
window['MittAll'] = useEmitt().emitter.all
|
||||
window['I18n'] = i18n
|
||||
window['VueDe'] = Vue
|
||||
window['AxiosDe'] = axios
|
||||
window['PiniaDe'] = Pinia
|
||||
window['vueRouterDe'] = router
|
||||
window['MittAllDe'] = useEmitt().emitter.all
|
||||
window['I18nDe'] = i18n
|
||||
const url = `/xpackComponent/pluginStaticInfo/${moduleName}`
|
||||
request.get({ url }).then(async res => {
|
||||
new Function(res.data || res)()
|
||||
|
@ -1,6 +1,25 @@
|
||||
<template>
|
||||
<div style="width: 100%" ref="bgForm">
|
||||
<el-form label-position="top" style="width: 100%; margin-bottom: 16px">
|
||||
<el-form-item
|
||||
class="form-item no-margin-bottom"
|
||||
:class="'form-item-' + themes"
|
||||
label="数据大屏字体选择"
|
||||
>
|
||||
<el-select
|
||||
:effect="themes"
|
||||
v-model="canvasStyleData.fontFamily"
|
||||
@change="onFontFamilyChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in fontFamily"
|
||||
:key="option.value"
|
||||
:label="option.name"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="form-item no-margin-bottom" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
size="small"
|
||||
@ -63,11 +82,29 @@ import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { ElFormItem, ElIcon } from 'element-plus-secondary'
|
||||
import Icon from '../icon-custom/src/Icon.vue'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
import { CHART_FONT_FAMILY } from '@/views/chart/components/editor/util/chart'
|
||||
import { adaptTitleFontFamilyAll } from '@/utils/canvasStyle'
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { canvasStyleData } = storeToRefs(dvMainStore)
|
||||
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const fontFamily = CHART_FONT_FAMILY.concat(
|
||||
appearanceStore.fontList.map(ele => ({
|
||||
name: ele.name,
|
||||
value: ele.name
|
||||
}))
|
||||
)
|
||||
const onFontFamilyChange = () => {
|
||||
appearanceStore.setCurrentFont(canvasStyleData.value.fontFamily)
|
||||
document.documentElement.style.setProperty(
|
||||
'--de-canvas_custom_font',
|
||||
`${canvasStyleData.value.fontFamily}`
|
||||
)
|
||||
adaptTitleFontFamilyAll(canvasStyleData.value.fontFamily)
|
||||
snapshotStore.recordSnapshotCache('renderChart')
|
||||
}
|
||||
const onThemeChange = () => {
|
||||
snapshotStore.recordSnapshotCache()
|
||||
}
|
||||
|
@ -196,141 +196,275 @@
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-row style="margin-bottom: 8px" :gutter="8">
|
||||
<el-col :span="7"> 源字段 </el-col>
|
||||
<el-col :span="2"></el-col>
|
||||
<el-col :span="7" style="margin-left: -2.9%">
|
||||
{{ t('visualization.link_view_field') }}
|
||||
</el-col>
|
||||
<el-col :span="8"></el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="main-scrollbar-container">
|
||||
<el-scrollbar height="fit-content" max-height="208px">
|
||||
<div
|
||||
style="display: flex; margin-bottom: 6px"
|
||||
v-for="(targetViewInfo, index) in state.linkJumpInfo.targetViewInfoList"
|
||||
:key="index"
|
||||
>
|
||||
<div style="flex: 1">
|
||||
<el-select
|
||||
v-model="targetViewInfo.sourceFieldActiveId"
|
||||
:placeholder="'请选择字段'"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="curViewField in state.linkJumpCurViewFieldArray"
|
||||
:key="curViewField.id"
|
||||
:label="curViewField.name"
|
||||
:value="curViewField.id"
|
||||
>
|
||||
<span class="custom-option">
|
||||
<Icon
|
||||
><component
|
||||
class="svg-icon"
|
||||
style="width: 14px; height: 14px"
|
||||
:class="`field-icon-${fieldType[curViewField.deType]}`"
|
||||
:is="iconFieldMap[fieldType[curViewField.deType]]"
|
||||
></component
|
||||
></Icon>
|
||||
<span style="float: left; margin-left: 4px; font-size: 14px">{{
|
||||
curViewField.name
|
||||
}}</span>
|
||||
</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="icon-center">
|
||||
<Icon name="dv-link-target"
|
||||
><dvLinkTarget style="width: 20px; height: 20px" class="svg-icon"
|
||||
/></Icon>
|
||||
</div>
|
||||
<div style="flex: 1">
|
||||
<el-select
|
||||
v-model="targetViewInfo.targetViewId"
|
||||
:disabled="!targetViewInfo.sourceFieldActiveId"
|
||||
:placeholder="'请选择图表'"
|
||||
style="width: 100%"
|
||||
@change="viewInfoOnChange(targetViewInfo)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in state.currentLinkPanelViewArray"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id"
|
||||
>
|
||||
<span class="custom-option">
|
||||
<Icon
|
||||
><component
|
||||
class="svg-icon view-type-icon"
|
||||
style="width: 14px; height: 14px"
|
||||
:is="iconChartMap[item.type]"
|
||||
></component
|
||||
></Icon>
|
||||
<span style="float: left; margin-left: 4px; font-size: 14px">{{
|
||||
item.title
|
||||
}}</span>
|
||||
</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div style="flex: 1; margin: 0 8px">
|
||||
<el-select
|
||||
v-model="targetViewInfo.targetFieldId"
|
||||
:placeholder="'请选择字段'"
|
||||
:disabled="fieldIdDisabledCheck(targetViewInfo)"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="viewField in state.viewIdFieldArrayMap[
|
||||
targetViewInfo.targetViewId
|
||||
]"
|
||||
:key="viewField.id"
|
||||
:label="viewField.name"
|
||||
:value="viewField.id"
|
||||
>
|
||||
<span class="custom-option">
|
||||
<Icon
|
||||
><component
|
||||
class="svg-icon"
|
||||
style="width: 14px; height: 14px"
|
||||
:class="`field-icon-${fieldType[viewField.deType]}`"
|
||||
:is="iconFieldMap[fieldType[viewField.deType]]"
|
||||
></component
|
||||
></Icon>
|
||||
<span style="float: left; margin-left: 4px; font-size: 14px">{{
|
||||
viewField.name
|
||||
}}</span>
|
||||
</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
class="m-del-icon-btn"
|
||||
text
|
||||
@click="deleteLinkJumpField(index)"
|
||||
<div class="jump-com-list">
|
||||
<el-tabs size="small" v-model="state.activeCollapse">
|
||||
<el-tab-pane label="联动图表" name="view"> </el-tab-pane>
|
||||
<el-tab-pane label="携带查询条件" name="filter"> </el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<template v-if="state.activeCollapse === 'view'">
|
||||
<el-row style="margin-bottom: 8px" :gutter="8">
|
||||
<el-col :span="7"> 源字段 </el-col>
|
||||
<el-col :span="2"></el-col>
|
||||
<el-col :span="7" style="margin-left: -2.9%">
|
||||
{{ t('visualization.link_view_field') }}
|
||||
</el-col>
|
||||
<el-col :span="8"></el-col>
|
||||
</el-row>
|
||||
<div class="main-scrollbar-container">
|
||||
<el-scrollbar height="fit-content" max-height="178px">
|
||||
<div
|
||||
style="display: flex; margin-bottom: 6px"
|
||||
v-for="(
|
||||
targetViewInfo, index
|
||||
) in state.linkJumpInfo.targetViewInfoList.filter(
|
||||
item => item.targetType === 'view'
|
||||
)"
|
||||
:key="index"
|
||||
>
|
||||
<el-icon size="20px">
|
||||
<Icon name="icon_delete-trash_outlined"
|
||||
><icon_deleteTrash_outlined class="svg-icon"
|
||||
<div style="flex: 1">
|
||||
<el-select
|
||||
v-model="targetViewInfo.sourceFieldActiveId"
|
||||
:placeholder="'请选择字段'"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="curViewField in state.linkJumpCurViewFieldArray"
|
||||
:key="curViewField.id"
|
||||
:label="curViewField.name"
|
||||
:value="curViewField.id"
|
||||
>
|
||||
<span class="custom-option">
|
||||
<Icon
|
||||
><component
|
||||
class="svg-icon"
|
||||
style="width: 14px; height: 14px"
|
||||
:class="`field-icon-${fieldType[curViewField.deType]}`"
|
||||
:is="iconFieldMap[fieldType[curViewField.deType]]"
|
||||
></component
|
||||
></Icon>
|
||||
<span
|
||||
style="float: left; margin-left: 4px; font-size: 14px"
|
||||
>{{ curViewField.name }}</span
|
||||
>
|
||||
</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="icon-center">
|
||||
<Icon name="dv-link-target"
|
||||
><dvLinkTarget style="width: 20px; height: 20px" class="svg-icon"
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
</div>
|
||||
<div style="flex: 1">
|
||||
<el-select
|
||||
v-model="targetViewInfo.targetViewId"
|
||||
:disabled="!targetViewInfo.sourceFieldActiveId"
|
||||
:placeholder="'请选择图表'"
|
||||
style="width: 100%"
|
||||
@change="viewInfoOnChange(targetViewInfo)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in state.currentLinkPanelViewArray.filter(
|
||||
item => item.type !== 'outerParams'
|
||||
)"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id"
|
||||
>
|
||||
<span class="custom-option">
|
||||
<Icon
|
||||
><component
|
||||
class="svg-icon view-type-icon"
|
||||
style="width: 14px; height: 14px"
|
||||
:is="iconChartMap[item.type]"
|
||||
></component
|
||||
></Icon>
|
||||
<span
|
||||
style="float: left; margin-left: 4px; font-size: 14px"
|
||||
>{{ item.title }}</span
|
||||
>
|
||||
</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div style="flex: 1; margin: 0 8px">
|
||||
<el-select
|
||||
v-model="targetViewInfo.targetFieldId"
|
||||
:placeholder="'请选择字段'"
|
||||
:disabled="fieldIdDisabledCheck(targetViewInfo)"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="viewField in state.viewIdFieldArrayMap[
|
||||
targetViewInfo.targetViewId
|
||||
]"
|
||||
:key="viewField.id"
|
||||
:label="viewField.name"
|
||||
:value="viewField.id"
|
||||
>
|
||||
<span class="custom-option">
|
||||
<Icon
|
||||
><component
|
||||
class="svg-icon"
|
||||
style="width: 14px; height: 14px"
|
||||
:class="`field-icon-${fieldType[viewField.deType]}`"
|
||||
:is="iconFieldMap[fieldType[viewField.deType]]"
|
||||
></component
|
||||
></Icon>
|
||||
<span
|
||||
style="float: left; margin-left: 4px; font-size: 14px"
|
||||
>{{ viewField.name }}</span
|
||||
>
|
||||
</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
class="m-del-icon-btn"
|
||||
text
|
||||
@click="deleteLinkJumpFieldById(targetViewInfo.targetId)"
|
||||
>
|
||||
<el-icon size="20px">
|
||||
<Icon name="icon_delete-trash_outlined"
|
||||
><icon_deleteTrash_outlined class="svg-icon"
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<el-button
|
||||
style="margin-top: 8px"
|
||||
:disabled="!state.linkJumpInfo.targetDvId"
|
||||
type="primary"
|
||||
icon="Plus"
|
||||
text
|
||||
@click="addLinkJumpField('view')"
|
||||
>
|
||||
{{ t('visualization.add_jump_field') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="state.activeCollapse === 'filter'">
|
||||
<template v-if="state.currentOutParams.length === 0">
|
||||
<span
|
||||
>目标仪表板无外部参数,因此无法携带条件查询,如有需要,<a
|
||||
class="target_jump"
|
||||
@click="resourceEdit(state.linkJumpInfo.targetDvId)"
|
||||
>请前往设置外部参数</a
|
||||
></span
|
||||
>
|
||||
</template>
|
||||
<template v-if="state.currentOutParams.length > 0">
|
||||
<el-row style="margin-bottom: 8px" :gutter="8">
|
||||
<el-col :span="12"> 源条件 </el-col>
|
||||
<el-col :span="1"></el-col>
|
||||
<el-col :span="10" style="margin-left: -2.9%"> 联动外部参数 </el-col>
|
||||
</el-row>
|
||||
<div class="main-scrollbar-container">
|
||||
<el-scrollbar height="fit-content" max-height="178px">
|
||||
<div
|
||||
style="display: flex; margin-bottom: 6px"
|
||||
v-for="(
|
||||
targetViewInfo, index
|
||||
) in state.linkJumpInfo.targetViewInfoList.filter(
|
||||
item => item.targetType === 'outerParams'
|
||||
)"
|
||||
:key="index"
|
||||
>
|
||||
<div style="flex: 1">
|
||||
<el-select
|
||||
v-model="targetViewInfo.sourceFieldActiveId"
|
||||
:placeholder="'请选择字段'"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="curFilterField in state.linkJumpCurFilterFieldArray"
|
||||
:key="curFilterField.id"
|
||||
:label="curFilterField.name"
|
||||
:value="curFilterField.id"
|
||||
>
|
||||
<span class="custom-option">
|
||||
<Icon
|
||||
><component
|
||||
class="svg-icon"
|
||||
style="width: 14px; height: 14px"
|
||||
:is="iconChartMap['filter']"
|
||||
></component
|
||||
></Icon>
|
||||
<span
|
||||
style="float: left; margin-left: 4px; font-size: 14px"
|
||||
>{{ curFilterField.name }}</span
|
||||
>
|
||||
</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="icon-center">
|
||||
<Icon name="dv-link-target"
|
||||
><dvLinkTarget
|
||||
style="width: 20px; height: 20px"
|
||||
class="svg-icon"
|
||||
/></Icon>
|
||||
</div>
|
||||
<div style="flex: 1">
|
||||
<el-select
|
||||
v-model="targetViewInfo.targetViewId"
|
||||
:disabled="!targetViewInfo.sourceFieldActiveId"
|
||||
:placeholder="'请选择参数'"
|
||||
style="width: 100%"
|
||||
@change="viewInfoOnChange(targetViewInfo)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in state.currentOutParams"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id"
|
||||
>
|
||||
<span class="custom-option">
|
||||
<Icon
|
||||
><component
|
||||
class="svg-icon view-type-icon"
|
||||
style="width: 14px; height: 14px"
|
||||
:is="iconChartMap[item.type]"
|
||||
></component
|
||||
></Icon>
|
||||
<span
|
||||
style="float: left; margin-left: 4px; font-size: 14px"
|
||||
>{{ item.title }}</span
|
||||
>
|
||||
</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
class="m-del-icon-btn"
|
||||
text
|
||||
@click="deleteLinkJumpFieldById(targetViewInfo.targetId)"
|
||||
>
|
||||
<el-icon size="20px">
|
||||
<Icon name="icon_delete-trash_outlined"
|
||||
><icon_deleteTrash_outlined class="svg-icon"
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<el-button
|
||||
style="margin-top: 8px"
|
||||
:disabled="!state.linkJumpInfo.targetDvId"
|
||||
type="primary"
|
||||
icon="Plus"
|
||||
text
|
||||
@click="addLinkJumpField('outerParams')"
|
||||
>
|
||||
{{ t('visualization.add_jump_field') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<el-button
|
||||
style="margin-top: 8px"
|
||||
:disabled="!state.linkJumpInfo.targetDvId"
|
||||
type="primary"
|
||||
icon="Plus"
|
||||
text
|
||||
@click="addLinkJumpField"
|
||||
>
|
||||
{{ t('visualization.add_jump_field') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
@ -426,6 +560,10 @@
|
||||
</el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
<XpackComponent
|
||||
ref="openHandler"
|
||||
jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvT3BlbkhhbmRsZXI="
|
||||
/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
@ -458,18 +596,28 @@ import { Search } from '@element-plus/icons-vue'
|
||||
import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot'
|
||||
import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue'
|
||||
import { filterEmptyFolderTree } from '@/utils/canvasUtils'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { useAppStoreWithOut } from '@/store/modules/app'
|
||||
import { XpackComponent } from '@/components/plugin'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { useEmbedded } from '@/store/modules/embedded'
|
||||
import { guid } from '@/views/visualized/data/dataset/form/util'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { dvInfo, canvasViewInfo, componentData } = storeToRefs(dvMainStore)
|
||||
const linkJumpInfoTree = ref(null)
|
||||
const { t } = useI18n()
|
||||
const dialogShow = ref(false)
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const appStore = useAppStoreWithOut()
|
||||
const { wsCache } = useCache()
|
||||
const embeddedStore = useEmbedded()
|
||||
|
||||
const resourceType = computed(() =>
|
||||
dvInfo.value.type === 'dashboard' ? t('work_branch.dashboard') : t('work_branch.big_data_screen')
|
||||
)
|
||||
|
||||
const state = reactive({
|
||||
activeCollapse: 'view',
|
||||
loading: false,
|
||||
showSelected: false,
|
||||
curJumpViewInfo: {},
|
||||
@ -506,6 +654,7 @@ const state = reactive({
|
||||
linkJumpInfoArray: [],
|
||||
linkJumpInfoXArray: [],
|
||||
linkJumpCurViewFieldArray: [],
|
||||
linkJumpCurFilterFieldArray: [], //当前过滤条件明细
|
||||
mapJumpInfoArray: {},
|
||||
panelList: [],
|
||||
linkJumpInfo: null,
|
||||
@ -526,7 +675,8 @@ const state = reactive({
|
||||
quotaList: [],
|
||||
quotaData: [],
|
||||
dimension: [],
|
||||
quota: []
|
||||
quota: [],
|
||||
currentOutParams: []
|
||||
})
|
||||
|
||||
const outerContentEditor = ref(null)
|
||||
@ -541,6 +691,7 @@ const dialogInit = viewItem => {
|
||||
const init = viewItem => {
|
||||
state.initState = false
|
||||
state.viewId = viewItem.id
|
||||
state.activeCollapse = 'view'
|
||||
const chartDetails = canvasViewInfo.value[state.viewId] as ChartObj
|
||||
state.curJumpViewInfo = chartDetails
|
||||
let checkAllAxisStr =
|
||||
@ -579,12 +730,27 @@ const init = viewItem => {
|
||||
state.panelList = filterEmptyFolderTree(state.panelList)
|
||||
})
|
||||
|
||||
// 获取当前过滤条件明细 过滤原则:1.在当前仪表板或者大屏 2.作用于当前图表
|
||||
state.linkJumpCurFilterFieldArray = []
|
||||
componentData.value.forEach(componentItem => {
|
||||
if (componentItem.component === 'VQuery') {
|
||||
componentItem.propValue.forEach(filterItem => {
|
||||
if (filterItem.checkedFields.includes(state.viewId)) {
|
||||
state.linkJumpCurFilterFieldArray.push({
|
||||
id: filterItem.id,
|
||||
name: filterItem.name,
|
||||
deType: 'filter'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (chartDetails.tableId) {
|
||||
// 获取当前数据集信息
|
||||
getDatasetDetails(chartDetails.tableId).then(res => {
|
||||
state.curDatasetInfo = res || {}
|
||||
})
|
||||
|
||||
// 获取当前图表的字段信息
|
||||
listFieldByDatasetGroup(chartDetails.tableId).then(rsp => {
|
||||
state.linkJumpCurViewFieldArray = []
|
||||
@ -705,6 +871,17 @@ const getPanelViewList = dvId => {
|
||||
state.viewIdFieldArrayMap[view.id] = view.tableFields
|
||||
})
|
||||
}
|
||||
// 外部参数 currentLinkPanelViewArray 也加入
|
||||
// 在图表侧进行隐藏 保存的时候直接保存currentLinkPanelViewArray 方便处理
|
||||
state.currentOutParams = rsp.data.outParamsJumpInfo || []
|
||||
if (state.currentOutParams && state.currentOutParams.length > 0) {
|
||||
state.currentOutParams.forEach(outerParamsItem => {
|
||||
state.currentLinkPanelViewArray.push(outerParamsItem)
|
||||
state.viewIdFieldArrayMap[outerParamsItem.id] = [
|
||||
{ id: '1000001', name: t('visualization.out_params_no_select') }
|
||||
]
|
||||
})
|
||||
}
|
||||
// 增加过滤组件匹配
|
||||
JSON.parse(rsp.data.bashComponentData).forEach(componentItem => {
|
||||
if (componentItem.component === 'VQuery') {
|
||||
@ -723,6 +900,7 @@ const getPanelViewList = dvId => {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const dvNodeClick = data => {
|
||||
if (data.leaf) {
|
||||
state.linkJumpInfo.targetViewInfoList = []
|
||||
@ -730,12 +908,29 @@ const dvNodeClick = data => {
|
||||
getPanelViewList(data.id)
|
||||
}
|
||||
}
|
||||
const addLinkJumpField = () => {
|
||||
const addLinkJumpField = (type = 'view') => {
|
||||
state.linkJumpInfo.targetViewInfoList.push({
|
||||
targetId: guid(),
|
||||
targetViewId: '',
|
||||
targetType: type,
|
||||
targetFieldId: ''
|
||||
})
|
||||
}
|
||||
|
||||
const deleteLinkJumpFieldById = targetId => {
|
||||
if (targetId) {
|
||||
let indexResult
|
||||
state.linkJumpInfo.targetViewInfoList.forEach((item, index) => {
|
||||
if (targetId === item.targetId) {
|
||||
indexResult = index
|
||||
}
|
||||
})
|
||||
if (indexResult !== undefined) {
|
||||
state.linkJumpInfo.targetViewInfoList.splice(indexResult, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const deleteLinkJumpField = index => {
|
||||
state.linkJumpInfo.targetViewInfoList.splice(index, 1)
|
||||
}
|
||||
@ -783,6 +978,39 @@ const filterNodeMethod = (value, data) => {
|
||||
return !value || data.checked
|
||||
}
|
||||
|
||||
const isEmbedded = computed(() => appStore.getIsDataEaseBi || appStore.getIsIframe)
|
||||
const openType = wsCache.get('open-backend') === '1' ? '_self' : '_blank'
|
||||
|
||||
const resourceEdit = resourceId => {
|
||||
const baseUrl = dvInfo.value.type === 'dataV' ? '#/dvCanvas?dvId=' : '#/dashboard?resourceId='
|
||||
if (isEmbedded.value) {
|
||||
embeddedStore.clearState()
|
||||
if (dvInfo.value.type === 'dataV') {
|
||||
embeddedStore.setDvId(resourceId)
|
||||
} else {
|
||||
embeddedStore.setResourceId(resourceId)
|
||||
}
|
||||
useEmitt().emitter.emit(
|
||||
'changeCurrentComponent',
|
||||
dvInfo.value.type === 'dataV' ? 'VisualizationEditor' : 'DashboardEditor'
|
||||
)
|
||||
return
|
||||
}
|
||||
const newWindow = window.open(baseUrl + resourceId, openType)
|
||||
initOpenHandler(newWindow)
|
||||
}
|
||||
|
||||
const openHandler = ref(null)
|
||||
const initOpenHandler = newWindow => {
|
||||
if (openHandler?.value) {
|
||||
const pm = {
|
||||
methodName: 'initOpenHandler',
|
||||
args: newWindow
|
||||
}
|
||||
openHandler.value.invokeMethod(pm)
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => state.showSelected,
|
||||
newValue => {
|
||||
@ -1244,4 +1472,47 @@ span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.jump-com-list {
|
||||
width: 100%;
|
||||
margin-top: -18px;
|
||||
:deep(.ed-collapse) {
|
||||
--ed-collapse-header-font-size: 14px;
|
||||
--ed-collapse-content-font-size: 14px;
|
||||
}
|
||||
:deep(.ed-tabs__active-bar) {
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
& > :deep(.ed-tabs) {
|
||||
--ed-tabs-header-height: 36px;
|
||||
margin-bottom: 12px;
|
||||
position: sticky;
|
||||
background: #fff;
|
||||
.ed-tabs__header {
|
||||
&::before {
|
||||
content: '';
|
||||
width: 8px;
|
||||
height: 1px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: #1f232926;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ed-tabs__item) {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
:deep(.ed-tabs__item):not(.is-active) {
|
||||
color: #646a73;
|
||||
}
|
||||
}
|
||||
|
||||
.target_jump {
|
||||
color: var(--ed-color-primary);
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
@ -596,8 +596,14 @@ const jsonArrayCheck = params => {
|
||||
const save = () => {
|
||||
const outerParamsCopy = deepCopy(state.outerParams)
|
||||
let checkErrorNum = 0
|
||||
let checkNullErrorNum = 0
|
||||
let checkMessage = ''
|
||||
const paramNameArray = []
|
||||
outerParamsCopy.outerParamsInfoArray?.forEach(outerParamsInfo => {
|
||||
if (!outerParamsInfo.paramName || paramNameArray.includes(outerParamsInfo.paramName)) {
|
||||
checkNullErrorNum++
|
||||
}
|
||||
paramNameArray.push(outerParamsInfo.paramName)
|
||||
if (outerParamsInfo.defaultValue && !jsonArrayCheck(outerParamsInfo.defaultValue)) {
|
||||
checkErrorNum++
|
||||
checkMessage = checkMessage + `【${outerParamsInfo.paramName}】`
|
||||
@ -636,6 +642,14 @@ const save = () => {
|
||||
})
|
||||
return
|
||||
}
|
||||
if (checkNullErrorNum > 0) {
|
||||
ElMessage({
|
||||
message: `存在未配置的参数名或者参数名称重复!`,
|
||||
type: 'warning',
|
||||
showClose: true
|
||||
})
|
||||
return
|
||||
}
|
||||
updateOuterParamsSet(outerParamsCopy).then(() => {
|
||||
ElMessage({
|
||||
message: t('commons.save_success'),
|
||||
|
@ -3,7 +3,11 @@
|
||||
<el-dropdown :teleported="false" trigger="click">
|
||||
<input id="input" ref="trackButton" type="button" hidden />
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu class="track-menu" :append-to-body="false">
|
||||
<el-dropdown-menu
|
||||
class="track-menu"
|
||||
:style="{ 'font-family': fontFamily }"
|
||||
:append-to-body="false"
|
||||
>
|
||||
<el-dropdown-item
|
||||
v-for="(item, key) in trackMenu"
|
||||
:key="key"
|
||||
@ -27,6 +31,11 @@ const props = defineProps({
|
||||
trackMenu: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
fontFamily: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'inherit'
|
||||
}
|
||||
})
|
||||
const { trackMenu } = toRefs(props)
|
||||
|
@ -53,6 +53,34 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item class="form-item no-margin-bottom" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
size="small"
|
||||
:effect="themes"
|
||||
v-model="state.commonBackground.backdropFilterEnable"
|
||||
@change="onBackgroundChange"
|
||||
>
|
||||
{{ $t('chart.backdrop_blur') }}
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
<div class="indented-container">
|
||||
<div class="indented-item">
|
||||
<el-form-item class="form-item" :class="'form-item-' + themes">
|
||||
<el-input-number
|
||||
style="width: 100%"
|
||||
:effect="themes"
|
||||
controls-position="right"
|
||||
size="middle"
|
||||
:min="0"
|
||||
:max="30"
|
||||
:disabled="!state.commonBackground.backdropFilterEnable"
|
||||
v-model="state.commonBackground.backdropFilter"
|
||||
@change="onBackgroundChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-form-item class="form-item no-margin-bottom" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
size="small"
|
||||
|
@ -11,12 +11,18 @@ const refreshUrl = '/login/refresh'
|
||||
|
||||
const expConstants = 10000
|
||||
|
||||
const expTimeConstants = 90000
|
||||
|
||||
const isExpired = () => {
|
||||
const exp = wsCache.get('user.exp')
|
||||
if (!exp) {
|
||||
return false
|
||||
}
|
||||
return exp - new Date().getTime() < expConstants
|
||||
const time = wsCache.get('user.time')
|
||||
if (!time) {
|
||||
return exp - Date.now() < expConstants
|
||||
}
|
||||
return Date.now() - time > expTimeConstants
|
||||
}
|
||||
|
||||
const delayExecute = (token: string) => {
|
||||
@ -25,10 +31,6 @@ const delayExecute = (token: string) => {
|
||||
cb(token)
|
||||
})
|
||||
requestStore.cleanCacheRequest()
|
||||
/* cachedRequestList.forEach(cb => {
|
||||
cb(token)
|
||||
})
|
||||
cachedRequestList = [] */
|
||||
}
|
||||
|
||||
const getRefreshStatus = () => {
|
||||
@ -40,7 +42,6 @@ const setRefreshStatus = (status: boolean) => {
|
||||
|
||||
const cacheRequest = cb => {
|
||||
requestStore.addCacheRequest(cb)
|
||||
// cachedRequestList.push(cb)
|
||||
}
|
||||
|
||||
export const configHandler = config => {
|
||||
@ -61,6 +62,7 @@ export const configHandler = config => {
|
||||
.then(res => {
|
||||
userStore.setToken(res.data.token)
|
||||
userStore.setExp(res.data.exp)
|
||||
userStore.setTime(Date.now())
|
||||
config.headers['X-DE-TOKEN'] = res.data.token
|
||||
delayExecute(res.data.token)
|
||||
})
|
||||
|
@ -89,6 +89,14 @@ const backgroundCustomShow = computed(() => {
|
||||
!['CanvasBoard', 'CanvasIcon', 'CircleShape', 'RectShape'].includes(element.value.component))
|
||||
)
|
||||
})
|
||||
const tabTitleShow = computed(() => {
|
||||
return element.value && element.value.style && element.value.component === 'DeTabs'
|
||||
})
|
||||
|
||||
const styleShow = computed(() => {
|
||||
return element.value && element.value.style && element.value.component !== 'DeTabs'
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
const erd = elementResizeDetectorMaker()
|
||||
containerWidth.value = containerRef.value?.offsetWidth
|
||||
@ -122,8 +130,23 @@ onMounted(() => {
|
||||
/>
|
||||
</el-collapse-item>
|
||||
<slot></slot>
|
||||
<collapse-switch-item
|
||||
v-if="tabTitleShow"
|
||||
v-model="element.style.showTabTitle"
|
||||
@modelChange="val => onStyleAttrChange({ key: 'showTabTitle', value: val })"
|
||||
:themes="themes"
|
||||
title="Tab标签"
|
||||
name="tabTitle"
|
||||
class="common-style-area"
|
||||
>
|
||||
<common-style-set
|
||||
@onStyleAttrChange="onStyleAttrChange"
|
||||
:themes="themes"
|
||||
:element="element"
|
||||
></common-style-set>
|
||||
</collapse-switch-item>
|
||||
<el-collapse-item
|
||||
v-if="element && element.style"
|
||||
v-if="styleShow"
|
||||
:effect="themes"
|
||||
title="样式"
|
||||
name="style"
|
||||
|
@ -96,6 +96,7 @@ watch(
|
||||
class="color-picker-style"
|
||||
:triggerWidth="65"
|
||||
is-custom
|
||||
show-alpha
|
||||
:predefine="state.predefineColors"
|
||||
@change="changeStylePre('borderColor')"
|
||||
>
|
||||
@ -135,6 +136,7 @@ watch(
|
||||
class="color-picker-style"
|
||||
:triggerWidth="65"
|
||||
is-custom
|
||||
show-alpha
|
||||
:effect="themes"
|
||||
:predefine="state.predefineColors"
|
||||
@change="changeStylePre('borderColor')"
|
||||
|
@ -57,6 +57,7 @@
|
||||
:prefix-icon="styleColorKey.icon"
|
||||
:triggerWidth="styleColorKey.width"
|
||||
is-custom
|
||||
show-alpha
|
||||
:predefine="state.predefineColors"
|
||||
@change="
|
||||
changeStyle({ key: styleColorKey.value, value: styleForm[styleColorKey.value] })
|
||||
@ -291,6 +292,7 @@ import dvStyleHeadFontColor from '@/assets/svg/dv-style-headFontColor.svg'
|
||||
import dvStyleScrollSpeed from '@/assets/svg/dv-style-scroll-speed.svg'
|
||||
import dvStyleOpacity from '@/assets/svg/dv-style-opacity.svg'
|
||||
import dvStyleTabHead from '@/assets/svg/dv-style-tab-head.svg'
|
||||
import dvStyleBlur from '@/assets/svg/dv-style-blur.svg'
|
||||
import dvStyleFontSize from '@/assets/svg/dv-style-fontSize.svg'
|
||||
import dvStyleLetterSpacing from '@/assets/svg/dv-style-letterSpacing.svg'
|
||||
import dvStyleActiveFont from '@/assets/svg/dv-style-activeFont.svg'
|
||||
@ -371,10 +373,38 @@ const opacitySizeList = [
|
||||
{ name: '0.9', value: 0.9 },
|
||||
{ name: '1', value: 1 }
|
||||
]
|
||||
|
||||
const titleHideList = [
|
||||
{ name: '隐藏', value: true },
|
||||
{ name: '显示', value: false }
|
||||
const backdropBlurList = [
|
||||
{ name: '0', value: 'blur(0px)' },
|
||||
{ name: '1', value: 'blur(1px)' },
|
||||
{ name: '2', value: 'blur(2px)' },
|
||||
{ name: '3', value: 'blur(3px)' },
|
||||
{ name: '4', value: 'blur(4px)' },
|
||||
{ name: '5', value: 'blur(5px)' },
|
||||
{ name: '6', value: 'blur(6px)' },
|
||||
{ name: '7', value: 'blur(7px)' },
|
||||
{ name: '8', value: 'blur(8px)' },
|
||||
{ name: '9', value: 'blur(9px)' },
|
||||
{ name: '10', value: 'blur(10px)' },
|
||||
{ name: '11', value: 'blur(11px)' },
|
||||
{ name: '12', value: 'blur(12px)' },
|
||||
{ name: '13', value: 'blur(13px)' },
|
||||
{ name: '14', value: 'blur(14px)' },
|
||||
{ name: '15', value: 'blur(15px)' },
|
||||
{ name: '16', value: 'blur(16px)' },
|
||||
{ name: '17', value: 'blur(17px)' },
|
||||
{ name: '18', value: 'blur(18px)' },
|
||||
{ name: '19', value: 'blur(19px)' },
|
||||
{ name: '20', value: 'blur(20px)' },
|
||||
{ name: '21', value: 'blur(21px)' },
|
||||
{ name: '22', value: 'blur(22px)' },
|
||||
{ name: '23', value: 'blur(23px)' },
|
||||
{ name: '24', value: 'blur(24px)' },
|
||||
{ name: '25', value: 'blur(25px)' },
|
||||
{ name: '26', value: 'blur(26px)' },
|
||||
{ name: '27', value: 'blur(27px)' },
|
||||
{ name: '28', value: 'blur(28px)' },
|
||||
{ name: '29', value: 'blur(29px)' },
|
||||
{ name: '30', value: 'blur(30px)' }
|
||||
]
|
||||
|
||||
const styleForm = computed<any>(() => element.value.style)
|
||||
@ -474,11 +504,11 @@ const styleOptionKeyArray = [
|
||||
icon: dvStyleOpacity
|
||||
},
|
||||
{
|
||||
value: 'titleHide',
|
||||
label: '标题样式',
|
||||
customOption: titleHideList,
|
||||
value: 'backdropFilter',
|
||||
label: '背景模糊',
|
||||
customOption: backdropBlurList,
|
||||
width: '90px',
|
||||
icon: dvStyleTabHead
|
||||
icon: dvStyleBlur
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -177,12 +177,14 @@ export const MULTI_DIMENSIONAL = {
|
||||
|
||||
export const COMMON_COMPONENT_BACKGROUND_BASE = {
|
||||
backgroundColorSelect: true,
|
||||
backdropFilterEnable: false,
|
||||
backgroundImageEnable: false,
|
||||
backgroundType: 'innerImage',
|
||||
innerImage: 'board/board_1.svg',
|
||||
outerImage: null,
|
||||
innerPadding: 12,
|
||||
borderRadius: 0
|
||||
borderRadius: 0,
|
||||
backdropFilter: 4
|
||||
}
|
||||
|
||||
export const COMMON_COMPONENT_BACKGROUND_LIGHT = {
|
||||
@ -455,7 +457,8 @@ const list = [
|
||||
style: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
color: ''
|
||||
color: '',
|
||||
backdropFilter: 'blur(0px)'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -474,7 +477,8 @@ const list = [
|
||||
style: {
|
||||
width: 600,
|
||||
height: 300,
|
||||
color: 'rgb(255, 255, 255,1)'
|
||||
color: 'rgb(255, 255, 255,1)',
|
||||
backdropFilter: 'blur(0px)'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -487,7 +491,8 @@ const list = [
|
||||
width: 200,
|
||||
height: 200,
|
||||
backgroundColor: 'rgba(236,231,231,0.1)',
|
||||
borderActive: true
|
||||
borderActive: true,
|
||||
backdropFilter: 'blur(0px)'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -502,7 +507,8 @@ const list = [
|
||||
borderWidth: 1,
|
||||
borderStyle: 'solid',
|
||||
borderColor: '#cccccc',
|
||||
backgroundColor: 'rgba(236,231,231,0.1)'
|
||||
backgroundColor: 'rgba(236,231,231,0.1)',
|
||||
backdropFilter: 'blur(0px)'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -516,7 +522,8 @@ const list = [
|
||||
height: 200,
|
||||
borderWidth: 1,
|
||||
borderColor: '#cccccc',
|
||||
backgroundColor: 'rgba(236,231,231,0.1)'
|
||||
backgroundColor: 'rgba(236,231,231,0.1)',
|
||||
backdropFilter: 'blur(0px)'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -547,7 +554,8 @@ const list = [
|
||||
headHorizontalPosition: 'left',
|
||||
headFontColor: '#000000',
|
||||
headFontActiveColor: '#000000',
|
||||
titleHide: false
|
||||
titleHide: false,
|
||||
showTabTitle: true
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -5,8 +5,8 @@
|
||||
:class="[
|
||||
headClass,
|
||||
`ed-tabs-${curThemes}`,
|
||||
{ 'title-hidde-tab': hideTitle },
|
||||
{ 'title-show-tab': !hideTitle }
|
||||
{ 'title-hidde-tab': !showTabTitleFlag },
|
||||
{ 'title-show-tab': showTabTitleFlag }
|
||||
]"
|
||||
class="custom-tabs-head"
|
||||
ref="tabComponentRef"
|
||||
@ -19,7 +19,7 @@
|
||||
:active-color="activeColor"
|
||||
:border-color="noBorderColor"
|
||||
:border-active-color="borderActiveColor"
|
||||
:hide-title="hideTitle"
|
||||
:hide-title="!showTabTitleFlag"
|
||||
>
|
||||
<template :key="tabItem.name" v-for="tabItem in element.propValue">
|
||||
<el-tab-pane
|
||||
@ -42,7 +42,7 @@
|
||||
<el-icon v-if="isEdit"><ArrowDown /></el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-menu :style="{ 'font-family': fontFamily }">
|
||||
<el-dropdown-item :command="beforeHandleCommand('editTitle', tabItem)">
|
||||
编辑标题
|
||||
</el-dropdown-item>
|
||||
@ -77,6 +77,7 @@
|
||||
:canvas-id="element.id + '--' + tabItem.name"
|
||||
:class="moveActive ? 'canvas-move-in' : ''"
|
||||
:canvas-active="editableTabsValue === tabItem.name"
|
||||
:font-family="fontFamily"
|
||||
></de-canvas>
|
||||
<de-preview
|
||||
v-else
|
||||
@ -90,6 +91,7 @@
|
||||
:preview-active="editableTabsValue === tabItem.name"
|
||||
:show-position="showPosition"
|
||||
:outer-scale="scale"
|
||||
:font-family="fontFamily"
|
||||
:outer-search-count="searchCount"
|
||||
></de-preview>
|
||||
</div>
|
||||
@ -190,6 +192,12 @@ const props = defineProps({
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0
|
||||
},
|
||||
// 仪表板字体
|
||||
fontFamily: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'inherit'
|
||||
}
|
||||
})
|
||||
const {
|
||||
@ -217,16 +225,11 @@ const editableTabsValue = ref(null)
|
||||
const noBorderColor = ref('none')
|
||||
let currentInstance
|
||||
|
||||
const hideTitle = computed(() => {
|
||||
if (
|
||||
element.value &&
|
||||
element.value.style &&
|
||||
element.value.style.titleHide &&
|
||||
typeof element.value.style.titleHide === 'boolean'
|
||||
) {
|
||||
return element.value.style.titleHide
|
||||
} else {
|
||||
const showTabTitleFlag = computed(() => {
|
||||
if (element.value && element.value.style && element.value.style?.showTabTitle === false) {
|
||||
return false
|
||||
} else {
|
||||
return element.value.style?.showTabTitle
|
||||
}
|
||||
})
|
||||
|
||||
@ -566,6 +569,9 @@ onBeforeMount(() => {
|
||||
:deep(.ed-tabs__content) {
|
||||
height: calc(100% - 46px) !important;
|
||||
}
|
||||
:deep(.ed-tabs__item) {
|
||||
font-family: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.ed-tabs-dark {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="pic-main" @click="onPictureClick">
|
||||
<div class="pic-main">
|
||||
<img
|
||||
draggable="false"
|
||||
v-if="propValue['url']"
|
||||
@ -8,7 +8,7 @@
|
||||
/>
|
||||
<div v-else class="pic-upload">
|
||||
<span
|
||||
><el-button @click="uploadImg" text style="color: #646a73" icon="Plus"
|
||||
><el-button @click="uploadImg" text style="font-family: inherit; color: #646a73" icon="Plus"
|
||||
>请上传图片...</el-button
|
||||
></span
|
||||
>
|
||||
@ -55,16 +55,6 @@ const imageAdapter = computed(() => {
|
||||
}
|
||||
return style as CSSProperties
|
||||
})
|
||||
const onPictureClick = e => {
|
||||
if (element.value.events && element.value.events.checked) {
|
||||
if (element.value.events.type === 'displayChange') {
|
||||
// 打开弹框区域
|
||||
nextTick(() => {
|
||||
dvMainStore.popAreaActiveSwitch()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
const uploadImg = () => {
|
||||
nextTick(() => {
|
||||
eventBus.emit('uploadImg')
|
||||
@ -77,7 +67,6 @@ const uploadImg = () => {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
.pic-upload {
|
||||
display: flex;
|
||||
|
@ -143,7 +143,7 @@ const curFontFamily = () => {
|
||||
value: ele.name
|
||||
}))
|
||||
).forEach(font => {
|
||||
result = result + font.name + '=' + font.name + ';'
|
||||
result = result + font.name + '=' + font.value + ';'
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
@ -58,6 +58,11 @@ const props = defineProps({
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'common'
|
||||
},
|
||||
fontFamily: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'inherit'
|
||||
}
|
||||
})
|
||||
|
||||
@ -87,6 +92,7 @@ const onPointClick = param => {
|
||||
:search-count="searchCount"
|
||||
:disabled="disabled"
|
||||
:suffixId="suffixId"
|
||||
:font-family="fontFamily"
|
||||
@onPointClick="onPointClick"
|
||||
></chart>
|
||||
</div>
|
||||
|
@ -698,6 +698,7 @@ const autoStyle = computed(() => {
|
||||
<el-button
|
||||
:disabled="showPosition === 'preview' || mobileInPc"
|
||||
@click="addCriteriaConfigOut"
|
||||
style="font-family: inherit"
|
||||
text
|
||||
>
|
||||
{{ t('v_query.add_query_condition') }}
|
||||
@ -825,7 +826,6 @@ const autoStyle = computed(() => {
|
||||
justify-content: center;
|
||||
color: #646a73;
|
||||
text-align: center;
|
||||
font-family: var(--de-custom_font, 'PingFang');
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
@ -841,7 +841,6 @@ const autoStyle = computed(() => {
|
||||
.title {
|
||||
color: #1f2329;
|
||||
font-feature-settings: 'clig' off, 'liga' off;
|
||||
font-family: var(--de-custom_font, 'PingFang');
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
@ -900,7 +899,6 @@ const autoStyle = computed(() => {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
color: #1f2329;
|
||||
font-family: var(--de-custom_font, 'PingFang');
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
|
@ -197,7 +197,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: t('dynamic_month.dynamic_month'),
|
||||
label: t('dynamic_month.last'),
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
@ -354,9 +354,9 @@ defineExpose({
|
||||
<div class="bottom-line"></div>
|
||||
</div>
|
||||
<div class="condition-type" v-if="[1, 2].includes(curComponent.conditionType)">
|
||||
<sapn class="condition-type-tip">{{
|
||||
<span class="condition-type-tip">{{
|
||||
curComponent.conditionType === 1 ? t('chart.and') : t('chart.or')
|
||||
}}</sapn>
|
||||
}}</span>
|
||||
<el-select
|
||||
v-if="!curComponent.hideConditionSwitching"
|
||||
class="condition-value-select"
|
||||
|
@ -7,7 +7,7 @@
|
||||
class="custom-sort_filter"
|
||||
width="300px"
|
||||
>
|
||||
<div>
|
||||
<div style="max-height: 400px; overflow-y: auto">
|
||||
<draggable :list="sortList" animation="300" class="drag-list">
|
||||
<template #item="{ element }">
|
||||
<span :key="element.name" class="item-dimension" :title="element">
|
||||
|
@ -167,6 +167,13 @@ onBeforeMount(() => {
|
||||
v-model="selectValue"
|
||||
:type="config.timeGranularity"
|
||||
:prefix-icon="Calendar"
|
||||
:popper-class="'custom-dynamic-time-popper_class'"
|
||||
:placeholder="$t('commons.date.select_date_time')"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style lang="less">
|
||||
.custom-dynamic-time-popper_class {
|
||||
font-family: var(--de-canvas_custom_font);
|
||||
}
|
||||
</style>
|
||||
|
@ -170,8 +170,14 @@ const formatDate = computed(() => {
|
||||
:type="config.timeGranularityMultiple"
|
||||
:prefix-icon="Calendar"
|
||||
:format="formatDate"
|
||||
:popper-class="'custom-dynamic-time-range-popper_class'"
|
||||
:range-separator="$t('cron.to')"
|
||||
:start-placeholder="$t('datasource.start_time')"
|
||||
:end-placeholder="$t('datasource.end_time')"
|
||||
/>
|
||||
</template>
|
||||
<style lang="less">
|
||||
.custom-dynamic-time-range-popper_class {
|
||||
font-family: var(--de-canvas_custom_font);
|
||||
}
|
||||
</style>
|
||||
|
@ -147,8 +147,15 @@ const formatDate = computed(() => {
|
||||
:type="timeInterval"
|
||||
:prefix-icon="Calendar"
|
||||
:format="formatDate"
|
||||
:popper-class="'custom-dynamic-time-range-filter-popper_class'"
|
||||
:range-separator="$t('cron.to')"
|
||||
:start-placeholder="$t('datasource.start_time')"
|
||||
:end-placeholder="$t('datasource.end_time')"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style lang="less">
|
||||
.custom-dynamic-time-range-filter-popper_class {
|
||||
font-family: var(--de-canvas_custom_font);
|
||||
}
|
||||
</style>
|
||||
|
@ -198,7 +198,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: t('dynamic_month.dynamic_month'),
|
||||
label: t('dynamic_month.last'),
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
@ -283,7 +283,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
<div class="setting" v-if="timeRange.intervalType !== 'timeInterval'">
|
||||
<div class="setting-label">{{ t('dynamic_time.relative') }}</div>
|
||||
<div class="setting-value select">
|
||||
<el-select v-model="timeRange.relativeToCurrent">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrent">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentList"
|
||||
:key="item.value"
|
||||
@ -296,7 +296,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
<div class="setting" v-if="timeRange.relativeToCurrent === 'custom'">
|
||||
<div class="setting-input">
|
||||
<el-input-number v-model="timeRange.timeNum" :min="0" controls-position="right" />
|
||||
<el-select v-model="timeRange.relativeToCurrentType">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentType">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentTypeList"
|
||||
:key="item.value"
|
||||
@ -304,7 +304,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="timeRange.around">
|
||||
<el-select :teleported="false" v-model="timeRange.around">
|
||||
<el-option
|
||||
v-for="item in aroundList"
|
||||
:key="item.value"
|
||||
@ -319,7 +319,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
<div class="setting">
|
||||
<div class="setting-label">{{ t('dynamic_time.relative') }}</div>
|
||||
<div class="setting-value select">
|
||||
<el-select v-model="timeRange.relativeToCurrentRange">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentRange">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentListRange"
|
||||
:key="item.value"
|
||||
@ -342,7 +342,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
/>
|
||||
<el-select v-model="timeRange.relativeToCurrentType">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentType">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentTypeList"
|
||||
:key="item.value"
|
||||
@ -350,7 +350,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="timeRange.around">
|
||||
<el-select :teleported="false" v-model="timeRange.around">
|
||||
<el-option
|
||||
v-for="item in aroundList"
|
||||
:key="item.value"
|
||||
@ -372,7 +372,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
step-strictly
|
||||
controls-position="right"
|
||||
/>
|
||||
<el-select v-model="timeRange.relativeToCurrentTypeRange">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentTypeRange">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentTypeList"
|
||||
:key="item.value"
|
||||
@ -380,7 +380,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="timeRange.aroundRange">
|
||||
<el-select :teleported="false" v-model="timeRange.aroundRange">
|
||||
<el-option
|
||||
v-for="item in aroundList"
|
||||
:key="item.value"
|
||||
|
@ -1948,7 +1948,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: t('dynamic_month.dynamic_month'),
|
||||
label: t('dynamic_month.last'),
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
|
@ -209,7 +209,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: t('dynamic_month.dynamic_month'),
|
||||
label: t('dynamic_month.last'),
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
@ -294,7 +294,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
<div class="setting" v-if="timeRange.intervalType !== 'timeInterval'">
|
||||
<div class="setting-label">{{ t('dynamic_time.relative') }}</div>
|
||||
<div class="setting-value select">
|
||||
<el-select v-model="timeRange.relativeToCurrent">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrent">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentList"
|
||||
:key="item.value"
|
||||
@ -307,7 +307,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
<div class="setting" v-if="timeRange.relativeToCurrent === 'custom'">
|
||||
<div class="setting-input">
|
||||
<el-input-number v-model="timeRange.timeNum" :min="0" controls-position="right" />
|
||||
<el-select v-model="timeRange.relativeToCurrentType">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentType">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentTypeList"
|
||||
:key="item.value"
|
||||
@ -315,7 +315,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="timeRange.around">
|
||||
<el-select :teleported="false" v-model="timeRange.around">
|
||||
<el-option
|
||||
v-for="item in aroundList"
|
||||
:key="item.value"
|
||||
@ -330,7 +330,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
<div class="setting">
|
||||
<div class="setting-label">{{ t('dynamic_time.relative') }}</div>
|
||||
<div class="setting-value select">
|
||||
<el-select v-model="timeRange.relativeToCurrentRange">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentRange">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentListRange"
|
||||
:key="item.value"
|
||||
@ -356,7 +356,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
/>
|
||||
<el-select v-model="timeRange.relativeToCurrentType">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentType">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentTypeList"
|
||||
:key="item.value"
|
||||
@ -364,7 +364,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="timeRange.around">
|
||||
<el-select :teleported="false" v-model="timeRange.around">
|
||||
<el-option
|
||||
v-for="item in aroundList"
|
||||
:key="item.value"
|
||||
@ -389,7 +389,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
step-strictly
|
||||
controls-position="right"
|
||||
/>
|
||||
<el-select v-model="timeRange.relativeToCurrentTypeRange">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentTypeRange">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentTypeList"
|
||||
:key="item.value"
|
||||
@ -397,7 +397,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="timeRange.aroundRange">
|
||||
<el-select :teleported="false" v-model="timeRange.aroundRange">
|
||||
<el-option
|
||||
v-for="item in aroundList"
|
||||
:key="item.value"
|
||||
|
@ -290,9 +290,20 @@ const setOldMapValue = arr => {
|
||||
|
||||
const customSort = () => {
|
||||
if (config.value.sortList?.length && config.value.sort === 'customSort') {
|
||||
options.value.sort(
|
||||
(a, b) => config.value.sortList.indexOf(a.value) - config.value.sortList.indexOf(b.value)
|
||||
)
|
||||
options.value = [
|
||||
...options.value
|
||||
.sort(a => {
|
||||
if (config.value.sortList.indexOf(a.value) !== -1) {
|
||||
return -1
|
||||
}
|
||||
})
|
||||
.sort((a, b) => {
|
||||
if (config.value.sortList.indexOf(a.value) === -1) {
|
||||
return 0
|
||||
}
|
||||
return config.value.sortList.indexOf(a.value) - config.value.sortList.indexOf(b.value)
|
||||
})
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -515,7 +526,7 @@ const setOptions = (num: number) => {
|
||||
handleFieldIdChange({
|
||||
queryId: field.id,
|
||||
displayId: displayId || field.id,
|
||||
sort: sort === 'customSort' ? '' : sort,
|
||||
sort: sort === 'customSort' ? 'asc' : sort,
|
||||
sortId,
|
||||
resultMode: config.value.resultMode || 0,
|
||||
searchText: searchText.value,
|
||||
@ -646,6 +657,7 @@ defineExpose({
|
||||
<style lang="less">
|
||||
.filter-select-popper_class {
|
||||
--ed-fill-color-light: #f5f7fa47;
|
||||
font-family: var(--de-canvas_custom_font);
|
||||
.ed-vl__window.ed-select-dropdown__list {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
@ -142,9 +142,9 @@ const handleInnerMouseDown = e => {
|
||||
<div :style="lineWidth" class="bottom-line"></div>
|
||||
</div>
|
||||
<div class="condition-type" v-if="[1, 2].includes(config.conditionType)">
|
||||
<sapn class="condition-type-tip">{{
|
||||
<span class="condition-type-tip">{{
|
||||
config.conditionType === 1 ? t('chart.and') : t('chart.or')
|
||||
}}</sapn>
|
||||
}}</span>
|
||||
<el-select
|
||||
v-if="!config.hideConditionSwitching"
|
||||
class="condition-value-select"
|
||||
|
@ -254,6 +254,7 @@ export const searchQuery = (queryComponentList, filter, curComponentId, firstLoa
|
||||
if (item.checkedFields.includes(curComponentId) && item.checkedFieldsMap[curComponentId]) {
|
||||
let selectValue
|
||||
const {
|
||||
id,
|
||||
selectValue: value,
|
||||
timeGranularityMultiple,
|
||||
defaultNumValueEnd,
|
||||
@ -471,6 +472,7 @@ export const searchQuery = (queryComponentList, filter, curComponentId, firstLoa
|
||||
}
|
||||
|
||||
filter.push({
|
||||
filterId: id,
|
||||
componentId: ele.id,
|
||||
fieldId,
|
||||
operator,
|
||||
|
@ -8,7 +8,9 @@ export const useMoveLine = (type: Sidebar) => {
|
||||
const width = ref(wsCache.get(type) || 280)
|
||||
|
||||
const getCoordinates = () => {
|
||||
document.querySelector('.sidebar-move-line').className = 'sidebar-move-line dragging'
|
||||
if (document.querySelector('.sidebar-move-line')) {
|
||||
document.querySelector('.sidebar-move-line').className = 'sidebar-move-line dragging'
|
||||
}
|
||||
document.addEventListener('mousemove', setCoordinates)
|
||||
document.addEventListener('mouseup', cancelEvent)
|
||||
document.querySelector('body').style['user-select'] = 'none'
|
||||
@ -26,7 +28,9 @@ export const useMoveLine = (type: Sidebar) => {
|
||||
}
|
||||
|
||||
const cancelEvent = () => {
|
||||
document.querySelector('.sidebar-move-line').className = 'sidebar-move-line'
|
||||
if (document.querySelector('.sidebar-move-line')) {
|
||||
document.querySelector('.sidebar-move-line').className = 'sidebar-move-line'
|
||||
}
|
||||
document.querySelector('body').style['user-select'] = 'auto'
|
||||
wsCache.set(type, width.value)
|
||||
document.removeEventListener('mousemove', setCoordinates)
|
||||
|
55
core/core-frontend/src/layout/components/DesktopSetting.vue
Normal file
55
core/core-frontend/src/layout/components/DesktopSetting.vue
Normal file
@ -0,0 +1,55 @@
|
||||
<script lang="ts" setup>
|
||||
import iconSetting from '@/assets/svg/icon-setting.svg'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const navigateBg = computed(() => appearanceStore.getNavigateBg)
|
||||
const { push, resolve } = useRouter()
|
||||
const redirectUser = () => {
|
||||
const sysMenu = resolve('/sys-setting')
|
||||
const kidPath = sysMenu.matched[0].children[0].path
|
||||
push(`${sysMenu.path}/${kidPath}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-tooltip class="box-item" effect="dark" content="系统设置" placement="top">
|
||||
<div
|
||||
class="sys-setting in-iframe-setting"
|
||||
:class="{
|
||||
'is-light-setting': navigateBg && navigateBg === 'light'
|
||||
}"
|
||||
>
|
||||
<el-icon @click="redirectUser">
|
||||
<Icon class="icon-setting" name="icon-setting"
|
||||
><iconSetting class="svg-icon icon-setting"
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sys-setting {
|
||||
margin: 0 10px 0 0;
|
||||
padding: 5px;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: #1e2738;
|
||||
}
|
||||
}
|
||||
.in-iframe-setting {
|
||||
margin-left: 10px !important;
|
||||
}
|
||||
.is-light-setting {
|
||||
&:hover {
|
||||
background-color: #1f23291a !important;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -11,7 +11,6 @@ import { formatRoute } from '@/router/establish'
|
||||
import HeaderMenuItem from './HeaderMenuItem.vue'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { Icon } from '@/components/icon-custom'
|
||||
import { ElHeader, ElMenu } from 'element-plus-secondary'
|
||||
import SystemCfg from './SystemCfg.vue'
|
||||
import ToolboxCfg from './ToolboxCfg.vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
@ -24,12 +23,14 @@ import AiComponent from '@/layout/components/AiComponent.vue'
|
||||
import { findBaseParams } from '@/api/aiComponent'
|
||||
import AiTips from '@/layout/components/AiTips.vue'
|
||||
import CopilotCom from '@/layout/components/Copilot.vue'
|
||||
import DesktopSetting from './DesktopSetting.vue'
|
||||
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const { push } = useRouter()
|
||||
const route = useRoute()
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { msgCountApi } from '@/api/msg'
|
||||
const { wsCache } = useCache('localStorage')
|
||||
const aiBaseUrl = ref('https://maxkb.fit2cloud.com/ui/chat/2ddd8b594ce09dbb?mode=embed')
|
||||
const handleIconClick = () => {
|
||||
@ -119,12 +120,17 @@ const copilotConfirm = () => {
|
||||
wsCache.set('DE-COPILOT-TIPS-CHECK', 'CHECKED')
|
||||
showOverlayCopilot.value = false
|
||||
}
|
||||
const badgeCount = ref(0)
|
||||
|
||||
onMounted(() => {
|
||||
initShowSystem()
|
||||
initShowToolbox()
|
||||
initAiBase()
|
||||
initCopilotBase()
|
||||
|
||||
msgCountApi().then(res => {
|
||||
badgeCount.value = res?.data || 0
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -184,15 +190,17 @@ onMounted(() => {
|
||||
<ToolboxCfg v-if="showToolbox" />
|
||||
<TopDoc v-if="appearanceStore.getShowDoc" />
|
||||
<el-tooltip effect="dark" :content="$t('v_query.msg_center')" placement="bottom">
|
||||
<el-icon
|
||||
class="preview-download_icon"
|
||||
style="margin-right: 10px"
|
||||
:class="navigateBg === 'light' && 'is-light-setting'"
|
||||
>
|
||||
<Icon name="dv-preview-download"
|
||||
><msgNotice @click="msgNoticePush" class="svg-icon"
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
<el-badge :hidden="badgeCount === 0" :value="badgeCount" class="item">
|
||||
<el-icon
|
||||
class="preview-download_icon"
|
||||
style="margin-right: 10px"
|
||||
:class="navigateBg === 'light' && 'is-light-setting'"
|
||||
>
|
||||
<Icon name="dv-preview-download"
|
||||
><msgNotice @click="msgNoticePush" class="svg-icon"
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
</el-badge>
|
||||
</el-tooltip>
|
||||
|
||||
<SystemCfg v-if="showSystem" />
|
||||
@ -204,6 +212,9 @@ onMounted(() => {
|
||||
<div v-if="showOverlay && appearanceStore.getShowAi" class="overlay"></div>
|
||||
<div v-if="showOverlayCopilot && appearanceStore.getShowCopilot" class="overlay"></div>
|
||||
</div>
|
||||
<div v-else class="operate-setting">
|
||||
<desktop-setting />
|
||||
</div>
|
||||
</el-header>
|
||||
</template>
|
||||
|
||||
|
@ -7,10 +7,11 @@ import { useRouter } from 'vue-router'
|
||||
import AccountOperator from '@/layout/components/AccountOperator.vue'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { isDesktop } from '@/utils/ModelUtil'
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const { push } = useRouter()
|
||||
const { t } = useI18n()
|
||||
|
||||
const desktop = isDesktop()
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
title: string
|
||||
@ -43,7 +44,7 @@ const navigate = computed(() => appearanceStore.getNavigate)
|
||||
<span class="work">{{ t('work_branch.back_to_work_branch') }}</span>
|
||||
</span>
|
||||
|
||||
<AccountOperator />
|
||||
<AccountOperator v-if="!desktop" />
|
||||
</div>
|
||||
</el-header>
|
||||
</template>
|
||||
|
@ -18,6 +18,7 @@ import variable from '@/assets/svg/variable.svg'
|
||||
import watermark from '@/assets/svg/watermark.svg'
|
||||
import icon_font from '@/assets/svg/icon_font.svg'
|
||||
import icon_msg_fill from '@/assets/svg/icon_msg_fill.svg'
|
||||
import icon_free from '@/assets/svg/icon_free.svg'
|
||||
|
||||
const iconMap = {
|
||||
appearance: appearance,
|
||||
@ -29,7 +30,8 @@ const iconMap = {
|
||||
variable: variable,
|
||||
watermark: watermark,
|
||||
icon_font: icon_font,
|
||||
icon_msg_fill,
|
||||
icon_msg_fill: icon_msg_fill,
|
||||
icon_free: icon_free,
|
||||
auth: auth,
|
||||
association: association,
|
||||
threshold: threshold,
|
||||
|
@ -83,9 +83,8 @@ onMounted(() => {
|
||||
|
||||
<style lang="less">
|
||||
.toolbox-top-popover {
|
||||
height: 82px;
|
||||
min-width: 208px !important;
|
||||
padding: 16px !important;
|
||||
padding: 8px !important;
|
||||
display: flex;
|
||||
.doc-card {
|
||||
margin: auto;
|
||||
|
@ -29,17 +29,15 @@ const cardInfoList = [
|
||||
:show-arrow="false"
|
||||
popper-class="top-popover"
|
||||
placement="bottom-end"
|
||||
width="208"
|
||||
width="210"
|
||||
trigger="hover"
|
||||
>
|
||||
<el-row>
|
||||
<top-doc-card
|
||||
:span="12"
|
||||
v-for="(item, index) in cardInfoList"
|
||||
:key="index"
|
||||
:card-info="item"
|
||||
></top-doc-card>
|
||||
</el-row>
|
||||
<top-doc-card
|
||||
:span="12"
|
||||
v-for="(item, index) in cardInfoList"
|
||||
:key="index"
|
||||
:card-info="item"
|
||||
></top-doc-card>
|
||||
<template #reference>
|
||||
<div
|
||||
class="sys-setting"
|
||||
@ -75,6 +73,11 @@ const cardInfoList = [
|
||||
|
||||
<style lang="less">
|
||||
.top-popover {
|
||||
padding: 0 0 16px 0 !important;
|
||||
display: flex;
|
||||
padding: 8px !important;
|
||||
flex-wrap: wrap;
|
||||
.doc-card {
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -27,33 +27,28 @@ const openBlank = () => {
|
||||
|
||||
<template>
|
||||
<div class="doc-card" @click="openBlank">
|
||||
<el-row class="base-show">
|
||||
<Icon class-name="item-top-icon"
|
||||
><component class="svg-icon item-top-icon" :is="cardInfo.icon"></component
|
||||
></Icon>
|
||||
</el-row>
|
||||
<el-row class="base-show show-content"> {{ cardInfo.name }}</el-row>
|
||||
<div class="base-show">
|
||||
<Icon><component class="svg-icon item-top-icon" :is="cardInfo.icon"></component></Icon>
|
||||
</div>
|
||||
<div class="base-show show-content">{{ cardInfo.name }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.doc-card {
|
||||
padding-top: 2px;
|
||||
margin-top: 16px;
|
||||
margin-left: 16px;
|
||||
width: 80px;
|
||||
height: 50px;
|
||||
padding: 8px 0;
|
||||
width: 96px;
|
||||
height: 66px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: rgba(30, 39, 56, 0.05);
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
&:hover,
|
||||
&:active {
|
||||
background-color: rgba(30, 39, 56, 0.1);
|
||||
background-color: #1f23291a;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
.base-show {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.show-content {
|
||||
font-size: 14px;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -492,6 +492,7 @@ export default {
|
||||
click_to_show: '点击显示',
|
||||
click_to_hide: '点击隐藏',
|
||||
basic_settings: '基础设置',
|
||||
login_settings: '登录设置',
|
||||
and_0_seconds: '0分0秒',
|
||||
time_0_seconds: '分钟(执行时间:0秒)',
|
||||
and_0_seconds_de: '小时(执行时间:0分0秒)',
|
||||
@ -754,7 +755,7 @@ export default {
|
||||
reset_success: '重置成功',
|
||||
modify_cur_pwd: '修改当前用户密码后需要重新登录',
|
||||
switch_success: '切换成功',
|
||||
user_name_pattern_error: '只允许数字字母以及._-且必须数字或字母开头',
|
||||
user_name_pattern_error: "只允许数字字母以及{'@'}._-且必须数字或字母开头",
|
||||
pwd_pattern_error: '6-20位且至少一位大写字母、小写字母、数字、特殊字符',
|
||||
special_characters_are_not_supported: '不允许特殊字符',
|
||||
phone_format: '请填写正确格式手机号',
|
||||
@ -1245,6 +1246,7 @@ export default {
|
||||
quick_calc: '快速计算',
|
||||
show_name_set: '编辑显示名称',
|
||||
show_name: '显示名称',
|
||||
backdrop_blur: '背景模糊',
|
||||
color: '颜色',
|
||||
color_case: '配色方案',
|
||||
pls_slc_color_case: '请选择配色方案',
|
||||
@ -1379,8 +1381,8 @@ export default {
|
||||
table_header_show_vertical_border: '表头纵边框线',
|
||||
table_cell_show_horizon_border: '单元格横边框线',
|
||||
table_cell_show_vertical_border: '单元格纵边框线',
|
||||
table_col_freeze_tip: '第一列到',
|
||||
tbale_row_freeze_tip: '第一行到',
|
||||
table_col_freeze_tip: '冻结前 n 列',
|
||||
table_row_freeze_tip: '冻结前 n 行',
|
||||
table_freeze: '冻结',
|
||||
stripe: '斑马纹',
|
||||
start_angle: '起始角度',
|
||||
@ -1794,7 +1796,8 @@ export default {
|
||||
p_bottom: '下对齐',
|
||||
p_center: '居中',
|
||||
table_auto_break_line: '自动换行',
|
||||
table_break_line_tip: '开启自动换行,表格行高设置将失效',
|
||||
table_break_line_tip: '开启自动换行,表头行高设置将失效',
|
||||
table_break_line_max_lines: '最大行数',
|
||||
step: '步长(px)',
|
||||
no_function: '函数尚未支持直接引用,请在字段表达式中手动输入。',
|
||||
chart_flow_map: '流向地图',
|
||||
@ -2672,6 +2675,7 @@ export default {
|
||||
column_name: '字段名称'
|
||||
},
|
||||
visualization: {
|
||||
out_params_no_select: '外部参数无需选择',
|
||||
filter_no_select: '过滤组件无需选择',
|
||||
forbidden_copy: '当前组件不允许复制',
|
||||
url_check_error: '跳转错误,URL不合法',
|
||||
@ -3082,7 +3086,10 @@ export default {
|
||||
shareDisable: '禁用分享',
|
||||
sharePeRequire: '分享有效期密码必填',
|
||||
defaultSort: '资源默认排序方式',
|
||||
defaultOpen: '页面打开方式'
|
||||
defaultOpen: '页面打开方式',
|
||||
loginLimit: '限制登录',
|
||||
loginLimitRate: '限制登录失败次数(次)',
|
||||
loginLimitTime: '限制登录失败时间(分)'
|
||||
},
|
||||
resource_sort: {
|
||||
time_asc: '按创建时间升序',
|
||||
@ -3532,6 +3539,7 @@ export default {
|
||||
exporting: '后台导出中,可前往',
|
||||
progress_to_download: '查看进度,进行下载',
|
||||
form: {
|
||||
confirm_to_mark_as_complete: '确认标记为完成?',
|
||||
mobile_number_format_is_incorrect: '手机号码格式不正确',
|
||||
email_format_is_incorrect: '邮箱格式不正确',
|
||||
name: '名称',
|
||||
@ -3823,5 +3831,35 @@ export default {
|
||||
delete_api_key: '确定删除该 API key 吗? ',
|
||||
api_key_desc:
|
||||
'API Key 是您访问 DataEase API 的密钥,具有账户的完全权限,请您务必妥善保管!不要以任何方式公开 API Key 到外部渠道,避免被他人利用造成安全威胁。'
|
||||
},
|
||||
free: {
|
||||
title: '游离资源管理',
|
||||
no_data: '暂无游离资源',
|
||||
sync: '迁移',
|
||||
quick: '一键',
|
||||
batch: '批量',
|
||||
resource: '资源',
|
||||
view_association: '查看血缘关系',
|
||||
quick_sync_tips: '所有仪表板、数据大屏、数据集、数据源,将全部迁移到【迁移资源】文件夹。',
|
||||
batch_sync_tips:
|
||||
'1. 与选中资源相关的仪表板、数据大屏、数据集、数据源,也将一并迁移到对应资源的【迁移资源】文件夹;',
|
||||
batch_sync_tips1: '2. 迁移文件夹将同时迁移该文件夹下的子文件夹和资源。',
|
||||
quick_del_confirm: '确定删除所有游离资源吗?',
|
||||
quick_del_tips: '资源删除后,不可撤销。',
|
||||
quick_sync_confirm: '确定迁移所有游离资源吗?',
|
||||
quick_sync_confirm_tips: '迁移资源后,不可撤销,请谨慎操作。',
|
||||
batch_sync_confirm: '确定迁移 {0} 项及其相关游离资源吗?',
|
||||
single_sync_confirm: '确定迁移该资源吗',
|
||||
batch_del_confirm: '确定删除 {0} 项资源吗?',
|
||||
batch_del_confirm_tips: '资源删除后,不可撤销,请谨慎操作。',
|
||||
del_tips_dataset: '删除数据集会造成相关数据集失效,确定删除?',
|
||||
del_tips_datasource: '有数据集正在使用这些数据源,删除后数据集不可用,确定删除?',
|
||||
single_del_confirm: '确定删除该{0}吗?',
|
||||
single_del_tips_dataset: '该数据集存在如下血缘关系,删除会造成相关视图失效,确定删除?',
|
||||
single_del_tips_datasource: '有 {0} 个数据集正在使用此数据源,删除后数据集不可用,确定删除?',
|
||||
folder: '文件夹',
|
||||
del_folder_tips: '删除后,此文件夹下的所有资源都会被删除,请谨慎操作。',
|
||||
sync_to_org: '迁移至目标组织',
|
||||
sync_org_placeholder: '请选择目标组织'
|
||||
}
|
||||
}
|
||||
|
@ -326,6 +326,14 @@ declare interface ChartBasicStyle {
|
||||
* 表格鼠标悬浮样式
|
||||
*/
|
||||
showHoverStyle: boolean
|
||||
/**
|
||||
* 明细表单元格自动换行
|
||||
*/
|
||||
autoWrap: boolean
|
||||
/**
|
||||
* 最大行数
|
||||
*/
|
||||
maxLines?: boolean
|
||||
}
|
||||
/**
|
||||
* 表头属性
|
||||
|
@ -147,6 +147,10 @@ declare interface ChartThreshold {
|
||||
* 文本卡阈值
|
||||
*/
|
||||
textLabelThreshold: Threshold[]
|
||||
/**
|
||||
* 折线阈值
|
||||
*/
|
||||
lineThreshold: TableThreshold[]
|
||||
}
|
||||
declare interface TableThreshold {
|
||||
/**
|
||||
|
@ -11,6 +11,7 @@ interface UserState {
|
||||
oid: string
|
||||
language: string
|
||||
exp: number
|
||||
time: number
|
||||
}
|
||||
|
||||
export const userStore = defineStore('user', {
|
||||
@ -21,7 +22,8 @@ export const userStore = defineStore('user', {
|
||||
name: null,
|
||||
oid: null,
|
||||
language: 'zh-CN',
|
||||
exp: null
|
||||
exp: null,
|
||||
time: null
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
@ -42,6 +44,9 @@ export const userStore = defineStore('user', {
|
||||
},
|
||||
getExp(): number {
|
||||
return this.exp
|
||||
},
|
||||
getTime(): number {
|
||||
return this.time
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
@ -57,7 +62,8 @@ export const userStore = defineStore('user', {
|
||||
const data = res.data
|
||||
data.token = wsCache.get('user.token')
|
||||
data.exp = wsCache.get('user.exp')
|
||||
const keys: string[] = ['token', 'uid', 'name', 'oid', 'language', 'exp']
|
||||
data.time = wsCache.get('user.time')
|
||||
const keys: string[] = ['token', 'uid', 'name', 'oid', 'language', 'exp', 'time']
|
||||
|
||||
keys.forEach(key => {
|
||||
const dkey = key === 'uid' ? 'id' : key
|
||||
@ -74,6 +80,10 @@ export const userStore = defineStore('user', {
|
||||
wsCache.set('user.exp', exp)
|
||||
this.exp = exp
|
||||
},
|
||||
setTime(time: number) {
|
||||
wsCache.set('user.time', time)
|
||||
this.time = time
|
||||
},
|
||||
setUid(uid: string) {
|
||||
wsCache.set('user.uid', uid)
|
||||
this.uid = uid
|
||||
@ -95,7 +105,7 @@ export const userStore = defineStore('user', {
|
||||
locale.setLang(language)
|
||||
},
|
||||
clear() {
|
||||
const keys: string[] = ['token', 'uid', 'name', 'oid', 'language', 'exp']
|
||||
const keys: string[] = ['token', 'uid', 'name', 'oid', 'language', 'exp', 'time']
|
||||
keys.forEach(key => wsCache.delete('user.' + key))
|
||||
}
|
||||
}
|
||||
|
@ -590,6 +590,13 @@ strong {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.preview-content-inner-size-keep {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
overflow-x: auto;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.preview-content-inner-height-first {
|
||||
width: auto;
|
||||
height: 100%;
|
||||
@ -607,3 +614,7 @@ strong {
|
||||
.ed-message .ed-message__closeBtn:hover {
|
||||
background: #ebebebe6 !important;
|
||||
}
|
||||
|
||||
.canvas_keep-size {
|
||||
overflow-x: auto!important;
|
||||
}
|
||||
|
@ -421,6 +421,41 @@ export function adaptCurTheme(customStyle, customAttr) {
|
||||
}
|
||||
}
|
||||
|
||||
export function adaptTitleFontFamily(fontFamily, viewInfo) {
|
||||
if (viewInfo) {
|
||||
viewInfo.customStyle['text']['fontFamily'] = fontFamily
|
||||
}
|
||||
}
|
||||
|
||||
export function adaptTitleFontFamilyAll(fontFamily) {
|
||||
const componentData = dvMainStore.componentData
|
||||
componentData.forEach(item => {
|
||||
if (item.component === 'UserView') {
|
||||
const viewDetails = dvMainStore.canvasViewInfo[item.id]
|
||||
adaptTitleFontFamily(fontFamily, viewDetails)
|
||||
useEmitt().emitter.emit('renderChart-' + item.id, viewDetails)
|
||||
} else if (item.component === 'Group') {
|
||||
item.propValue.forEach(groupItem => {
|
||||
if (groupItem.component === 'UserView') {
|
||||
const viewDetails = dvMainStore.canvasViewInfo[item.id]
|
||||
adaptTitleFontFamily(fontFamily, viewDetails)
|
||||
useEmitt().emitter.emit('renderChart-' + item.id, viewDetails)
|
||||
}
|
||||
})
|
||||
} else if (item.component === 'DeTabs') {
|
||||
item.propValue.forEach(tabItem => {
|
||||
tabItem.componentData.forEach(tabComponent => {
|
||||
if (tabComponent.component === 'UserView') {
|
||||
const viewDetails = dvMainStore.canvasViewInfo[item.id]
|
||||
adaptTitleFontFamily(fontFamily, viewDetails)
|
||||
useEmitt().emitter.emit('renderChart-' + item.id, viewDetails)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function adaptCurThemeCommonStyle(component) {
|
||||
if (['DeTabs'].includes(component.component)) {
|
||||
component.commonBackground['innerPadding'] = 0
|
||||
|
@ -17,7 +17,8 @@ import {
|
||||
findById,
|
||||
findCopyResource,
|
||||
saveCanvas,
|
||||
updateCanvas
|
||||
updateCanvas,
|
||||
updateCheckVersion
|
||||
} from '@/api/visualization/dataVisualization'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { getPanelAllLinkageInfo } from '@/api/visualization/linkage'
|
||||
@ -35,8 +36,11 @@ const { inMobile, dvInfo, canvasStyleData, componentData, canvasViewInfo, appDat
|
||||
storeToRefs(dvMainStore)
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
const { t } = useI18n()
|
||||
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const { wsCache } = useCache()
|
||||
export function chartTransStr2Object(targetIn, copy) {
|
||||
const target = copy === 'Y' ? cloneDeep(targetIn) : targetIn
|
||||
return target
|
||||
@ -146,7 +150,7 @@ export function historyItemAdaptor(
|
||||
}
|
||||
|
||||
if (componentItem.component === 'DeTabs') {
|
||||
componentItem.style['titleHide'] = componentItem.style['titleHide'] || false
|
||||
componentItem.style['showTabTitle'] = componentItem.style['showTabTitle'] || true
|
||||
}
|
||||
|
||||
componentItem['expand'] = componentItem['expand'] || false
|
||||
@ -222,7 +226,14 @@ export function historyAdaptor(
|
||||
attachInfo,
|
||||
canvasVersion
|
||||
) {
|
||||
const curVersion = wsCache.get('x-de-execute-version')
|
||||
if (canvasInfo?.checkVersion === curVersion) {
|
||||
return
|
||||
}
|
||||
//历史字段适配
|
||||
canvasStyleResult.component['seniorStyleSetting'] =
|
||||
canvasStyleResult.component['seniorStyleSetting'] || deepCopy(SENIOR_STYLE_SETTING_LIGHT)
|
||||
canvasStyleResult['fontFamily'] = canvasStyleResult['fontFamily'] || 'PingFang'
|
||||
canvasStyleResult.dashboard['showGrid'] = canvasStyleResult.dashboard['showGrid'] || false
|
||||
canvasStyleResult.dashboard['matrixBase'] = canvasStyleResult.dashboard['matrixBase'] || 4
|
||||
canvasStyleResult.component['seniorStyleSetting'] =
|
||||
@ -251,6 +262,9 @@ export function historyAdaptor(
|
||||
canvasDataResult.forEach(componentItem => {
|
||||
historyItemAdaptor(componentItem, reportFilterInfo, attachInfo, canvasVersion, canvasInfo)
|
||||
})
|
||||
if (canvasInfo && canvasInfo.id) {
|
||||
updateCheckVersion(canvasInfo.id)
|
||||
}
|
||||
}
|
||||
|
||||
// 重置仪表板、大屏中的其他组件
|
||||
@ -338,13 +352,15 @@ export function initCanvasDataPrepare(dvId, busiFlag, callBack) {
|
||||
const canvasStyleResult = JSON.parse(canvasInfo.canvasStyleData)
|
||||
const canvasViewInfoPreview = canvasInfo.canvasViewInfo
|
||||
historyAdaptor(canvasStyleResult, canvasDataResult, canvasInfo, attachInfo, canvasVersion)
|
||||
//历史字段适配
|
||||
canvasStyleResult.component['seniorStyleSetting'] =
|
||||
canvasStyleResult.component['seniorStyleSetting'] || deepCopy(SENIOR_STYLE_SETTING_LIGHT)
|
||||
const curPreviewGap =
|
||||
dvInfo.type === 'dashboard' && canvasStyleResult['dashboard'].gap === 'yes'
|
||||
? canvasStyleResult['dashboard'].gapSize
|
||||
: 0
|
||||
appearanceStore.setCurrentFont(canvasStyleResult.fontFamily)
|
||||
document.documentElement.style.setProperty(
|
||||
'--de-canvas_custom_font',
|
||||
`${canvasStyleResult.fontFamily}`
|
||||
)
|
||||
callBack({ canvasDataResult, canvasStyleResult, dvInfo, canvasViewInfoPreview, curPreviewGap })
|
||||
})
|
||||
}
|
||||
|
@ -200,7 +200,8 @@ export function getCanvasStyle(canvasStyleData, canvasId = 'canvas-main') {
|
||||
backgroundColor,
|
||||
backgroundImageEnable,
|
||||
fontSize,
|
||||
mobileSetting
|
||||
mobileSetting,
|
||||
fontFamily
|
||||
} = canvasStyleData
|
||||
const style = { fontSize: fontSize + 'px', color: canvasStyleData.color }
|
||||
if (isMainCanvas(canvasId)) {
|
||||
@ -225,6 +226,7 @@ export function getCanvasStyle(canvasStyleData, canvasId = 'canvas-main') {
|
||||
style['background'] = `url(${imgUrlTrans(background)}) no-repeat`
|
||||
}
|
||||
}
|
||||
style['font-family'] = fontFamily + '!important'
|
||||
}
|
||||
|
||||
return style
|
||||
@ -249,16 +251,17 @@ export function createGroupStyle(groupComponent) {
|
||||
|
||||
function dataVTabSizeStyleAdaptor(tabComponent) {
|
||||
const parentStyleAdaptor = { ...tabComponent.style }
|
||||
const offset = parentStyleAdaptor.showTabTitle ? 46 : 0
|
||||
const domId =
|
||||
dvMainStore.editMode === 'edit'
|
||||
? 'component' + tabComponent.id
|
||||
: 'enlarge-inner-content' + tabComponent.id
|
||||
const tabDom = document.getElementById(domId)
|
||||
if (tabDom) {
|
||||
parentStyleAdaptor.height = tabDom.clientHeight - 46
|
||||
parentStyleAdaptor.height = tabDom.clientHeight - offset
|
||||
parentStyleAdaptor.width = tabDom.clientWidth
|
||||
} else {
|
||||
parentStyleAdaptor.height = parentStyleAdaptor.height - 46
|
||||
parentStyleAdaptor.height = parentStyleAdaptor.height - offset
|
||||
}
|
||||
|
||||
tabComponent.propValue.forEach(tabItem => {
|
||||
@ -288,6 +291,18 @@ export function groupStyleRevertBatch(groupComponent, parentStyle) {
|
||||
}
|
||||
}
|
||||
|
||||
export function tabInnerStyleRevert(tabOuterComponent) {
|
||||
const parentStyle = {
|
||||
width: tabOuterComponent.style.width,
|
||||
height: tabOuterComponent.style.height - (tabOuterComponent.style.showTabTitle ? 46 : 0)
|
||||
}
|
||||
tabOuterComponent.propValue.forEach(tabItem => {
|
||||
tabItem.componentData.forEach(tabComponent => {
|
||||
groupStyleRevert(tabComponent, parentStyle)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function groupStyleRevert(innerComponent, parentStyle) {
|
||||
const innerStyle = { ...innerComponent.style }
|
||||
innerComponent.groupStyle.left = innerStyle.left / parentStyle.width
|
||||
@ -313,6 +328,6 @@ export function dataVTabComponentAdd(innerComponent, parentComponent) {
|
||||
innerComponent.style.left = 0
|
||||
const parentStyleAdaptor = { ...parentComponent.style }
|
||||
// 去掉tab头部高度
|
||||
parentStyleAdaptor.height = parentStyleAdaptor.height - 48
|
||||
parentStyleAdaptor.height = parentStyleAdaptor.height - (parentComponent.showTabTitle ? 46 : 0)
|
||||
groupStyleRevert(innerComponent, parentStyleAdaptor)
|
||||
}
|
||||
|
@ -39,6 +39,12 @@ const props = defineProps({
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 1
|
||||
},
|
||||
// 仪表板字体
|
||||
fontFamily: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'inherit'
|
||||
}
|
||||
})
|
||||
const { canvasStyleData, componentData, canvasViewInfo, canvasId, canvasActive, outerScale } =
|
||||
@ -98,7 +104,9 @@ const handleNewFromCanvasMain = newComponentInfo => {
|
||||
adaptCurThemeCommonStyle(component)
|
||||
nextTick(() => {
|
||||
cyGridster.value.addItemBox(component) //在适当的时候初始化布局组件
|
||||
scrollTo(component.y)
|
||||
nextTick(() => {
|
||||
scrollTo(component.y)
|
||||
})
|
||||
})
|
||||
snapshotStore.recordSnapshotCache('renderChart', component.id)
|
||||
}
|
||||
@ -319,6 +327,7 @@ defineExpose({
|
||||
:base-margin-top="baseMarginTop"
|
||||
:base-width="baseWidth"
|
||||
:base-height="baseHeight"
|
||||
:font-family="fontFamily"
|
||||
@scrollCanvasToTop="scrollTo(1)"
|
||||
></canvas-core>
|
||||
</div>
|
||||
|
@ -7,6 +7,7 @@ import { DEFAULT_THRESHOLD } from '@/views/chart/components/editor/util/chart'
|
||||
import TableThresholdEdit from '@/views/chart/components/editor/editor-senior/components/dialog/TableThresholdEdit.vue'
|
||||
import TextLabelThresholdEdit from '@/views/chart/components/editor/editor-senior/components/dialog/TextLabelThresholdEdit.vue'
|
||||
import TextThresholdEdit from '@/views/chart/components/editor/editor-senior/components/dialog/TextThresholdEdit.vue'
|
||||
import LineThresholdEdit from '@/views/chart/components/editor/editor-senior/components/dialog/LineThresholdEdit.vue'
|
||||
import { fieldType } from '@/utils/attr'
|
||||
import { defaultsDeep } from 'lodash-es'
|
||||
import { iconFieldMap } from '@/components/icon-group/field-list'
|
||||
@ -50,7 +51,9 @@ const state = reactive({
|
||||
editLabelThresholdDialog: false,
|
||||
thresholdArr: [],
|
||||
editTableThresholdDialog: false,
|
||||
tableThresholdArr: []
|
||||
tableThresholdArr: [],
|
||||
editLineThresholdDialog: false,
|
||||
lineThresholdArr: []
|
||||
})
|
||||
|
||||
const init = () => {
|
||||
@ -63,6 +66,7 @@ const init = () => {
|
||||
state.textThresholdArr = JSON.parse(JSON.stringify(state.thresholdForm.textLabelThreshold))
|
||||
state.thresholdArr = JSON.parse(JSON.stringify(state.thresholdForm.labelThreshold))
|
||||
state.tableThresholdArr = JSON.parse(JSON.stringify(state.thresholdForm.tableThreshold))
|
||||
state.lineThresholdArr = JSON.parse(JSON.stringify(state.thresholdForm.lineThreshold ?? []))
|
||||
}
|
||||
}
|
||||
const changeThreshold = () => {
|
||||
@ -257,6 +261,77 @@ const changeTableThreshold = () => {
|
||||
changeThreshold()
|
||||
closeTableThreshold()
|
||||
}
|
||||
|
||||
const lineThresholdChange = val => {
|
||||
state.lineThresholdArr = val
|
||||
}
|
||||
const editLineThreshold = () => {
|
||||
state.editLineThresholdDialog = true
|
||||
}
|
||||
const closeLineThreshold = () => {
|
||||
state.editLineThresholdDialog = false
|
||||
}
|
||||
const changeLineThreshold = () => {
|
||||
// check line config
|
||||
for (let i = 0; i < state.lineThresholdArr?.length; i++) {
|
||||
const field = state.lineThresholdArr[i]
|
||||
if (!field.fieldId) {
|
||||
ElMessage.error(t('chart.field_can_not_empty'))
|
||||
return
|
||||
}
|
||||
if (!field.conditions || field.conditions.length === 0) {
|
||||
ElMessage.error(t('chart.conditions_can_not_empty'))
|
||||
return
|
||||
}
|
||||
for (let j = 0; j < field.conditions.length; j++) {
|
||||
const ele = field.conditions[j]
|
||||
if (!ele.term || ele.term === '') {
|
||||
ElMessage.error(t('chart.exp_can_not_empty'))
|
||||
return
|
||||
}
|
||||
if (ele.term === 'between') {
|
||||
if (
|
||||
!ele.term.includes('null') &&
|
||||
!ele.term.includes('empty') &&
|
||||
(ele.min === '' || ele.max === '')
|
||||
) {
|
||||
ElMessage.error(t('chart.value_can_not_empty'))
|
||||
return
|
||||
}
|
||||
if (
|
||||
(field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) &&
|
||||
(parseFloat(ele.min).toString() === 'NaN' || parseFloat(ele.max).toString() === 'NaN')
|
||||
) {
|
||||
ElMessage.error(t('chart.value_error'))
|
||||
return
|
||||
}
|
||||
if (
|
||||
(field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) &&
|
||||
parseFloat(ele.min) > parseFloat(ele.max)
|
||||
) {
|
||||
ElMessage.error(t('chart.value_min_max_invalid'))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (!ele.term.includes('null') && !ele.term.includes('empty') && ele.value === '') {
|
||||
ElMessage.error(t('chart.value_can_not_empty'))
|
||||
return
|
||||
}
|
||||
if (
|
||||
(field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) &&
|
||||
parseFloat(ele.value).toString() === 'NaN'
|
||||
) {
|
||||
ElMessage.error(t('chart.value_error'))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
state.thresholdForm.lineThreshold = JSON.parse(JSON.stringify(state.lineThresholdArr ?? []))
|
||||
changeThreshold()
|
||||
closeLineThreshold()
|
||||
}
|
||||
|
||||
const getFieldName = field => (field.chartShowName ? field.chartShowName : field.name)
|
||||
|
||||
const getDynamicStyleLabel = (item, fieldObj) => {
|
||||
@ -713,6 +788,129 @@ init()
|
||||
</div>
|
||||
</el-col>
|
||||
</el-col>
|
||||
<!--折线-->
|
||||
<el-col v-show="showProperty('lineThreshold')">
|
||||
<el-col>
|
||||
<div class="inner-container">
|
||||
<span class="label" :class="'label-' + props.themes">条件样式设置</span>
|
||||
<span class="right-btns">
|
||||
<span
|
||||
class="set-text-info"
|
||||
:class="{ 'set-text-info-dark': themes === 'dark' }"
|
||||
v-if="state.thresholdForm?.tableThreshold?.length > 0"
|
||||
>
|
||||
已设置
|
||||
</span>
|
||||
<el-button
|
||||
:title="t('chart.edit')"
|
||||
:class="'label-' + props.themes"
|
||||
:style="{ width: '24px', marginLeft: '6px' }"
|
||||
:disabled="!state.thresholdForm.enable"
|
||||
class="circle-button"
|
||||
text
|
||||
size="small"
|
||||
@click="editLineThreshold"
|
||||
>
|
||||
<template #icon>
|
||||
<el-icon size="14px">
|
||||
<Icon name="icon_edit_outlined"><icon_edit_outlined class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="threshold-container"
|
||||
:class="{ 'threshold-container-dark': themes === 'dark' }"
|
||||
v-if="state.thresholdForm.lineThreshold?.length > 0"
|
||||
>
|
||||
<el-row
|
||||
v-for="(fieldItem, fieldIndex) in state.thresholdForm.lineThreshold"
|
||||
:key="fieldIndex"
|
||||
style="flex-direction: column"
|
||||
>
|
||||
<div class="field-style" :class="{ 'field-style-dark': themes === 'dark' }">
|
||||
<el-icon>
|
||||
<Icon :className="`field-icon-${fieldType[fieldItem.field.deType]}`"
|
||||
><component
|
||||
class="svg-icon"
|
||||
:class="`field-icon-${fieldType[fieldItem.field.deType]}`"
|
||||
:is="iconFieldMap[fieldType[fieldItem.field.deType]]"
|
||||
></component
|
||||
></Icon>
|
||||
</el-icon>
|
||||
<span :title="fieldItem.field.name" class="field-text">{{
|
||||
fieldItem.field.name
|
||||
}}</span>
|
||||
</div>
|
||||
<div v-for="(item, index) in fieldItem.conditions" :key="index" class="line-style">
|
||||
<div style="flex: 1">
|
||||
<span v-if="item.term === 'lt'" :title="t('chart.filter_lt')">
|
||||
{{ t('chart.filter_lt') }}
|
||||
</span>
|
||||
<span v-else-if="item.term === 'gt'" :title="t('chart.filter_gt')">
|
||||
{{ t('chart.filter_gt') }}
|
||||
</span>
|
||||
<span v-else-if="item.term === 'le'" :title="t('chart.filter_le')">
|
||||
{{ t('chart.filter_le') }}
|
||||
</span>
|
||||
<span v-else-if="item.term === 'ge'" :title="t('chart.filter_ge')">
|
||||
{{ t('chart.filter_ge') }}
|
||||
</span>
|
||||
<span v-else-if="item.term === 'between'" :title="t('chart.filter_between')">
|
||||
{{ t('chart.filter_between') }}
|
||||
</span>
|
||||
<span v-else-if="item.term === 'default'" title="默认"> 默认 </span>
|
||||
</div>
|
||||
<div v-if="item.type !== 'dynamic'" style="flex: 1; margin: 0 8px">
|
||||
<span style="margin: 0 8px">
|
||||
{{ t('chart.fix') }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-else style="flex: 1; margin: 0 8px">
|
||||
<span style="margin: 0 8px">
|
||||
{{ t('chart.dynamic') }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="item.type !== 'dynamic'" style="flex: 1; margin: 0 8px">
|
||||
<span
|
||||
v-if="
|
||||
!item.term.includes('null') &&
|
||||
!item.term.includes('default') &&
|
||||
!item.term.includes('empty') &&
|
||||
item.term !== 'between'
|
||||
"
|
||||
:title="item.value + ''"
|
||||
>{{ item.value }}</span
|
||||
>
|
||||
<span
|
||||
v-else-if="
|
||||
!item.term.includes('null') &&
|
||||
!item.term.includes('empty') &&
|
||||
item.term === 'between'
|
||||
"
|
||||
:title="item.min + ' ≤= ' + t('chart.drag_block_label_value') + ' ≤ ' + item.max"
|
||||
>
|
||||
{{ item.min }} ≤{{ t('chart.drag_block_label_value') }}≤ {{ item.max }}
|
||||
</span>
|
||||
<span v-else> </span>
|
||||
</div>
|
||||
<template v-if="chart.type !== 'picture-group'">
|
||||
<div
|
||||
:title="t('chart.color')"
|
||||
:style="{
|
||||
backgroundColor: item.color
|
||||
}"
|
||||
class="color-div"
|
||||
:class="{ 'color-div-dark': themes === 'dark' }"
|
||||
></div>
|
||||
</template>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-col>
|
||||
|
||||
<!--编辑文本卡阈值-->
|
||||
<el-dialog
|
||||
@ -794,6 +992,30 @@ init()
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!--编辑折线阈值-->
|
||||
<el-dialog
|
||||
v-if="state.editLineThresholdDialog"
|
||||
v-model="state.editLineThresholdDialog"
|
||||
:title="t('chart.threshold')"
|
||||
:visible="state.editLineThresholdDialog"
|
||||
width="1050px"
|
||||
class="dialog-css"
|
||||
append-to-body
|
||||
>
|
||||
<line-threshold-edit
|
||||
:threshold="state.thresholdForm.lineThreshold"
|
||||
:chart="chart"
|
||||
@onLineThresholdChange="lineThresholdChange"
|
||||
/>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeLineThreshold">{{ t('chart.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="changeLineThreshold">{{
|
||||
t('chart.confirm')
|
||||
}}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -0,0 +1,499 @@
|
||||
<script lang="tsx" setup>
|
||||
import icon_info_filled from '@/assets/svg/icon_info_filled.svg'
|
||||
import icon_deleteTrash_outlined from '@/assets/svg/icon_delete-trash_outlined.svg'
|
||||
import icon_add_outlined from '@/assets/svg/icon_add_outlined.svg'
|
||||
import { PropType, reactive } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { COLOR_PANEL } from '../../../util/chart'
|
||||
import { fieldType } from '@/utils/attr'
|
||||
import { iconFieldMap } from '@/components/icon-group/field-list'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
chart: {
|
||||
type: Object as PropType<ChartObj>,
|
||||
required: true
|
||||
},
|
||||
threshold: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['onLineThresholdChange'])
|
||||
|
||||
const thresholdCondition = {
|
||||
term: 'lt',
|
||||
field: '0',
|
||||
value: '0',
|
||||
color: '#ff0000ff',
|
||||
backgroundColor: '#ffffff00',
|
||||
min: '0',
|
||||
max: '1',
|
||||
type: 'fixed'
|
||||
}
|
||||
const valueOptions = [
|
||||
{
|
||||
label: '',
|
||||
options: [
|
||||
{
|
||||
value: 'lt',
|
||||
label: t('chart.filter_lt')
|
||||
},
|
||||
{
|
||||
value: 'gt',
|
||||
label: t('chart.filter_gt')
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
options: [
|
||||
{
|
||||
value: 'between',
|
||||
label: t('chart.filter_between')
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
const predefineColors = COLOR_PANEL
|
||||
|
||||
const state = reactive({
|
||||
thresholdArr: [] as LineThreshold[],
|
||||
fields: [],
|
||||
thresholdObj: {
|
||||
fieldId: '',
|
||||
field: {},
|
||||
conditions: []
|
||||
} as LineThreshold
|
||||
})
|
||||
|
||||
const init = () => {
|
||||
state.thresholdArr = JSON.parse(JSON.stringify(props.threshold)) as LineThreshold[]
|
||||
initFields()
|
||||
}
|
||||
const initOptions = (item, fieldObj) => {
|
||||
if (fieldObj) {
|
||||
item.options = JSON.parse(JSON.stringify(valueOptions))
|
||||
item.conditions &&
|
||||
item.conditions.forEach(ele => {
|
||||
ele.term = ''
|
||||
})
|
||||
}
|
||||
}
|
||||
const initFields = () => {
|
||||
let fields = []
|
||||
const yAxis = JSON.parse(JSON.stringify(props.chart.yAxis))
|
||||
fields = [...yAxis]
|
||||
state.fields.splice(0, state.fields.length, ...fields)
|
||||
// 字段不存在时
|
||||
let change = false
|
||||
state.thresholdArr.forEach(item => {
|
||||
const fieldItemObj = state.fields.filter(ele => ele.id === item.fieldId)
|
||||
if (fieldItemObj.length === 0) {
|
||||
change = true
|
||||
item.fieldId = null
|
||||
}
|
||||
})
|
||||
if (change) {
|
||||
changeThreshold()
|
||||
}
|
||||
}
|
||||
const addThreshold = () => {
|
||||
state.thresholdArr.push(JSON.parse(JSON.stringify(state.thresholdObj)))
|
||||
changeThreshold()
|
||||
}
|
||||
const removeThreshold = index => {
|
||||
state.thresholdArr.splice(index, 1)
|
||||
changeThreshold()
|
||||
}
|
||||
|
||||
const changeThreshold = () => {
|
||||
emit('onLineThresholdChange', state.thresholdArr)
|
||||
}
|
||||
|
||||
const addConditions = item => {
|
||||
const newCondition = JSON.parse(JSON.stringify(thresholdCondition))
|
||||
item.conditions.push(newCondition)
|
||||
changeThreshold()
|
||||
}
|
||||
const removeCondition = (item, index) => {
|
||||
item.conditions.splice(index, 1)
|
||||
changeThreshold()
|
||||
}
|
||||
|
||||
const addField = item => {
|
||||
// get field
|
||||
if (state.fields && state.fields.length > 0) {
|
||||
state.fields.forEach(ele => {
|
||||
if (item.fieldId === ele.id) {
|
||||
item.field = JSON.parse(JSON.stringify(ele))
|
||||
initOptions(item, item.field)
|
||||
}
|
||||
})
|
||||
}
|
||||
changeThreshold()
|
||||
}
|
||||
|
||||
const fieldOptions = [{ label: t('chart.field_fixed'), value: 'fixed' }]
|
||||
|
||||
const isNotEmptyAndNull = item => {
|
||||
return !item.term.includes('null') && !item.term.includes('empty')
|
||||
}
|
||||
|
||||
const isBetween = item => {
|
||||
return item.term === 'between'
|
||||
}
|
||||
|
||||
const isDynamic = item => {
|
||||
return item.type === 'dynamic'
|
||||
}
|
||||
|
||||
const getFieldOptions = fieldItem => {
|
||||
const deType = state.fields.filter(ele => ele.id === fieldItem.fieldId)?.[0]?.deType
|
||||
if (deType === 1) {
|
||||
return fieldOptions.filter(ele => ele.value === 'fixed')
|
||||
} else {
|
||||
return fieldOptions
|
||||
}
|
||||
}
|
||||
|
||||
init()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-col>
|
||||
<div class="tip">
|
||||
<Icon name="icon_info_filled" class="icon-style"
|
||||
><icon_info_filled class="svg-icon icon-style"
|
||||
/></Icon>
|
||||
<span style="padding-left: 10px">{{ t('chart.table_threshold_tip') }}</span>
|
||||
</div>
|
||||
|
||||
<div @keydown.stop @keyup.stop style="max-height: 50vh; overflow-y: auto">
|
||||
<div
|
||||
v-for="(fieldItem, fieldIndex) in state.thresholdArr"
|
||||
:key="fieldIndex"
|
||||
class="field-item"
|
||||
>
|
||||
<el-row style="margin-top: 6px; align-items: center; justify-content: space-between">
|
||||
<el-form-item class="form-item">
|
||||
<el-select v-model="fieldItem.fieldId" @change="addField(fieldItem)">
|
||||
<el-option
|
||||
class="series-select-option"
|
||||
v-for="fieldOption in state.fields"
|
||||
:key="fieldOption.id"
|
||||
:label="fieldOption.name"
|
||||
:value="fieldOption.id"
|
||||
:disabled="chart.type === 'table-info' && fieldOption.deType === 7"
|
||||
>
|
||||
<el-icon style="margin-right: 8px">
|
||||
<Icon
|
||||
><component
|
||||
:class="`field-icon-${
|
||||
fieldType[[2, 3].includes(fieldOption.deType) ? 2 : 0]
|
||||
}`"
|
||||
class="svg-icon"
|
||||
:is="iconFieldMap[fieldType[fieldOption.deType]]"
|
||||
></component
|
||||
></Icon>
|
||||
</el-icon>
|
||||
{{ fieldOption.name }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-button
|
||||
class="circle-button m-icon-btn"
|
||||
text
|
||||
:style="{ float: 'right' }"
|
||||
@click="removeThreshold(fieldIndex)"
|
||||
>
|
||||
<el-icon size="20px" style="color: #646a73">
|
||||
<Icon name="icon_delete-trash_outlined"
|
||||
><icon_deleteTrash_outlined class="svg-icon"
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-row>
|
||||
|
||||
<el-row :style="{ marginTop: '16px', borderTop: '1px solid #d5d6d8' }">
|
||||
<el-row
|
||||
v-for="(item, index) in fieldItem.conditions"
|
||||
:key="index"
|
||||
class="line-item"
|
||||
:gutter="12"
|
||||
>
|
||||
<el-col :span="4">
|
||||
<el-form-item class="form-item">
|
||||
<el-select v-model="item.term" @change="changeThreshold">
|
||||
<el-option-group
|
||||
v-for="(group, idx) in fieldItem.options"
|
||||
:key="idx"
|
||||
:label="group.label"
|
||||
>
|
||||
<el-option
|
||||
v-for="opt in group.options"
|
||||
:key="opt.value"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
/>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4" v-if="isNotEmptyAndNull(item)" style="padding-left: 0 !important">
|
||||
<el-form-item class="form-item">
|
||||
<el-select v-model="item.type" class="select-item" style="width: 100%">
|
||||
<el-option
|
||||
v-for="opt in getFieldOptions(fieldItem)"
|
||||
:key="opt.value"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!--不是between 不是动态值-->
|
||||
<el-col
|
||||
v-if="isNotEmptyAndNull(item) && !isBetween(item) && !isDynamic(item)"
|
||||
:span="12"
|
||||
style="text-align: center"
|
||||
>
|
||||
<el-form-item class="form-item">
|
||||
<el-input-number
|
||||
v-model="item.value"
|
||||
v-if="[2, 3].includes(fieldItem.field.deType)"
|
||||
:placeholder="t('chart.drag_block_label_value')"
|
||||
controls-position="right"
|
||||
class="value-item"
|
||||
clearable
|
||||
@change="changeThreshold"
|
||||
/>
|
||||
<el-input
|
||||
v-model="item.value"
|
||||
v-else
|
||||
:placeholder="t('chart.drag_block_label_value')"
|
||||
controls-position="right"
|
||||
clearable
|
||||
@change="changeThreshold"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!--between 开始值-->
|
||||
<el-col
|
||||
v-if="isNotEmptyAndNull(item) && isBetween(item) && !isDynamic(item)"
|
||||
:span="5"
|
||||
style="text-align: center"
|
||||
>
|
||||
<el-form-item class="form-item">
|
||||
<el-input-number
|
||||
v-model="item.min"
|
||||
controls-position="right"
|
||||
class="between-item"
|
||||
:placeholder="t('chart.axis_value_min')"
|
||||
clearable
|
||||
@change="changeThreshold"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col
|
||||
v-if="isBetween(item) && !isDynamic(item)"
|
||||
:span="2"
|
||||
style="margin-top: 4px; text-align: center"
|
||||
>
|
||||
<span style="margin: 0 -5px">
|
||||
≤ {{ t('chart.drag_block_label_value') }} ≤
|
||||
</span>
|
||||
</el-col>
|
||||
<!--between 结束值-->
|
||||
<el-col
|
||||
v-if="isNotEmptyAndNull(item) && isBetween(item) && !isDynamic(item)"
|
||||
:span="5"
|
||||
style="text-align: center"
|
||||
>
|
||||
<el-form-item class="form-item">
|
||||
<el-input-number
|
||||
v-model="item.max"
|
||||
controls-position="right"
|
||||
class="between-item"
|
||||
:placeholder="t('chart.axis_value_max')"
|
||||
clearable
|
||||
@change="changeThreshold"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="3">
|
||||
<el-form-item class="form-item" :label="t('chart.textColor')">
|
||||
<el-color-picker
|
||||
is-custom
|
||||
size="large"
|
||||
v-model="item.color"
|
||||
show-alpha
|
||||
class="color-picker-style"
|
||||
:predefine="predefineColors"
|
||||
@change="changeThreshold"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="1">
|
||||
<div style="display: flex; align-items: center; justify-content: center">
|
||||
<el-button
|
||||
class="circle-button m-icon-btn"
|
||||
text
|
||||
@click="removeCondition(fieldItem, index)"
|
||||
>
|
||||
<el-icon size="20px" style="color: #646a73">
|
||||
<Icon name="icon_delete-trash_outlined"
|
||||
><icon_deleteTrash_outlined class="svg-icon"
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-row>
|
||||
|
||||
<el-button
|
||||
style="margin-top: 10px"
|
||||
class="circle-button"
|
||||
type="primary"
|
||||
text
|
||||
@click="addConditions(fieldItem)"
|
||||
>
|
||||
<template #icon>
|
||||
<Icon name="icon_add_outlined"><icon_add_outlined class="svg-icon" /></Icon>
|
||||
</template>
|
||||
{{ t('chart.add_style') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
class="circle-button"
|
||||
text
|
||||
type="primary"
|
||||
style="margin-top: 10px"
|
||||
@click="addThreshold"
|
||||
>
|
||||
<template #icon>
|
||||
<Icon name="icon_add_outlined"><icon_add_outlined class="svg-icon" /></Icon>
|
||||
</template>
|
||||
{{ t('chart.add_condition') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.field-item {
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
padding: 10px 16px;
|
||||
margin-top: 10px;
|
||||
background: #f5f6f7;
|
||||
}
|
||||
|
||||
.line-item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
align-items: center;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
height: 28px !important;
|
||||
:deep(.el-form-item__label) {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.value-item {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.between-item {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.select-item {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.el-select-dropdown__item {
|
||||
padding: 0 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.color-picker-style {
|
||||
cursor: pointer;
|
||||
z-index: 1003;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.color-picker-style :deep(.el-color-picker__trigger) {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.color-title {
|
||||
color: #646a73;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-size: 12px;
|
||||
background: #d6e2ff;
|
||||
border-radius: 4px;
|
||||
padding: 10px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.ed-form-item) {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.icon-style {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
color: var(--ed-color-primary);
|
||||
}
|
||||
|
||||
.m-icon-btn {
|
||||
&:hover {
|
||||
background: rgba(31, 35, 41, 0.1) !important;
|
||||
}
|
||||
&:focus {
|
||||
background: rgba(31, 35, 41, 0.1) !important;
|
||||
}
|
||||
&:active {
|
||||
background: rgba(31, 35, 41, 0.2) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.series-select-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 0 11px;
|
||||
}
|
||||
</style>
|
@ -297,6 +297,33 @@ initParams()
|
||||
:predefine="COLOR_PANEL"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="form-item margin-bottom-8" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
size="small"
|
||||
:effect="themes"
|
||||
v-model="commonBackgroundPop.backdropFilterEnable"
|
||||
>
|
||||
{{ $t('chart.backdrop_blur') }}
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
style="padding-left: 20px"
|
||||
class="form-item margin-bottom-8"
|
||||
:class="'form-item-' + themes"
|
||||
>
|
||||
<el-input-number
|
||||
style="width: 100%"
|
||||
:effect="themes"
|
||||
controls-position="right"
|
||||
size="middle"
|
||||
:min="0"
|
||||
:max="30"
|
||||
:disabled="!commonBackgroundPop.backdropFilterEnable"
|
||||
v-model="commonBackgroundPop.backdropFilter"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="form-item margin-bottom-8" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
:effect="themes"
|
||||
@ -504,6 +531,7 @@ initParams()
|
||||
<el-select
|
||||
v-model="currentPlaceholder"
|
||||
@change="handleCurrentPlaceholder"
|
||||
:effect="themes"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user