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 3007bbcb9c..e518a888f6 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 = "operation"; + private static final String busi = "template"; /** * 这是要生成代码的表名称 */ - private static final String TABLE_NAME = "core_opt_recent"; + private static final String TABLE_NAME = "visualization_template_category_map"; /** * 下面两个配置基本上不用动 diff --git a/core/core-backend/src/main/java/io/dataease/template/dao/ext/ExtVisualizationTemplateMapper.java b/core/core-backend/src/main/java/io/dataease/template/dao/ext/ExtVisualizationTemplateMapper.java index 51021a4388..aab0d1be59 100644 --- a/core/core-backend/src/main/java/io/dataease/template/dao/ext/ExtVisualizationTemplateMapper.java +++ b/core/core-backend/src/main/java/io/dataease/template/dao/ext/ExtVisualizationTemplateMapper.java @@ -12,6 +12,9 @@ import java.util.List; public interface ExtVisualizationTemplateMapper{ List findTemplateList(TemplateManageRequest request); - List findBaseTemplateList(@Param("nodeType") String nodeType); + + List findCategories(TemplateManageRequest request); + + List findBaseTemplateList(); } diff --git a/core/core-backend/src/main/java/io/dataease/template/manage/TemplateCenterManage.java b/core/core-backend/src/main/java/io/dataease/template/manage/TemplateCenterManage.java index f446ff2c24..85d631dfca 100644 --- a/core/core-backend/src/main/java/io/dataease/template/manage/TemplateCenterManage.java +++ b/core/core-backend/src/main/java/io/dataease/template/manage/TemplateCenterManage.java @@ -11,6 +11,8 @@ import io.dataease.constant.CommonConstants; import io.dataease.exception.DEException; import io.dataease.operation.manage.CoreOptRecentManage; import io.dataease.system.manage.SysParameterManage; +import io.dataease.template.dao.auto.entity.VisualizationTemplateCategoryMap; +import io.dataease.template.dao.auto.mapper.VisualizationTemplateCategoryMapMapper; import io.dataease.template.dao.ext.ExtVisualizationTemplateMapper; import io.dataease.utils.HttpClientConfig; import io.dataease.utils.HttpClientUtil; @@ -19,6 +21,7 @@ import io.dataease.utils.LogUtil; import jakarta.annotation.Resource; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import java.util.*; import java.util.function.Function; @@ -40,6 +43,9 @@ public class TemplateCenterManage { @Resource private ExtVisualizationTemplateMapper templateManageMapper; + @Resource + private VisualizationTemplateCategoryMapMapper categoryMapMapper; + /** * @param templateUrl template url * @Description Get template file from template market @@ -88,8 +94,8 @@ public class TemplateCenterManage { private List searchTemplateFromManage() { try { - List manageResult = templateManageMapper.findBaseTemplateList("template"); - List categories = templateManageMapper.findBaseTemplateList("folder"); + List manageResult = templateManageMapper.findBaseTemplateList(); + List categories = templateManageMapper.findCategories(null); Map categoryMap = categories.stream() .collect(Collectors.toMap(TemplateManageDTO::getId, TemplateManageDTO::getName)); return baseManage2MarketTrans(manageResult, categoryMap); @@ -103,7 +109,12 @@ public class TemplateCenterManage { List result = new ArrayList<>(); manageResult.stream().forEach(templateManageDTO -> { templateManageDTO.setCategoryName(categoryMap.get(templateManageDTO.getPid())); - result.add(new TemplateMarketDTO(templateManageDTO)); + List categories = templateManageDTO.getCategories(); + if(!CollectionUtils.isEmpty(categories)){ + List categoryNames = categories.stream().map(categoryId ->categoryMap.get(categoryId)).collect(Collectors.toList()); + templateManageDTO.setCategoryNames(categoryNames); + result.add(new TemplateMarketDTO(templateManageDTO)); + } }); return result; } @@ -178,7 +189,7 @@ public class TemplateCenterManage { contents.stream().forEach(templateMarketDTO -> { Long recentUseTime = useTime.get(templateMarketDTO.getId()); templateMarketDTO.setRecentUseTime(recentUseTime == null ? 0 : recentUseTime); - activeCategoriesName.add(templateMarketDTO.getMainCategory()); + activeCategoriesName.addAll(templateMarketDTO.getCategoryNames()); }); if (v2BaseResponse != null) { v2BaseResponse.getItems().stream().forEach(marketTemplateV2ItemResult -> { @@ -214,7 +225,7 @@ public class TemplateCenterManage { public List getCategoriesV2() { List allCategories = new ArrayList<>(); - List manageCategories = templateManageMapper.findBaseTemplateList("folder"); + List manageCategories = templateManageMapper.findCategories(null); List manageCategoriesTrans = manageCategories.stream() .map(templateCategory -> new MarketMetaDataVO(templateCategory.getId(), templateCategory.getName(), CommonConstants.TEMPLATE_SOURCE.MANAGE)) .collect(Collectors.toList()); diff --git a/core/core-backend/src/main/java/io/dataease/template/service/TemplateManageService.java b/core/core-backend/src/main/java/io/dataease/template/service/TemplateManageService.java index bc70d8d4f6..295f0ff262 100644 --- a/core/core-backend/src/main/java/io/dataease/template/service/TemplateManageService.java +++ b/core/core-backend/src/main/java/io/dataease/template/service/TemplateManageService.java @@ -8,6 +8,10 @@ import io.dataease.api.template.vo.VisualizationTemplateVO; import io.dataease.constant.CommonConstants; import io.dataease.exception.DEException; import io.dataease.template.dao.auto.entity.VisualizationTemplate; +import io.dataease.template.dao.auto.entity.VisualizationTemplateCategory; +import io.dataease.template.dao.auto.entity.VisualizationTemplateCategoryMap; +import io.dataease.template.dao.auto.mapper.VisualizationTemplateCategoryMapMapper; +import io.dataease.template.dao.auto.mapper.VisualizationTemplateCategoryMapper; import io.dataease.template.dao.auto.mapper.VisualizationTemplateMapper; import io.dataease.template.dao.ext.ExtVisualizationTemplateMapper; import io.dataease.utils.AuthUtils; @@ -37,6 +41,11 @@ public class TemplateManageService implements TemplateManageApi { @Resource private VisualizationTemplateMapper templateMapper; + + @Resource + private VisualizationTemplateCategoryMapper templateCategoryMapper; + @Resource + private VisualizationTemplateCategoryMapMapper categoryMapMapper; @Resource private ExtVisualizationTemplateMapper extTemplateMapper; @Resource @@ -72,19 +81,6 @@ public class TemplateManageService implements TemplateManageApi { request.setId(UUID.randomUUID().toString()); request.setCreateTime(System.currentTimeMillis()); request.setCreateBy(AuthUtils.getUser().getUserId().toString()); - //如果level 是0(第一级)指的是分类目录 设置父级为对应的templateType - if (request.getLevel() == 0) { - request.setPid(request.getTemplateType()); - String nameCheckResult = this.nameCheck(CommonConstants.OPT_TYPE.INSERT, request.getName(), request.getPid(), null); - if (CommonConstants.CHECK_RESULT.EXIST_ALL.equals(nameCheckResult)) { - DEException.throwException("名称已存在"); - } - } else {//模板插入 相同文件夹同名的模板进行覆盖(先删除) - QueryWrapper wrapper = new QueryWrapper<>(); - wrapper.eq("pid",request.getPid()); - wrapper.eq("name",request.getName()); - templateMapper.delete(wrapper); - } if ("template".equals(request.getNodeType())) { //Store static resource into the server staticResourceServer.saveFilesToServe(request.getStaticResource()); @@ -92,18 +88,52 @@ public class TemplateManageService implements TemplateManageApi { staticResourceServer.saveSingleFileToServe(snapshotName, request.getSnapshot().replace("data:image/jpeg;base64,", "")); request.setSnapshot("/" + UPLOAD_URL_PREFIX + '/' + snapshotName); } + //如果level 是0(第一级)指的是分类目录 设置父级为对应的templateType + if (request.getLevel() == 0) { + request.setPid(request.getTemplateType()); + String nameCheckResult = this.categoryNameCheck(CommonConstants.OPT_TYPE.INSERT, request.getName(), null); + if (CommonConstants.CHECK_RESULT.EXIST_ALL.equals(nameCheckResult)) { + DEException.throwException("名称已存在"); + } + VisualizationTemplateCategory templateCategory = new VisualizationTemplateCategory(); + BeanUtils.copyBean(templateCategory,request); + templateCategoryMapper.insert(templateCategory); + } else {//模板插入 同名的模板进行覆盖(先删除) + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("name",request.getName()); + templateMapper.delete(wrapper); + VisualizationTemplate template = new VisualizationTemplate(); + BeanUtils.copyBean(template,request); + templateMapper.insert(template); + // 插入分类关系 + request.getCategories().forEach(categoryId ->{ + VisualizationTemplateCategoryMap categoryMap = new VisualizationTemplateCategoryMap(); + categoryMap.setId(UUID.randomUUID().toString()); + categoryMap.setCategoryId(categoryId); + categoryMap.setTemplateId(template.getId()); + categoryMapMapper.insert(categoryMap); + }); - VisualizationTemplate template = new VisualizationTemplate(); - BeanUtils.copyBean(template,request); - templateMapper.insert(template); - } else { - String nameCheckResult = this.nameCheck(CommonConstants.OPT_TYPE.UPDATE, request.getName(), request.getPid(), request.getId()); - if (CommonConstants.CHECK_RESULT.EXIST_ALL.equals(nameCheckResult)) { - DEException.throwException("名称已存在"); } - VisualizationTemplate template = new VisualizationTemplate(); - BeanUtils.copyBean(template,request); - templateMapper.updateById(template); + } else { + if (request.getLevel() == 0) { + String nameCheckResult = this.categoryNameCheck(CommonConstants.OPT_TYPE.UPDATE, request.getName(), request.getId()); + if (CommonConstants.CHECK_RESULT.EXIST_ALL.equals(nameCheckResult)) { + DEException.throwException("名称已存在"); + } + VisualizationTemplateCategory templateCategory = new VisualizationTemplateCategory(); + BeanUtils.copyBean(templateCategory,request); + templateCategoryMapper.updateById(templateCategory); + }else{ + String nameCheckResult = this.nameCheck(CommonConstants.OPT_TYPE.UPDATE, request.getName(), request.getId()); + if (CommonConstants.CHECK_RESULT.EXIST_ALL.equals(nameCheckResult)) { + DEException.throwException("名称已存在"); + } + VisualizationTemplate template = new VisualizationTemplate(); + BeanUtils.copyBean(template,request); + templateMapper.updateById(template); + } + } TemplateManageDTO templateManageDTO = new TemplateManageDTO(); BeanUtils.copyBean(templateManageDTO, request); @@ -112,13 +142,11 @@ public class TemplateManageService implements TemplateManageApi { } //名称检查 - public String nameCheck(String optType, String name, String pid, String id) { + public String nameCheck(String optType, String name,String id) { QueryWrapper wrapper = new QueryWrapper<>(); if (CommonConstants.OPT_TYPE.INSERT.equals(optType)) { - wrapper.eq("pid",pid); wrapper.eq("name",name); } else if (CommonConstants.OPT_TYPE.UPDATE.equals(optType)) { - wrapper.eq("pid",pid); wrapper.eq("name",name); wrapper.ne("id",id); } @@ -129,10 +157,26 @@ public class TemplateManageService implements TemplateManageApi { return CommonConstants.CHECK_RESULT.EXIST_ALL; } } + + //名称检查 + public String categoryNameCheck(String optType, String name, String id) { + QueryWrapper wrapper = new QueryWrapper<>(); + if (CommonConstants.OPT_TYPE.INSERT.equals(optType)) { + wrapper.eq("name",name); + } else if (CommonConstants.OPT_TYPE.UPDATE.equals(optType)) { + wrapper.eq("name",name); + wrapper.ne("id",id); + } + List templateList = templateCategoryMapper.selectList(wrapper); + if (CollectionUtils.isEmpty(templateList)) { + return CommonConstants.CHECK_RESULT.NONE; + } else { + return CommonConstants.CHECK_RESULT.EXIST_ALL; + } + } @Override public String nameCheck(TemplateManageRequest request) { - return nameCheck(request.getOptType(), request.getName(), request.getPid(), request.getId()); - + return nameCheck(request.getOptType(), request.getName(), request.getId()); } @Override public void delete(String id) { @@ -140,6 +184,11 @@ public class TemplateManageService implements TemplateManageApi { templateMapper.deleteById(id); } @Override + public void deleteCategory(String id) { + Assert.notNull(id, "id cannot be null"); + templateCategoryMapper.deleteById(id); + } + @Override public VisualizationTemplateVO findOne(String templateId) { VisualizationTemplate template = templateMapper.selectById(templateId); if(template != null){ @@ -155,4 +204,8 @@ public class TemplateManageService implements TemplateManageApi { return extTemplateMapper.findTemplateList(request); } + @Override + public List findCategories(TemplateManageRequest request) { + return extTemplateMapper.findCategories(request); + } } 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 7407153084..987569eb3d 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 @@ -1,38 +1,73 @@ DROP TABLE IF EXISTS `visualization_template`; CREATE TABLE `visualization_template` ( - `id` varchar(50) NOT NULL COMMENT '主键', - `name` varchar(255) DEFAULT NULL COMMENT '名称', - `pid` varchar(255) DEFAULT NULL COMMENT '父级id', - `level` int(10) DEFAULT NULL COMMENT '层级', - `dv_type` varchar(255) DEFAULT NULL COMMENT '模板种类 dataV or dashboard 目录或者文件夹', - `node_type` varchar(255) DEFAULT NULL COMMENT '节点类型 folder or panel 目录或者文件夹', - `create_by` varchar(255) DEFAULT NULL COMMENT '创建人', - `create_time` bigint(13) DEFAULT NULL COMMENT '创建时间', - `snapshot` longtext COMMENT '缩略图', - `template_type` varchar(255) DEFAULT NULL COMMENT '模板类型 system 系统内置 self 用户自建 ', - `template_style` longtext COMMENT 'template 样式', - `template_data` longtext COMMENT 'template 数据', - `dynamic_data` longtext COMMENT '预存数据', - PRIMARY KEY (`id`) -); + `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '主键', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '名称', + `pid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '父级id', + `level` int DEFAULT NULL COMMENT '层级', + `dv_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '模版种类 dataV or dashboard 目录或者文件夹', + `node_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '节点类型 folder or panel 目录或者文件夹', + `create_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '创建人', + `create_time` bigint DEFAULT NULL COMMENT '创建时间', + `snapshot` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '缩略图', + `template_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '模版类型 system 系统内置 self 用户自建 ', + `template_style` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT 'template 样式', + `template_data` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT 'template 数据', + `dynamic_data` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '预存数据', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='模板表'; -BEGIN; -INSERT INTO `core_menu` -VALUES (19, 0, 2, 'template-market', 'template-market', 4, NULL, '/template-market', 1, 1, 0); -INSERT INTO `core_menu` -VALUES (20, 15, 2, 'template-setting', 'system/template-setting', 4, 'icon_template', '/template-setting', 0, 1, 1); -COMMIT; +-- ---------------------------- +-- Table structure for visualization_template_category +-- ---------------------------- +DROP TABLE IF EXISTS `visualization_template_category`; +CREATE TABLE `visualization_template_category` ( + `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '主键', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '名称', + `pid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '父级id', + `level` int DEFAULT NULL COMMENT '层级', + `dv_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '模版种类 dataV or dashboard 目录或者文件夹', + `node_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '节点类型 folder or panel 目录或者文件夹', + `create_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '创建人', + `create_time` bigint DEFAULT NULL COMMENT '创建时间', + `snapshot` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '缩略图', + `template_type` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='模板表'; +-- ---------------------------- +-- Table structure for visualization_template_category_map +-- ---------------------------- +DROP TABLE IF EXISTS `visualization_template_category_map`; +CREATE TABLE `visualization_template_category_map` ( + `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '主键', + `category_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '名称', + `template_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '父级id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='模板表'; + +-- ---------------------------- +-- Table structure for visualization_template_extend_data +-- ---------------------------- DROP TABLE IF EXISTS `visualization_template_extend_data`; CREATE TABLE `visualization_template_extend_data` ( `id` bigint NOT NULL, `dv_id` bigint DEFAULT NULL, `view_id` bigint DEFAULT NULL, - `view_details` longtext, - `copy_from` varchar(255) DEFAULT NULL, - `copy_id` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`) -); + `view_details` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci, + `copy_from` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, + `copy_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +BEGIN; +INSERT INTO `core_menu` +VALUES (19, 0, 2, 'template-market', 'template-market', 4, NULL, '/template-market', 1, 1, 0); +INSERT INTO `core_menu` +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); +COMMIT; + ALTER TABLE `core_opt_recent` MODIFY COLUMN `resource_id` bigint NULL COMMENT '资源ID' AFTER `id`, diff --git a/core/core-backend/src/main/resources/db/migration/V2.1__ddl.sql b/core/core-backend/src/main/resources/db/migration/V2.1__ddl.sql index 5567701ebf..350529c7bb 100644 --- a/core/core-backend/src/main/resources/db/migration/V2.1__ddl.sql +++ b/core/core-backend/src/main/resources/db/migration/V2.1__ddl.sql @@ -1,22 +1,63 @@ DROP TABLE IF EXISTS `visualization_template`; -CREATE TABLE `visualization_template` -( - `id` varchar(50) NOT NULL COMMENT '主键', - `name` varchar(255) DEFAULT NULL COMMENT '名称', - `pid` varchar(255) DEFAULT NULL COMMENT '父级id', - `level` int(10) DEFAULT NULL COMMENT '层级', - `dv_type` varchar(255) DEFAULT NULL COMMENT '模板种类 dataV or dashboard 目录或者文件夹', - `node_type` varchar(255) DEFAULT NULL COMMENT '节点类型 folder or panel 目录或者文件夹', - `create_by` varchar(255) DEFAULT NULL COMMENT '创建人', - `create_time` bigint(13) DEFAULT NULL COMMENT '创建时间', - `snapshot` longtext COMMENT '缩略图', - `template_type` varchar(255) DEFAULT NULL COMMENT '模板类型 system 系统内置 self 用户自建 ', - `template_style` longtext COMMENT 'template 样式', - `template_data` longtext COMMENT 'template 数据', - `dynamic_data` longtext COMMENT '预存数据', - PRIMARY KEY (`id`) -) ENGINE = InnoDB - DEFAULT CHARSET = utf8mb4 COMMENT ='模板表'; +CREATE TABLE `visualization_template` ( + `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '主键', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '名称', + `pid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '父级id', + `level` int DEFAULT NULL COMMENT '层级', + `dv_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '模版种类 dataV or dashboard 目录或者文件夹', + `node_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '节点类型 folder or panel 目录或者文件夹', + `create_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '创建人', + `create_time` bigint DEFAULT NULL COMMENT '创建时间', + `snapshot` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '缩略图', + `template_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '模版类型 system 系统内置 self 用户自建 ', + `template_style` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT 'template 样式', + `template_data` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT 'template 数据', + `dynamic_data` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '预存数据', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='模板表'; + +-- ---------------------------- +-- Table structure for visualization_template_category +-- ---------------------------- +DROP TABLE IF EXISTS `visualization_template_category`; +CREATE TABLE `visualization_template_category` ( + `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '主键', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '名称', + `pid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '父级id', + `level` int DEFAULT NULL COMMENT '层级', + `dv_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '模版种类 dataV or dashboard 目录或者文件夹', + `node_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '节点类型 folder or panel 目录或者文件夹', + `create_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '创建人', + `create_time` bigint DEFAULT NULL COMMENT '创建时间', + `snapshot` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci COMMENT '缩略图', + `template_type` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='模板表'; + +-- ---------------------------- +-- Table structure for visualization_template_category_map +-- ---------------------------- +DROP TABLE IF EXISTS `visualization_template_category_map`; +CREATE TABLE `visualization_template_category_map` ( + `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '主键', + `category_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '名称', + `template_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '父级id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='模板表'; + +-- ---------------------------- +-- Table structure for visualization_template_extend_data +-- ---------------------------- +DROP TABLE IF EXISTS `visualization_template_extend_data`; +CREATE TABLE `visualization_template_extend_data` ( + `id` bigint NOT NULL, + `dv_id` bigint DEFAULT NULL, + `view_id` bigint DEFAULT NULL, + `view_details` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci, + `copy_from` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, + `copy_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; BEGIN; INSERT INTO `core_menu` @@ -27,18 +68,6 @@ INSERT INTO `core_menu` VALUES (31, 30, 2, 'template-setting', 'toolbox/template-setting', 1, 'icon_template', '/template-setting', 0, 1, 1); COMMIT; -DROP TABLE IF EXISTS `visualization_template_extend_data`; -CREATE TABLE `visualization_template_extend_data` -( - `id` bigint NOT NULL, - `dv_id` bigint DEFAULT NULL, - `view_id` bigint DEFAULT NULL, - `view_details` longtext, - `copy_from` varchar(255) DEFAULT NULL, - `copy_id` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`) -); - ALTER TABLE `core_opt_recent` MODIFY COLUMN `resource_id` bigint NULL COMMENT '资源ID' AFTER `id`, diff --git a/core/core-backend/src/main/resources/mybatis/ExtVisualizationTemplateMapper.xml b/core/core-backend/src/main/resources/mybatis/ExtVisualizationTemplateMapper.xml index 05898e3bd6..1971a6d26b 100644 --- a/core/core-backend/src/main/resources/mybatis/ExtVisualizationTemplateMapper.xml +++ b/core/core-backend/src/main/resources/mybatis/ExtVisualizationTemplateMapper.xml @@ -7,6 +7,7 @@ + @@ -23,77 +24,68 @@ + + + + + + - visualization_template.id, visualization_template.`name`, visualization_template.pid, visualization_template.`level`,visualization_template.`dv_type`, visualization_template.node_type, visualization_template.create_by, visualization_template.create_time, visualization_template.template_type, visualization_template.snapshot + vt.id, vt.`name`, vt.pid, vt.`level`,vt.`dv_type`, vt.node_type, vt.create_by, vt.create_time, vt.template_type, vt.snapshot - visualization_template.template_style, visualization_template.template_data, visualization_template.dynamic_data + ,vt.template_style, vt.template_data, vt.dynamic_data - SELECT - + vt.id, + vt.`name`, + vt.pid, + vt.`level`, + vt.`dv_type`, + vt.node_type, + vt.create_by, + vt.create_time, + vt.template_type, + vt.SNAPSHOT, + vtcm.category_id FROM - visualization_template - - - and visualization_template.node_type = #{nodeType} - - - order by visualization_template.create_time desc + visualization_template vt + LEFT JOIN visualization_template_category_map vtcm ON vt.id = vtcm.template_id + ORDER BY + vt.create_time DESC + + + diff --git a/core/core-frontend/src/api/template.ts b/core/core-frontend/src/api/template.ts index 320cc93401..a9f48b0fe9 100644 --- a/core/core-frontend/src/api/template.ts +++ b/core/core-frontend/src/api/template.ts @@ -13,6 +13,12 @@ export function templateDelete(id) { }) } +export function deleteCategory(id) { + return request.post({ + url: '/templateManage/deleteCategory/' + id + }) +} + export function showTemplateList(data) { return request.post({ url: '/templateManage/templateList', @@ -34,6 +40,14 @@ export function find(data) { }) } +export function findCategories(data) { + return request.post({ + url: '/templateManage/findCategories', + data: data, + loading: true + }) +} + export function nameCheck(data) { return request.post({ url: '/templateManage/nameCheck', diff --git a/core/core-frontend/src/views/template/component/DeTemplateImport.vue b/core/core-frontend/src/views/template/component/DeTemplateImport.vue index a49e06fd72..23053de7fb 100644 --- a/core/core-frontend/src/views/template/component/DeTemplateImport.vue +++ b/core/core-frontend/src/views/template/component/DeTemplateImport.vue @@ -5,10 +5,11 @@ class="de-form-item" :model="state.templateInfo" :rules="state.templateInfoRules" + label-position="top" >
- + {{ t('visualization.upload_template') }} @@ -22,8 +23,23 @@ />
+ + + + + + - + {{ t('commons.cancel') }} {{ t('commons.confirm') }} @@ -44,10 +60,15 @@ const props = defineProps({ pid: { type: String, required: true + }, + templateCategories: { + type: Array, + required: true } }) const state = reactive({ + categories: [], nameList: [], importTemplateInfo: { snapshot: '' @@ -59,12 +80,20 @@ const state = reactive({ message: t('commons.input_content'), trigger: 'change' } + ], + categories: [ + { + required: true, + message: t('commons.input_content'), + trigger: 'change' + } ] }, recover: false, templateInfo: { level: '1', pid: props.pid, + categories: [], dvType: 'dashboard', name: '', templateStyle: null, @@ -103,26 +132,34 @@ const saveTemplate = () => { ElMessage.warning(t('chart.template_can_not_empty')) return false } + + if (!state.templateInfo.categories.length) { + ElMessage.warning('请选择分类') + return false + } + const nameCheckRequest = { pid: state.templateInfo.pid, name: state.templateInfo.name, + categories: state.templateInfo.categories, optType: 'insert' } nameCheck(nameCheckRequest).then(response => { if (response.data.indexOf('exist') > -1) { - const options = { - title: 'commons.prompt', - content: 'system_parameter_setting.to_overwrite_them', - type: 'primary', - cb: () => - save(state.templateInfo).then(response => { - ElMessage.success('导入成功') - emits('refresh') - emits('closeEditTemplateDialog') - }), - confirmButtonText: t('template.override') - } - handlerConfirm(options) + ElMessage.warning(t('当前模版名称已经存在')) + // const options = { + // title: 'commons.prompt', + // content: 'system_parameter_setting.to_overwrite_them', + // type: 'primary', + // cb: () => + // save(state.templateInfo).then(response => { + // ElMessage.success('导入成功') + // emits('refresh') + // emits('closeEditTemplateDialog') + // }), + // confirmButtonText: t('template.override') + // } + // handlerConfirm(options) } else { save(state.templateInfo).then(response => { ElMessage.success(t('导入成功')) diff --git a/core/core-frontend/src/views/template/component/DeTemplateList.vue b/core/core-frontend/src/views/template/component/DeTemplateList.vue index d43ba69808..7a0ef47fb8 100644 --- a/core/core-frontend/src/views/template/component/DeTemplateList.vue +++ b/core/core-frontend/src/views/template/component/DeTemplateList.vue @@ -11,16 +11,6 @@ :description="'没有找到相关内容'" />
    -
  • - - - - 默认分类 -
  • -
  • @@ -68,12 +48,13 @@ import { useI18n } from '@/hooks/web/useI18n' import { computed, reactive } from 'vue' import NoneImage from '@/assets/none.png' import NothingImage from '@/assets/nothing.png' +import { ElMessageBox } from 'element-plus-secondary' const { t } = useI18n() const emits = defineEmits([ 'showCurrentTemplate', 'showTemplateEditDialog', - 'templateDelete', + 'categoryDelete', 'templateEdit', 'templateImport' ]) @@ -108,28 +89,30 @@ const clickMore = (type, data) => { templateEdit(data) break case 'delete': - templateDelete(data) + categoryDelete(data) break case 'import': templateImport(data) break } } -const nodeClick = ({ id, label }) => { +const nodeClick = ({ id, name }) => { state.activeTemplate = id - emits('showCurrentTemplate', id, label) + emits('showCurrentTemplate', id, name) } const add = () => { emits('showTemplateEditDialog', 'new') } -const templateDelete = template => { - const options = { - title: 'system_parameter_setting.delete_this_category', - content: 'system_parameter_setting.also_be_deleted', - type: 'primary', - cb: () => emits('templateDelete', template.id) - } - handlerConfirm(options) +const categoryDelete = template => { + ElMessageBox.confirm('确定删除该分类吗?', { + tip: '删除后,该分类下的所有模版也将删除。', + confirmButtonType: 'danger', + type: 'warning', + autofocus: false, + showClose: false + }).then(() => { + emits('categoryDelete', template.id) + }) } const templateEdit = template => { emits('templateEdit', template) @@ -153,10 +136,10 @@ defineExpose({ position: relative; ul { - margin: 16px 0 20px 0; + margin: 0px 0 0 0; padding: 0; overflow-y: auto; - max-height: calc(100% - 90px); + max-height: 100%; } li { diff --git a/core/core-frontend/src/views/template/index.vue b/core/core-frontend/src/views/template/index.vue index 8c4f5db288..9cfd54c6ae 100644 --- a/core/core-frontend/src/views/template/index.vue +++ b/core/core-frontend/src/views/template/index.vue @@ -4,6 +4,12 @@ {{ t('visualization.import') }} + + 添加分类 + @@ -110,7 +117,7 @@ @@ -403,7 +398,7 @@ onMounted(() => { background: #fff; width: 269px; border-right: 1px solid rgba(31, 35, 41, 0.15); - padding: 24px; + padding: 12px 8px; } .de-tabs-right { @@ -471,6 +466,5 @@ onMounted(() => { .template-search-class { float: right; width: 320px; - margin-right: 12px; } diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/template/TemplateManageApi.java b/sdk/api/api-base/src/main/java/io/dataease/api/template/TemplateManageApi.java index 852830e444..b32a851874 100644 --- a/sdk/api/api-base/src/main/java/io/dataease/api/template/TemplateManageApi.java +++ b/sdk/api/api-base/src/main/java/io/dataease/api/template/TemplateManageApi.java @@ -17,12 +17,18 @@ public interface TemplateManageApi { @PostMapping("/delete/{id}") void delete(@PathVariable String id); + @PostMapping("/deleteCategory/{id}") + void deleteCategory(@PathVariable String id); + @GetMapping("/findOne/{templateId}") VisualizationTemplateVO findOne(@PathVariable String templateId) throws Exception; @PostMapping("/find") List find(@RequestBody TemplateManageRequest request); + @PostMapping("/findCategories") + List findCategories(@RequestBody TemplateManageRequest request); + @PostMapping("/nameCheck") String nameCheck(@RequestBody TemplateManageRequest request); diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/template/dto/TemplateManageDTO.java b/sdk/api/api-base/src/main/java/io/dataease/api/template/dto/TemplateManageDTO.java index 2081bdfc32..14ef9d613e 100644 --- a/sdk/api/api-base/src/main/java/io/dataease/api/template/dto/TemplateManageDTO.java +++ b/sdk/api/api-base/src/main/java/io/dataease/api/template/dto/TemplateManageDTO.java @@ -20,5 +20,9 @@ public class TemplateManageDTO extends VisualizationTemplateVO { private List children; + private List categories; + + private List categoryNames; + } diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/template/dto/TemplateMarketDTO.java b/sdk/api/api-base/src/main/java/io/dataease/api/template/dto/TemplateMarketDTO.java index 5848887f27..5e52f7bd71 100644 --- a/sdk/api/api-base/src/main/java/io/dataease/api/template/dto/TemplateMarketDTO.java +++ b/sdk/api/api-base/src/main/java/io/dataease/api/template/dto/TemplateMarketDTO.java @@ -8,6 +8,7 @@ import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; @Data @NoArgsConstructor @@ -42,10 +43,10 @@ public class TemplateMarketDTO implements Comparable { this.id = manageDTO.getId(); this.title = manageDTO.getName(); this.mainCategory = manageDTO.getCategoryName(); - this.categories = Arrays.asList(new MarketCategoryVO(manageDTO.getCategoryName())); - this.categoryNames = Arrays.asList(manageDTO.getCategoryName()); + this.categories = manageDTO.getCategoryNames().stream().map(category->new MarketCategoryVO(category)).collect(Collectors.toList()); + this.categoryNames = manageDTO.getCategoryNames(); this.metas = new MarketMetasVO(manageDTO.getSnapshot()); - this.templateType = "dataV".equalsIgnoreCase("manageDTO.getTemplateType()") ? "SCREEN" : "PANEL"; + this.templateType = "dataV".equalsIgnoreCase(manageDTO.getTemplateType()) ? "SCREEN" : "PANEL"; this.thumbnail = manageDTO.getSnapshot(); this.source = "manage"; if (manageDTO.getRecentUseTime() != null) { diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/template/request/TemplateManageRequest.java b/sdk/api/api-base/src/main/java/io/dataease/api/template/request/TemplateManageRequest.java index 5c1b1e01e9..021eb8c4bf 100644 --- a/sdk/api/api-base/src/main/java/io/dataease/api/template/request/TemplateManageRequest.java +++ b/sdk/api/api-base/src/main/java/io/dataease/api/template/request/TemplateManageRequest.java @@ -3,6 +3,8 @@ package io.dataease.api.template.request; import io.dataease.api.template.vo.VisualizationTemplateVO; import lombok.Data; +import java.util.List; + /** * Author: wangjiahao * Date: 2021-03-05 @@ -21,7 +23,12 @@ public class TemplateManageRequest extends VisualizationTemplateVO { private String leafDvType; + private String categoryId; + + private List categories; + public TemplateManageRequest() { + } public TemplateManageRequest(String pid,String dvType) { diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/template/vo/VisualizationTemplateCategoryVO.java b/sdk/api/api-base/src/main/java/io/dataease/api/template/vo/VisualizationTemplateCategoryVO.java new file mode 100644 index 0000000000..8d191f6ed7 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/template/vo/VisualizationTemplateCategoryVO.java @@ -0,0 +1,56 @@ +package io.dataease.api.template.vo; + +import lombok.Data; + +/** + * @author : WangJiaHao + * @date : 2023/11/7 13:22 + */ +@Data +public class VisualizationTemplateCategoryVO { + + /** + * 主键 + */ + private String id; + + /** + * 名称 + */ + private String name; + + /** + * 父级id + */ + private String pid; + + /** + * 层级 + */ + private Integer level; + + /** + * 模板种类 dataV or dashboard 目录或者文件夹 + */ + private String dvType; + + /** + * 节点类型 folder or panel 目录或者文件夹 + */ + private String nodeType; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + private Long createTime; + + /** + * 缩略图 + */ + private String snapshot; +}