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 856622cbc1..e30b2a6339 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 @@ -17,6 +17,7 @@ import io.dataease.extensions.datasource.dto.DatasetTableDTO; import io.dataease.extensions.datasource.dto.DatasourceDTO; import io.dataease.extensions.datasource.dto.DatasourceRequest; import io.dataease.extensions.datasource.dto.TableField; +import io.dataease.extensions.datasource.vo.DatasourceConfiguration; import io.dataease.job.schedule.ExtractDataJob; import io.dataease.job.schedule.ScheduleManager; import io.dataease.utils.BeanUtils; @@ -26,7 +27,6 @@ import org.apache.commons.lang3.StringUtils; import org.quartz.JobExecutionContext; import org.quartz.JobKey; import org.quartz.TriggerKey; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import java.util.Date; @@ -50,7 +50,6 @@ public class DatasourceSyncManage { @Resource private CalciteProvider calciteProvider; - @Async public void extractExcelData(CoreDatasource coreDatasource, String type) { if (coreDatasource == null) { LogUtil.error("Can not find CoreDatasource: " + coreDatasource.getName()); @@ -85,7 +84,12 @@ public class DatasourceSyncManage { } datasetTableTaskLog.setTaskStatus(TaskStatus.Error.toString()); datasetTableTaskLog.setInfo(datasetTableTaskLog.getInfo() + "/n Failed to sync datatable: " + datasourceRequest.getTable() + ", " + e.getMessage()); - DEException.throwException(e); + if (e.getMessage().contains("Duplicate entry")) { + DEException.throwException("不能追加主键相同的数据, " + e.getMessage()); + } else { + DEException.throwException(e); + } + } finally { datasourceTaskServer.saveLog(datasetTableTaskLog); } @@ -237,7 +241,7 @@ public class DatasourceSyncManage { totalPage = dataList.size() / pageNumber; } for (int page = 1; page <= totalPage; page++) { - engineRequest.setQuery(engineProvider.insertSql(datasourceRequest.getTable(), extractType, dataList, page, pageNumber, tableFields)); + engineRequest.setQuery(engineProvider.insertSql(DatasourceConfiguration.DatasourceType.API.name(), datasourceRequest.getTable(), extractType, dataList, page, pageNumber, tableFields)); calciteProvider.exec(engineRequest); } } @@ -257,7 +261,7 @@ public class DatasourceSyncManage { totalPage = dataList.size() / pageNumber; } for (int page = 1; page <= totalPage; page++) { - engineRequest.setQuery(engineProvider.insertSql(datasourceRequest.getTable(), extractType, dataList, page, pageNumber, tableFields)); + engineRequest.setQuery(engineProvider.insertSql(DatasourceConfiguration.DatasourceType.Excel.name(), datasourceRequest.getTable(), extractType, dataList, page, pageNumber, tableFields)); calciteProvider.exec(engineRequest); } } diff --git a/core/core-backend/src/main/java/io/dataease/datasource/provider/EngineProvider.java b/core/core-backend/src/main/java/io/dataease/datasource/provider/EngineProvider.java index 1618a273ac..2b21ca4b1d 100644 --- a/core/core-backend/src/main/java/io/dataease/datasource/provider/EngineProvider.java +++ b/core/core-backend/src/main/java/io/dataease/datasource/provider/EngineProvider.java @@ -22,7 +22,7 @@ public abstract class EngineProvider { public abstract String createTableSql(String name, List tableFields, CoreDeEngine engine); - public abstract String insertSql(String tableName, DatasourceServer.UpdateType extractType, List dataList, int page, int pageNumber, List tableFields); + public abstract String insertSql(String dsType, String tableName, DatasourceServer.UpdateType extractType, List dataList, int page, int pageNumber, List tableFields); } 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 ef7624ddca..d3c87940d1 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 @@ -25,7 +25,7 @@ public class H2EngineProvider extends EngineProvider { } @Override - public String insertSql(String tableName, DatasourceServer.UpdateType extractType, List dataList, int page, int pageNumber,List tableFields) { + public String insertSql(String dsType, String tableName, DatasourceServer.UpdateType extractType, List dataList, int page, int pageNumber,List tableFields) { String engineTableName; switch (extractType) { case all_scope: 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 588b29a84f..f03536bbbf 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 @@ -31,7 +31,7 @@ public class MysqlEngineProvider extends EngineProvider { } @Override - public String insertSql(String tableName, DatasourceServer.UpdateType extractType, List dataList, int page, int pageNumber, List tableFields) { + public String insertSql(String dsType, String tableName, DatasourceServer.UpdateType extractType, List dataList, int page, int pageNumber, List tableFields) { String engineTableName; switch (extractType) { case all_scope: @@ -62,17 +62,20 @@ public class MysqlEngineProvider extends EngineProvider { values.append("('").append(String.join("','", Arrays.asList(strings1))) .append("'),"); } - 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 "; - List updateColumes = new ArrayList<>(); - for (TableField notKey : notKeys) { - updateColumes.add("column = VALUES(column)".replace("column", notKey.getName())); + if (dsType.equalsIgnoreCase("api")) { + List keys = tableFields.stream().filter(tableField -> tableField.isPrimaryKey() && tableField.isChecked()).toList(); + List notKeys = tableFields.stream().filter(tableField -> tableField.isChecked() && !tableField.isPrimaryKey()).toList(); + if (CollectionUtils.isNotEmpty(keys) && extractType.equals(DatasourceServer.UpdateType.add_scope)) { + insetSql = insetSql + " ON DUPLICATE KEY UPDATE "; + List updateColumes = new ArrayList<>(); + for (TableField notKey : notKeys) { + updateColumes.add("column = VALUES(column)".replace("column", notKey.getName())); + } + insetSql = insetSql + updateColumes.stream().collect(Collectors.joining(",")); } - insetSql = insetSql + updateColumes.stream().collect(Collectors.joining(",")); } + return insetSql; } diff --git a/core/core-backend/src/main/java/io/dataease/font/manage/FontManage.java b/core/core-backend/src/main/java/io/dataease/font/manage/FontManage.java index 5a55e3280e..7ff0ccdf42 100644 --- a/core/core-backend/src/main/java/io/dataease/font/manage/FontManage.java +++ b/core/core-backend/src/main/java/io/dataease/font/manage/FontManage.java @@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ResourceLoader; +import java.awt.*; import java.io.*; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @@ -181,9 +182,10 @@ public class FontManage { unit = "KB"; size = Double.valueOf(String.format("%.2f", (double) length / 1024)); } + Font font = Font.createFont(Font.TRUETYPE_FONT, new File(filePath)); fontDto.setSize(size); fontDto.setSizeType(unit); - + fontDto.setName(font.getFontName()); } catch (Exception e) { DEException.throwException(e); } diff --git a/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtDataVisualizationMapper.java b/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtDataVisualizationMapper.java index 270a91819e..866d87b58b 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtDataVisualizationMapper.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/dao/ext/mapper/ExtDataVisualizationMapper.java @@ -37,7 +37,7 @@ public interface ExtDataVisualizationMapper { DataVisualizationVO findDvInfo(@Param("dvId") Long dvId,@Param("dvType") String dvType); - IPage findRecent(IPage page, @Param("uid") Long uid, @Param("ew") QueryWrapper ew); + IPage findRecent(IPage page, @Param("uid") Long uid, @Param("keyword") String keyword, @Param("ew") QueryWrapper ew); void copyLinkJump(@Param("copyId") Long copyId); 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 cfb906119a..06f8514aab 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 @@ -12,9 +12,9 @@ import org.apache.ibatis.annotations.Param; import java.util.List; @Mapper public interface ExtVisualizationLinkJumpMapper { - List queryWithDvId(@Param("dvId") Long dvId,@Param("uid") Long uid); + List queryWithDvId(@Param("dvId") Long dvId,@Param("uid") Long uid,@Param("isDesktop") Boolean isDesktop); - VisualizationLinkJumpDTO queryWithViewId(@Param("dvId") Long dvId,@Param("viewId") Long viewId,@Param("uid") Long uid); + VisualizationLinkJumpDTO queryWithViewId(@Param("dvId") Long dvId,@Param("viewId") Long viewId,@Param("uid") Long uid,@Param("isDesktop") Boolean isDesktop); void deleteJumpTargetViewInfo(@Param("dvId") Long dvId,@Param("viewId") Long viewId); 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 7b55e015af..9d4fe99f6e 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 @@ -199,15 +199,12 @@ public class CoreVisualizationManage { } queryWrapper.eq("dvResource.type", request.getType()); } - 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); + return extDataVisualizationMapper.findRecent(page, uid, request.getKeyword(), 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 f05aaacb63..3ce84d207d 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 @@ -106,7 +106,7 @@ public class VisualizationStoreManage { queryWrapper.eq("s.resource_type", busiResourceEnum.getFlag()); } if (StringUtils.isNotBlank(request.getKeyword())) { - queryWrapper.like("v.name", request.getKeyword()); + queryWrapper.apply("LOWER(v.name) LIKE LOWER(CONCAT('%', {0}, '%'))", request.getKeyword()); } String info = CommunityUtils.getInfo(); if (StringUtils.isNotBlank(info)) { 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 1ef6f50762..41a841ef4c 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 @@ -42,6 +42,7 @@ import io.dataease.log.DeLog; import io.dataease.model.BusiNodeRequest; import io.dataease.model.BusiNodeVO; import io.dataease.operation.manage.CoreOptRecentManage; +import io.dataease.system.manage.CoreUserManage; import io.dataease.template.dao.auto.entity.VisualizationTemplate; import io.dataease.template.dao.auto.entity.VisualizationTemplateExtendData; import io.dataease.template.dao.auto.mapper.VisualizationTemplateExtendDataMapper; @@ -138,6 +139,9 @@ public class DataVisualizationServer implements DataVisualizationApi { @Resource private CoreLicManage coreLicManage; + @Resource + private CoreUserManage coreUserManage; + @Override public DataVisualizationVO findCopyResource(Long dvId, String busiFlag) { DataVisualizationVO result = Objects.requireNonNull(CommonBeanFactory.proxy(this.getClass())).findById(new DataVisualizationBaseRequest(dvId, busiFlag)); @@ -156,6 +160,11 @@ public class DataVisualizationServer implements DataVisualizationApi { Long dvId = request.getId(); String busiFlag = request.getBusiFlag(); DataVisualizationVO result = extDataVisualizationMapper.findDvInfo(dvId, busiFlag); + // get creator + String userName = coreUserManage.getUserName(Long.valueOf(result.getCreateBy())); + if (StringUtils.isNotBlank(userName)) { + result.setCreatorName(userName); + } if (result != null) { //获取图表信息 List chartViewDTOS = chartViewManege.listBySceneId(dvId); @@ -511,38 +520,38 @@ public class DataVisualizationServer implements DataVisualizationApi { @Override public List tree(BusiNodeRequest request) { String busiFlag = request.getBusiFlag(); - if(busiFlag.equals("dashboard-dataV")){ + if (busiFlag.equals("dashboard-dataV")) { BusiNodeRequest requestDv = new BusiNodeRequest(); - BeanUtils.copyBean(requestDv,request); + BeanUtils.copyBean(requestDv, request); requestDv.setBusiFlag("dashboard"); - List dashboardResult = coreVisualizationManage.tree(requestDv); + List dashboardResult = coreVisualizationManage.tree(requestDv); requestDv.setBusiFlag("dataV"); - List dataVResult = coreVisualizationManage.tree(requestDv); + List dataVResult = coreVisualizationManage.tree(requestDv); List result = new ArrayList<>(); - if(!CollectionUtils.isEmpty(dashboardResult)){ + if (!CollectionUtils.isEmpty(dashboardResult)) { BusiNodeVO dashboardResultParent = new BusiNodeVO(); dashboardResultParent.setName(Translator.get("i18n_menu.panel")); dashboardResultParent.setId(-101L); - if(dashboardResult.get(0).getId() == 0){ + if (dashboardResult.get(0).getId() == 0) { dashboardResultParent.setChildren(dashboardResult.get(0).getChildren()); - }else{ + } else { dashboardResultParent.setChildren(dashboardResult); } result.add(dashboardResultParent); } - if(!CollectionUtils.isEmpty(dataVResult)){ + if (!CollectionUtils.isEmpty(dataVResult)) { BusiNodeVO dataVResultParent = new BusiNodeVO(); dataVResultParent.setName(Translator.get("i18n_menu.screen")); dataVResultParent.setId(-102L); - if(dataVResult.get(0).getId() == 0){ + if (dataVResult.get(0).getId() == 0) { dataVResultParent.setChildren(dataVResult.get(0).getChildren()); - }else{ + } else { dataVResultParent.setChildren(dataVResult); } result.add(dataVResultParent); } return result; - }else{ + } else { return coreVisualizationManage.tree(request); } } @@ -820,7 +829,7 @@ public class DataVisualizationServer implements DataVisualizationApi { wrapper.eq("name", request.getName().trim()); wrapper.eq("node_type", request.getNodeType()); wrapper.eq("type", request.getType()); - if(AuthUtils.getUser().getDefaultOid() != null){ + if (AuthUtils.getUser().getDefaultOid() != null) { wrapper.eq("org_id", AuthUtils.getUser().getDefaultOid()); } if (visualizationInfoMapper.exists(wrapper)) { 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 c5caa5c3a9..42734e6a2a 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 @@ -15,6 +15,7 @@ import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO; import io.dataease.utils.AuthUtils; import io.dataease.utils.BeanUtils; import io.dataease.utils.IDUtils; +import io.dataease.utils.ModelUtils; import io.dataease.visualization.dao.auto.entity.DataVisualizationInfo; import io.dataease.visualization.dao.auto.entity.VisualizationLinkJump; import io.dataease.visualization.dao.auto.entity.VisualizationLinkJumpInfo; @@ -74,7 +75,7 @@ public class VisualizationLinkJumpService implements VisualizationLinkJumpApi { @Override public VisualizationLinkJumpBaseResponse queryVisualizationJumpInfo(Long dvId) { Map resultBase = new HashMap<>(); - List resultLinkJumpList = extVisualizationLinkJumpMapper.queryWithDvId(dvId, AuthUtils.getUser().getUserId()); + List resultLinkJumpList = extVisualizationLinkJumpMapper.queryWithDvId(dvId, AuthUtils.getUser().getUserId(), ModelUtils.isDesktop()); Optional.ofNullable(resultLinkJumpList).orElse(new ArrayList<>()).forEach(resultLinkJump -> { if (resultLinkJump.getChecked()) { Long sourceViewId = resultLinkJump.getSourceViewId(); @@ -99,7 +100,7 @@ public class VisualizationLinkJumpService implements VisualizationLinkJumpApi { @Override public VisualizationLinkJumpDTO queryWithViewId(Long dvId, Long viewId) { - return extVisualizationLinkJumpMapper.queryWithViewId(dvId, viewId, AuthUtils.getUser().getUserId()); + return extVisualizationLinkJumpMapper.queryWithViewId(dvId, viewId, AuthUtils.getUser().getUserId(), ModelUtils.isDesktop()); } @Transactional diff --git a/core/core-backend/src/main/resources/db/desktop/V2.0__core_ddl.sql b/core/core-backend/src/main/resources/db/desktop/V2.0__core_ddl.sql index 3a48e682fb..8d1fa065fd 100644 --- a/core/core-backend/src/main/resources/db/desktop/V2.0__core_ddl.sql +++ b/core/core-backend/src/main/resources/db/desktop/V2.0__core_ddl.sql @@ -4186,14 +4186,14 @@ SET FOREIGN_KEY_CHECKS = 1; INSERT INTO `visualization_subject` (`id`, `name`, `type`, `details`, `delete_flag`, `cover_url`, `create_num`, `create_time`, `create_by`, `update_time`, `update_by`, `delete_time`, `delete_by`) VALUES ('10001', '浅色主题', 'system', - '{\"width\":1920,\"height\":1080,\"refreshViewEnable\":false,\"refreshViewLoading\":true,\"refreshUnit\":\"minute\",\"refreshTime\":5,\"scale\":60,\"scaleWidth\":100,\"scaleHeight\":100,\"backgroundColorSelect\":true,\"backgroundImageEnable\":false,\"backgroundType\":\"backgroundColor\",\"background\":\"\",\"openCommonStyle\":true,\"opacity\":1,\"fontSize\":14,\"themeId\":\"10001\",\"color\":\"#000000\",\"backgroundColor\":\"rgba(245, 246, 247, 1)\",\"dashboard\":{\"gap\":\"yes\",\"gapSize\":5,\"resultMode\":\"all\",\"resultCount\":1000,\"themeColor\":\"light\",\"mobileSetting\":{\"customSetting\":false,\"imageUrl\":null,\"backgroundType\":\"image\",\"color\":\"#000\"}},\"component\":{\"chartTitle\":{\"show\":true,\"fontSize\":\"18\",\"hPosition\":\"left\",\"vPosition\":\"top\",\"isItalic\":false,\"isBolder\":true,\"remarkShow\":false,\"remark\":\"\",\"fontFamily\":\"Microsoft YaHei\",\"letterSpace\":\"0\",\"fontShadow\":false,\"color\":\"#000000\",\"remarkBackgroundColor\":\"#ffffff\"},\"chartColor\":{\"basicStyle\":{\"colorScheme\":\"default\",\"colors\":[\"#1E90FF\",\"#90EE90\",\"#00CED1\",\"#E2BD84\",\"#7A90E0\",\"#3BA272\",\"#2BE7FF\",\"#0A8ADA\",\"#FFD700\"],\"alpha\":100,\"gradient\":false,\"mapStyle\":\"normal\",\"areaBaseColor\":\"#FFFFFF\",\"areaBorderColor\":\"#303133\",\"gaugeStyle\":\"default\",\"tableBorderColor\":\"#E6E7E4\",\"tableScrollBarColor\":\"#00000024\"},\"misc\":{\"mapLineGradient\":false,\"mapLineSourceColor\":\"#146C94\",\"mapLineTargetColor\":\"#576CBC\",\"nameFontColor\":\"#000000\",\"valueFontColor\":\"#5470c6\"},\"tableHeader\":{\"tableHeaderBgColor\":\"#1E90FF\",\"tableHeaderFontColor\":\"#000000\"},\"tableCell\":{\"tableItemBgColor\":\"#FFFFFF\",\"tableFontColor\":\"#000000\"}},\"chartCommonStyle\":{\"backgroundColorSelect\":true,\"backgroundImageEnable\":false,\"backgroundType\":\"innerImage\",\"innerImage\":\"board/board_1.svg\",\"outerImage\":null,\"innerPadding\":12,\"borderRadius\":0,\"backgroundColor\":\"rgba(255,255,255,1)\",\"innerImageColor\":\"rgba(16, 148, 229,1)\"},\"filterStyle\":{\"layout\":\"horizontal\",\"titleLayout\":\"left\",\"labelColor\":\"#000000\",\"titleColor\":\"#000000\",\"color\":\"#000000\",\"borderColor\":\"#F3E7E7\",\"text\":\"#484747\",\"bgColor\":\"#FFFFFF\"},\"tabStyle\":{\"headPosition\":\"left\",\"headFontColor\":\"#OOOOOO\",\"headFontActiveColor\":\"#OOOOOO\",\"headBorderColor\":\"#OOOOOO\",\"headBorderActiveColor\":\"#OOOOOO\"}}}', + '{"width":1920,"height":1080,"refreshViewEnable":false,"refreshViewLoading":true,"refreshUnit":"minute","refreshTime":5,"scale":60,"scaleWidth":100,"scaleHeight":100,"backgroundColorSelect":true,"backgroundImageEnable":false,"backgroundType":"backgroundColor","background":"","openCommonStyle":true,"opacity":1,"fontSize":14,"themeId":"10001","color":"#000000","backgroundColor":"rgba(245, 246, 247, 1)","dashboard":{"gap":"yes","gapSize":5,"resultMode":"all","resultCount":1000,"themeColor":"light","mobileSetting":{"customSetting":false,"imageUrl":null,"backgroundType":"image","color":"#000"}},"component":{"chartTitle":{"show":true,"fontSize":"18","hPosition":"left","vPosition":"top","isItalic":false,"isBolder":true,"remarkShow":false,"remark":"","fontFamily":"Microsoft YaHei","letterSpace":"0","fontShadow":false,"color":"#000000","remarkBackgroundColor":"#ffffff"},"chartColor":{"basicStyle":{"colorScheme":"default","colors":["#1E90FF","#90EE90","#00CED1","#E2BD84","#7A90E0","#3BA272","#2BE7FF","#0A8ADA","#FFD700"],"alpha":100,"gradient":false,"mapStyle":"normal","areaBaseColor":"#FFFFFF","areaBorderColor":"#303133","gaugeStyle":"default","tableBorderColor":"#E6E7E4","tableScrollBarColor":"#00000024"},"misc":{"mapLineGradient":false,"mapLineSourceColor":"#146C94","mapLineTargetColor":"#576CBC","nameFontColor":"#000000","valueFontColor":"#5470c6"},"tableHeader":{"tableHeaderBgColor":"#1E90FF","tableHeaderFontColor":"#000000"},"tableCell":{"tableItemBgColor":"#FFFFFF","tableFontColor":"#000000"}},"chartCommonStyle":{"backgroundColorSelect":true,"backgroundImageEnable":false,"backgroundType":"innerImage","innerImage":"board/board_1.svg","outerImage":null,"innerPadding":12,"borderRadius":0,"backgroundColor":"rgba(255,255,255,1)","innerImageColor":"rgba(16, 148, 229,1)"},"filterStyle":{"layout":"horizontal","titleLayout":"left","labelColor":"#000000","titleColor":"#000000","color":"#000000","borderColor":"#F3E7E7","text":"#484747","bgColor":"#FFFFFF"},"tabStyle":{"headPosition":"left","headFontColor":"#OOOOOO","headFontActiveColor":"#OOOOOO","headBorderColor":"#OOOOOO","headBorderActiveColor":"#OOOOOO"}}}', 0, 'data:image/png;base64,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', 0, 1696427707737, NULL, NULL, NULL, NULL, NULL); INSERT INTO `visualization_subject` (`id`, `name`, `type`, `details`, `delete_flag`, `cover_url`, `create_num`, `create_time`, `create_by`, `update_time`, `update_by`, `delete_time`, `delete_by`) VALUES ('10002', '深色主题', 'system', - '{\"width\":1920,\"height\":1080,\"refreshViewEnable\":false,\"refreshViewLoading\":true,\"refreshUnit\":\"minute\",\"refreshTime\":5,\"scale\":60,\"scaleWidth\":100,\"scaleHeight\":100,\"backgroundColorSelect\":true,\"backgroundImageEnable\":false,\"backgroundType\":\"backgroundColor\",\"background\":\"\",\"openCommonStyle\":true,\"opacity\":1,\"fontSize\":14,\"themeId\":\"10002\",\"color\":\"#000000\",\"backgroundColor\":\"rgba(3, 11, 46, 1)\",\"dashboard\":{\"gap\":\"yes\",\"gapSize\":5,\"resultMode\":\"all\",\"resultCount\":1000,\"themeColor\":\"dark\",\"mobileSetting\":{\"customSetting\":false,\"imageUrl\":null,\"backgroundType\":\"image\",\"color\":\"#000\"}},\"component\":{\"chartTitle\":{\"show\":true,\"fontSize\":\"18\",\"hPosition\":\"left\",\"vPosition\":\"top\",\"isItalic\":false,\"isBolder\":true,\"remarkShow\":false,\"remark\":\"\",\"fontFamily\":\"Microsoft YaHei\",\"letterSpace\":\"0\",\"fontShadow\":false,\"color\":\"#FFFFFF\",\"remarkBackgroundColor\":\"#5A5C62\"},\"chartColor\":{\"basicStyle\":{\"colorScheme\":\"default\",\"colors\":[\"#1E90FF\",\"#90EE90\",\"#00CED1\",\"#E2BD84\",\"#7A90E0\",\"#3BA272\",\"#2BE7FF\",\"#0A8ADA\",\"#FFD700\"],\"alpha\":100,\"gradient\":false,\"mapStyle\":\"darkblue\",\"areaBaseColor\":\"5470C6\",\"areaBorderColor\":\"#EBEEF5\",\"gaugeStyle\":\"default\",\"tableBorderColor\":\"#CCCCCC\",\"tableScrollBarColor\":\"#FFFFFF80\"},\"misc\":{\"mapLineGradient\":false,\"mapLineSourceColor\":\"#2F58CD\",\"mapLineTargetColor\":\"#3795BD\",\"nameFontColor\":\"#ffffff\",\"valueFontColor\":\"#5470c6\"},\"tableHeader\":{\"tableHeaderBgColor\":\"#1E90FF\",\"tableHeaderFontColor\":\"#FFFFFF\"},\"tableCell\":{\"tableItemBgColor\":\"#131E42\",\"tableFontColor\":\"#FFFFFF\"}},\"chartCommonStyle\":{\"backgroundColorSelect\":true,\"backgroundImageEnable\":false,\"backgroundType\":\"innerImage\",\"innerImage\":\"board/board_1.svg\",\"outerImage\":null,\"innerPadding\":12,\"borderRadius\":0,\"backgroundColor\":\"rgba(19,28,66,1)\",\"innerImageColor\":\"#1094E5\"},\"filterStyle\":{\"layout\":\"horizontal\",\"titleLayout\":\"left\",\"labelColor\":\"#FFFFFF\",\"titleColor\":\"#FFFFFF\",\"color\":\"#FFFFFF\",\"borderColor\":\"#484747\",\"text\":\"#AFAFAF\",\"bgColor\":\"#131C42\"},\"tabStyle\":{\"headPosition\":\"left\",\"headFontColor\":\"#FFFFFF\",\"headFontActiveColor\":\"#FFFFFF\",\"headBorderColor\":\"#131E42\",\"headBorderActiveColor\":\"#131E42\"}}}', + '{"width":1920,"height":1080,"refreshViewEnable":false,"refreshViewLoading":true,"refreshUnit":"minute","refreshTime":5,"scale":60,"scaleWidth":100,"scaleHeight":100,"backgroundColorSelect":true,"backgroundImageEnable":false,"backgroundType":"backgroundColor","background":"","openCommonStyle":true,"opacity":1,"fontSize":14,"themeId":"10002","color":"#000000","backgroundColor":"rgba(3, 11, 46, 1)","dashboard":{"gap":"yes","gapSize":5,"resultMode":"all","resultCount":1000,"themeColor":"dark","mobileSetting":{"customSetting":false,"imageUrl":null,"backgroundType":"image","color":"#000"}},"component":{"chartTitle":{"show":true,"fontSize":"18","hPosition":"left","vPosition":"top","isItalic":false,"isBolder":true,"remarkShow":false,"remark":"","fontFamily":"Microsoft YaHei","letterSpace":"0","fontShadow":false,"color":"#FFFFFF","remarkBackgroundColor":"#5A5C62"},"chartColor":{"basicStyle":{"colorScheme":"default","colors":["#1E90FF","#90EE90","#00CED1","#E2BD84","#7A90E0","#3BA272","#2BE7FF","#0A8ADA","#FFD700"],"alpha":100,"gradient":false,"mapStyle":"darkblue","areaBaseColor":"5470C6","areaBorderColor":"#EBEEF5","gaugeStyle":"default","tableBorderColor":"#CCCCCC","tableScrollBarColor":"#FFFFFF80"},"misc":{"mapLineGradient":false,"mapLineSourceColor":"#2F58CD","mapLineTargetColor":"#3795BD","nameFontColor":"#ffffff","valueFontColor":"#5470c6"},"tableHeader":{"tableHeaderBgColor":"#1E90FF","tableHeaderFontColor":"#FFFFFF"},"tableCell":{"tableItemBgColor":"#131E42","tableFontColor":"#FFFFFF"}},"chartCommonStyle":{"backgroundColorSelect":true,"backgroundImageEnable":false,"backgroundType":"innerImage","innerImage":"board/board_1.svg","outerImage":null,"innerPadding":12,"borderRadius":0,"backgroundColor":"rgba(19,28,66,1)","innerImageColor":"#1094E5"},"filterStyle":{"layout":"horizontal","titleLayout":"left","labelColor":"#FFFFFF","titleColor":"#FFFFFF","color":"#FFFFFF","borderColor":"#484747","text":"#AFAFAF","bgColor":"#131C42"},"tabStyle":{"headPosition":"left","headFontColor":"#FFFFFF","headFontActiveColor":"#FFFFFF","headBorderColor":"#131E42","headBorderActiveColor":"#131E42"}}}', 0, 'data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb/2wBDAAsICAoIBwsKCQoNDAsNERwSEQ8PESIZGhQcKSQrKigkJyctMkA3LTA9MCcnOEw5PUNFSElIKzZPVU5GVEBHSEX/2wBDAQwNDREPESESEiFFLicuRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUX/wAARCABSAK4DASIAAhEBAxEB/8QAGwAAAgMBAQEAAAAAAAAAAAAAAAMBAgQFBgf/xAA/EAABAwICBwMIBwkBAQAAAAABAAIDBBESIQUTMUFRYZEUItEjQlNUcYGSoSQzk6Ox4fAGFRYyUmOiwfFDYv/EABgBAQEBAQEAAAAAAAAAAAAAAAEAAgME/8QAKhEAAgIBAwEHBAMAAAAAAAAAAAECESEDEjFRBBMUIjJB8GGBscFxofH/2gAMAwEAAhEDEQA/APmbq6R8jpJO/I4klzjck8U5zaqRpmOqsRiNnt4X2X+SwWuVpNFIBfHDtt9a3xXrepLqc9qLMM0kb5G6vCzbctB6HbsXU0Z+z9ZpWnbLBLC0OubPIbsNt64bm4HFpIJHA3Cs2WRos17gOAK3CaT8+TM4tryujbX0U1BUMhe9jnPbiBGQ28/Ysj3PY9zHEXBsbWKo57nm73Fx5m6lrLi5IA4lEpW7jhDFNLzchrHcfkpxu4joryU5jYJA5skZNsbL2vwzzCpGGGRokcWsJGJwFyB7EPcsMcMMbuXRGN36C3mDReE/TJy6+R1OW/n7Pmphp9FF411dO1uw4YLm/wAWxFsaMGM/oIDjy6LdJBottO90dbO6W3cZqbAnLIm+W/PksCrZFsR/QRiKqpTYE4ipxFVUqEm5RcqFKSJuUXUKVESE6nq6ijeX008kLiLExuLSR7kkIUyM8RAmZcEjELgC9/cvRVtXoyemqBFo+VkrgwCbszWgEEeaD3b5g2JvcLzjWlzw1u0mwXTboPSD88IN95eiGlPUzBNmXOMeWdn96aGE88p0W8ukthJpWYGWcCQI72GV95J5BIptLaFg1xdSOeXz6xpfSxus247tr5DI5DbeyxN/ZzSbjkxv2gWWPRNVK6RrGAmN5Y7vbxtSuzat1tZPUhymbtMaR0XVUEcVDTOjmbJic4wRsxDvXzab722GwW3rBSw4oxNJG59OwFrywBxacyMr5bs/an/w/X3+raPa4J8GgNKxyB1OMD9gLJLH5La7NqrmLDvI9TNUNYyCWSNr2wyta2PGzCXOBBJtc5DMX5rnrqaT0RpKkaZ9IAk4g0l77uuuYszTTSaoY5yizwA/INtyJIUZcleUHGbh3vZh+SrY8D0WDRGXJT0RhPPomak9n1t8sWG1uV1JWTYvLkpBsb2CLHgeinCbXsbexRF3zOkaGuwWHBoH4KmXJRY8+icyIOp5ZDfE0tAy438FpK+C4FZclOXJFjwPRPhYDT1BLblrRY22d4JSsG6EdE6GNsjJifMZiFuNwP8AaVb29Foph5Op2/VcP/pqYK2T4M/RCm1v+IWREQkNnjJNgHC59693T6foWRtY6Y5NDT9IIBy4LwTWlzg1oJJNgBvVzDICQY3gt2jCcl10O0vRTildnKelvdn0H986LLWiOeKMjaTLe64ujNKUtNPWl8uUkzy3DLhyJyPNeWLS21wRcXF1C7+PluUq/JnuFVWfQv4h0dI0tfIS027pqSR+CKXS2jQ/ytZEBbjfPnmF8/axz3YWNLjwAurPhkjF3xvaDvcCFrx06xH8me4jeWew/avSlFW6NZHS1DJCxzRkcyM93vt7l41CACSABcncvHqaj1Jbmd4R2qiXWJ7oAHC6cQ3scdgMeN1zbdYWz6pb4ZIyWvjc0g2ILSLKCHDJwI5FYTwaYJ9x2DDv1t/ks6m5ta+Sk6BqybexPa4dge3eZWn5HxWdTns3JToXkOi0RuApJmnaXNI+azoubWvklOgasnotEJAp6gHaWi3ULMFa5AyO1SdC1ZPRPpyAye++Ow6jwS44JZReOJ7xxa0lVc18bi1wc128EWKVayDp4BChSsiIje+KRskbi17SC0jaCug3S+lY3F3aJcRc513C+ZILto5Bc5mT23sc967cs1Y2R2Oqgc7E8kiuJucr54s75e23Jc0k8k3WDjSySSvxSkl3Eqq11Mo1x1scUrzmXCRzr++6Vro/V2fE7xWqXULCmqpqOYTU0hjkGxwT63S9fpFjWVlS+ZrTcB25I1sfq7OrvFGtj9Azq7xW02lW7H3ClzQSzTyNAmfI5oOWIlLBLXAg2IzBC01T3vZGXva7gBIXEdTksqwaOoNM6Wa57hUTYpHYnOw5uJ525DosVTUT1UgkqXFz7WBItlf/AKuprKrBGO0wYThsO2O7owm1+9lYXHK9liqZrvBmZHK4jbrXO/2pRSSBuzEpTtdF6tH8TvFGuj9Wj+J3itUuoWKQna6P1dnxO8Ua2P1dnxO8U0uo2JQE7Wx+rs6u8Ua2P1dnV3iqvqVikJutj9Azq7xRrY/QM6u8U0uo2PpNKVtCwspamSJpNyGnely1lRNUOqJJnmZ2198yq61noGdXeKNYz0LOp8VpttU2FLmiJHSSOL5S5zic3ONyVVaZ3udTsxOYW5BrRIXEe6+Sz7lhiZmXxtwmxuLG9re9dcsh9dqhmf8A0jOWVvP9vyXIbbGL7L55XXVkLHPLuwYRd2XZnDhl/Pu/2uaWLshE4lEnkKl7mcXzNB+Tkv6V6f74eKtLC2WQFsMsd7ANZCbHq4qhpLebUfY/mt/OTJQyTg2MzvtPzVe+fO/yV+yy3I1UtwLnyZ2INNI0EmOUAC5JYs3ZpIJhGGM1bpHO87FawPKxSU+c3azyIjAFrhpGLqUlRHXayPCMVZUg5XtKw+bn5/G3uSZmygjUVMjhbPHM0Z+5xTLswsd2IlrcOfZzn3d/e37fckSwsfY6qWO2RwwHPq7kVvh1f9mXn/Ctqv0/348UWqvT/fjxUdkAP8tR9j+aOyi4GGoudg1O35pv5YUTaq9P98PFH0n033w8UCkvazag3/s/mlujia4hzpARtBjHim/liX+k+m++HioL5wbGV3uk/NUwxf1v+AeKrZvE9FNikM1k3pXfGoJkcbl9zzcq2bxPRTZvE9Fm2xJs7+r/ACR3/wCr/JRZvE9EWbxPRRDXhmqbZzy/eCRb8UrcnP8AqG+Swi+T8JF8uN0lRGUGxuNq1S11WXm9VN/MT9Yd9r/gOiELm/T9/wBMVy/4/aIGkKwZirnBH9wo7fV+tT5C31h2IQsgS3SNa0WFXUAZZCV27ZvVXVdQ9pa6olcDtBeT+tpQhKEo6R7wMb3OtkLm9lVCEoDU6tqmhoFTMAA2wDzuFh8slDa+rYbtqpwb3ykKEKl62PsiTX1bjc1U5zvnIdu1Ar6tosKqcDgJChCiA11Wb3qpjfb5Q5pTnukcXPcXOO0k3KEJQEIQhaIshCFECAhCSGOke5oa57i0bATkFVCFexH/2Q==', 0, 1696427762072, NULL, NULL, NULL, NULL, NULL); @@ -4213,7 +4213,7 @@ DROP TABLE IF EXISTS `core_opt_recent`; CREATE TABLE `core_opt_recent` ( `id` bigint NOT NULL COMMENT 'ID', - `resource_id` bigint NOT NULL COMMENT '资源ID', + `resource_id` bigint DEFAULT NULL COMMENT '资源ID', `uid` bigint NOT NULL COMMENT '用户ID', `resource_type` int NOT NULL COMMENT '资源类型', `opt_type` int DEFAULT NULL COMMENT '1 新建 2 修改', diff --git a/core/core-backend/src/main/resources/db/desktop/V2.10.4__ddl.sql b/core/core-backend/src/main/resources/db/desktop/V2.10.4__ddl.sql index 8ad2a52368..5d9a8827b4 100644 --- a/core/core-backend/src/main/resources/db/desktop/V2.10.4__ddl.sql +++ b/core/core-backend/src/main/resources/db/desktop/V2.10.4__ddl.sql @@ -2,4 +2,92 @@ UPDATE `visualization_background` SET `name` = 'Board10' WHERE `id` = 'dark_1'; UPDATE `visualization_subject` SET `name` = 'chart.light_theme' WHERE `id` = '10001'; UPDATE `visualization_subject` SET `name` = 'chart.dark_theme' WHERE `id` = '10002'; ALTER TABLE core_chart_view ADD COLUMN sort_priority longtext null comment '字段排序优先级'; -DELETE FROM area where id = '156320571'; \ No newline at end of file +DELETE FROM area where id = '156320571'; + +ALTER TABLE `core_api_traffic` COMMENT = 'API并发限流阈值设置表'; + +ALTER TABLE `core_copilot_config` + MODIFY COLUMN `copilot_url` varchar(255) NULL DEFAULT NULL COMMENT 'copilot服务端地址', + MODIFY COLUMN `username` varchar(255) NULL DEFAULT NULL COMMENT '用户名', + MODIFY COLUMN `pwd` varchar(255) NULL DEFAULT NULL COMMENT '密码', + COMMENT = 'copilot配置信息表'; + +ALTER TABLE `core_copilot_msg` COMMENT = 'copilot问答信息表'; + +ALTER TABLE `core_copilot_token` + MODIFY COLUMN `token` longtext NULL COMMENT 'token值', + MODIFY COLUMN `update_time` bigint(0) NULL DEFAULT NULL COMMENT '更新时间', + COMMENT = 'copilot token记录表'; + +ALTER TABLE `core_font` + MODIFY COLUMN `size` double NULL DEFAULT NULL COMMENT '文件大小', + MODIFY COLUMN `size_type` varchar(255) NULL DEFAULT NULL COMMENT '存储单位', + COMMENT = '字体表'; + +ALTER TABLE `de_template_version` + MODIFY COLUMN `installed_rank` int(0) NOT NULL COMMENT '主键', + MODIFY COLUMN `version` varchar(50) NULL DEFAULT NULL COMMENT '版本', + MODIFY COLUMN `description` varchar(200) NULL DEFAULT NULL COMMENT '描述', + MODIFY COLUMN `type` varchar(20) NULL DEFAULT NULL COMMENT '类型', + MODIFY COLUMN `script` varchar(1000) NOT NULL COMMENT '脚本', + MODIFY COLUMN `checksum` int(0) NULL DEFAULT NULL COMMENT 'CheckSum校验码', + MODIFY COLUMN `installed_by` varchar(100) NULL DEFAULT NULL COMMENT '安装人', + MODIFY COLUMN `installed_on` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '安装时间', + MODIFY COLUMN `execution_time` int(0) NULL DEFAULT NULL COMMENT '执行时间', + MODIFY COLUMN `success` tinyint(1) NOT NULL COMMENT '执行状态', + COMMENT = 'dataease模板配置版本记录表'; + +ALTER TABLE `demo_tea_material` COMMENT = '连锁茶饮销售看板demo数据'; + +ALTER TABLE `demo_tea_order` COMMENT = '连锁茶饮销售看板demo数据'; + +ALTER TABLE `license` + MODIFY COLUMN `id` bigint(0) NOT NULL COMMENT 'ID', + MODIFY COLUMN `update_time` bigint(0) NULL DEFAULT NULL COMMENT '更新时间', + MODIFY COLUMN `license` longtext NULL COMMENT 'license', + MODIFY COLUMN `f2c_license` longtext NULL COMMENT 'license描述信息', + COMMENT = '企业版许可证信息表'; + +ALTER TABLE `visualization_report_filter` COMMENT = '定时报告过自定义过滤组件信息'; + +ALTER TABLE `visualization_subject` + MODIFY COLUMN `id` varchar(50) NOT NULL COMMENT '主键'; + +ALTER TABLE `xpack_platform_token` + MODIFY COLUMN `id` int(0) NOT NULL COMMENT '主键', + MODIFY COLUMN `token` varchar(255) NOT NULL COMMENT '认证token', + MODIFY COLUMN `create_time` bigint(0) NOT NULL COMMENT '创建时间', + MODIFY COLUMN `exp_time` bigint(0) NOT NULL COMMENT '过期时间', + COMMENT = '认证token信息表'; + +ALTER TABLE `xpack_setting_authentication` COMMENT = '认证设置'; + +ALTER TABLE `xpack_share` COMMENT = '公共链接'; + +ALTER TABLE `xpack_threshold_info` + MODIFY COLUMN `id` bigint(0) NOT NULL COMMENT '主键', + COMMENT = '告警信息表'; + +ALTER TABLE `xpack_threshold_instance` + MODIFY COLUMN `id` bigint(0) NOT NULL COMMENT '主键', + COMMENT = '告警实例表'; + +ALTER TABLE `core_area_custom` + MODIFY COLUMN `id` varchar(255) NOT NULL COMMENT '主键', + MODIFY COLUMN `name` varchar(255) NOT NULL COMMENT '自定义区域名称', + MODIFY COLUMN `pid` varchar(255) NOT NULL COMMENT '父级ID'; + +ALTER TABLE `core_export_task` + MODIFY COLUMN `id` varchar(255) NOT NULL COMMENT '主键', + MODIFY COLUMN `user_id` bigint(0) NOT NULL COMMENT '用户ID', + MODIFY COLUMN `file_name` varchar(2048) NULL DEFAULT NULL COMMENT '文件名称', + MODIFY COLUMN `file_size` double NULL DEFAULT NULL COMMENT '文件大小', + MODIFY COLUMN `file_size_unit` varchar(255) NULL DEFAULT NULL COMMENT '单位', + MODIFY COLUMN `export_from` varchar(255) NULL DEFAULT NULL COMMENT '导出来源ID', + MODIFY COLUMN `export_status` varchar(255) NULL DEFAULT NULL COMMENT '导出状态', + MODIFY COLUMN `export_from_type` varchar(255) NULL DEFAULT NULL COMMENT '导出来源类型', + MODIFY COLUMN `export_time` bigint(0) NULL DEFAULT NULL COMMENT '导出时间', + MODIFY COLUMN `export_progress` varchar(255) NULL DEFAULT NULL COMMENT '导出进度', + MODIFY COLUMN `export_machine_name` varchar(512) NULL DEFAULT NULL COMMENT '导出机器名称'; + +ALTER TABLE `core_ds_finish_page` COMMENT = '是否显示完成页面记录表'; diff --git a/core/core-backend/src/main/resources/db/desktop/V2.1__ddl.sql b/core/core-backend/src/main/resources/db/desktop/V2.1__ddl.sql index 43b2e5bdf7..1486e594e8 100644 --- a/core/core-backend/src/main/resources/db/desktop/V2.1__ddl.sql +++ b/core/core-backend/src/main/resources/db/desktop/V2.1__ddl.sql @@ -70,6 +70,10 @@ VALUES (30, 0, 1, 'toolbox', null, 7, 'icon_template', '/toolbox', 1, 1, 0); INSERT INTO `core_menu` VALUES (31, 30, 2, 'template-setting', 'toolbox/template-setting', 1, 'icon_template', '/template-setting', 0, 1, 1); + +ALTER TABLE `core_opt_recent` + MODIFY COLUMN `resource_id` bigint NULL COMMENT '资源ID'; + ALTER TABLE core_opt_recent ADD `resource_name` varchar(255) NULL COMMENT '资源名称'; diff --git a/core/core-backend/src/main/resources/db/migration/V2.10.4__ddl.sql b/core/core-backend/src/main/resources/db/migration/V2.10.4__ddl.sql index 2c6eeb5277..0891a2ece8 100644 --- a/core/core-backend/src/main/resources/db/migration/V2.10.4__ddl.sql +++ b/core/core-backend/src/main/resources/db/migration/V2.10.4__ddl.sql @@ -4,3 +4,91 @@ UPDATE `visualization_subject` SET `name` = 'chart.dark_theme' WHERE `id` = '100 CREATE INDEX idx_dataset_table_task_log_A ON core_datasource_task_log(ds_id, table_name, start_time); ALTER TABLE core_chart_view ADD COLUMN sort_priority longtext null comment '字段排序优先级'; DELETE FROM area where id = '156320571'; + +ALTER TABLE `core_api_traffic` COMMENT = 'API并发限流阈值设置表'; + +ALTER TABLE `core_copilot_config` + MODIFY COLUMN `copilot_url` varchar(255) NULL DEFAULT NULL COMMENT 'copilot服务端地址', + MODIFY COLUMN `username` varchar(255) NULL DEFAULT NULL COMMENT '用户名', + MODIFY COLUMN `pwd` varchar(255) NULL DEFAULT NULL COMMENT '密码', + COMMENT = 'copilot配置信息表'; + +ALTER TABLE `core_copilot_msg` COMMENT = 'copilot问答信息表'; + +ALTER TABLE `core_copilot_token` + MODIFY COLUMN `token` longtext NULL COMMENT 'token值', + MODIFY COLUMN `update_time` bigint(0) NULL DEFAULT NULL COMMENT '更新时间', + COMMENT = 'copilot token记录表'; + +ALTER TABLE `core_font` + MODIFY COLUMN `size` double NULL DEFAULT NULL COMMENT '文件大小', + MODIFY COLUMN `size_type` varchar(255) NULL DEFAULT NULL COMMENT '存储单位', + COMMENT = '字体表'; + +ALTER TABLE `de_template_version` + MODIFY COLUMN `installed_rank` int(0) NOT NULL COMMENT '主键', + MODIFY COLUMN `version` varchar(50) NULL DEFAULT NULL COMMENT '版本', + MODIFY COLUMN `description` varchar(200) NULL DEFAULT NULL COMMENT '描述', + MODIFY COLUMN `type` varchar(20) NULL DEFAULT NULL COMMENT '类型', + MODIFY COLUMN `script` varchar(1000) NOT NULL COMMENT '脚本', + MODIFY COLUMN `checksum` int(0) NULL DEFAULT NULL COMMENT 'CheckSum校验码', + MODIFY COLUMN `installed_by` varchar(100) NULL DEFAULT NULL COMMENT '安装人', + MODIFY COLUMN `installed_on` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '安装时间', + MODIFY COLUMN `execution_time` int(0) NULL DEFAULT NULL COMMENT '执行时间', + MODIFY COLUMN `success` tinyint(1) NOT NULL COMMENT '执行状态', + COMMENT = 'dataease模板配置版本记录表'; + +ALTER TABLE `demo_tea_material` COMMENT = '连锁茶饮销售看板demo数据'; + +ALTER TABLE `demo_tea_order` COMMENT = '连锁茶饮销售看板demo数据'; + +ALTER TABLE `license` + MODIFY COLUMN `id` bigint(0) NOT NULL COMMENT 'ID', + MODIFY COLUMN `update_time` bigint(0) NULL DEFAULT NULL COMMENT '更新时间', + MODIFY COLUMN `license` longtext NULL COMMENT 'license', + MODIFY COLUMN `f2c_license` longtext NULL COMMENT 'license描述信息', + COMMENT = '企业版许可证信息表'; + +ALTER TABLE `visualization_report_filter` COMMENT = '定时报告过自定义过滤组件信息'; + +ALTER TABLE `visualization_subject` + MODIFY COLUMN `id` varchar(50) NOT NULL COMMENT '主键'; + +ALTER TABLE `xpack_platform_token` + MODIFY COLUMN `id` int(0) NOT NULL COMMENT '主键', + MODIFY COLUMN `token` varchar(255) NOT NULL COMMENT '认证token', + MODIFY COLUMN `create_time` bigint(0) NOT NULL COMMENT '创建时间', + MODIFY COLUMN `exp_time` bigint(0) NOT NULL COMMENT '过期时间', + COMMENT = '认证token信息表'; + +ALTER TABLE `xpack_setting_authentication` COMMENT = '认证设置'; + +ALTER TABLE `xpack_share` COMMENT = '公共链接'; + +ALTER TABLE `xpack_threshold_info` + MODIFY COLUMN `id` bigint(0) NOT NULL COMMENT '主键', + COMMENT = '告警信息表'; + +ALTER TABLE `xpack_threshold_instance` + MODIFY COLUMN `id` bigint(0) NOT NULL COMMENT '主键', + COMMENT = '告警实例表'; + +ALTER TABLE `core_area_custom` + MODIFY COLUMN `id` varchar(255) NOT NULL COMMENT '主键', + MODIFY COLUMN `name` varchar(255) NOT NULL COMMENT '自定义区域名称', + MODIFY COLUMN `pid` varchar(255) NOT NULL COMMENT '父级ID'; + +ALTER TABLE `core_export_task` + MODIFY COLUMN `id` varchar(255) NOT NULL COMMENT '主键', + MODIFY COLUMN `user_id` bigint(0) NOT NULL COMMENT '用户ID', + MODIFY COLUMN `file_name` varchar(2048) NULL DEFAULT NULL COMMENT '文件名称', + MODIFY COLUMN `file_size` double NULL DEFAULT NULL COMMENT '文件大小', + MODIFY COLUMN `file_size_unit` varchar(255) NULL DEFAULT NULL COMMENT '单位', + MODIFY COLUMN `export_from` varchar(255) NULL DEFAULT NULL COMMENT '导出来源ID', + MODIFY COLUMN `export_status` varchar(255) NULL DEFAULT NULL COMMENT '导出状态', + MODIFY COLUMN `export_from_type` varchar(255) NULL DEFAULT NULL COMMENT '导出来源类型', + MODIFY COLUMN `export_time` bigint(0) NULL DEFAULT NULL COMMENT '导出时间', + MODIFY COLUMN `export_progress` varchar(255) NULL DEFAULT NULL COMMENT '导出进度', + MODIFY COLUMN `export_machine_name` varchar(512) NULL DEFAULT NULL COMMENT '导出机器名称'; + +ALTER TABLE `core_ds_finish_page` COMMENT = '是否显示完成页面记录表'; diff --git a/core/core-backend/src/main/resources/mybatis/ExtDataVisualizationMapper.xml b/core/core-backend/src/main/resources/mybatis/ExtDataVisualizationMapper.xml index 1eaac4ce15..908a83503c 100644 --- a/core/core-backend/src/main/resources/mybatis/ExtDataVisualizationMapper.xml +++ b/core/core-backend/src/main/resources/mybatis/ExtDataVisualizationMapper.xml @@ -233,7 +233,11 @@ LEFT JOIN core_store ON dvResource.id = core_store.resource_id AND core_store.uid = #{uid} INNER JOIN core_opt_recent ON dvResource.resource_id = core_opt_recent.resource_id - AND core_opt_recent.uid = #{uid} ${ew.customSqlSegment} + AND core_opt_recent.uid = #{uid} + + AND LOWER(dvResource.name) LIKE LOWER(CONCAT('%', #{keyword}, '%')) + + ${ew.customSqlSegment} @@ -409,8 +413,8 @@ core_chart_view.table_id, core_chart_view.`type`, core_chart_view.render, - core_chart_view.scene_id as 'visualization_id', core_dataset_table_field.id AS 'field_id', core_dataset_table_field.origin_name, - core_dataset_table_field.`name` AS 'field_name', core_dataset_table_field.type AS 'field_type', core_dataset_table_field.de_type + core_chart_view.scene_id as `visualization_id`, core_dataset_table_field.id AS `field_id`, core_dataset_table_field.origin_name, + core_dataset_table_field.`name` AS `field_name`, core_dataset_table_field.type AS `field_type`, core_dataset_table_field.de_type FROM core_chart_view LEFT JOIN core_dataset_table_field ON core_chart_view.table_id = core_dataset_table_field.dataset_group_id diff --git a/core/core-backend/src/main/resources/mybatis/ExtVisualizationLinkJumpMapper.xml b/core/core-backend/src/main/resources/mybatis/ExtVisualizationLinkJumpMapper.xml index 0413c7dde2..e1be07a325 100644 --- a/core/core-backend/src/main/resources/mybatis/ExtVisualizationLinkJumpMapper.xml +++ b/core/core-backend/src/main/resources/mybatis/ExtVisualizationLinkJumpMapper.xml @@ -30,7 +30,7 @@ @@ -85,7 +85,9 @@ visualization_link_jump_info.window_size, visualization_link_jump_info.target_dv_id, visualization_link_jump_info.content, + 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, @@ -102,20 +104,29 @@ LEFT JOIN visualization_link_jump_info ON visualization_link_jump.id = visualization_link_jump_info.link_jump_id AND core_dataset_table_field.id = visualization_link_jump_info.source_field_id 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' - ORDER BY - CONVERT ( - core_dataset_table_field.NAME USING gbk) + + ORDER BY + CONVERT ( + core_dataset_table_field.NAME USING gbk) + + + ORDER BY core_dataset_table_field.name; + + SELECT core_chart_view.id AS source_view_id, ${uid} as queryUid, + ${isDesktop} as isDesktop, visualization_link_jump.id, #{dvId} as source_dv_id, visualization_link_jump.link_jump_info, ifnull(visualization_link_jump.checked, 0) AS checked @@ -176,109 +188,58 @@ - DELETE - ljtv - FROM - visualization_link_jump_target_view_info ljtv, - visualization_link_jump_info lji, - visualization_link_jump lj - WHERE - ljtv.link_jump_info_id = lji.id - AND lji.link_jump_id = lj.id - AND lj.source_dv_id = - #{dvId} - AND - lj - . - source_view_id - = - #{viewId} + DELETE FROM visualization_link_jump_target_view_info + WHERE link_jump_info_id IN ( + SELECT lji.id + FROM visualization_link_jump_info lji + JOIN visualization_link_jump lj ON lji.link_jump_id = lj.id + WHERE lj.source_dv_id = #{dvId} + AND lj.source_view_id = #{viewId} + ); - DELETE - lji - FROM - visualization_link_jump_info lji, - visualization_link_jump lj - WHERE - lji.link_jump_id = lj.id - AND lj.source_dv_id = - #{dvId} - AND - lj - . - source_view_id - = - #{viewId} + DELETE FROM visualization_link_jump_info + WHERE link_jump_id IN ( + SELECT lj.id + FROM visualization_link_jump lj + WHERE lj.source_dv_id = #{dvId} + AND lj.source_view_id = #{viewId} + ); - DELETE - lj - FROM - visualization_link_jump lj - WHERE - lj.source_dv_id = - #{dvId} - AND - lj - . - source_view_id - = - #{viewId} + DELETE FROM visualization_link_jump + WHERE source_dv_id = #{dvId} + AND source_view_id = #{viewId} - DELETE - ljtv - FROM - visualization_link_jump_target_view_info ljtv, - visualization_link_jump_info lji, - visualization_link_jump lj - WHERE - ljtv.link_jump_info_id = lji.id - AND lji.link_jump_id = lj.id - AND (lj.source_dv_id = - #{dvId} - or - lji - . - target_dv_id - = - #{dvId} + DELETE FROM visualization_link_jump_target_view_info + WHERE link_jump_info_id IN ( + SELECT lji.id + FROM visualization_link_jump_info lji + JOIN visualization_link_jump lj ON lji.link_jump_id = lj.id + WHERE lj.source_dv_id = #{dvId} + OR lji.target_dv_id = #{dvId} ) - DELETE - lji - FROM - visualization_link_jump_info lji, - visualization_link_jump lj - WHERE - lji.link_jump_id = lj.id - AND (lj.source_dv_id = - #{dvId} - or - lji - . - target_dv_id - = - #{dvId} + DELETE FROM visualization_link_jump_info + WHERE link_jump_id IN ( + SELECT lj.id + FROM visualization_link_jump lj + WHERE lj.source_dv_id = #{dvId} + OR lj.target_dv_id = #{dvId} ) - - DELETE - lj - FROM - visualization_link_jump lj - WHERE - lj.source_dv_id = - #{dvId} - + + DELETE FROM visualization_link_jump + WHERE source_dv_id = #{dvId} + diff --git a/core/core-frontend/src/assets/svg/circle-packing-dark.svg b/core/core-frontend/src/assets/svg/circle-packing-dark.svg new file mode 100644 index 0000000000..0e663153ae --- /dev/null +++ b/core/core-frontend/src/assets/svg/circle-packing-dark.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/core/core-frontend/src/assets/svg/circle-packing-origin.svg b/core/core-frontend/src/assets/svg/circle-packing-origin.svg new file mode 100644 index 0000000000..f71ca3188f --- /dev/null +++ b/core/core-frontend/src/assets/svg/circle-packing-origin.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/core/core-frontend/src/assets/svg/circle-packing.svg b/core/core-frontend/src/assets/svg/circle-packing.svg new file mode 100644 index 0000000000..73380f1ad1 --- /dev/null +++ b/core/core-frontend/src/assets/svg/circle-packing.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/core/core-frontend/src/components/dashboard/DbToolbar.vue b/core/core-frontend/src/components/dashboard/DbToolbar.vue index 88dc7311d2..10e6cd2fa2 100644 --- a/core/core-frontend/src/components/dashboard/DbToolbar.vue +++ b/core/core-frontend/src/components/dashboard/DbToolbar.vue @@ -81,6 +81,7 @@ const outerParamsSetRef = ref(null) const { wsCache } = useCache('localStorage') const userStore = useUserStoreWithOut() const isIframe = computed(() => appStore.getIsIframe) +const desktop = wsCache.get('app.desktop') const props = defineProps({ createType: { @@ -619,18 +620,20 @@ const initOpenHandler = newWindow => { />
- - - + diff --git a/core/core-frontend/src/components/data-visualization/RealTimeGroup.vue b/core/core-frontend/src/components/data-visualization/RealTimeGroup.vue index b95b564845..585f277396 100644 --- a/core/core-frontend/src/components/data-visualization/RealTimeGroup.vue +++ b/core/core-frontend/src/components/data-visualization/RealTimeGroup.vue @@ -61,6 +61,8 @@ import dvShow from '@/assets/svg/dv-show.svg' import dvUnlock from '@/assets/svg/dv-unlock.svg' import dvLock from '@/assets/svg/dv-lock.svg' import dvMore from '@/assets/svg/dv-more.svg' +import dvExpandDown from '@/assets/svg/dv-expand-down.svg' +import dvExpandRight from '@/assets/svg/dv-expand-right.svg' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' import { snapshotStoreWithOut } from '@/store/modules/data-visualization/snapshot' import { layerStoreWithOut } from '@/store/modules/data-visualization/layer' @@ -73,6 +75,8 @@ import { lockStoreWithOut } from '@/store/modules/data-visualization/lock' import ContextMenuAsideDetails from '@/components/data-visualization/canvas/ContextMenuAsideDetails.vue' import ComposeShow from '@/components/data-visualization/canvas/ComposeShow.vue' import { composeStoreWithOut } from '@/store/modules/data-visualization/compose' +import circlePackingOrigin from '@/assets/svg/circle-packing-origin.svg' +import RealTimeTab from '@/components/data-visualization/RealTimeTab.vue' const dropdownMore = ref(null) const lockStore = lockStoreWithOut() @@ -233,7 +237,8 @@ const iconMap = { 'waterfall-origin': waterfallOrigin, 'word-cloud-origin': wordCloudOrigin, 't-heatmap-origin': tHeatmapOrigin, - group: group + group: group, + 'circle-packing-origin': circlePackingOrigin } const getIconName = item => { if (item.component === 'UserView') { @@ -276,6 +281,9 @@ const handleContextMenu = e => { document.body.removeChild(customContextMenu) }) } +const expandClick = component => { + component['expand'] = !component['expand'] +} diff --git a/core/core-frontend/src/views/chart/components/editor/editor-style/components/TooltipSelector.vue b/core/core-frontend/src/views/chart/components/editor/editor-style/components/TooltipSelector.vue index 218c9c52dc..a422617311 100644 --- a/core/core-frontend/src/views/chart/components/editor/editor-style/components/TooltipSelector.vue +++ b/core/core-frontend/src/views/chart/components/editor/editor-style/components/TooltipSelector.vue @@ -839,6 +839,7 @@ onMounted(() => { @@ -849,6 +850,7 @@ onMounted(() => { diff --git a/core/core-frontend/src/views/chart/components/editor/editor-style/components/table/TableHeaderSelector.vue b/core/core-frontend/src/views/chart/components/editor/editor-style/components/table/TableHeaderSelector.vue index c38ea05da4..3931d8f226 100644 --- a/core/core-frontend/src/views/chart/components/editor/editor-style/components/table/TableHeaderSelector.vue +++ b/core/core-frontend/src/views/chart/components/editor/editor-style/components/table/TableHeaderSelector.vue @@ -7,7 +7,7 @@ import icon_rightAlignment_outlined from '@/assets/svg/icon_right-alignment_outl import { computed, onMounted, PropType, reactive, watch } from 'vue' import { useI18n } from '@/hooks/web/useI18n' import { COLOR_PANEL, DEFAULT_TABLE_HEADER } from '@/views/chart/components/editor/util/chart' -import { ElSpace } from 'element-plus-secondary' +import { ElDivider, ElSpace } from 'element-plus-secondary' import { cloneDeep, defaultsDeep } from 'lodash-es' import { convertToAlphaColor, isAlphaColor } from '@/views/chart/components/js/util' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' @@ -94,67 +94,24 @@ onMounted(() => { ref="tableHeaderForm" label-position="top" > - - - - - - - - - + + + { + + + { .mobile-style { margin-top: 25px; } +.m-divider { + margin: 0 0 16px; + border-color: rgba(31, 35, 41, 0.15); + + &.divider-dark { + border-color: rgba(255, 255, 255, 0.15); + } +} 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 96491e194a..6032dd4dbc 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 @@ -44,7 +44,9 @@ export const DEFAULT_COLOR_CASE: DeepPartial = { tableHeaderBgColor: '#1E90FF', tableHeaderCornerBgColor: '#1E90FF', tableHeaderColBgColor: '#1E90FF', - tableHeaderFontColor: '#000000' + tableHeaderFontColor: '#000000', + tableHeaderCornerFontColor: '#000000', + tableHeaderColFontColor: '#000000' }, tableCell: { tableItemBgColor: '#FFFFFF', @@ -94,7 +96,9 @@ export const DEFAULT_COLOR_CASE_LIGHT: DeepPartial = { tableHeaderBgColor: '#1E90FF', tableHeaderCornerBgColor: '#1E90FF', tableHeaderColBgColor: '#1E90FF', - tableHeaderFontColor: '#000000' + tableHeaderFontColor: '#000000', + tableHeaderCornerFontColor: '#000000', + tableHeaderColFontColor: '#000000' }, tableCell: { tableItemBgColor: '#FFFFFF', @@ -143,7 +147,9 @@ export const DEFAULT_COLOR_CASE_DARK: DeepPartial = { tableHeaderBgColor: '#1E90FF', tableHeaderCornerBgColor: '#1E90FF', tableHeaderColBgColor: '#1E90FF', - tableHeaderFontColor: '#FFFFFF' + tableHeaderFontColor: '#FFFFFF', + tableHeaderCornerFontColor: '#FFFFFF', + tableHeaderColFontColor: '#FFFFFF' }, tableCell: { tableItemBgColor: '#131E42', @@ -418,11 +424,17 @@ export const DEFAULT_TABLE_HEADER: ChartTableHeaderAttr = { indexLabel: t('relation.index'), showIndex: false, tableHeaderAlign: 'left', + tableHeaderCornerAlign: 'left', + tableHeaderColAlign: 'left', tableHeaderBgColor: '#1E90FF', tableHeaderCornerBgColor: '#1E90FF', tableHeaderColBgColor: '#1E90FF', tableHeaderFontColor: '#000000', + tableHeaderCornerFontColor: '#000000', + tableHeaderColFontColor: '#000000', tableTitleFontSize: 12, + tableTitleCornerFontSize: 12, + tableTitleColFontSize: 12, tableTitleHeight: 36, tableHeaderSort: false, showColTooltip: false, @@ -431,7 +443,11 @@ export const DEFAULT_TABLE_HEADER: ChartTableHeaderAttr = { showHorizonBorder: true, showVerticalBorder: true, isItalic: false, - isBolder: true + isCornerItalic: false, + isColItalic: false, + isBolder: true, + isCornerBolder: true, + isColBolder: true } export const DEFAULT_TABLE_CELL: ChartTableCellAttr = { tableFontColor: '#000000', @@ -1504,6 +1520,13 @@ export const CHART_TYPE_CONFIGS = [ value: 'sankey', title: t('chart.chart_sankey'), icon: 'sankey' + }, + { + render: 'antv', + category: 'distribute', + value: 'circle-packing', + title: t('chart.chart_circle_packing'), + icon: 'circle-packing' } ] }, 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 e752aaf600..e12fa58245 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 @@ -246,8 +246,12 @@ export class SymbolicMap extends L7ChartView { const extBubbleIds = chart.extBubble.map(i => i.id) conditions = filter(conditions, c => extBubbleIds.includes(c.fieldId)) + const baseColor = colorsWithAlpha[0] + const baseColorList = [] + const data = chart.data?.tableRow ? chart.data.tableRow.map((item, index) => { + item['_index'] = '_index' + index // 颜色标识 const identifier = item[xAxisExt[0]?.dataeaseName] // 检查该标识是否已有颜色分配,如果没有则分配 @@ -257,6 +261,9 @@ export class SymbolicMap extends L7ChartView { // 记录分配的颜色 colorAssignments.set(identifier, color) } + + baseColorList[index] = color + if (conditions.length > 0) { for (let i = 0; i < conditions.length; i++) { const c = conditions[i] @@ -271,38 +278,45 @@ export class SymbolicMap extends L7ChartView { const start = parseFloat(t.min) const end = parseFloat(t.max) if (start <= value && value <= end) { - color = t.color - colorsWithAlpha[index] = hexColorToRGBA(_color, alpha) + color = hexColorToRGBA(_color, alpha) + colorsWithAlpha[index] = color + baseColorList[index] = color } } else if ('lt' === t.term) { if (value < v) { - color = t.color - colorsWithAlpha[index] = hexColorToRGBA(_color, alpha) + color = hexColorToRGBA(_color, alpha) + colorsWithAlpha[index] = color + baseColorList[index] = color } } else if ('le' === t.term) { if (value <= v) { - color = t.color - colorsWithAlpha[index] = hexColorToRGBA(_color, alpha) + color = hexColorToRGBA(_color, alpha) + colorsWithAlpha[index] = color + baseColorList[index] = color } } else if ('gt' === t.term) { if (value > v) { - color = t.color - colorsWithAlpha[index] = hexColorToRGBA(_color, alpha) + color = hexColorToRGBA(_color, alpha) + colorsWithAlpha[index] = color + baseColorList[index] = color } } else if ('ge' === t.term) { if (value >= v) { - color = t.color - colorsWithAlpha[index] = hexColorToRGBA(_color, alpha) + color = hexColorToRGBA(_color, alpha) + colorsWithAlpha[index] = color + baseColorList[index] = color } } else if ('eq' === t.term) { if (value === v) { - color = t.color - colorsWithAlpha[index] = hexColorToRGBA(_color, alpha) + color = hexColorToRGBA(_color, alpha) + colorsWithAlpha[index] = color + baseColorList[index] = color } } else if ('not_eq' === t.term) { if (value !== v) { - color = t.color - colorsWithAlpha[index] = hexColorToRGBA(_color, alpha) + color = hexColorToRGBA(_color, alpha) + colorsWithAlpha[index] = color + baseColorList[index] = color } } } @@ -349,7 +363,7 @@ export class SymbolicMap extends L7ChartView { }) } } else { - pointLayer.shape(mapSymbol).color(xAxisExt[0]?.dataeaseName, colorsWithAlpha) + pointLayer.shape(mapSymbol).color('_index', colorsWithAlpha) pointLayer.style({ stroke: { field: 'color' @@ -366,7 +380,7 @@ export class SymbolicMap extends L7ChartView { pointLayer.shape('customIcon') } else { const parser = new DOMParser() - const color = colorsWithAlpha[0] + const color = baseColor const fillRegex = /(fill="[^"]*")/g const svgStr = basicStyle.customIcon.replace(fillRegex, '') const doc = parser.parseFromString(svgStr, 'image/svg+xml') @@ -378,9 +392,11 @@ export class SymbolicMap extends L7ChartView { } else { pointLayer .shape(mapSymbol) - .color(colorsWithAlpha[0]) + .color('_index', baseColorList) .style({ - stroke: colorsWithAlpha[0], + stroke: { + field: 'color' + }, strokeWidth: mapSymbolStrokeWidth, opacity: mapSymbolOpacity / 10 }) diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/others/circle-packing.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/others/circle-packing.ts new file mode 100644 index 0000000000..0235050396 --- /dev/null +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/others/circle-packing.ts @@ -0,0 +1,298 @@ +import { + G2PlotChartView, + G2PlotDrawOptions +} from '@/views/chart/components/js/panel/types/impl/g2plot' +import type { + CirclePacking as G2CirclePacking, + CirclePackingOptions +} from '@antv/g2plot/esm/plots/circle-packing' +import { flow, parseJson } from '@/views/chart/components/js/util' +import { getPadding } from '@/views/chart/components/js/panel/common/common_antv' +import { useI18n } from '@/hooks/web/useI18n' +import type { Datum } from '@antv/g2plot/esm/types/common' +import { valueFormatter } from '@/views/chart/components/js/formatter' +import { cloneDeep } from 'lodash-es' + +const { t } = useI18n() +const DEFAULT_DATA = [] +/** + * 圆形填充图 + */ +export class CirclePacking extends G2PlotChartView { + properties: EditorProperty[] = [ + 'basic-style-selector', + 'background-overall-component', + 'border-style', + 'label-selector', + 'legend-selector', + 'title-selector', + 'tooltip-selector', + 'jump-set', + 'linkage' + ] + propertyInner: EditorPropertyInner = { + 'background-overall-component': ['all'], + 'border-style': ['all'], + 'basic-style-selector': ['colors', 'alpha', 'circleBorderStyle'], + 'title-selector': [ + 'title', + 'fontSize', + 'color', + 'hPosition', + 'isItalic', + 'isBolder', + 'remarkShow', + 'fontFamily', + 'letterSpace', + 'fontShadow' + ], + 'function-cfg': ['emptyDataStrategy'], + 'label-selector': ['color', 'fontSize'], + 'legend-selector': ['icon', 'orient', 'fontSize', 'color', 'hPosition', 'vPosition'], + 'tooltip-selector': ['color', 'fontSize', 'backgroundColor', 'tooltipFormatter', 'show'] + } + axis: AxisType[] = ['xAxis', 'yAxis', 'filter', 'drill'] + axisConfig: AxisConfig = { + xAxis: { + name: `${t('chart.circle_packing_name')} / ${t('chart.dimension')}`, + type: 'd' + }, + yAxis: { + name: `${t('chart.circle_packing_value')} / ${t('chart.quota')}`, + type: 'q', + limit: 1, + allowEmpty: true + } + } + async drawChart(drawOptions: G2PlotDrawOptions): Promise { + const { chart, container, action } = drawOptions + if (chart?.data?.tableRow?.length) { + // data + const data = chart.data.tableRow + const { xAxis, yAxis } = chart + const ySort = yAxis[0]?.sort ?? 'none' + const sort = { + sort: (a, b) => + ySort === 'asc' ? a.value - b.value : ySort === 'desc' ? b.value - a.value : 0 + } + // 根据配置获取节点的key,用于构建节点树,拖入字段顺序即为节点的层级 + const nodeKeys = xAxis.map(item => item.dataeaseName) + // 将数据转为圆形填充图数据格式 + const getCirclePackingData = () => { + const result = [{ name: t('commons.all'), children: [] }] + const addNode = (nodes, item, level) => { + if (level >= nodeKeys.length) return + const key = nodeKeys[level] + const value = item[key] + let node = nodes.find(n => n.name === value) + if (!node) { + node = { name: value, field: xAxis.find(f => f.dataeaseName === key), children: [] } + nodes.push(node) + } + if (level === nodeKeys.length - 1) { + node.value = yAxis.length ? item[yAxis[0].dataeaseName] : 1 + } else { + addNode(node.children, item, level + 1) + } + } + data.forEach(item => addNode(result[0].children, item, 0)) + return result[0] + } + // options + const initOptions: CirclePackingOptions = { + data: getCirclePackingData(), + appendPadding: getPadding(chart), + hierarchyConfig: { + ...(ySort === 'none' ? {} : sort) + }, + interactions: [ + { + type: 'legend-active', + cfg: { + start: [{ trigger: 'legend-item:mouseenter', action: ['element-active:reset'] }], + end: [{ trigger: 'legend-item:mouseleave', action: ['element-active:reset'] }] + } + }, + { + type: 'legend-filter', + cfg: { + start: [ + { + trigger: 'legend-item:click', + action: [ + 'list-unchecked:toggle', + 'data-filter:filter', + 'element-active:reset', + 'element-highlight:reset' + ] + } + ] + } + } + ] + } + const options = this.setupOptions(chart, initOptions) + const { CirclePacking: G2CirclePacking } = await import( + '@antv/g2plot/esm/plots/circle-packing' + ) + const newChart = new G2CirclePacking(container, options) + newChart.on('point:click', param => { + const data = param?.data?.data + if (data?.name === t('commons.all')) { + return + } + action({ + x: param.x, + y: param.y, + data: { + data: { + ...data, + dimensionList: [ + { + id: data?.field?.id, + value: data.name, + name: data.name + } + ] + } + } + }) + }) + return newChart + } + } + + protected configBasicStyle(chart: Chart, options: CirclePackingOptions): CirclePackingOptions { + // size + const customAttr: DeepPartial = parseJson(chart.customAttr) + const s = JSON.parse(JSON.stringify(customAttr.basicStyle)) + // 圆形边框样式 + const pointStyle = { + stroke: s.circleBorderColor, + lineWidth: s.circleBorderWidth ?? 0 + } + const padding = s.circlePadding + return { + ...options, + hierarchyConfig: { + ...options.hierarchyConfig, + padding: padding / 100 ?? 0 + }, + pointStyle + } + } + + protected configLabel(chart: Chart, options: CirclePackingOptions): CirclePackingOptions { + const tmpOptions = super.configLabel(chart, options) + if (!tmpOptions.label) { + return { + ...tmpOptions, + label: false + } + } + const { label: labelAttr } = parseJson(chart.customAttr) + const label = { + ...tmpOptions.label, + textAlign: 'center', + offsetY: 5, + layout: labelAttr.fullDisplay ? [{ type: 'limit-in-plot' }] : tmpOptions.label.layout, + formatter: (d: Datum, _point) => { + return d.children.length === 0 ? d.name : '' + } + } + return { + ...tmpOptions, + label + } + } + + protected configTooltip(chart: Chart, options: CirclePackingOptions): CirclePackingOptions { + const temOptions = super.configTooltip(chart, options) + if (!temOptions.tooltip) { + return temOptions + } + const tooltipAttr = parseJson(chart.customAttr).tooltip + return { + ...temOptions, + tooltip: { + ...temOptions, + fields: ['name', 'value'], + formatter: d => { + let value = d.value + if (tooltipAttr.tooltipFormatter) { + value = valueFormatter(value, tooltipAttr.tooltipFormatter) + } + return { name: d.name, value } + } + } + } + } + configEmptyDataStrategy(chart: Chart, options: CirclePackingOptions): CirclePackingOptions { + const { functionCfg } = parseJson(chart.senior) + const emptyDataStrategy = functionCfg.emptyDataStrategy + const setChildren = children => { + if (emptyDataStrategy === 'ignoreData') { + for (let i = children.length - 1; i >= 0; i--) { + let isNotNullChildren = [] + if (children[i].children?.length) { + isNotNullChildren = children[i].children.filter(item => item.value !== null) + } + if (children[i].children?.length && isNotNullChildren.length) { + setChildren(children[i].children) + } + if (children[i]?.hasOwnProperty('value') && children[i].value === null) { + children.splice(i, 1) + } + if (!children[i]?.hasOwnProperty('value') && isNotNullChildren.length === 0) { + children.splice(i, 1) + } + } + } else { + for (let i = children.length - 1; i >= 0; i--) { + let isNotNullChildren = [] + if (children[i].children?.length) { + isNotNullChildren = children[i].children.filter(item => item.value !== null) + if (!isNotNullChildren.length) { + children[i].children = [] + continue + } + } + setChildren(children[i].children) + } + } + } + const data = cloneDeep(options.data.children) + setChildren(data) + options.data.children = data + return options + } + setupDefaultOptions(chart: ChartObj): ChartObj { + const { customAttr, customStyle, senior } = chart + const { label, basicStyle } = customAttr + const { legend } = customStyle + senior.functionCfg.emptyDataStrategy = 'ignoreData' + customAttr.label = { + ...label, + show: true + } + legend.show = false + basicStyle.circleBorderWidth = 0 + basicStyle.circleBorderColor = '#fff' + basicStyle.circlePadding = 0 + return chart + } + protected setupOptions(chart: Chart, options: CirclePackingOptions): CirclePackingOptions { + return flow( + this.configTheme, + this.configEmptyDataStrategy, + this.configBasicStyle, + this.configLabel, + this.configTooltip, + this.configLegend + )(chart, options) + } + + constructor() { + super('circle-packing', DEFAULT_DATA) + } +} diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-pivot.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-pivot.ts index 3cd930c124..c4b095c5cc 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-pivot.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-pivot.ts @@ -388,8 +388,20 @@ export class TablePivot extends S2ChartView { tableBorderColor = hexColorToRGBA(tableBorderColor, basicStyle.alpha) } const tableHeaderFontColor = hexColorToRGBA(tableHeader.tableHeaderFontColor, basicStyle.alpha) + const tableHeaderColFontColor = hexColorToRGBA( + tableHeader.tableHeaderColFontColor, + basicStyle.alpha + ) + const tableHeaderCornerFontColor = hexColorToRGBA( + tableHeader.tableHeaderCornerFontColor, + basicStyle.alpha + ) const fontStyle = tableHeader.isItalic ? 'italic' : 'normal' + const colFontStyle = tableHeader.isColItalic ? 'italic' : 'normal' + const cornerFontStyle = tableHeader.isCornerItalic ? 'italic' : 'normal' const fontWeight = tableHeader.isBolder === false ? 'normal' : 'bold' + const colFontWeight = tableHeader.isColBolder === false ? 'normal' : 'bold' + const cornerFontWeight = tableHeader.isCornerBolder === false ? 'normal' : 'bold' const pivotTheme = { rowCell: { cell: { @@ -398,38 +410,59 @@ export class TablePivot extends S2ChartView { verticalBorderColor: tableBorderColor }, text: { - fill: tableHeaderFontColor, - fontSize: tableHeader.tableTitleFontSize, - textAlign: tableHeader.tableHeaderAlign, + fill: tableHeaderColFontColor, + fontSize: tableHeader.tableTitleColFontSize, + textAlign: tableHeader.tableHeaderColAlign, textBaseline: 'top', - fontStyle, - fontWeight + fontStyle: colFontStyle, + fontWeight: colFontWeight }, bolderText: { - fill: tableHeaderFontColor, - fontSize: tableHeader.tableTitleFontSize, - textAlign: tableHeader.tableHeaderAlign, - fontStyle, - fontWeight + fill: tableHeaderColFontColor, + fontSize: tableHeader.tableTitleColFontSize, + textAlign: tableHeader.tableHeaderColAlign, + fontStyle: colFontStyle, + fontWeight: colFontWeight }, measureText: { - fill: tableHeaderFontColor, - fontSize: tableHeader.tableTitleFontSize, - textAlign: tableHeader.tableHeaderAlign, - fontStyle, - fontWeight + fill: tableHeaderColFontColor, + fontSize: tableHeader.tableTitleColFontSize, + textAlign: tableHeader.tableHeaderColAlign, + fontStyle: colFontStyle, + fontWeight: colFontWeight }, seriesText: { - fill: tableHeaderFontColor, - fontSize: tableHeader.tableTitleFontSize, - textAlign: tableHeader.tableHeaderAlign, - fontStyle, - fontWeight + fill: tableHeaderColFontColor, + fontSize: tableHeader.tableTitleColFontSize, + textAlign: tableHeader.tableHeaderColAlign, + fontStyle: colFontStyle, + fontWeight: colFontWeight } }, cornerCell: { cell: { backgroundColor: tableHeaderCornerBgColor + }, + text: { + fill: tableHeaderCornerFontColor, + fontSize: tableHeader.tableTitleCornerFontSize, + textAlign: tableHeader.tableHeaderCornerAlign, + fontStyle: cornerFontStyle, + fontWeight: cornerFontWeight + }, + bolderText: { + fill: tableHeaderCornerFontColor, + fontSize: tableHeader.tableTitleCornerFontSize, + textAlign: tableHeader.tableHeaderCornerAlign, + fontStyle: cornerFontStyle, + fontWeight: cornerFontWeight + }, + measureText: { + fill: tableHeaderCornerFontColor, + fontSize: tableHeader.tableTitleCornerFontSize, + textAlign: tableHeader.tableHeaderCornerAlign, + fontStyle: cornerFontStyle, + fontWeight: cornerFontWeight } } } @@ -527,7 +560,7 @@ function customCalcFunc(query, data, status, chart, totalCfgMap, axisMap, custom } } -function getCustomCalcResult(query, axisMap, chart: ChartObj, status: TotalStatus, customCalc) { +function getTreeCustomCalcResult(query, axisMap, status: TotalStatus, customCalc) { const quotaField = query[EXTRA_FIELD] const { row, col } = axisMap // 行列交叉总计 @@ -537,26 +570,18 @@ function getCustomCalcResult(query, axisMap, chart: ChartObj, status: TotalStatu // 列总计 if (status.isColTotal && !status.isRowSubTotal) { const { colTotal, rowSubInColTotal } = customCalc - const { tableLayoutMode } = chart.customAttr.basicStyle const path = getTreePath(query, row) let val if (path.length) { - if (tableLayoutMode === 'grid' && colTotal) { + const subLevel = getSubLevel(query, row) + if (subLevel + 1 === row.length && colTotal) { path.push(quotaField) val = get(colTotal.data, path) } - // 树形模式的行小计放在列总计里面 - if (tableLayoutMode === 'tree') { - const subLevel = getSubLevel(query, row) - if (subLevel + 1 === row.length && colTotal) { - path.push(quotaField) - val = get(colTotal.data, path) - } - if (subLevel + 1 < row.length && rowSubInColTotal) { - const data = rowSubInColTotal?.[subLevel]?.data - path.push(quotaField) - val = get(data, path) - } + if (subLevel + 1 < row.length && rowSubInColTotal) { + const data = rowSubInColTotal?.[subLevel]?.data + path.push(quotaField) + val = get(data, path) } } return val @@ -581,13 +606,133 @@ function getCustomCalcResult(query, axisMap, chart: ChartObj, status: TotalStatu const { rowTotal } = customCalc const path = getTreePath(query, col) let val - if (path.length && rowTotal) { - path.push(quotaField) - val = get(rowTotal.data, path) + if (rowTotal) { + if (path.length) { + path.push(quotaField) + val = get(rowTotal.data, path) + } + // 列维度为空,行维度不为空 + if (!col.length && row.length) { + val = get(rowTotal.data, quotaField) + } } - // 列维度为空,行维度不为空 - if (!col.length && row.length) { - val = get(rowTotal.data, quotaField) + return val + } + // 行小计 + if (status.isRowSubTotal) { + // 列维度为空,行小计直接当成列总计 + if ( + (!status.isColTotal && !status.isColSubTotal) || + (!col.length && status.isColTotal && status.isRowSubTotal) + ) { + const { rowSubTotal } = customCalc + const rowLevel = getSubLevel(query, row) + const colPath = getTreePath(query, col) + const rowPath = getTreePath(query, row) + const path = [...colPath, ...rowPath] + const data = rowSubTotal?.[rowLevel]?.data + let val + if (path.length && rowSubTotal) { + path.push(quotaField) + val = get(data, path) + } + return val + } + } + // 行总计里面的列小计 + if (status.isRowTotal && status.isColSubTotal) { + const { colSubInRowTotal } = customCalc + const colLevel = getSubLevel(query, col) + const { data } = colSubInRowTotal?.[colLevel] + const colPath = getTreePath(query, col) + let val + if (colPath.length && colSubInRowTotal) { + colPath.push(quotaField) + val = get(data, colPath) + } + return val + } + // 列总计里面的行小计 + if (status.isColTotal && status.isRowSubTotal) { + const { rowSubInColTotal } = customCalc + const rowSubLevel = getSubLevel(query, row) + const data = rowSubInColTotal?.[rowSubLevel]?.data + const path = getTreePath(query, row) + let val + if (path.length && rowSubInColTotal) { + path.push(quotaField) + val = get(data, path) + } + return val + } + // 列小计里面的行小计 + if (status.isColSubTotal && status.isRowSubTotal) { + const { rowSubInColSub } = customCalc + const rowSubLevel = getSubLevel(query, row) + const colSubLevel = getSubLevel(query, col) + const data = rowSubInColSub?.[rowSubLevel]?.[colSubLevel]?.data + const rowPath = getTreePath(query, row) + const colPath = getTreePath(query, col) + const path = [...rowPath, ...colPath] + let val + if (path.length && rowSubInColSub) { + path.push(quotaField) + val = get(data, path) + } + return val + } + return NaN +} + +function getGridCustomCalcResult(query, axisMap, status: TotalStatus, customCalc) { + const quotaField = query[EXTRA_FIELD] + const { row, col } = axisMap + // 行列交叉总计 + if (status.isRowTotal && status.isColTotal) { + return customCalc.rowColTotal?.data?.[quotaField] + } + // 列总计 + if (status.isColTotal && !status.isRowSubTotal) { + const { colTotal } = customCalc + const path = getTreePath(query, row) + let val + if (path.length) { + if (colTotal) { + path.push(quotaField) + val = get(colTotal.data, path) + } + } + return val + } + // 列小计 + if (status.isColSubTotal && !status.isRowTotal && !status.isRowSubTotal) { + const { colSubTotal } = customCalc + const subLevel = getSubLevel(query, col) + const rowPath = getTreePath(query, row) + const colPath = getTreePath(query, col) + const path = [...rowPath, ...colPath] + const data = colSubTotal?.[subLevel]?.data + let val + if (path.length && data) { + path.push(quotaField) + val = get(data, path) + } + return val + } + // 行总计 + if (status.isRowTotal && !status.isColSubTotal) { + const { rowTotal } = customCalc + const path = getTreePath(query, col) + let val + if (rowTotal) { + if (path.length) { + path.push(quotaField) + val = get(rowTotal.data, path) + } + // 列维度为空,行维度不为空 + if (!col.length && row.length) { + val = get(rowTotal.data, quotaField) + } } return val } @@ -649,6 +794,13 @@ function getCustomCalcResult(query, axisMap, chart: ChartObj, status: TotalStatu return val } } +function getCustomCalcResult(query, axisMap, chart: ChartObj, status: TotalStatus, customCalc) { + const { tableLayoutMode } = chart.customAttr.basicStyle + if (tableLayoutMode === 'tree') { + return getTreeCustomCalcResult(query, axisMap, status, customCalc) + } + return getGridCustomCalcResult(query, axisMap, status, customCalc) +} function getSubLevel(query, axis) { const fields: [] = axis.map(a => a.dataeaseName) 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 9dfc5730ce..b673f5abc9 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 @@ -185,7 +185,6 @@ export function getLabel(chart: Chart) { layout.push({ type: 'hide-overlap' }) } else { layout.push({ type: 'limit-in-plot' }) - layout.push({ type: 'fixed-overlap' }) layout.push({ type: 'hide-overlap' }) } } 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 7173729042..f38e9a87a4 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 @@ -1647,7 +1647,7 @@ const drawTextShape = (cell, isHeader) => { // 宽度能放几个字符,就放几个,放不下就换行 let wrapText = getWrapText(formattedValue ? formattedValue?.toString() : emptyPlaceholder, textStyle, cell.meta.width, cell.spreadsheet) const lines = wrapText.split(lineBreak) - + let extraStyleFontSize = textStyle.fontSize // 不是表头,处理文本高度和换行 if (!isHeader) { const textHeight = getWrapTextHeight(wrapText.replaceAll(lineBreak, ''), textStyle, cell.spreadsheet, maxLines) @@ -1655,8 +1655,8 @@ const drawTextShape = (cell, isHeader) => { const wrapTextArr = lines.slice(0, lineCountInCell) // 根据行数调整换行后的文本内容 - wrapText = lineCountInCell === 1 - ? lines[0].slice(0, -1) + ellipsis + wrapText = lineCountInCell < 1 + ? ellipsis : wrapTextArr.join(lineBreak) || ellipsis const resultWrapArr = wrapText.split(lineBreak) // 控制最大行数 @@ -1668,6 +1668,9 @@ const drawTextShape = (cell, isHeader) => { temp[temp.length - 1] = temp[temp.length-1].slice(0,firstLineStrNumber - 1) + ellipsis wrapText = temp.join(lineBreak) } + if (wrapText === ellipsis) { + extraStyleFontSize = 12 + } } else { const resultWrapArr = wrapText.split(lineBreak) // 控制最大行数 @@ -1687,7 +1690,7 @@ const drawTextShape = (cell, isHeader) => { // 获取文本位置并渲染文本 const position = cell.getTextPosition() // 绘制文本 - cell.textShape = renderText(cell, [cell.textShape], position.x, position.y, wrapText, textStyle) + cell.textShape = renderText(cell, [cell.textShape], position.x, position.y, wrapText, textStyle, {fontSize:extraStyleFontSize}) // 将文本形状添加到形状数组 cell.textShapes.push(cell.textShape) 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 d8f760a173..b1fe86fb15 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 @@ -27,7 +27,8 @@ import { deepCopy, isMobile } from '@/utils/utils' import { isDashboard, trackBarStyleCheck } from '@/utils/canvasUtils' import { useEmitt } from '@/hooks/web/useEmitt' import { L7ChartView } from '@/views/chart/components/js/panel/types/impl/l7' - +import { useI18n } from '@/hooks/web/useI18n' +const { t } = useI18n() const dvMainStore = dvMainStoreWithOut() const { nowPanelTrackInfo, nowPanelJumpInfo, mobileInPc, embeddedCallBack, inMobile } = storeToRefs(dvMainStore) @@ -86,6 +87,7 @@ const emit = defineEmits([ const g2TypeSeries1 = ['bidirectional-bar'] const g2TypeSeries0 = ['bar-range'] +const g2TypeTree = ['circle-packing'] const { view, showPosition, scale, terminal, suffixId } = toRefs(props) @@ -165,6 +167,14 @@ const checkSelected = param => { return state.linkageActiveParam.name === param.field } else if (g2TypeSeries0.includes(view.value.type)) { return state.linkageActiveParam.category === param.category + } else if (g2TypeTree.includes(view.value.type)) { + if ( + param.path?.startsWith(state.linkageActiveParam.name) || + state.linkageActiveParam.name === t('commons.all') + ) { + return true + } + return state.linkageActiveParam.name === param.name } else { return ( (state.linkageActiveParam.name === param.name || @@ -444,7 +454,7 @@ const trackClick = trackAction => { } } let quotaList = state.pointParam.data.quotaList - if (curView.type === 'bar-range') { + if (['bar-range', 'circle-packing'].includes(curView.type)) { quotaList = state.pointParam.data.dimensionList } else { quotaList[0]['value'] = state.pointParam.data.value diff --git a/core/core-frontend/src/views/chart/components/views/index.vue b/core/core-frontend/src/views/chart/components/views/index.vue index c2c83298dd..a5ee63e857 100644 --- a/core/core-frontend/src/views/chart/components/views/index.vue +++ b/core/core-frontend/src/views/chart/components/views/index.vue @@ -352,6 +352,13 @@ const chartClick = param => { ElMessage.error(t('chart.drill_field_error')) return } + if ( + view.value.type === 'circle-packing' && + (param.data?.childNodeCount === 0 || param.data.name === t('commons.all')) + ) { + ElMessage.error(t('chart.last_layer')) + return + } if (state.drillClickDimensionList.length < props.view.drillFields.length - 1) { state.drillClickDimensionList.push({ dimensionList: param.data.dimensionList, diff --git a/core/core-frontend/src/views/copilot/index.vue b/core/core-frontend/src/views/copilot/index.vue index 5b87d9a119..6de8535ac5 100644 --- a/core/core-frontend/src/views/copilot/index.vue +++ b/core/core-frontend/src/views/copilot/index.vue @@ -409,6 +409,7 @@ const queryAnswer = (event?: KeyboardEvent) => { bottom: 25px; border-radius: 8px; left: 180px; + z-index: 100; box-sizing: border-box; background: #fff; box-shadow: 0px 6px 24px 0px #1f232914; diff --git a/core/core-frontend/src/views/data-visualization/PreviewHead.vue b/core/core-frontend/src/views/data-visualization/PreviewHead.vue index 5ff4851a41..3c8dd436ad 100644 --- a/core/core-frontend/src/views/data-visualization/PreviewHead.vue +++ b/core/core-frontend/src/views/data-visualization/PreviewHead.vue @@ -20,6 +20,7 @@ import { useEmitt } from '@/hooks/web/useEmitt' import { useShareStoreWithOut } from '@/store/modules/share' import { exportPermission } from '@/utils/utils' import { useCache } from '@/hooks/web/useCache' +import { isDesktop } from '@/utils/ModelUtil' const shareStore = useShareStoreWithOut() const { wsCache } = useCache('localStorage') @@ -39,7 +40,7 @@ const preview = () => { } const isDataEaseBi = computed(() => appStore.getIsDataEaseBi) const isIframe = computed(() => appStore.getIsIframe) -const shareDisable = computed(() => shareStore.getShareDisable) +const shareDisable = computed(() => shareStore.getShareDisable || isDesktop()) const exportPermissions = computed(() => exportPermission(dvInfo.value['weight'], dvInfo.value['ext']) ) diff --git a/core/core-frontend/src/views/system/font/UploadDetail.vue b/core/core-frontend/src/views/system/font/UploadDetail.vue index d9b8c9985f..b2ba33986c 100644 --- a/core/core-frontend/src/views/system/font/UploadDetail.vue +++ b/core/core-frontend/src/views/system/font/UploadDetail.vue @@ -20,6 +20,7 @@ const uploadExcel = () => { loading.value = true return uploadFontFile(formData) .then(res => { + ruleForm.name = res.data.name ruleForm.size = res.data.size ruleForm.sizeType = res.data.sizeType ruleForm.fileTransName = res.data.fileTransName diff --git a/core/core-frontend/src/views/template-market/component/TemplateSkeleton.vue b/core/core-frontend/src/views/template-market/component/TemplateSkeleton.vue new file mode 100644 index 0000000000..5426e3f3f5 --- /dev/null +++ b/core/core-frontend/src/views/template-market/component/TemplateSkeleton.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/core/core-frontend/src/views/template-market/index.vue b/core/core-frontend/src/views/template-market/index.vue index a27421b889..11e97d151d 100644 --- a/core/core-frontend/src/views/template-market/index.vue +++ b/core/core-frontend/src/views/template-market/index.vue @@ -116,30 +116,14 @@ id="template-show-area" class="template-right" > - - - - - + +
@@ -183,6 +188,7 @@ import { useCache } from '@/hooks/web/useCache' import MarketPreviewV2 from '@/views/template-market/component/MarketPreviewV2.vue' import { imgUrlTrans } from '@/utils/imgUtils' import CategoryTemplateV2 from '@/views/template-market/component/CategoryTemplateV2.vue' +import TemplateSkeleton from '@/views/template-market/component/TemplateSkeleton.vue' import { interactiveStoreWithOut } from '@/store/modules/interactive' import { XpackComponent } from '@/components/plugin' import { useEmitt } from '@/hooks/web/useEmitt' diff --git a/core/core-frontend/src/views/template/component/DeTemplateImport.vue b/core/core-frontend/src/views/template/component/DeTemplateImport.vue index 0f33fd13ec..a5a5e0a5ba 100644 --- a/core/core-frontend/src/views/template/component/DeTemplateImport.vue +++ b/core/core-frontend/src/views/template/component/DeTemplateImport.vue @@ -11,7 +11,7 @@
diff --git a/core/core-frontend/src/views/visualized/data/datasource/form/ApiBody.vue b/core/core-frontend/src/views/visualized/data/datasource/form/ApiBody.vue index e2261d1116..d8eca16f4b 100644 --- a/core/core-frontend/src/views/visualized/data/datasource/form/ApiBody.vue +++ b/core/core-frontend/src/views/visualized/data/datasource/form/ApiBody.vue @@ -191,7 +191,7 @@ const emits = defineEmits(['headersChange']) diff --git a/core/core-frontend/src/views/workbranch/ShortcutTable.vue b/core/core-frontend/src/views/workbranch/ShortcutTable.vue index 3061fb2206..ba01ba95b6 100644 --- a/core/core-frontend/src/views/workbranch/ShortcutTable.vue +++ b/core/core-frontend/src/views/workbranch/ShortcutTable.vue @@ -54,7 +54,7 @@ const state = reactive({ }) const busiDataMap = computed(() => interactiveStore.getData) const shareDisable = computed(() => { - return shareStore.getShareDisable + return shareStore.getShareDisable || desktop }) const iconMap = { panel: icon_dashboard_outlined, diff --git a/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/embedded/api/EmbeddedApi.java b/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/embedded/api/EmbeddedApi.java index 1667367ec3..960f806351 100644 --- a/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/embedded/api/EmbeddedApi.java +++ b/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/embedded/api/EmbeddedApi.java @@ -1,5 +1,6 @@ package io.dataease.api.permissions.embedded.api; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; import com.github.xiaoymin.knife4j.annotations.ApiSupport; import io.dataease.api.permissions.embedded.dto.EmbeddedCreator; @@ -8,6 +9,7 @@ import io.dataease.api.permissions.embedded.dto.EmbeddedOrigin; import io.dataease.api.permissions.embedded.dto.EmbeddedResetRequest; import io.dataease.api.permissions.embedded.vo.EmbeddedGridVO; import io.dataease.license.config.XpackResource; +import io.dataease.model.KeywordRequest; import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -28,8 +30,8 @@ public interface EmbeddedApi { @Operation(summary = "查询") @ApiOperationSupport(order = 1) - @GetMapping("/queryGrid") - List queryGrid(); + @PostMapping("/pager/{goPage}/{pageSize}") + IPage queryGrid(@PathVariable("goPage") int goPage, @PathVariable("pageSize") int pageSize, @RequestBody KeywordRequest request); @Operation(summary = "创建") @ApiOperationSupport(order = 2) @@ -47,6 +49,11 @@ public interface EmbeddedApi { @PostMapping("/delete/{id}") void delete(@PathVariable("id") Long id); + @Operation(summary = "批量删除") + @ApiOperationSupport(order = 4) + @PostMapping("/batchDelete") + void batchDelete(@RequestBody List ids); + @ApiOperationSupport(order = 5) @Operation(summary = "重置密钥") @PostMapping("/reset")