From 2a881be1fd8b93e7ed7da8d1f829ca4330bd8eaa Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Wed, 8 Nov 2023 10:45:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=A8=A1=E7=89=88=E5=B8=82=E5=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auto/entity/VisualizationTemplate.java | 206 ++++++++ .../mapper/VisualizationTemplateMapper.java | 18 + .../ext/ExtVisualizationTemplateMapper.java | 15 + .../service/TemplateManageService.java | 150 ++++++ .../main/resources/db/desktop/V2.1__ddl.sql | 17 + .../main/resources/db/migration/V2.1__ddl.sql | 17 + .../RealTimeComponentTreeList.vue | 494 ++++++++++++++++++ .../api/template/TemplateManageApi.java | 18 +- .../api/template/dto/TemplateManageDTO.java | 7 +- .../request/TemplateManageRequest.java | 29 + .../template/vo/VisualizationTemplateVO.java | 76 +++ .../io/dataease/constant/CommonConstants.java | 82 +++ 12 files changed, 1127 insertions(+), 2 deletions(-) create mode 100644 core/core-backend/src/main/java/io/dataease/template/dao/auto/entity/VisualizationTemplate.java create mode 100644 core/core-backend/src/main/java/io/dataease/template/dao/auto/mapper/VisualizationTemplateMapper.java create mode 100644 core/core-backend/src/main/java/io/dataease/template/dao/ext/ExtVisualizationTemplateMapper.java create mode 100644 core/core-backend/src/main/java/io/dataease/template/service/TemplateManageService.java create mode 100644 core/core-backend/src/main/resources/db/desktop/V2.1__ddl.sql create mode 100644 core/core-backend/src/main/resources/db/migration/V2.1__ddl.sql create mode 100644 core/core-frontend/src/components/data-visualization/RealTimeComponentTreeList.vue create mode 100644 sdk/api/api-base/src/main/java/io/dataease/api/template/request/TemplateManageRequest.java create mode 100644 sdk/api/api-base/src/main/java/io/dataease/api/template/vo/VisualizationTemplateVO.java create mode 100644 sdk/common/src/main/java/io/dataease/constant/CommonConstants.java diff --git a/core/core-backend/src/main/java/io/dataease/template/dao/auto/entity/VisualizationTemplate.java b/core/core-backend/src/main/java/io/dataease/template/dao/auto/entity/VisualizationTemplate.java new file mode 100644 index 0000000000..03baecb4f5 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/template/dao/auto/entity/VisualizationTemplate.java @@ -0,0 +1,206 @@ +package io.dataease.template.dao.auto.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; + +/** + *

+ * 仪表板模板表 + *

+ * + * @author fit2cloud + * @since 2023-11-06 + */ +@TableName("visualization_template") +public class VisualizationTemplate implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + 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; + + /** + * 模版类型 system 系统内置 self 用户自建 + */ + private String templateType; + + /** + * template 样式 + */ + private String templateStyle; + + /** + * template 数据 + */ + private String templateData; + + /** + * 预存数据 + */ + private String dynamicData; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public Integer getLevel() { + return level; + } + + public void setLevel(Integer level) { + this.level = level; + } + + public String getDvType() { + return dvType; + } + + public void setDvType(String dvType) { + this.dvType = dvType; + } + + public String getNodeType() { + return nodeType; + } + + public void setNodeType(String nodeType) { + this.nodeType = nodeType; + } + + public String getCreateBy() { + return createBy; + } + + public void setCreateBy(String createBy) { + this.createBy = createBy; + } + + public Long getCreateTime() { + return createTime; + } + + public void setCreateTime(Long createTime) { + this.createTime = createTime; + } + + public String getSnapshot() { + return snapshot; + } + + public void setSnapshot(String snapshot) { + this.snapshot = snapshot; + } + + public String getTemplateType() { + return templateType; + } + + public void setTemplateType(String templateType) { + this.templateType = templateType; + } + + public String getTemplateStyle() { + return templateStyle; + } + + public void setTemplateStyle(String templateStyle) { + this.templateStyle = templateStyle; + } + + public String getTemplateData() { + return templateData; + } + + public void setTemplateData(String templateData) { + this.templateData = templateData; + } + + public String getDynamicData() { + return dynamicData; + } + + public void setDynamicData(String dynamicData) { + this.dynamicData = dynamicData; + } + + @Override + public String toString() { + return "VisualizationTemplate{" + + "id = " + id + + ", name = " + name + + ", pid = " + pid + + ", level = " + level + + ", dvType = " + dvType + + ", nodeType = " + nodeType + + ", createBy = " + createBy + + ", createTime = " + createTime + + ", snapshot = " + snapshot + + ", templateType = " + templateType + + ", templateStyle = " + templateStyle + + ", templateData = " + templateData + + ", dynamicData = " + dynamicData + + "}"; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/template/dao/auto/mapper/VisualizationTemplateMapper.java b/core/core-backend/src/main/java/io/dataease/template/dao/auto/mapper/VisualizationTemplateMapper.java new file mode 100644 index 0000000000..2a8c72964f --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/template/dao/auto/mapper/VisualizationTemplateMapper.java @@ -0,0 +1,18 @@ +package io.dataease.template.dao.auto.mapper; + +import io.dataease.template.dao.auto.entity.VisualizationTemplate; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 仪表板模板表 Mapper 接口 + *

+ * + * @author fit2cloud + * @since 2023-11-06 + */ +@Mapper +public interface VisualizationTemplateMapper extends BaseMapper { + +} 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 new file mode 100644 index 0000000000..3455251da6 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/template/dao/ext/ExtVisualizationTemplateMapper.java @@ -0,0 +1,15 @@ +package io.dataease.template.dao.ext; + +import io.dataease.api.template.dto.TemplateManageDTO; +import io.dataease.api.template.request.TemplateManageRequest; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + + +@Mapper +public interface ExtVisualizationTemplateMapper{ + + List findTemplateList(TemplateManageRequest request); + +} 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 new file mode 100644 index 0000000000..52aea40e7a --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/template/service/TemplateManageService.java @@ -0,0 +1,150 @@ +package io.dataease.template.service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.dataease.api.template.dto.TemplateManageDTO; +import io.dataease.api.template.request.TemplateManageRequest; +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.mapper.VisualizationTemplateMapper; +import io.dataease.template.dao.ext.ExtVisualizationTemplateMapper; +import io.dataease.utils.AuthUtils; +import io.dataease.utils.BeanUtils; +import io.dataease.visualization.server.StaticResourceServer; +import jakarta.annotation.Resource; +import org.apache.commons.lang3.StringUtils; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import static io.dataease.constant.StaticResourceConstants.UPLOAD_URL_PREFIX; + +/** + * @author : WangJiaHao + * @date : 2023/11/7 13:29 + */ +public class TemplateManageService { + + @Resource + private VisualizationTemplateMapper templateMapper; + @Resource + private ExtVisualizationTemplateMapper extTemplateMapper; + @Resource + private StaticResourceServer staticResourceServer; + + public List templateList(TemplateManageRequest request) { + request.setWithBlobs("N"); + List templateList = extTemplateMapper.findTemplateList(request); + if (request.getWithChildren()) { + getTreeChildren(templateList); + } + return templateList; + } + + public void getTreeChildren(List parentTemplateList) { + Optional.ofNullable(parentTemplateList).ifPresent(parent -> parent.forEach(parentTemplate -> { + List panelTemplateDTOChildren = extTemplateMapper.findTemplateList(new TemplateManageRequest(parentTemplate.getId())); + parentTemplate.setChildren(panelTemplateDTOChildren); + getTreeChildren(panelTemplateDTOChildren); + })); + } + + public List getSystemTemplateType(TemplateManageRequest request) { + return extTemplateMapper.findTemplateList(request); + } + + @Transactional + public TemplateManageDTO save(TemplateManageRequest request) { + if (StringUtils.isEmpty(request.getId())) { + 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()); + String snapshotName = "template-" + request.getId() + ".jpeg"; + staticResourceServer.saveSingleFileToServe(snapshotName, request.getSnapshot().replace("data:image/jpeg;base64,", "")); + request.setSnapshot("/" + UPLOAD_URL_PREFIX + '/' + snapshotName); + } + + 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); + } + TemplateManageDTO templateManageDTO = new TemplateManageDTO(); + BeanUtils.copyBean(templateManageDTO, request); + templateManageDTO.setLabel(request.getName()); + return templateManageDTO; + } + + //名称检查 + public String nameCheck(String optType, String name, String pid, 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); + } + List templateList = templateMapper.selectList(wrapper); + if (CollectionUtils.isEmpty(templateList)) { + return CommonConstants.CHECK_RESULT.NONE; + } else { + return CommonConstants.CHECK_RESULT.EXIST_ALL; + } + } + + public String nameCheck(TemplateManageRequest request) { + return nameCheck(request.getOptType(), request.getName(), request.getPid(), request.getId()); + + } + + public void delete(String id) { + Assert.notNull(id, "id cannot be null"); + templateMapper.deleteById(id); + } + + public VisualizationTemplateVO findOne(String panelId) { + VisualizationTemplate template = templateMapper.selectById(panelId); + if(template != null){ + VisualizationTemplateVO templateVO = new VisualizationTemplateVO(); + BeanUtils.copyBean(templateVO,template); + return templateVO; + }else{ + return null; + } + } + + public List find(TemplateManageRequest request) { + return extTemplateMapper.findTemplateList(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 new file mode 100644 index 0000000000..4bff33b67d --- /dev/null +++ b/core/core-backend/src/main/resources/db/desktop/V2.1__ddl.sql @@ -0,0 +1,17 @@ +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='模板表'; \ No newline at end of file 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 new file mode 100644 index 0000000000..4bff33b67d --- /dev/null +++ b/core/core-backend/src/main/resources/db/migration/V2.1__ddl.sql @@ -0,0 +1,17 @@ +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='模板表'; \ No newline at end of file diff --git a/core/core-frontend/src/components/data-visualization/RealTimeComponentTreeList.vue b/core/core-frontend/src/components/data-visualization/RealTimeComponentTreeList.vue new file mode 100644 index 0000000000..98e516e4b0 --- /dev/null +++ b/core/core-frontend/src/components/data-visualization/RealTimeComponentTreeList.vue @@ -0,0 +1,494 @@ + + + + + + + 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 a702967020..6716678803 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 @@ -1,8 +1,9 @@ package io.dataease.api.template; import io.dataease.api.template.dto.TemplateManageDTO; +import io.dataease.api.template.request.TemplateManageRequest; +import io.dataease.api.template.vo.VisualizationTemplateVO; import org.springframework.web.bind.annotation.*; - import java.util.List; public interface TemplateManageApi { @@ -10,4 +11,19 @@ public interface TemplateManageApi { @PostMapping("/templateList") List templateList(); + @PostMapping("/save") + TemplateManageDTO save(@RequestBody TemplateManageRequest request); + + @DeleteMapping("/delete/{id}") + void delete(@PathVariable String id); + + @GetMapping("/findOne/{id}") + VisualizationTemplateVO findOne(@PathVariable String id) throws Exception; + + @PostMapping("/find") + List find(@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 a1f43cd40e..3942345561 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 @@ -1,15 +1,20 @@ package io.dataease.api.template.dto; +import io.dataease.api.template.vo.VisualizationTemplateVO; import lombok.Data; +import java.util.List; @Data -public class TemplateManageDTO { +public class TemplateManageDTO extends VisualizationTemplateVO { private String label; + private Integer childrenCount; + private List children; + } 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 new file mode 100644 index 0000000000..bce7bc15fc --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/template/request/TemplateManageRequest.java @@ -0,0 +1,29 @@ +package io.dataease.api.template.request; + +import io.dataease.api.template.vo.VisualizationTemplateVO; +import lombok.Data; + +/** + * Author: wangjiahao + * Date: 2021-03-05 + * Description: + */ +@Data +public class TemplateManageRequest extends VisualizationTemplateVO { + private String sort; + private String withBlobs="N"; + + private String optType; + + private String staticResource; + + private Boolean withChildren = false; + + public TemplateManageRequest() { + } + + public TemplateManageRequest(String pid) { + super.setPid(pid); + withBlobs="N"; + } +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/template/vo/VisualizationTemplateVO.java b/sdk/api/api-base/src/main/java/io/dataease/api/template/vo/VisualizationTemplateVO.java new file mode 100644 index 0000000000..cf68b2c5b4 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/template/vo/VisualizationTemplateVO.java @@ -0,0 +1,76 @@ +package io.dataease.api.template.vo; + +import lombok.Data; + +/** + * @author : WangJiaHao + * @date : 2023/11/7 13:22 + */ +@Data +public class VisualizationTemplateVO { + + /** + * 主键 + */ + 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; + + /** + * 模版类型 system 系统内置 self 用户自建 + */ + private String templateType; + + /** + * template 样式 + */ + private String templateStyle; + + /** + * template 数据 + */ + private String templateData; + + /** + * 预存数据 + */ + private String dynamicData; +} diff --git a/sdk/common/src/main/java/io/dataease/constant/CommonConstants.java b/sdk/common/src/main/java/io/dataease/constant/CommonConstants.java new file mode 100644 index 0000000000..652fa25c28 --- /dev/null +++ b/sdk/common/src/main/java/io/dataease/constant/CommonConstants.java @@ -0,0 +1,82 @@ +package io.dataease.constant; + +/** + * Author: wangjiahao + * Description: + */ +public class CommonConstants { + + + //操作类型 + public static final class OPT_TYPE { + + public static final String INSERT = "insert"; + + public static final String UPDATE = "update"; + + public static final String DELETE = "delete"; + + public static final String SELECT = "select"; + + } + + //操作类型 + public static final class CHECK_RESULT { + + // 不存在 + public static final String NONE = "none"; + + // 全局存在 + public static final String EXIST_ALL = "exist_all"; + + // 当前用户存在 + public static final String EXIST_USER = "exist_user"; + + // 其他用户存在 + public static final String EXIST_OTHER = "exist_other"; + + } + + //视图数据查询来源 + public static final class VIEW_QUERY_FROM { + + // 仪表板 + public static final String PANEL = "panel"; + + // 仪表板编辑 + public static final String PANEL_EDIT = "panel_edit"; + + } + + //视图数据查询模式 + public static final class VIEW_RESULT_MODE { + + // 所有 + public static final String ALL = "all"; + + // 自定义 + public static final String CUSTOM = "custom"; + } + + //视图数据查询来源 + public static final class VIEW_EDIT_FROM { + + // 仪表板 + public static final String PANEL = "panel"; + + // 仪表板编辑 + public static final String CACHE = "cache"; + + } + + //视图数据读取来源 + public static final class VIEW_DATA_FROM { + + // 模板数据 + public static final String TEMPLATE = "template"; + + //数据集数据 + public static final String CHART = "dataset"; + + } +}