diff --git a/core/core-backend/src/main/java/io/dataease/MybatisPlusGenerator.java b/core/core-backend/src/main/java/io/dataease/MybatisPlusGenerator.java index ed819dd4b1..ab90be4089 100644 --- a/core/core-backend/src/main/java/io/dataease/MybatisPlusGenerator.java +++ b/core/core-backend/src/main/java/io/dataease/MybatisPlusGenerator.java @@ -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"; /** * 下面两个配置基本上不用动 diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/YoyChartHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/YoyChartHandler.java index 519ba6afc8..6f64f5b993 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/YoyChartHandler.java +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/YoyChartHandler.java @@ -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 xAxisSortList = view.getXAxis().stream().filter(x -> !StringUtils.equalsIgnoreCase("none", x.getSort())).toList(); // 指标排序 - List yAxisSortList = view.getYAxis().stream().filter(y -> !StringUtils.equalsIgnoreCase("none", y.getSort())).toList(); + List 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)) { // 指标排序仅第一个生效 diff --git a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java index 2cdc8d5578..aff3756164 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java +++ b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewManege.java @@ -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 wrapper = new QueryWrapper<>(); wrapper.eq("scene_id", sceneId); List chartViewDTOS = transChart(coreChartViewMapper.selectList(wrapper)); - for (ChartViewDTO dto : chartViewDTOS) { - QueryWrapper wp = new QueryWrapper<>(); - wp.eq("dataset_group_id", dto.getTableId()); - List coreDatasetTableFields = coreDatasetTableFieldMapper.selectList(wp); - dto.setCalParams(Utils.getParams(datasetTableFieldManage.transDTO(coreDatasetTableFields))); + if (!CollectionUtils.isEmpty(chartViewDTOS)) { + List tableIds = chartViewDTOS.stream() + .map(ChartViewDTO::getTableId).distinct() + .toList(); + if (!CollectionUtils.isEmpty(tableIds)) { + QueryWrapper wp = new QueryWrapper<>(); + wp.in("dataset_group_id", tableIds); + List coreDatasetTableFields = coreDatasetTableFieldMapper.selectList(wp); + Map> 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; } diff --git a/core/core-backend/src/main/java/io/dataease/commons/utils/SqlparserUtils.java b/core/core-backend/src/main/java/io/dataease/commons/utils/SqlparserUtils.java index 53b54bc5b8..0dc588fe92 100644 --- a/core/core-backend/src/main/java/io/dataease/commons/utils/SqlparserUtils.java +++ b/core/core-backend/src/main/java/io/dataease/commons/utils/SqlparserUtils.java @@ -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) { diff --git a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetDataManage.java b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetDataManage.java index 69703e730f..aaf5b8b249 100644 --- a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetDataManage.java +++ b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetDataManage.java @@ -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; diff --git a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetGroupManage.java b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetGroupManage.java index 52db3e5c46..1204c6250a 100644 --- a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetGroupManage.java +++ b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetGroupManage.java @@ -222,14 +222,17 @@ public class DatasetGroupManage { } - @XpackInteract(value = "authResourceTree", replace = true) + @XpackInteract(value = "authResourceTree", replace = true, invalid = true) public List tree(BusiNodeRequest request) { QueryWrapper 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 pos = coreDataSetExtMapper.query(queryWrapper); List nodes = new ArrayList<>(); diff --git a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetSQLManage.java b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetSQLManage.java index 520be1882a..ed7cce3aaf 100644 --- a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetSQLManage.java +++ b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetSQLManage.java @@ -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); diff --git a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetTableFieldManage.java b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetTableFieldManage.java index 38a5ff9b91..7831068c0d 100644 --- a/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetTableFieldManage.java +++ b/core/core-backend/src/main/java/io/dataease/dataset/manage/DatasetTableFieldManage.java @@ -279,18 +279,23 @@ public class DatasetTableFieldManage { } public List transDTO(List 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> tokenType = new TypeReference<>() { - }; - List 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> tokenType = new TypeReference<>() { + }; + List calParams = JsonUtil.parseList(ele.getParams(), tokenType); + dto.setParams(calParams); + } + return dto; + }).collect(Collectors.toList()); + }else{ + return new ArrayList<>(); + } + } private CoreDatasetTableField transDTO2Record(DatasetTableFieldDTO dto) { diff --git a/core/core-backend/src/main/java/io/dataease/datasource/manage/DataSourceManage.java b/core/core-backend/src/main/java/io/dataease/datasource/manage/DataSourceManage.java index 648effd623..a5c0a94e14 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/manage/DataSourceManage.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/manage/DataSourceManage.java @@ -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 tree(BusiNodeRequest request) { QueryWrapper 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 nodes = new ArrayList<>(); List pos = dataSourceExtMapper.selectList(queryWrapper); diff --git a/core/core-backend/src/main/java/io/dataease/datasource/manage/DatasourceSyncManage.java b/core/core-backend/src/main/java/io/dataease/datasource/manage/DatasourceSyncManage.java index 9807a444bd..d1096a5cc7 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/manage/DatasourceSyncManage.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/manage/DatasourceSyncManage.java @@ -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 tableFields) throws Exception { ExcelUtils excelUtils = new ExcelUtils(); List 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); } } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/provider/ExcelUtils.java b/core/core-backend/src/main/java/io/dataease/datasource/provider/ExcelUtils.java index f7393748cf..3ae742deb7 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/provider/ExcelUtils.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/provider/ExcelUtils.java @@ -437,6 +437,7 @@ public class ExcelUtils { tableFiled.setFieldType(null); tableFiled.setName(s); tableFiled.setOriginName(s); + tableFiled.setChecked(true); fields.add(tableFiled); } List data = new ArrayList<>(noModelDataListener.getData()); diff --git a/core/core-backend/src/main/java/io/dataease/datasource/provider/H2EngineProvider.java b/core/core-backend/src/main/java/io/dataease/datasource/provider/H2EngineProvider.java index b0c9adedd1..e3e954bedb 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/provider/H2EngineProvider.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/provider/H2EngineProvider.java @@ -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("`, "); } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/provider/MysqlEngineProvider.java b/core/core-backend/src/main/java/io/dataease/datasource/provider/MysqlEngineProvider.java index 5edc98e7d3..588b29a84f 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/provider/MysqlEngineProvider.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/provider/MysqlEngineProvider.java @@ -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 keys = tableFields.stream().filter(TableField::isPrimaryKey).toList(); - List notKeys = tableFields.stream().filter(tableField -> !tableField.isPrimaryKey()).toList(); + List keys = tableFields.stream().filter(tableField -> tableField.isPrimaryKey() && tableField.isChecked()).toList(); + List 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("`, "); } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/server/DatasourceServer.java b/core/core-backend/src/main/java/io/dataease/datasource/server/DatasourceServer.java index ca3eb8bea1..d1b4912d6f 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/server/DatasourceServer.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/server/DatasourceServer.java @@ -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 sourceTables = ExcelUtils.getTables(sourceTableRequest).stream().map(DatasetTableDTO::getTableName).collect(Collectors.toList()); List 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 newTableFields = deepCopy(sheet.getFields()); - newTableFields.sort((o1, o2) -> { - return o1.getName().compareTo(o2.getName()); - }); + List newTableFields = sheet.getFields(); datasourceRequest.setTable(datasetTableDTO.getTableName()); List 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 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 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 newTableFields, List 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 oldFields, List 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; + } } diff --git a/core/core-backend/src/main/java/io/dataease/engine/trans/ExtWhere2Str.java b/core/core-backend/src/main/java/io/dataease/engine/trans/ExtWhere2Str.java index 97e5b31153..015c32b064 100644 --- a/core/core-backend/src/main/java/io/dataease/engine/trans/ExtWhere2Str.java +++ b/core/core-backend/src/main/java/io/dataease/engine/trans/ExtWhere2Str.java @@ -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, "','") + "')"; + } } } } diff --git a/core/core-backend/src/main/java/io/dataease/menu/manage/MenuManage.java b/core/core-backend/src/main/java/io/dataease/menu/manage/MenuManage.java index 28b89b129d..2f0cbaf27f 100644 --- a/core/core-backend/src/main/java/io/dataease/menu/manage/MenuManage.java +++ b/core/core-backend/src/main/java/io/dataease/menu/manage/MenuManage.java @@ -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); } } diff --git a/core/core-backend/src/main/java/io/dataease/msgCenter/MsgCenterServer.java b/core/core-backend/src/main/java/io/dataease/msgCenter/MsgCenterServer.java new file mode 100644 index 0000000000..f05b1b4c5c --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/msgCenter/MsgCenterServer.java @@ -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; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/share/manage/XpackShareManage.java b/core/core-backend/src/main/java/io/dataease/share/manage/XpackShareManage.java index 60aeaf8f32..10f3529f00 100644 --- a/core/core-backend/src/main/java/io/dataease/share/manage/XpackShareManage.java +++ b/core/core-backend/src/main/java/io/dataease/share/manage/XpackShareManage.java @@ -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 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 query(int pageNum, int pageSize, VisualizationWorkbranchQueryRequest request) { IPage poiPage = proxy().querySharePage(pageNum, pageSize, request); List vos = proxy().formatResult(poiPage.getRecords()); diff --git a/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/entity/DataVisualizationInfo.java b/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/entity/DataVisualizationInfo.java index cdfca78b09..67ba543ecd 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/entity/DataVisualizationInfo.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/entity/DataVisualizationInfo.java @@ -5,11 +5,11 @@ import java.io.Serializable; /** *

- * + * 可视化大屏信息表 *

* * @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 + "}"; } } diff --git a/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/entity/VisualizationLinkJumpTargetViewInfo.java b/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/entity/VisualizationLinkJumpTargetViewInfo.java index d011a62394..7a7673a484 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/entity/VisualizationLinkJumpTargetViewInfo.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/entity/VisualizationLinkJumpTargetViewInfo.java @@ -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; /** *

- * + * 跳转目标仪表板图表字段配置表 *

* * @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 + "}"; } } diff --git a/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/mapper/DataVisualizationInfoMapper.java b/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/mapper/DataVisualizationInfoMapper.java index 9b34106a11..890d6f7448 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/mapper/DataVisualizationInfoMapper.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/mapper/DataVisualizationInfoMapper.java @@ -10,7 +10,7 @@ import org.apache.ibatis.annotations.Mapper; *

* * @author fit2cloud - * @since 2024-11-18 + * @since 2024-11-22 */ @Mapper public interface DataVisualizationInfoMapper extends BaseMapper { diff --git a/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/mapper/VisualizationLinkJumpTargetViewInfoMapper.java b/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/mapper/VisualizationLinkJumpTargetViewInfoMapper.java index c4c21b4252..df62b642f8 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/mapper/VisualizationLinkJumpTargetViewInfoMapper.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/dao/auto/mapper/VisualizationLinkJumpTargetViewInfoMapper.java @@ -6,11 +6,11 @@ import org.apache.ibatis.annotations.Mapper; /** *

- * Mapper 接口 + * 跳转目标仪表板图表字段配置表 Mapper 接口 *

* * @author fit2cloud - * @since 2023-09-22 + * @since 2024-11-20 */ @Mapper public interface VisualizationLinkJumpTargetViewInfoMapper extends BaseMapper { diff --git a/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtVisualizationLinkJumpMapper.java b/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtVisualizationLinkJumpMapper.java index e28e305771..cfb906119a 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtVisualizationLinkJumpMapper.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtVisualizationLinkJumpMapper.java @@ -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 findLinkJumpWithDvId(@Param("dvId")Long dvId); + List findLinkJumpInfoWithDvId(@Param("dvId")Long dvId); + List getViewTableDetails(@Param("dvId")Long dvId); + + List queryOutParamsTargetWithDvId(@Param("dvId")Long dvId); } diff --git a/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtVisualizationOuterParamsMapper.java b/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtVisualizationOuterParamsMapper.java index abe21e2657..32b85f99eb 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtVisualizationOuterParamsMapper.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtVisualizationOuterParamsMapper.java @@ -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 getVisualizationOuterParamsInfo(@Param("visualizationId") String visualizationId); + List getVisualizationOuterParamsInfoBase(@Param("visualizationId") String visualizationId); + List queryDsWithVisualizationId(@Param("visualizationId") String visualizationId); } diff --git a/core/core-backend/src/main/java/io/dataease/visualization/manage/CoreVisualizationManage.java b/core/core-backend/src/main/java/io/dataease/visualization/manage/CoreVisualizationManage.java index ff95c68ec8..08749ef3b0 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/manage/CoreVisualizationManage.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/manage/CoreVisualizationManage.java @@ -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 tree(BusiNodeRequest request) { List 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 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 query(int pageNum, int pageSize, VisualizationWorkbranchQueryRequest request) { IPage 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 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 page = new Page<>(goPage, pageSize); return extDataVisualizationMapper.findRecent(page, uid, queryWrapper); diff --git a/core/core-backend/src/main/java/io/dataease/visualization/manage/VisualizationStoreManage.java b/core/core-backend/src/main/java/io/dataease/visualization/manage/VisualizationStoreManage.java index 23993efc0e..6af3bf242a 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/manage/VisualizationStoreManage.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/manage/VisualizationStoreManage.java @@ -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 query(int pageNum, int pageSize, VisualizationWorkbranchQueryRequest request) { IPage 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 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 page = new Page<>(goPage, pageSize); return coreStoreExtMapper.query(page, queryWrapper); diff --git a/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java b/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java index 2e26522b8f..0d15cef9f1 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java @@ -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 { diff --git a/core/core-backend/src/main/java/io/dataease/visualization/server/VisualizationLinkJumpService.java b/core/core-backend/src/main/java/io/dataease/visualization/server/VisualizationLinkJumpService.java index ecd35afbfb..c5caa5c3a9 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/server/VisualizationLinkJumpService.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/server/VisualizationLinkJumpService.java @@ -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 result; + List 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); } diff --git a/core/core-backend/src/main/java/io/dataease/visualization/server/VisualizationOuterParamsService.java b/core/core-backend/src/main/java/io/dataease/visualization/server/VisualizationOuterParamsService.java index b3f4bdf018..ffdf7add03 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/server/VisualizationOuterParamsService.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/server/VisualizationOuterParamsService.java @@ -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 paramsInfoNameIdMap = new HashMap<>(); + List 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 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); diff --git a/core/core-backend/src/main/resources/db/desktop/V2.10.3__ddl.sql b/core/core-backend/src/main/resources/db/desktop/V2.10.3__ddl.sql index 64bffd3f86..e8570bb31b 100644 --- a/core/core-backend/src/main/resources/db/desktop/V2.10.3__ddl.sql +++ b/core/core-backend/src/main/resources/db/desktop/V2.10.3__ddl.sql @@ -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 '内容标识'; \ No newline at end of file + 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'; \ No newline at end of file diff --git a/core/core-backend/src/main/resources/db/migration/V2.10.3__ddl.sql b/core/core-backend/src/main/resources/db/migration/V2.10.3__ddl.sql index 74e4c91f76..b912d2baff 100644 --- a/core/core-backend/src/main/resources/db/migration/V2.10.3__ddl.sql +++ b/core/core-backend/src/main/resources/db/migration/V2.10.3__ddl.sql @@ -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'; \ No newline at end of file diff --git a/core/core-backend/src/main/resources/i18n/core_en_US.properties b/core/core-backend/src/main/resources/i18n/core_en_US.properties index 088c0e13d7..c3e65682d8 100644 --- a/core/core-backend/src/main/resources/i18n/core_en_US.properties +++ b/core/core-backend/src/main/resources/i18n/core_en_US.properties @@ -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 diff --git a/core/core-backend/src/main/resources/i18n/core_zh_CN.properties b/core/core-backend/src/main/resources/i18n/core_zh_CN.properties index 91c260a425..8eec27e3a4 100644 --- a/core/core-backend/src/main/resources/i18n/core_zh_CN.properties +++ b/core/core-backend/src/main/resources/i18n/core_zh_CN.properties @@ -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 diff --git a/core/core-backend/src/main/resources/i18n/core_zh_TW.properties b/core/core-backend/src/main/resources/i18n/core_zh_TW.properties index fb41f15197..af514bbe63 100644 --- a/core/core-backend/src/main/resources/i18n/core_zh_TW.properties +++ b/core/core-backend/src/main/resources/i18n/core_zh_TW.properties @@ -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 diff --git a/core/core-backend/src/main/resources/mybatis/ExtDataVisualizationMapper.xml b/core/core-backend/src/main/resources/mybatis/ExtDataVisualizationMapper.xml index 793a8539d4..d3a5415ede 100644 --- a/core/core-backend/src/main/resources/mybatis/ExtDataVisualizationMapper.xml +++ b/core/core-backend/src/main/resources/mybatis/ExtDataVisualizationMapper.xml @@ -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} diff --git a/core/core-backend/src/main/resources/mybatis/ExtVisualizationLinkJumpMapper.xml b/core/core-backend/src/main/resources/mybatis/ExtVisualizationLinkJumpMapper.xml index acfa2d8f7a..0413c7dde2 100644 --- a/core/core-backend/src/main/resources/mybatis/ExtVisualizationLinkJumpMapper.xml +++ b/core/core-backend/src/main/resources/mybatis/ExtVisualizationLinkJumpMapper.xml @@ -43,9 +43,12 @@ + + + @@ -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} + + DELETE ljtv diff --git a/core/core-backend/src/main/resources/mybatis/ExtVisualizationOuterParamsMapper.xml b/core/core-backend/src/main/resources/mybatis/ExtVisualizationOuterParamsMapper.xml index 9e8361b763..3136e80801 100644 --- a/core/core-backend/src/main/resources/mybatis/ExtVisualizationOuterParamsMapper.xml +++ b/core/core-backend/src/main/resources/mybatis/ExtVisualizationOuterParamsMapper.xml @@ -139,6 +139,17 @@ and popi.checked=1 + + diff --git a/core/core-frontend/src/layout/components/MenuItem.vue b/core/core-frontend/src/layout/components/MenuItem.vue index 7bb05254ce..6c8e33e190 100644 --- a/core/core-frontend/src/layout/components/MenuItem.vue +++ b/core/core-frontend/src/layout/components/MenuItem.vue @@ -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, diff --git a/core/core-frontend/src/layout/components/ToolboxCfg.vue b/core/core-frontend/src/layout/components/ToolboxCfg.vue index e31ca8dec5..633faac003 100644 --- a/core/core-frontend/src/layout/components/ToolboxCfg.vue +++ b/core/core-frontend/src/layout/components/ToolboxCfg.vue @@ -83,9 +83,8 @@ onMounted(() => { diff --git a/core/core-frontend/src/layout/components/TopDocCard.vue b/core/core-frontend/src/layout/components/TopDocCard.vue index 0e4797b747..41211ac028 100644 --- a/core/core-frontend/src/layout/components/TopDocCard.vue +++ b/core/core-frontend/src/layout/components/TopDocCard.vue @@ -27,33 +27,28 @@ const openBlank = () => { diff --git a/core/core-frontend/src/views/chart/components/editor/editor-style/VQueryChartStyle.vue b/core/core-frontend/src/views/chart/components/editor/editor-style/VQueryChartStyle.vue index e6641a4ed9..b876469ab4 100644 --- a/core/core-frontend/src/views/chart/components/editor/editor-style/VQueryChartStyle.vue +++ b/core/core-frontend/src/views/chart/components/editor/editor-style/VQueryChartStyle.vue @@ -297,6 +297,33 @@ initParams() :predefine="COLOR_PANEL" /> + + + + {{ $t('chart.backdrop_blur') }} + + + + + + { v-model="state.basicStyleForm.areaBorderColor" :effect="themes" is-custom + show-alpha :trigger-width="108" class="color-picker-style" :predefine="predefineColors" @@ -725,6 +726,7 @@ onMounted(() => { :persistent="false" v-model="state.basicStyleForm.areaBaseColor" is-custom + show-alpha :effect="themes" :trigger-width="108" class="color-picker-style" @@ -1051,6 +1053,42 @@ onMounted(() => { @blur="changeBasicStyle('summaryLabel')" /> + + + + {{ t('chart.table_auto_break_line') }} + + + + + + + + + + + + { controls-position="right" v-model="state.tableCellForm.tableItemHeight" :min="20" - :max="100" + :max="1000" @change="changeTableCell('tableItemHeight')" /> @@ -353,7 +353,7 @@ onMounted(() => { { {{ t('chart.merge_cells') }} diff --git a/core/core-frontend/src/views/chart/components/editor/util/chart.ts b/core/core-frontend/src/views/chart/components/editor/util/chart.ts index 35cc74eac1..28d1f9a69e 100644 --- a/core/core-frontend/src/views/chart/components/editor/util/chart.ts +++ b/core/core-frontend/src/views/chart/components/editor/util/chart.ts @@ -761,7 +761,8 @@ export const DEFAULT_THRESHOLD: ChartThreshold = { liquidThreshold: '', labelThreshold: [], tableThreshold: [], - textLabelThreshold: [] + textLabelThreshold: [], + lineLabelThreshold: [] } export const DEFAULT_SCROLL: ScrollCfg = { open: false, @@ -1604,7 +1605,9 @@ export const DEFAULT_BASIC_STYLE: ChartBasicStyle = { }, zoomLevel: 7, customIcon: '', - showHoverStyle: true + showHoverStyle: true, + autoWrap: false, + maxLines: 3 } export const BASE_VIEW_CONFIG = { diff --git a/core/core-frontend/src/views/chart/components/editor/util/dataVisualization.ts b/core/core-frontend/src/views/chart/components/editor/util/dataVisualization.ts index 69ab686328..379ae9d550 100644 --- a/core/core-frontend/src/views/chart/components/editor/util/dataVisualization.ts +++ b/core/core-frontend/src/views/chart/components/editor/util/dataVisualization.ts @@ -102,7 +102,8 @@ export const DEFAULT_CANVAS_STYLE_DATA_BASE = { background: '', openCommonStyle: true, opacity: 1, // 废弃 - fontSize: 14 + fontSize: 14, + fontFamily: 'PingFang' //字体设置 默认PingFang } // 基础亮色主题 diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/line/area.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/line/area.ts index 835b151151..18c155090c 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/line/area.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/line/area.ts @@ -13,6 +13,8 @@ import { import { cloneDeep } from 'lodash-es' import { flow, + getLineConditions, + getLineLabelColorByCondition, hexColorToRGBA, parseJson, setUpStackSeriesColor @@ -135,6 +137,7 @@ export class Area extends G2PlotChartView { } } const { label: labelAttr, basicStyle } = parseJson(chart.customAttr) + const conditions = getLineConditions(chart) const formatterMap = labelAttr.seriesLabelFormatter?.reduce((pre, next) => { pre[next.id] = next return pre @@ -163,6 +166,9 @@ export class Area extends G2PlotChartView { ? -2 - basicStyle.lineSymbolSize : 10 + basicStyle.lineSymbolSize const value = valueFormatter(data.value, labelCfg.formatterCfg) + const color = + getLineLabelColorByCondition(conditions, data.value, data.quotaList[0].id) || + labelCfg.color const group = new Group({}) group.addShape({ type: 'text', @@ -173,7 +179,7 @@ export class Area extends G2PlotChartView { textAlign: 'start', textBaseline: 'top', fontSize: labelCfg.fontSize, - fill: labelCfg.color + fill: color } }) return group @@ -281,7 +287,8 @@ export class Area extends G2PlotChartView { this.configXAxis, this.configYAxis, this.configSlider, - this.configAnalyse + this.configAnalyse, + this.configConditions )(chart, options, {}, this) } @@ -310,6 +317,7 @@ export class StackArea extends Area { } protected configLabel(chart: Chart, options: AreaOptions): AreaOptions { const { label: labelAttr, basicStyle } = parseJson(chart.customAttr) + const conditions = getLineConditions(chart) if (!labelAttr?.show) { return { ...options, @@ -333,7 +341,10 @@ export class StackArea extends Area { fill: labelAttr.color, fontSize: labelAttr.fontSize }, - formatter: function (param: Datum) { + formatter: function (param: Datum, point) { + point.color = + getLineLabelColorByCondition(conditions, param.value, point._origin.quotaList[0]) || + labelAttr.color return valueFormatter(param.value, labelAttr.labelFormatter) } } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/line/common.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/line/common.ts index 7d88df7f9e..ffc424174c 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/line/common.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/line/common.ts @@ -11,7 +11,8 @@ export const LINE_EDITOR_PROPERTY: EditorProperty[] = [ 'assist-line', 'function-cfg', 'jump-set', - 'linkage' + 'linkage', + 'threshold' ] export const LINE_EDITOR_PROPERTY_INNER: EditorPropertyInner = { 'background-overall-component': ['all'], @@ -59,7 +60,8 @@ export const LINE_EDITOR_PROPERTY_INNER: EditorPropertyInner = { 'fontShadow' ], 'legend-selector': ['icon', 'orient', 'fontSize', 'color', 'hPosition', 'vPosition'], - 'function-cfg': ['slider', 'emptyDataStrategy'] + 'function-cfg': ['slider', 'emptyDataStrategy'], + threshold: ['lineThreshold'] } export const LINE_AXIS_TYPE: AxisType[] = [ diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/line/line.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/line/line.ts index 92015890aa..5f30f318a2 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/line/line.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/line/line.ts @@ -11,6 +11,8 @@ import { } from '../../common/common_antv' import { flow, + getLineConditions, + getLineLabelColorByCondition, hexColorToRGBA, parseJson, setUpGroupSeriesColor @@ -134,6 +136,7 @@ export class Line extends G2PlotChartView { } } const { label: labelAttr, basicStyle } = parseJson(chart.customAttr) + const conditions = getLineConditions(chart) const formatterMap = labelAttr.seriesLabelFormatter?.reduce((pre, next) => { pre[next.id] = next return pre @@ -162,6 +165,9 @@ export class Line extends G2PlotChartView { ? -2 - basicStyle.lineSymbolSize : 10 + basicStyle.lineSymbolSize const value = valueFormatter(data.value, labelCfg.formatterCfg) + const color = + getLineLabelColorByCondition(conditions, data.value, data.quotaList[0].id) || + labelCfg.color const group = new Group({}) group.addShape({ type: 'text', @@ -172,7 +178,7 @@ export class Line extends G2PlotChartView { textAlign: 'start', textBaseline: 'top', fontSize: labelCfg.fontSize, - fill: labelCfg.color + fill: color } }) return group @@ -358,7 +364,8 @@ export class Line extends G2PlotChartView { this.configXAxis, this.configYAxis, this.configSlider, - this.configAnalyse + this.configAnalyse, + this.configConditions )(chart, options) } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/map/bubble-map.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/map/bubble-map.ts index 4d17ae08f5..7542b16ea7 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/map/bubble-map.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/map/bubble-map.ts @@ -220,7 +220,7 @@ export class BubbleMap extends L7PlotChartView { const senior = parseJson(chart.senior) const curAreaNameMapping = senior.areaMapping?.[areaId] handleGeoJson(geoJson, curAreaNameMapping) - options.color = hexColorToRGBA(basicStyle.areaBaseColor, basicStyle.alpha) + options.color = basicStyle.areaBaseColor if (!chart.data?.data?.length || !geoJson?.features?.length) { options.label && (options.label.field = 'name') return options diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/map/map.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/map/map.ts index b67ec32794..3f27def1da 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/map/map.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/map/map.ts @@ -334,7 +334,8 @@ export class Map extends L7PlotChartView { } } } - if (!misc.mapAutoLegend && misc.mapLegendRangeType === 'custom') { + // 不是自动图例、自定义图例区间、不是下钻时 + if (!misc.mapAutoLegend && misc.mapLegendRangeType === 'custom' && !chart.drill) { // 获取图例区间数据 const items = [] // 区间数组 @@ -342,10 +343,10 @@ export class Map extends L7PlotChartView { .slice(0, -1) .map((item, index) => [item, misc.mapLegendCustomRange[index + 1]]) ranges.forEach((range, index) => { - const tmpRange = [range[0]?.toFixed(0), range[1]?.toFixed(0)] + const tmpRange = [range[0], range[1]] const colorIndex = index % colors.length // 当区间第一个值小于最小值时,颜色取地图底色 - const isLessThanMin = range[0] < ranges[0][0] + const isLessThanMin = range[0] < ranges[0][0] && range[1] < ranges[0][0] let rangeColor = colors[colorIndex] if (isLessThanMin) { rangeColor = hexColorToRGBA(basicStyle.areaBaseColor, basicStyle.alpha) @@ -361,6 +362,11 @@ export class Map extends L7PlotChartView { } return '' } + options.color['value'] = ({ value }) => { + const item = items.find(item => value >= item.value[0] && value <= item.value[1]) + return item ? item.color : hexColorToRGBA(basicStyle.areaBaseColor, basicStyle.alpha) + } + options.color.scale.domain = [ranges[0][0], ranges[ranges.length - 1][1]] } else { customLegend['customContent'] = (_: string, items: CategoryLegendListItem[]) => { const showItems = items?.length > 30 ? items.slice(0, 30) : items @@ -370,6 +376,12 @@ export class Map extends L7PlotChartView { return '' } } + // 下钻时按照数据值计算图例 + if (chart.drill) { + getMaxAndMinValueByData(options.source.data, 'value', 0, 0, (max, min) => { + options.color.scale.domain = [min, max] + }) + } defaultsDeep(options, { legend: customLegend }) return options } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/map/symbolic-map.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/map/symbolic-map.ts index a3be048dc5..221f27fd33 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/map/symbolic-map.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/map/symbolic-map.ts @@ -106,6 +106,18 @@ export class SymbolicMap extends L7ChartView { if (basicStyle.autoFit === false) { center = [basicStyle.mapCenter.longitude, basicStyle.mapCenter.latitude] } + // 联动时,聚焦到数据点,多个取第一个 + if ( + chart.chartExtRequest?.linkageFilters?.length && + xAxis?.length === 2 && + chart.data?.tableRow.length + ) { + // 经度 + const lng = chart.data?.tableRow?.[0][chart.xAxis[0].dataeaseName] + // 纬度 + const lat = chart.data?.tableRow?.[0][chart.xAxis[1].dataeaseName] + center = [lng, lat] + } const chartObj = drawOption.chartObj as unknown as L7Wrapper let scene = chartObj?.getScene() if (!scene) { diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/others/gauge.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/others/gauge.ts index ec6f35f207..d3a8b1e002 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/others/gauge.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/others/gauge.ts @@ -276,7 +276,10 @@ export class Gauge extends G2PlotChartView { return '' } if (gaugePercentLabel === false) { - return v === '0' ? min : v === '1' ? max : min + (max - min) * v + const resultV = v === '0' ? min : v === '1' ? max : min + (max - min) * v + return labelFormatter.type === 'value' + ? valueFormatter(resultV, labelFormatter) + : resultV } return v === '0' ? v : v * 100 + '%' } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-info.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-info.ts index 025052c7b6..043f127649 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-info.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-info.ts @@ -5,7 +5,6 @@ import { S2Options, S2Theme, TableColCell, - TableDataCell, TableSheet, ViewMeta } from '@antv/s2' @@ -18,7 +17,9 @@ import { isNumber, merge } from 'lodash-es' import { copyContent, CustomDataCell, + CustomTableColCell, getRowIndex, + calculateHeaderHeight, SortTooltip } from '@/views/chart/components/js/panel/common/common_table' @@ -66,7 +67,8 @@ export class TableInfo extends S2ChartView { 'tableScrollBarColor', 'alpha', 'tablePageMode', - 'showHoverStyle' + 'showHoverStyle', + 'autoWrap' ], 'table-cell-selector': [ ...TABLE_EDITOR_PROPERTY_INNER['table-cell-selector'], @@ -205,6 +207,9 @@ export class TableInfo extends S2ChartView { pageInfo.pageSize * (pageInfo.currentPage - 1) + viewMeta.rowIndex + 1 } } + // 配置文本自动换行参数 + viewMeta.autoWrap = basicStyle.autoWrap + viewMeta.maxLines = basicStyle.maxLines return new CustomDataCell(viewMeta, viewMeta?.spreadsheet) } // tooltip @@ -228,10 +233,40 @@ export class TableInfo extends S2ChartView { // header interaction chart.container = container this.configHeaderInteraction(chart, s2Options) + s2Options.colCell = (node, sheet, config) => { + // 配置文本自动换行参数 + node.autoWrap = basicStyle.autoWrap + node.maxLines = basicStyle.maxLines + return new CustomTableColCell(node, sheet, config) + } } // 开始渲染 const newChart = new TableSheet(containerDom, s2DataConfig, s2Options) - + // 开启自动换行 + if (basicStyle.autoWrap) { + // 调整表头宽度时,计算表头高度 + newChart.on(S2Event.LAYOUT_RESIZE_COL_WIDTH, info => { + calculateHeaderHeight(info, newChart, tableHeader, basicStyle, null) + }) + newChart.on(S2Event.LAYOUT_AFTER_HEADER_LAYOUT, (ev: LayoutResult) => { + const maxHeight = newChart.store.get('autoCalcHeight') as number + if (maxHeight) { + // 更新列的高度 + ev.colLeafNodes.forEach(n => (n.height = maxHeight)) + ev.colsHierarchy.height = maxHeight + newChart.store.set('autoCalcHeight', undefined) + } else { + const { value, width } = ev.colLeafNodes[0] + calculateHeaderHeight( + { info: { meta: { value }, resizedWidth: width } }, + newChart, + tableHeader, + basicStyle, + ev + ) + } + }) + } // 自适应铺满 if (basicStyle.tableColumnMode === 'adapt') { newChart.on(S2Event.LAYOUT_RESIZE_COL_WIDTH, () => { diff --git a/core/core-frontend/src/views/chart/components/js/panel/common/common_antv.ts b/core/core-frontend/src/views/chart/components/js/panel/common/common_antv.ts index 674cecf6da..63543558bf 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/common/common_antv.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/common/common_antv.ts @@ -1,4 +1,4 @@ -import { hexColorToRGBA, parseJson } from '../../util' +import { hexColorToRGBA, isAlphaColor, isTransparent, parseJson } from '../../util' import { DEFAULT_BASIC_STYLE, DEFAULT_XAXIS_STYLE, @@ -172,6 +172,7 @@ export function getLabel(chart: Chart) { 'bar' ].includes(chart.type) ) { + layout.push({ type: 'limit-in-canvas' }) layout.push({ type: 'hide-overlap' }) } else { layout.push({ type: 'limit-in-plot' }) @@ -1328,3 +1329,56 @@ export const TOOLTIP_TPL = '{name}:' + '{value}' + '' + +export function getConditions(chart: Chart) { + const { threshold } = parseJson(chart.senior) + const annotations = [] + if (!threshold.enable) return annotations + const conditions = threshold.lineThreshold ?? [] + const yAxisIds = chart.yAxis.map(i => i.id) + for (const field of conditions) { + if (!yAxisIds.includes(field.fieldId)) { + continue + } + for (const t of field.conditions) { + if ([2, 3, 4].includes(field.field.deType)) { + const annotation = { + type: 'regionFilter', + start: ['start', 'median'], + end: ['end', 'min'], + color: t.color + } + // 加中线 + const annotationLine = { + type: 'line', + start: ['start', t.value], + end: ['end', t.value], + style: { + stroke: t.color, + lineDash: [2, 2] + } + } + if (t.term === 'between') { + annotation.start = ['start', parseFloat(t.min)] + annotation.end = ['end', parseFloat(t.max)] + annotationLine.start = ['start', parseFloat(t.min)] + annotationLine.end = ['end', parseFloat(t.min)] + annotations.push(JSON.parse(JSON.stringify(annotationLine))) + annotationLine.start = ['start', parseFloat(t.max)] + annotationLine.end = ['end', parseFloat(t.max)] + annotations.push(annotationLine) + } else if (['lt', 'le'].includes(t.term)) { + annotation.start = ['start', t.value] + annotation.end = ['end', 'min'] + annotations.push(annotationLine) + } else if (['gt', 'ge'].includes(t.term)) { + annotation.start = ['start', t.value] + annotation.end = ['end', 'max'] + annotations.push(annotationLine) + } + annotations.push(annotation) + } + } + } + return annotations +} diff --git a/core/core-frontend/src/views/chart/components/js/panel/common/common_table.ts b/core/core-frontend/src/views/chart/components/js/panel/common/common_table.ts index d69efad3d7..d11b58fb69 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/common/common_table.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/common/common_table.ts @@ -14,31 +14,34 @@ import { } from '@/views/chart/components/editor/util/chart' import { BaseTooltip, - getAutoAdjustPosition, - getTooltipDefaultOptions, - S2Theme, - setTooltipContainerStyle, - Style, - S2Options, - SERIES_NUMBER_FIELD, - type PivotSheet, - type Node, - type Meta, - S2DataConfig, - SpreadSheet, - InteractionStateName, - InteractionName, DataCellBrushSelection, - TableDataCell, - MergedCell, + getAutoAdjustPosition, + getEmptyPlaceholder, getPolygonPoints, - renderPolygon, + getTooltipDefaultOptions, + InteractionName, + InteractionStateName, + MergedCell, MergedCellInfo, - ViewMeta, + type Meta, + type Node, + type PivotSheet, + renderPolygon, + renderText, + S2DataConfig, + S2Options, + S2Theme, + SERIES_NUMBER_FIELD, + setTooltipContainerStyle, + SHAPE_STYLE_MAP, + SpreadSheet, + Style, + TableColCell, + TableDataCell, updateShapeAttr, - SHAPE_STYLE_MAP + ViewMeta } from '@antv/s2' -import { keys, intersection, filter, cloneDeep, merge, find, repeat } from 'lodash-es' +import { cloneDeep, filter, find, intersection, keys, merge, repeat } from 'lodash-es' import { createVNode, render } from 'vue' import TableTooltip from '@/views/chart/components/editor/common/TableTooltip.vue' import Exceljs from 'exceljs' @@ -1557,4 +1560,191 @@ export class CustomDataCell extends TableDataCell { updateShapeAttr(shape, SHAPE_STYLE_MAP.borderColor, 'transparent') }) } + + /** + * 重写绘制文本内容的方法 + * @protected + */ + protected drawTextShape() { + if (this.meta.autoWrap) { + drawTextShape(this, false) + } else { + super.drawTextShape() + } + } +} + +export class CustomTableColCell extends TableColCell { + + /** + * 重写是为了表头文本内容的换行 + * @protected + */ + protected drawTextShape() { + if (this.meta.autoWrap) { + drawTextShape(this, true) + } else { + super.drawTextShape() + } + } +} + +/** + * 绘制文本 换行 + * @param cell + * @param isHeader + */ +const drawTextShape = (cell, isHeader) => { + // 换行符 + const lineBreak = '\n' + // 省略号 + const ellipsis = '...' + // 用户配置的最大行数 + const maxLines = cell.meta.maxLines ?? 1 + const { + options: { placeholder }, + } = cell.spreadsheet; + const emptyPlaceholder = getEmptyPlaceholder(this, placeholder); + // 单元格文本 + const { formattedValue } = cell.getFormattedFieldValue() + // 获取文本样式 + const textStyle = cell.getTextStyle() + // 宽度能放几个字符,就放几个,放不下就换行 + let wrapText = getWrapText(formattedValue ? formattedValue?.toString() : emptyPlaceholder, textStyle, cell.meta.width, cell.spreadsheet) + const lines = wrapText.split(lineBreak) + + // 不是表头,处理文本高度和换行 + if (!isHeader) { + const textHeight = getWrapTextHeight(wrapText.replaceAll(lineBreak, ''), textStyle, cell.spreadsheet, maxLines) + const lineCountInCell = Math.floor(cell.meta.height / textHeight) + const wrapTextArr = lines.slice(0, lineCountInCell) + + // 根据行数调整换行后的文本内容 + wrapText = lineCountInCell === 1 + ? lines[0].slice(0, -1) + ellipsis + : wrapTextArr.join(lineBreak) || ellipsis + const resultWrapArr = wrapText.split(lineBreak) + // 控制最大行数 + if ( !wrapText.endsWith(ellipsis) && (lines.length > maxLines || lines.length > lineCountInCell)) { + // 第一行的字符个数 + const firstLineStrNumber = resultWrapArr[0].length + const temp = resultWrapArr.slice(0, Math.min(maxLines, lineCountInCell)) + // 修改最后一行的字符,按照第一行字符个数-1,修改最后一行的字符为... + temp[temp.length - 1] = temp[temp.length-1].slice(0,firstLineStrNumber - 1) + ellipsis + wrapText = temp.join(lineBreak) + } + } else { + const resultWrapArr = wrapText.split(lineBreak) + // 控制最大行数 + if (lines.length > maxLines) { + const temp = resultWrapArr.slice(0, maxLines) + // 第一行的字符个数 + const firstLineStrNumber = resultWrapArr[0].length + // 修改最后一行的字符 + temp[temp.length - 1] = temp[temp.length-1].slice(0,firstLineStrNumber - 1) + ellipsis + wrapText = temp.join(lineBreak) + } + } + // 设置最终文本和其宽度 + cell.actualText = wrapText + cell.actualTextWidth = cell.spreadsheet.measureTextWidth(wrapText, textStyle) + + // 获取文本位置并渲染文本 + const position = cell.getTextPosition() + // 绘制文本 + cell.textShape = renderText(cell, [cell.textShape], position.x, position.y, wrapText, textStyle) + + // 将文本形状添加到形状数组 + cell.textShapes.push(cell.textShape) +} + +/** + * 计算表头高度 + * @param info 单元格信息 + * @param newChart + * @param tableHeader 表头配置 + * @param basicStyle 表格基础样式 + * @param layoutResult + */ +export const calculateHeaderHeight = (info, newChart, tableHeader, basicStyle, layoutResult) => { + const ev = layoutResult || newChart.facet.layoutResult + const maxLines = basicStyle.maxLines ?? 1 + const textStyle = { ...newChart.theme.cornerCell.text } + const sourceText = info.info.meta.value + let maxHeight = getWrapTextHeight(getWrapText(sourceText, textStyle, info.info.resizedWidth, ev.spreadsheet), textStyle, ev.spreadsheet, maxLines) + + // 获取最大高度的列,排除当前列 + const maxHeightCol = ev.colLeafNodes.filter(n => n.colIndex !== info.info.meta.colIndex) + .reduce((maxHeightNode, currentNode) => { + const wrapTextHeight = getWrapTextHeight(getWrapText(currentNode.value, textStyle, currentNode.width, currentNode.spreadsheet), textStyle, currentNode.spreadsheet, maxLines) + return wrapTextHeight > maxHeightNode.height + ? { height: wrapTextHeight, colIndex: currentNode.colIndex } + : maxHeightNode + }, { height: 0 }) + + // 使用最大高度 + maxHeight = Math.max(maxHeight, maxHeightCol.height) + textStyle.fontSize + 10.5 + + if (layoutResult) { + if (basicStyle.tableColumnMode === 'adapt') maxHeight -= textStyle.fontSize - 2 + ev.colLeafNodes.forEach(n => n.height = maxHeight) + ev.colsHierarchy.height = maxHeight + } + + newChart.store.set('autoCalcHeight', maxHeight) +} + +/** + * 获取换行文本 + * 累加字符串单个字符的宽度,超过单元格宽度时,添加换行 + * @param sourceText + * @param textStyle + * @param cellWidth + * @param spreadsheet + */ +const getWrapText = (sourceText, textStyle, cellWidth, spreadsheet) => { + if (!sourceText && sourceText !== 0) return '' + sourceText = sourceText.toString().trim() + const getTextWidth = text => spreadsheet.measureTextWidthRoughly(text, textStyle) + + let resultWrapText = '' + let restText = '' + let restTextWidth = 10 + for (let i = 0; i < sourceText.length; i++) { + const char = sourceText[i] + const charWidth = getTextWidth(char) + restTextWidth += charWidth + restText += char + // 中文时,需要单元格宽度减去16个文字宽度,否则会超出单元格宽度 + const cWidth = char.charCodeAt(0) >= 128 ? 16 : 10 + // 添加换行 + if (restTextWidth >= cellWidth - textStyle.fontSize - cWidth) { + // 最后一个字符不添加换行符 + resultWrapText += restText + (i !== sourceText.length - 1 ? '\n' : '') + restText = '' + restTextWidth = 10 + } + } + + resultWrapText += restText + return resultWrapText +} +/** + * 计算文本行高 + * @param wrapText + * @param textStyle + * @param spreadsheet + * @param maxLines 最大行数 + */ +const getWrapTextHeight = (wrapText, textStyle, spreadsheet, maxLines) => { + // 行内最高 + let maxHeight = 0 + // 获取最高字符的高度 + for (const char of wrapText) { + const h = textStyle.fontSize / (char.charCodeAt(0) >= 128 ? 5 : 2.5) + maxHeight = Math.max(maxHeight, spreadsheet.measureTextHeight(char, textStyle) + h) + } + // 行数 + const lines = wrapText.split('\n').length + return Math.min(lines, maxLines) * maxHeight } diff --git a/core/core-frontend/src/views/chart/components/js/panel/types/impl/g2plot.ts b/core/core-frontend/src/views/chart/components/js/panel/types/impl/g2plot.ts index 4e9aa3f752..964f96dbcd 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/types/impl/g2plot.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/types/impl/g2plot.ts @@ -10,7 +10,8 @@ import { getTheme, getTooltip, getXAxis, - getYAxis + getYAxis, + getConditions } from '@/views/chart/components/js/panel/common/common_antv' import { AntVAbstractChartView, @@ -171,6 +172,14 @@ export abstract class G2PlotChartView< return undefined } + protected configConditions(chart: Chart, options: O) { + const annotations = getConditions(chart) + return { + ...options, + annotations: [...annotations, ...((options as unknown as Options).annotations || [])] + } + } + /** * 流式配置公共参数,处理常用的配置,后续如果有其他通用配置也可以放进来,需要单独配置的属性在各个图表自行实现。 * @param chart 数据库图表对象。 diff --git a/core/core-frontend/src/views/chart/components/js/util.ts b/core/core-frontend/src/views/chart/components/js/util.ts index 887d7bb211..380c686828 100644 --- a/core/core-frontend/src/views/chart/components/js/util.ts +++ b/core/core-frontend/src/views/chart/components/js/util.ts @@ -1071,3 +1071,51 @@ export function filterEmptyMinValue(sourceData, field) { ) return notEmptyMinValue } + +/** + * 获取折线条件样式 + * @param chart + */ +export function getLineConditions(chart) { + const { threshold } = parseJson(chart.senior) + const conditions = [] + if (threshold.enable) { + threshold.lineThreshold?.forEach(item => + item.conditions?.forEach(c => + conditions.push({ + fieldId: item.fieldId, + term: c.term, + value: c.value, + color: c.color, + min: c.min, + max: c.max + }) + ) + ) + } + return conditions +} + +/** + * 根据折线阈值条件获取新的标签颜色 + * @param conditions + * @param value + * @param fieldId + */ +export function getLineLabelColorByCondition(conditions, value, fieldId) { + const fieldConditions = conditions.filter(item => item.fieldId === fieldId) + let color = undefined + if (fieldConditions.length) { + fieldConditions.some(item => { + if ( + (item.term === 'lt' && value <= item.value) || + (item.term === 'gt' && value >= item.value) || + (item.term === 'between' && value >= item.min && value <= item.max) + ) { + color = item.color + return true + } + }) + } + return color +} diff --git a/core/core-frontend/src/views/chart/components/views/components/ChartComponentG2Plot.vue b/core/core-frontend/src/views/chart/components/views/components/ChartComponentG2Plot.vue index 35174072d9..e8c60059f8 100644 --- a/core/core-frontend/src/views/chart/components/views/components/ChartComponentG2Plot.vue +++ b/core/core-frontend/src/views/chart/components/views/components/ChartComponentG2Plot.vue @@ -68,6 +68,11 @@ const props = defineProps({ type: String, required: false, default: 'common' + }, + fontFamily: { + type: String, + required: false, + default: 'inherit' } }) @@ -568,6 +573,7 @@ onBeforeUnmount(() => { { { // 内部仪表板跳转 if (jumpInfo.linkType === 'inner') { if (jumpInfo.targetDvId) { + const filterOuterParams = {} + const curFilter = dvMainStore.getLastViewRequestInfo(param.viewId) + const targetViewInfoList = jumpInfo.targetViewInfoList + if ( + curFilter && + curFilter.filter && + curFilter.filter.length > 0 && + targetViewInfoList && + targetViewInfoList.length > 0 + ) { + // do filter + curFilter.filter.forEach(filterItem => { + targetViewInfoList.forEach(targetViewInfo => { + if (targetViewInfo.sourceFieldActiveId === filterItem.filterId) { + filterOuterParams[targetViewInfo.outerParamsName] = filterItem.value + } + }) + }) + } + let attachParamsInfo + if (Object.keys(filterOuterParams).length > 0) { + attachParamsInfo = + '&attachParams=' + encodeURIComponent(Base64.encode(JSON.stringify(filterOuterParams))) + } + // 携带外部参数 if (publicLinkStatus.value) { // 判断是否有公共链接ID if (jumpInfo.publicJumpId) { - const url = `${embeddedBaseUrl}#/de-link/${ + let url = `${embeddedBaseUrl}#/de-link/${ jumpInfo.publicJumpId }?fromLink=true&jumpInfoParam=${encodeURIComponent( Base64.encode(JSON.stringify(param)) )}` + if (attachParamsInfo) { + url = url + attachParamsInfo + } const currentUrl = window.location.href localStorage.setItem('beforeJumpUrl', currentUrl) windowsJump(url, jumpInfo.jumpType, jumpInfo.windowSize) @@ -481,9 +514,12 @@ const jumpClick = param => { ElMessage.warning(t('visualization.public_link_tips')) } } else { - const url = `${embeddedBaseUrl}#/preview?dvId=${ + let url = `${embeddedBaseUrl}#/preview?dvId=${ jumpInfo.targetDvId }&fromLink=true&jumpInfoParam=${encodeURIComponent(Base64.encode(JSON.stringify(param)))}` + if (attachParamsInfo) { + url = url + attachParamsInfo + } const currentUrl = window.location.href localStorage.setItem('beforeJumpUrl', currentUrl) if (isIframe.value || isDataEaseBi.value) { @@ -843,6 +879,9 @@ const toolTip = computed(() => { }) const marginBottom = computed(() => { + if (!titleShow.value) { + return 0 + } if (titleShow.value || trackMenu.value.length > 0 || state.title_remark.show) { return 12 * scale.value + 'px' } @@ -854,8 +893,22 @@ const iconSize = computed(() => { }) const titleIconStyle = computed(() => { + // 不显示标题时,图标的样式 + const style = { + position: 'absolute', + color: 'rgb(255, 252, 252)', + position: 'absolute', + border: '1px solid rgb(173, 170, 170)', + 'background-color': 'rgba(173, 170, 170)', + 'border-radius': '2px', + padding: '0 2px 0 2px', + top: '2px', + 'z-index': 1, + left: '6px' + } return { - color: canvasStyleData.value.component.seniorStyleSetting.linkageIconColor + color: canvasStyleData.value.component.seniorStyleSetting.linkageIconColor, + ...(titleShow.value ? {} : style) } }) const chartHover = ref(false) diff --git a/core/core-frontend/src/views/common/DeResourceTree.vue b/core/core-frontend/src/views/common/DeResourceTree.vue index 048841b7e0..e95360fa89 100644 --- a/core/core-frontend/src/views/common/DeResourceTree.vue +++ b/core/core-frontend/src/views/common/DeResourceTree.vue @@ -39,7 +39,6 @@ import { interactiveStoreWithOut } from '@/store/modules/interactive' import { useShareStoreWithOut } from '@/store/modules/share' const shareStore = useShareStoreWithOut() const interactiveStore = interactiveStoreWithOut() -import router from '@/router' import { useI18n } from '@/hooks/web/useI18n' import _ from 'lodash' import DeResourceCreateOptV2 from '@/views/common/DeResourceCreateOptV2.vue' @@ -47,6 +46,7 @@ import { useCache } from '@/hooks/web/useCache' import { findParentIdByChildIdRecursive } from '@/utils/canvasUtils' import { XpackComponent } from '@/components/plugin' import treeSort from '@/utils/treeSortUtils' +import router from '@/router' const { wsCache } = useCache() const dvMainStore = dvMainStoreWithOut() @@ -186,7 +186,10 @@ const menuList = computed(() => { return list }) -const dvId = embeddedStore.dvId || router.currentRoute.value.query.dvId +const infoId = wsCache.get(curCanvasType.value === 'dashboard' ? 'db-info-id' : 'dv-info-id') +const routerDvId = router.currentRoute.value.query.dvId +const dvId = embeddedStore.dvId || infoId || routerDvId +wsCache.delete(curCanvasType.value === 'dashboard' ? 'db-info-id' : 'dv-info-id') if (dvId && showPosition.value === 'preview') { selectedNodeKey.value = dvId returnMounted.value = true diff --git a/core/core-frontend/src/views/dashboard/DashboardPreviewShow.vue b/core/core-frontend/src/views/dashboard/DashboardPreviewShow.vue index b366921486..fc78405a43 100644 --- a/core/core-frontend/src/views/dashboard/DashboardPreviewShow.vue +++ b/core/core-frontend/src/views/dashboard/DashboardPreviewShow.vue @@ -252,7 +252,7 @@ defineExpose({
{ :component-data="componentData" :canvas-style-data="canvasStyleData" :canvas-view-info="canvasViewInfo" + :font-family="canvasStyleData.fontFamily" > diff --git a/core/core-frontend/src/views/data-visualization/DvPreview.vue b/core/core-frontend/src/views/data-visualization/DvPreview.vue index b5b787f3af..b0c4edabd3 100644 --- a/core/core-frontend/src/views/data-visualization/DvPreview.vue +++ b/core/core-frontend/src/views/data-visualization/DvPreview.vue @@ -52,6 +52,8 @@ const contentInnerClass = computed(() => { return 'preview-content-inner-height-first' } else if (props.canvasStylePreview.screenAdaptor === 'full') { return 'preview-content-inner-full' + } else if (props.canvasStylePreview.screenAdaptor === 'keep') { + return 'preview-content-inner-size-keep' } else { return 'preview-content-inner-width-first' } diff --git a/core/core-frontend/src/views/data-visualization/PreviewCanvas.vue b/core/core-frontend/src/views/data-visualization/PreviewCanvas.vue index b20650af8f..c3af3f48ce 100644 --- a/core/core-frontend/src/views/data-visualization/PreviewCanvas.vue +++ b/core/core-frontend/src/views/data-visualization/PreviewCanvas.vue @@ -1,6 +1,6 @@ diff --git a/core/core-frontend/src/views/mobile/personal/index.vue b/core/core-frontend/src/views/mobile/personal/index.vue index 120fbc9171..b17d3bdccd 100644 --- a/core/core-frontend/src/views/mobile/personal/index.vue +++ b/core/core-frontend/src/views/mobile/personal/index.vue @@ -98,6 +98,7 @@ const switchHandler = (id: number | string) => { const token = res.data.token userStore.setToken(token) userStore.setExp(res.data.exp) + userStore.setTime(Date.now()) window.location.reload() }) } diff --git a/core/core-frontend/src/views/system/common/InfoTemplate.vue b/core/core-frontend/src/views/system/common/InfoTemplate.vue index 3543a9c8d1..f0e4c81d5a 100644 --- a/core/core-frontend/src/views/system/common/InfoTemplate.vue +++ b/core/core-frontend/src/views/system/common/InfoTemplate.vue @@ -12,7 +12,7 @@ {{ t('commons.edit') }}
-
+
{{ t(item.pkey) }} @@ -222,7 +222,7 @@ formatLabel() } } .info-template-container { - padding: 24px; + padding: 24px 24px 0; .info-template-header { display: flex; margin-top: -4px; @@ -286,5 +286,10 @@ formatLabel() } } } + .clearfix::after { + content: ''; + display: table; + clear: both; + } } diff --git a/core/core-frontend/src/views/system/parameter/basic/BasicEdit.vue b/core/core-frontend/src/views/system/parameter/basic/BasicEdit.vue index 3ff3cacba5..3b7bae9372 100644 --- a/core/core-frontend/src/views/system/parameter/basic/BasicEdit.vue +++ b/core/core-frontend/src/views/system/parameter/basic/BasicEdit.vue @@ -250,7 +250,8 @@ defineExpose({ item.pkey === 'pwdStrategy' || item.pkey === 'dip' || item.pkey === 'shareDisable' || - item.pkey === 'sharePeRequire' + item.pkey === 'sharePeRequire' || + item.pkey === 'loginLimit' " active-value="true" inactive-value="false" @@ -290,7 +291,14 @@ defineExpose({ type="number" />
-
+
+